From 53db386731422c88d4e24e299e9e56a150dad3cf Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Aug 2020 22:06:30 -0600 Subject: [PATCH 0001/2651] Add support for blurhash (MSC2448) MSC: https://github.com/matrix-org/matrix-doc/pull/2448 While the image loads, we can show a blurred version of it (calculated at upload time) so we don't have a blank space in the timeline. --- package.json | 1 + src/ContentMessages.tsx | 10 +++- .../views/elements/BlurhashPlaceholder.tsx | 56 +++++++++++++++++++ src/components/views/messages/MImageBody.js | 18 +++--- yarn.lock | 5 ++ 5 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 src/components/views/elements/BlurhashPlaceholder.tsx diff --git a/package.json b/package.json index 548b33f353..989672d414 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@babel/runtime": "^7.10.5", "await-lock": "^2.0.1", "blueimp-canvas-to-blob": "^3.27.0", + "blurhash": "^1.1.3", "browser-encrypt-attachment": "^0.3.0", "browser-request": "^0.3.3", "classnames": "^2.2.6", diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index 6f55a75d0c..7e57b34ff7 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -334,6 +334,7 @@ function uploadFile(matrixClient: MatrixClient, roomId: string, file: File | Blo if (file.type) { encryptInfo.mimetype = file.type; } + // TODO: Blurhash for encrypted media? return {"file": encryptInfo}; }); (prom as IAbortablePromise).abort = () => { @@ -344,11 +345,15 @@ function uploadFile(matrixClient: MatrixClient, roomId: string, file: File | Blo } else { const basePromise = matrixClient.uploadContent(file, { progressHandler: progressHandler, + onlyContentUri: false, }); - const promise1 = basePromise.then(function(url) { + const promise1 = basePromise.then(function(body) { if (canceled) throw new UploadCanceledError(); // If the attachment isn't encrypted then include the URL directly. - return {"url": url}; + return { + "url": body.content_uri, + "blurhash": body["xyz.amorgan.blurhash"], // TODO: Use `body.blurhash` when MSC2448 lands + }; }); promise1.abort = () => { canceled = true; @@ -550,6 +555,7 @@ export default class ContentMessages { return upload.promise.then(function(result) { content.file = result.file; content.url = result.url; + content.info['xyz.amorgan.blurhash'] = result.blurhash; // TODO: Use `blurhash` when MSC2448 lands }); }).then(() => { // Await previous message being sent into the room diff --git a/src/components/views/elements/BlurhashPlaceholder.tsx b/src/components/views/elements/BlurhashPlaceholder.tsx new file mode 100644 index 0000000000..bed45bfe5a --- /dev/null +++ b/src/components/views/elements/BlurhashPlaceholder.tsx @@ -0,0 +1,56 @@ +/* + Copyright 2020 The Matrix.org Foundation C.I.C. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import React from 'react'; +import {decode} from "blurhash"; + +interface IProps { + blurhash: string; + width: number; + height: number; +} + +export default class BlurhashPlaceholder extends React.PureComponent { + private canvas: React.RefObject = React.createRef(); + + public componentDidMount() { + this.draw(); + } + + public componentDidUpdate() { + this.draw(); + } + + private draw() { + if (!this.canvas.current) return; + + try { + const {width, height} = this.props; + + const pixels = decode(this.props.blurhash, Math.ceil(width), Math.ceil(height)); + const ctx = this.canvas.current.getContext("2d"); + const imgData = ctx.createImageData(width, height); + imgData.data.set(pixels); + ctx.putImageData(imgData, 0, 0); + } catch (e) { + console.error("Error rendering blurhash: ", e); + } + } + + public render() { + return ; + } +} diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index c92ae475bf..e0ac24c641 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -27,6 +27,7 @@ import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import InlineSpinner from '../elements/InlineSpinner'; +import BlurhashPlaceholder from "../elements/BlurhashPlaceholder"; export default class MImageBody extends React.Component { static propTypes = { @@ -53,6 +54,8 @@ export default class MImageBody extends React.Component { this.onClick = this.onClick.bind(this); this._isGif = this._isGif.bind(this); + const imageInfo = this.props.mxEvent.getContent().info; + this.state = { decryptedUrl: null, decryptedThumbnailUrl: null, @@ -63,6 +66,7 @@ export default class MImageBody extends React.Component { loadedImageDimensions: null, hover: false, showImage: SettingsStore.getValue("showImages"), + blurhash: imageInfo ? imageInfo['xyz.amorgan.blurhash'] : null, // TODO: Use `blurhash` when MSC2448 lands. }; this._image = createRef(); @@ -329,7 +333,8 @@ export default class MImageBody extends React.Component { infoWidth = content.info.w; infoHeight = content.info.h; } else { - // Whilst the image loads, display nothing. + // Whilst the image loads, display nothing. We also don't display a blurhash image + // because we don't really know what size of image we'll end up with. // // Once loaded, use the loaded image dimensions stored in `loadedImageDimensions`. // @@ -368,8 +373,7 @@ export default class MImageBody extends React.Component { if (content.file !== undefined && this.state.decryptedUrl === null) { placeholder = ; } else if (!this.state.imgLoaded) { - // Deliberately, getSpinner is left unimplemented here, MStickerBody overides - placeholder = this.getPlaceholder(); + placeholder = this.getPlaceholder(maxWidth, maxHeight); } let showPlaceholder = Boolean(placeholder); @@ -391,7 +395,7 @@ export default class MImageBody extends React.Component { if (!this.state.showImage) { img = ; - showPlaceholder = false; // because we're hiding the image, so don't show the sticker icon. + showPlaceholder = false; // because we're hiding the image, so don't show the placeholder. } if (this._isGif() && !SettingsStore.getValue("autoplayGifsAndVideos") && !this.state.hover) { @@ -433,9 +437,9 @@ export default class MImageBody extends React.Component { } // Overidden by MStickerBody - getPlaceholder() { - // MImageBody doesn't show a placeholder whilst the image loads, (but it could do) - return null; + getPlaceholder(width, height) { + if (!this.state.blurhash) return null; + return ; } // Overidden by MStickerBody diff --git a/yarn.lock b/yarn.lock index 98fe42ef13..f1cace67a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2493,6 +2493,11 @@ blueimp-canvas-to-blob@^3.27.0: resolved "https://registry.yarnpkg.com/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.27.0.tgz#a2bd5c43587b95dedf0f6998603452d1bfcc9b9e" integrity sha512-AcIj+hCw6WquxzJuzC6KzgYmqxLFeTWe88KuY2BEIsW1zbEOfoinDAGlhyvFNGt+U3JElkVSK7anA1FaSdmmfA== +blurhash@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.1.3.tgz#dc325af7da836d07a0861d830bdd63694382483e" + integrity sha512-yUhPJvXexbqbyijCIE/T2NCXcj9iNPhWmOKbPTuR/cm7Q5snXYIfnVnz6m7MWOXxODMz/Cr3UcVkRdHiuDVRDw== + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: version "4.11.9" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" From 7d22bbc00f49356cd5fec3565a19376ef8b0ef05 Mon Sep 17 00:00:00 2001 From: Bryan Kok Date: Sat, 17 Oct 2020 23:52:18 +0800 Subject: [PATCH 0002/2651] Trim spurious whitespace of nicknames --- src/components/views/settings/ProfileSettings.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js index 92851ccaa0..294f80acd1 100644 --- a/src/components/views/settings/ProfileSettings.js +++ b/src/components/views/settings/ProfileSettings.js @@ -77,10 +77,12 @@ export default class ProfileSettings extends React.Component { const client = MatrixClientPeg.get(); const newState = {}; + const displayName = this.state.displayName.trim(); try { if (this.state.originalDisplayName !== this.state.displayName) { - await client.setDisplayName(this.state.displayName); - newState.originalDisplayName = this.state.displayName; + await client.setDisplayName(displayName); + newState.originalDisplayName = displayName; + newState.displayName = displayName; } if (this.state.avatarFile) { From fcbaea640daf3a036d55cb1bda5d7fed552c2d4e Mon Sep 17 00:00:00 2001 From: Bryan Kok Date: Sun, 18 Oct 2020 14:36:50 +0800 Subject: [PATCH 0003/2651] Trim room names changed through the UI --- src/components/views/room_settings/RoomProfileSettings.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/room_settings/RoomProfileSettings.js b/src/components/views/room_settings/RoomProfileSettings.js index ca09c3093a..b894663c16 100644 --- a/src/components/views/room_settings/RoomProfileSettings.js +++ b/src/components/views/room_settings/RoomProfileSettings.js @@ -95,10 +95,11 @@ export default class RoomProfileSettings extends React.Component { const newState = {}; // TODO: What do we do about errors? - + const displayName = this.state.displayName.trim(); if (this.state.originalDisplayName !== this.state.displayName) { - await client.setRoomName(this.props.roomId, this.state.displayName); - newState.originalDisplayName = this.state.displayName; + await client.setRoomName(this.props.roomId, displayName); + newState.originalDisplayName = displayName; + newState.displayName = displayName; } if (this.state.avatarFile) { From e33f4ba9c0e8c29cf074f566cbb69c27007f6c57 Mon Sep 17 00:00:00 2001 From: Resynth Date: Sun, 25 Oct 2020 22:04:39 +0000 Subject: [PATCH 0004/2651] Warn on Access Token reveal Signed-off-by: Resynth --- .../views/dialogs/AccessTokenDialog.tsx | 39 +++++++++++++++++++ .../settings/tabs/user/HelpUserSettingsTab.js | 14 ++++++- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/components/views/dialogs/AccessTokenDialog.tsx diff --git a/src/components/views/dialogs/AccessTokenDialog.tsx b/src/components/views/dialogs/AccessTokenDialog.tsx new file mode 100644 index 0000000000..81c48f219a --- /dev/null +++ b/src/components/views/dialogs/AccessTokenDialog.tsx @@ -0,0 +1,39 @@ + /* +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 React from 'react'; +import { _t } from '../../../languageHandler'; +import QuestionDialog from './QuestionDialog'; + +type IProps = Exclude< + React.ComponentProps, + "title" | "danger" | "description" + >; + +export default function AccessTokenDialog (props: IProps) { + return ( + + ); +} diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js index 85ba22a353..585a54ff86 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js @@ -27,6 +27,7 @@ import * as sdk from "../../../../../"; import PlatformPeg from "../../../../../PlatformPeg"; import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts"; import UpdateCheckButton from "../../UpdateCheckButton"; +import AccessTokenDialog from '../../../dialogs/AccessTokenDialog'; export default class HelpUserSettingsTab extends React.Component { static propTypes = { @@ -148,6 +149,17 @@ export default class HelpUserSettingsTab extends React.Component { ); } + onAccessTokenSpoilerClick = async (event) => { + // React throws away the event before we can use it (we are async, after all). + event.persist(); + + // We make the user accept a scary popup to combat Social Engineering. No peeking! + await Modal.createTrackedDialog('Reveal Access Token', '', AccessTokenDialog).finished; + + // Pass it onto the handler. + this._showSpoiler(event); + } + render() { const brand = SdkConfig.get().brand; @@ -266,7 +278,7 @@ export default class HelpUserSettingsTab extends React.Component { {_t("Homeserver is")} {MatrixClientPeg.get().getHomeserverUrl()}
{_t("Identity Server is")} {MatrixClientPeg.get().getIdentityServerUrl()}
{_t("Access Token:") + ' '} - <{ _t("click to reveal") }> From ae29168e077be47a83628f10b7765d6bcc9a7a0a Mon Sep 17 00:00:00 2001 From: Resynth Date: Sun, 25 Oct 2020 22:05:44 +0000 Subject: [PATCH 0005/2651] Lint Signed-off-by: Resynth --- src/components/views/dialogs/AccessTokenDialog.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/AccessTokenDialog.tsx b/src/components/views/dialogs/AccessTokenDialog.tsx index 81c48f219a..f95effd523 100644 --- a/src/components/views/dialogs/AccessTokenDialog.tsx +++ b/src/components/views/dialogs/AccessTokenDialog.tsx @@ -1,4 +1,4 @@ - /* +/* Copyright 2017 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,7 @@ type IProps = Exclude< "title" | "danger" | "description" >; -export default function AccessTokenDialog (props: IProps) { +export default function AccessTokenDialog(props: IProps) { return ( ); From 76edd551e5833cb1c94c1025fa069aeb79a9faa2 Mon Sep 17 00:00:00 2001 From: Resynth Date: Mon, 26 Oct 2020 00:34:14 +0000 Subject: [PATCH 0006/2651] Fix i18n Signed-off-by: Resynth --- src/i18n/strings/en_EN.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index eda69d68ea..ad6593f704 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1585,6 +1585,7 @@ "Add a new server...": "Add a new server...", "%(networkName)s rooms": "%(networkName)s rooms", "Matrix rooms": "Matrix rooms", + "Do not reveal your Access Token to anyone, under any circumstances. Sharing your Access Token with someone would allow them to login to your account, and access your private information.": "Do not reveal your Access Token to anyone, under any circumstances. Sharing your Access Token with someone would allow them to login to your account, and access your private information.", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Room ID", "email address": "email address", From a3212c0477ec0fc9166a56a49a9579bae4712d5f Mon Sep 17 00:00:00 2001 From: Resynth Date: Mon, 26 Oct 2020 23:46:53 +0000 Subject: [PATCH 0007/2651] Fix weird formatting Signed-off-by: Resynth --- src/components/views/dialogs/AccessTokenDialog.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/AccessTokenDialog.tsx b/src/components/views/dialogs/AccessTokenDialog.tsx index f95effd523..2d96d8ec20 100644 --- a/src/components/views/dialogs/AccessTokenDialog.tsx +++ b/src/components/views/dialogs/AccessTokenDialog.tsx @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2020 Resynth Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +22,7 @@ import QuestionDialog from './QuestionDialog'; type IProps = Exclude< React.ComponentProps, "title" | "danger" | "description" - >; +>; export default function AccessTokenDialog(props: IProps) { return ( From 29a81bbe85ca1ca1c4c54534fe94e9d477aef22c Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 10 Nov 2020 15:04:01 -0600 Subject: [PATCH 0008/2651] Warn when you attempt to leave room that you are the only member of Signed-off-by: Aaron Raimist --- src/components/structures/MatrixChat.tsx | 17 ++++++++++++++++- src/i18n/strings/en_EN.json | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 22cd73eff7..43e1798c6e 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1056,8 +1056,21 @@ export default class MatrixChat extends React.PureComponent { private leaveRoomWarnings(roomId: string) { const roomToLeave = MatrixClientPeg.get().getRoom(roomId); // Show a warning if there are additional complications. - const joinRules = roomToLeave.currentState.getStateEvents('m.room.join_rules', ''); const warnings = []; + + const memberCount = roomToLeave.currentState.getJoinedMemberCount(); + if (memberCount === 1) { + warnings.push( + + {' '/* Whitespace, otherwise the sentences get smashed together */ } + { _t("You are the only member of this room. This room will become unjoinable if you leave.") } + + ); + + return warnings; + } + + const joinRules = roomToLeave.currentState.getStateEvents('m.room.join_rules', ''); if (joinRules) { const rule = joinRules.getContent().join_rule; if (rule !== "public") { @@ -1076,6 +1089,7 @@ export default class MatrixChat extends React.PureComponent { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const roomToLeave = MatrixClientPeg.get().getRoom(roomId); const warnings = this.leaveRoomWarnings(roomId); + const hasWarnings = warnings.length > 0; Modal.createTrackedDialog('Leave room', '', QuestionDialog, { title: _t("Leave room"), @@ -1086,6 +1100,7 @@ export default class MatrixChat extends React.PureComponent { ), button: _t("Leave"), + danger: hasWarnings, onFinished: (shouldLeave) => { if (shouldLeave) { const d = leaveRoomBehaviour(roomId); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 78340447f3..b412db5ca0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2317,6 +2317,7 @@ "Cannot create rooms in this community": "Cannot create rooms in this community", "You do not have permission to create rooms in this community.": "You do not have permission to create rooms in this community.", "This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite.", + "You are the only member of this room. This room will become unjoinable if you leave.": "You are the only member of this room. This room will become unjoinable if you leave.", "Are you sure you want to leave the room '%(roomName)s'?": "Are you sure you want to leave the room '%(roomName)s'?", "Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s", "Signed Out": "Signed Out", From 80c4d54ccc56396e15a4979de84d9d18c83a70ad Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Wed, 18 Nov 2020 13:54:49 -0600 Subject: [PATCH 0009/2651] Fix lint Signed-off-by: Aaron Raimist --- src/components/structures/MatrixChat.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 43e1798c6e..17c21a2016 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1060,12 +1060,12 @@ export default class MatrixChat extends React.PureComponent { const memberCount = roomToLeave.currentState.getJoinedMemberCount(); if (memberCount === 1) { - warnings.push( + warnings.push(( {' '/* Whitespace, otherwise the sentences get smashed together */ } { _t("You are the only member of this room. This room will become unjoinable if you leave.") } - ); + )); return warnings; } From 34fbed3fbbbbb0ffc17a15631d256b855080b1ee Mon Sep 17 00:00:00 2001 From: Qt Resynth Date: Fri, 20 Nov 2020 01:15:58 +0000 Subject: [PATCH 0010/2651] Update src/components/views/dialogs/AccessTokenDialog.tsx --- src/components/views/dialogs/AccessTokenDialog.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/dialogs/AccessTokenDialog.tsx b/src/components/views/dialogs/AccessTokenDialog.tsx index 2d96d8ec20..6a943eb5a8 100644 --- a/src/components/views/dialogs/AccessTokenDialog.tsx +++ b/src/components/views/dialogs/AccessTokenDialog.tsx @@ -31,9 +31,7 @@ export default function AccessTokenDialog(props: IProps) { title="Reveal Access Token" danger={true} description={_t( - "Do not reveal your Access Token to anyone, under any circumstances. " + - "Sharing your Access Token with someone would allow them to login to " + - "your account, and access your private information.", + "Your access token gives full access to your account. Do not share it with anyone." )} > ); From 0e4d656e4bfc0fd16d4628ac44668f6aa2f5ae83 Mon Sep 17 00:00:00 2001 From: Resynth Date: Fri, 20 Nov 2020 18:21:39 +0000 Subject: [PATCH 0011/2651] Update src/i18n/strings/en_EN.json --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ad6593f704..8005f1cdef 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1585,7 +1585,7 @@ "Add a new server...": "Add a new server...", "%(networkName)s rooms": "%(networkName)s rooms", "Matrix rooms": "Matrix rooms", - "Do not reveal your Access Token to anyone, under any circumstances. Sharing your Access Token with someone would allow them to login to your account, and access your private information.": "Do not reveal your Access Token to anyone, under any circumstances. Sharing your Access Token with someone would allow them to login to your account, and access your private information.", + "Your access token gives full access to your account. Do not share it with anyone.", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Room ID", "email address": "email address", From 1b48b08525f75035b9a09993124a12d442d0f2e2 Mon Sep 17 00:00:00 2001 From: Resynth Date: Fri, 20 Nov 2020 18:23:18 +0000 Subject: [PATCH 0012/2651] Update src/i18n/strings/en_EN.json --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8005f1cdef..a57a68e7b4 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1585,7 +1585,7 @@ "Add a new server...": "Add a new server...", "%(networkName)s rooms": "%(networkName)s rooms", "Matrix rooms": "Matrix rooms", - "Your access token gives full access to your account. Do not share it with anyone.", + "Your access token gives full access to your account. Do not share it with anyone.": "Your access token gives full access to your account. Do not share it with anyone.", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Room ID", "email address": "email address", From d44aab6d321d04deb6733d9ace5f54b5fe1104bf Mon Sep 17 00:00:00 2001 From: Resynth Date: Mon, 23 Nov 2020 12:57:06 +0000 Subject: [PATCH 0013/2651] Update src/components/views/dialogs/AccessTokenDialog.tsx Co-authored-by: Michael Telatynski <7t3chguy@googlemail.com> --- src/components/views/dialogs/AccessTokenDialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/AccessTokenDialog.tsx b/src/components/views/dialogs/AccessTokenDialog.tsx index 6a943eb5a8..c0b1b929df 100644 --- a/src/components/views/dialogs/AccessTokenDialog.tsx +++ b/src/components/views/dialogs/AccessTokenDialog.tsx @@ -31,7 +31,7 @@ export default function AccessTokenDialog(props: IProps) { title="Reveal Access Token" danger={true} description={_t( - "Your access token gives full access to your account. Do not share it with anyone." + "Your access token gives full access to your account. Do not share it with anyone.", )} >
); From 2f988bc97fc1e414bd70149ac5f77301a3ef2833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 26 Nov 2020 13:51:03 +0100 Subject: [PATCH 0014/2651] Added UI --- .../views/settings/SpellCheckSettings.tsx | 111 ++++++++++++++++++ .../tabs/user/GeneralUserSettingsTab.js | 18 +++ 2 files changed, 129 insertions(+) create mode 100644 src/components/views/settings/SpellCheckSettings.tsx diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx new file mode 100644 index 0000000000..1bdcd882c9 --- /dev/null +++ b/src/components/views/settings/SpellCheckSettings.tsx @@ -0,0 +1,111 @@ +/* +Copyright 2019 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import LanguageDropdown from "../../../components/views/elements/LanguageDropdown"; +import AccessibleButton from "../../../components/views/elements/AccessibleButton"; +import {_t} from "../../../languageHandler"; + +interface ExistingSpellCheckLanguageIProps { + language: string, + onRemoved(language: string), +}; + +interface SpellCheckLanguagesIProps { + languages: Array, + onLanguagesChange(languages: Array), +}; + +interface SpellCheckLanguagesIState { + newLanguage: string, +} + +export class ExistingSpellCheckLanguage extends React.Component { + _onRemove = (e) => { + e.stopPropagation(); + e.preventDefault(); + + return this.props.onRemoved(this.props.language); + }; + + render() { + return ( +
+ {this.props.language} + + {_t("Remove")} + +
+ ); + } +} + +export default class SpellCheckLanguages extends React.Component { + constructor(props) { + super(props); + this.state = { + newLanguage: "", + } + } + + _onRemoved = (language) => { + const languages = this.props.languages.filter((e) => e !== language); + this.props.onLanguagesChange(languages); + }; + + _onAddClick = (e) => { + e.stopPropagation(); + e.preventDefault(); + + const language = this.state.newLanguage; + + if (!language) return; + if (this.props.languages.includes(language)) return; + + this.props.languages.push(language) + this.props.onLanguagesChange(this.props.languages); + }; + + _onNewLanguageChange = (language: string) => { + if (this.state.newLanguage === language) return; + this.setState({newLanguage: language}); + }; + + render() { + const existingSpellCheckLanguages = this.props.languages.map((e) => { + return ; + }); + + let addButton = ( + + {_t("Add")} + + ); + + return ( +
+ {existingSpellCheckLanguages} +
+ + {addButton} + +
+ ); + }; +} diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 35285351ab..6d04d83047 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -22,6 +22,7 @@ import ProfileSettings from "../../ProfileSettings"; import * as languageHandler from "../../../../../languageHandler"; import SettingsStore from "../../../../../settings/SettingsStore"; import LanguageDropdown from "../../../elements/LanguageDropdown"; +import SpellCheckSettings from "../../SpellCheckSettings" import AccessibleButton from "../../../elements/AccessibleButton"; import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog"; import PropTypes from "prop-types"; @@ -49,6 +50,7 @@ export default class GeneralUserSettingsTab extends React.Component { this.state = { language: languageHandler.getCurrentLanguage(), + spellCheckLanguages: [], haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()), serverSupportsSeparateAddAndBind: null, idServerHasUnsignedTerms: false, @@ -182,6 +184,10 @@ export default class GeneralUserSettingsTab extends React.Component { PlatformPeg.get().reload(); }; + _onSpellCheckLanguagesChange = (languages) => { + this.setState({spellCheckLanguages: languages}) + }; + _onPasswordChangeError = (err) => { // TODO: Figure out a design that doesn't involve replacing the current dialog let errMsg = err.error || ""; @@ -303,6 +309,17 @@ export default class GeneralUserSettingsTab extends React.Component { ); } + _renderSpellCheckSection() { + return ( +
+ {_t("Spell checking")} + +
+ ); + } + _renderDiscoverySection() { const SetIdServer = sdk.getComponent("views.settings.SetIdServer"); @@ -409,6 +426,7 @@ export default class GeneralUserSettingsTab extends React.Component { {this._renderProfileSection()} {this._renderAccountSection()} {this._renderLanguageSection()} + {this._renderSpellCheckSection()} { discoverySection } {this._renderIntegrationManagerSection() /* Has its own title */} { accountManagementSection } From 051368eaab50e4a7d6f2ce554ddff0ed957bb965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 26 Nov 2020 13:53:22 +0100 Subject: [PATCH 0015/2651] Fix i18n --- src/i18n/strings/en_EN.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0d50128f32..7fbcc1a350 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1109,6 +1109,7 @@ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Use an Integration Manager to manage bots, widgets, and sticker packs.", "Manage integrations": "Manage integrations", "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.", + "Add": "Add", "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", "Checking for an update...": "Checking for an update...", "No update available.": "No update available.", @@ -1140,6 +1141,7 @@ "Set a new account password...": "Set a new account password...", "Account": "Account", "Language and region": "Language and region", + "Spell checking": "Spell checking", "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.", "Account management": "Account management", "Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!", @@ -1337,7 +1339,6 @@ "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Unable to add email address": "Unable to add email address", - "Add": "Add", "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.", "Email Address": "Email Address", "Remove %(phone)s?": "Remove %(phone)s?", From 557e650a2c2e2eb24584f21bd4175e69cc7500a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 28 Nov 2020 19:37:49 +0100 Subject: [PATCH 0016/2651] Added spell-check-languages setting --- src/settings/Settings.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 31e133be72..409cd293d2 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -402,6 +402,10 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: "en", }, + "spell-check-languages": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, + default: [], + }, "breadcrumb_rooms": { // not really a setting supportedLevels: [SettingLevel.ACCOUNT], From 43daec03e24820a485f97da0b5cb0311f137e729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 28 Nov 2020 19:38:52 +0100 Subject: [PATCH 0017/2651] Added setSpellCheckLanguages() method --- src/languageHandler.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index b61f57d4b3..9b9e304294 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -346,6 +346,13 @@ export function setLanguage(preferredLangs: string | string[]) { }); } +export function setSpellCheckLanguages(preferredLangs: string[]) { + const plaf = PlatformPeg.get(); + if (plaf) { + plaf.setLanguage(preferredLangs); + } +} + export function getAllLanguagesFromJson() { return getLangsJson().then((langsObject) => { const langs = []; From 5e4f9907cf87e02b41791ce729b38d7474dcbf01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 28 Nov 2020 19:39:09 +0100 Subject: [PATCH 0018/2651] Added persistance --- .../views/settings/tabs/user/GeneralUserSettingsTab.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 6d04d83047..585f4fd5b7 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -50,7 +50,7 @@ export default class GeneralUserSettingsTab extends React.Component { this.state = { language: languageHandler.getCurrentLanguage(), - spellCheckLanguages: [], + spellCheckLanguages: SettingsStore.getValue("spell-check-languages", null, /*excludeDefault=*/true), haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()), serverSupportsSeparateAddAndBind: null, idServerHasUnsignedTerms: false, @@ -185,7 +185,9 @@ export default class GeneralUserSettingsTab extends React.Component { }; _onSpellCheckLanguagesChange = (languages) => { + SettingsStore.setValue("spell-check-languages", null, SettingLevel.DEVICE, languages); this.setState({spellCheckLanguages: languages}) + PlatformPeg.get().reload(); }; _onPasswordChangeError = (err) => { From f0bbed0c44270f8411c0ce0f4ee0cf08142a1c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Nov 2020 12:17:07 +0100 Subject: [PATCH 0019/2651] Allow default value --- .../views/settings/tabs/user/GeneralUserSettingsTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 585f4fd5b7..68a16463b0 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -50,7 +50,7 @@ export default class GeneralUserSettingsTab extends React.Component { this.state = { language: languageHandler.getCurrentLanguage(), - spellCheckLanguages: SettingsStore.getValue("spell-check-languages", null, /*excludeDefault=*/true), + spellCheckLanguages: SettingsStore.getValue("spell-check-languages", null, false), haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()), serverSupportsSeparateAddAndBind: null, idServerHasUnsignedTerms: false, From 8f40cd39fda1ee83ec6b177ba7935f913ed5a45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Nov 2020 12:29:05 +0100 Subject: [PATCH 0020/2651] Added styling --- res/css/_components.scss | 1 + .../views/settings/_SpellCheckLanguages.scss | 36 +++++++++++++++++++ .../views/settings/SpellCheckSettings.tsx | 9 +++-- .../tabs/user/GeneralUserSettingsTab.js | 7 ++-- 4 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 res/css/views/settings/_SpellCheckLanguages.scss diff --git a/res/css/_components.scss b/res/css/_components.scss index 445ed70ff4..1eb4b91a31 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -207,6 +207,7 @@ @import "./views/settings/_DevicesPanel.scss"; @import "./views/settings/_E2eAdvancedPanel.scss"; @import "./views/settings/_EmailAddresses.scss"; +@import "./views/settings/_SpellCheckLanguages.scss"; @import "./views/settings/_IntegrationManager.scss"; @import "./views/settings/_Notifications.scss"; @import "./views/settings/_PhoneNumbers.scss"; diff --git a/res/css/views/settings/_SpellCheckLanguages.scss b/res/css/views/settings/_SpellCheckLanguages.scss new file mode 100644 index 0000000000..734f669f0e --- /dev/null +++ b/res/css/views/settings/_SpellCheckLanguages.scss @@ -0,0 +1,36 @@ +/* +Copyright 2019 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ExistingSpellCheckLanguage { + display: flex; + align-items: center; + margin-bottom: 5px; +} + +.mx_ExistingSpellCheckLanguage_language { + flex: 1; + margin-right: 10px; +} + +.mx_GeneralUserSettingsTab_spellCheckLanguageInput { + margin-top: 1em; + margin-bottom: 1em; +} + +.mx_SpellCheckLanguages { + @mixin mx_Settings_fullWidthField; +} \ No newline at end of file diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx index 1bdcd882c9..befd98112e 100644 --- a/src/components/views/settings/SpellCheckSettings.tsx +++ b/src/components/views/settings/SpellCheckSettings.tsx @@ -43,8 +43,8 @@ export class ExistingSpellCheckLanguage extends React.Component - {this.props.language} +
+ {this.props.language} {_t("Remove")} @@ -96,10 +96,9 @@ export default class SpellCheckLanguages extends React.Component +
{existingSpellCheckLanguages} -
+ diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 68a16463b0..258ff6d318 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -313,11 +313,10 @@ export default class GeneralUserSettingsTab extends React.Component { _renderSpellCheckSection() { return ( -
+
{_t("Spell checking")} - +
); } From 7609f2004e6a004c22e0da189f58cee823bf4468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Nov 2020 13:22:50 +0100 Subject: [PATCH 0021/2651] Added newline to end --- res/css/views/settings/_SpellCheckLanguages.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/settings/_SpellCheckLanguages.scss b/res/css/views/settings/_SpellCheckLanguages.scss index 734f669f0e..ddfa0bf9e0 100644 --- a/res/css/views/settings/_SpellCheckLanguages.scss +++ b/res/css/views/settings/_SpellCheckLanguages.scss @@ -33,4 +33,4 @@ limitations under the License. .mx_SpellCheckLanguages { @mixin mx_Settings_fullWidthField; -} \ No newline at end of file +} From ead00dcdede9e6a24904599baba39bc91de0681a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Nov 2020 14:46:09 +0100 Subject: [PATCH 0022/2651] Set spell-check languages without reloading --- .../views/settings/tabs/user/GeneralUserSettingsTab.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 258ff6d318..ad7e04d677 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -187,7 +187,11 @@ export default class GeneralUserSettingsTab extends React.Component { _onSpellCheckLanguagesChange = (languages) => { SettingsStore.setValue("spell-check-languages", null, SettingLevel.DEVICE, languages); this.setState({spellCheckLanguages: languages}) - PlatformPeg.get().reload(); + + const plaf = PlatformPeg.get(); + if (plaf) { + plaf.setLanguage(languages); + } }; _onPasswordChangeError = (err) => { From 38080c5b2bccafb7dae5c9737e69ad7f295f1d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Nov 2020 20:46:47 +0100 Subject: [PATCH 0023/2651] Added getAvailableSpellCheckLanguages() methods --- src/BasePlatform.ts | 4 ++++ src/languageHandler.tsx | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index 0a1f06f0b3..9ac35092a7 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -237,6 +237,10 @@ export default abstract class BasePlatform { setLanguage(preferredLangs: string[]) {} + getAvailableSpellCheckLanguages(): Promise | null { + return null; + } + protected getSSOCallbackUrl(fragmentAfterLogin: string): URL { const url = new URL(window.location.href); url.hash = fragmentAfterLogin || ""; diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index 9b9e304294..b827e83ded 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -353,6 +353,11 @@ export function setSpellCheckLanguages(preferredLangs: string[]) { } } +export async function getAvailableSpellCheckLanguages(): Promise { + const plaf = PlatformPeg.get(); + return plaf.getAvailableSpellCheckLanguages(); +} + export function getAllLanguagesFromJson() { return getLangsJson().then((langsObject) => { const langs = []; From 5d9f5ba979d3fc89bf6eec5ad2f319bea7168aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 30 Nov 2020 08:35:51 +0100 Subject: [PATCH 0024/2651] Fix indentation --- src/components/views/elements/LanguageDropdown.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index e37109caff..03ec456af5 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -100,10 +100,10 @@ export default class LanguageDropdown extends React.Component { let language = SettingsStore.getValue("language", null, /*excludeDefault:*/true); let value = null; if (language) { - value = this.props.value || language; + value = this.props.value || language; } else { - language = navigator.language || navigator.userLanguage; - value = this.props.value || language; + language = navigator.language || navigator.userLanguage; + value = this.props.value || language; } return Date: Tue, 1 Dec 2020 16:59:02 +0100 Subject: [PATCH 0025/2651] Change label --- .../views/settings/tabs/user/GeneralUserSettingsTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index ad7e04d677..8d06ea3b36 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -318,7 +318,7 @@ export default class GeneralUserSettingsTab extends React.Component { _renderSpellCheckSection() { return (
- {_t("Spell checking")} + {_t("Spell check dictionaries")}
From cf61d50df40614a45c36c0d9886c3583ca69513e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 16:59:21 +0100 Subject: [PATCH 0026/2651] Added SpellCheckLanguagesDropdown --- .../elements/SpellCheckLanguagesDropdown.tsx | 125 ++++++++++++++++++ .../views/settings/SpellCheckSettings.tsx | 4 +- 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/components/views/elements/SpellCheckLanguagesDropdown.tsx diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx new file mode 100644 index 0000000000..db158fa3dd --- /dev/null +++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx @@ -0,0 +1,125 @@ +/* +Copyright 2017 Marcel Radzio (MTRNord) +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 React from 'react'; +import PropTypes from 'prop-types'; + +import Dropdown from "../../views/elements/Dropdown" +import PlatformPeg from "../../../PlatformPeg"; +import * as sdk from '../../../index'; +import * as languageHandler from '../../../languageHandler'; +import SettingsStore from "../../../settings/SettingsStore"; +import { _t } from "../../../languageHandler"; + +function languageMatchesSearchQuery(query, language) { + if (language.label.toUpperCase().includes(query.toUpperCase())) return true; + if (language.value.toUpperCase() === query.toUpperCase()) return true; + return false; +} + +interface SpellCheckLanguagesDropdownIProps { + className: string, + value: string, + onOptionChange(language: string), +}; + +interface SpellCheckLanguagesDropdownIState { + searchQuery: string, + languages: any, +} + +export default class SpellCheckLanguagesDropdown extends React.Component { + constructor(props) { + super(props); + this._onSearchChange = this._onSearchChange.bind(this); + + this.state = { + searchQuery: '', + languages: null, + }; + } + + componentDidMount() { + languageHandler.getAvailableSpellCheckLanguages().then((languages) => { + languages.sort(function(a, b) { + if (a < b) return -1; + if (a > b) return 1; + return 0; + }); + var langs = []; + languages.forEach((language) => { + langs.push({ + label: language, + value: language, + }) + }) + this.setState({languages: langs}); + }).catch((e) => { + this.setState({languages: ['en']}); + }); + } + + _onSearchChange(search) { + this.setState({ + searchQuery: search, + }); + } + + render() { + if (this.state.languages === null) { + const Spinner = sdk.getComponent('elements.Spinner'); + return ; + } + + let displayedLanguages; + if (this.state.searchQuery) { + displayedLanguages = this.state.languages.filter((lang) => { + return languageMatchesSearchQuery(this.state.searchQuery, lang); + }); + } else { + displayedLanguages = this.state.languages; + } + + const options = displayedLanguages.map((language) => { + return
+ { language.label } +
; + }); + + // default value here too, otherwise we need to handle null / undefined; + // values between mounting and the initial value propgating + let language = SettingsStore.getValue("language", null, /*excludeDefault:*/true); + let value = null; + if (language) { + value = this.props.value || language; + } else { + language = navigator.language || navigator.userLanguage; + value = this.props.value || language; + } + + return + { options } + ; + } +} diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx index befd98112e..37476d5f34 100644 --- a/src/components/views/settings/SpellCheckSettings.tsx +++ b/src/components/views/settings/SpellCheckSettings.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React from 'react'; -import LanguageDropdown from "../../../components/views/elements/LanguageDropdown"; +import SpellCheckLanguagesDropdown from "../../../components/views/elements/SpellCheckLanguagesDropdown"; import AccessibleButton from "../../../components/views/elements/AccessibleButton"; import {_t} from "../../../languageHandler"; @@ -99,7 +99,7 @@ export default class SpellCheckLanguages extends React.Component {existingSpellCheckLanguages} - {addButton} From a6d6af1a937fb6bc6cec2e320fbff453bef3c680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 17:19:45 +0100 Subject: [PATCH 0027/2651] Added defaults --- src/settings/Settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 409cd293d2..c83dbab897 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -404,7 +404,7 @@ export const SETTINGS: {[setting: string]: ISetting} = { }, "spell-check-languages": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - default: [], + default: ["en"], }, "breadcrumb_rooms": { // not really a setting From e9203d75715dbd6a677849dbb83a3d4706b2e6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 17:21:23 +0100 Subject: [PATCH 0028/2651] Removed unnecessary imports --- src/components/views/elements/SpellCheckLanguagesDropdown.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx index db158fa3dd..5e0fe3132c 100644 --- a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx +++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx @@ -16,10 +16,8 @@ limitations under the License. */ import React from 'react'; -import PropTypes from 'prop-types'; import Dropdown from "../../views/elements/Dropdown" -import PlatformPeg from "../../../PlatformPeg"; import * as sdk from '../../../index'; import * as languageHandler from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; From 8287f197f40869941d402e45da87c88d19514545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 19:49:31 +0100 Subject: [PATCH 0029/2651] Fix i18n --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 282c1ce686..9ccd0e1e75 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1149,7 +1149,7 @@ "Set a new account password...": "Set a new account password...", "Account": "Account", "Language and region": "Language and region", - "Spell checking": "Spell checking", + "Spell check dictionaries": "Spell check dictionaries", "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.", "Account management": "Account management", "Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!", From 44a363f188fb95927fff942b4c6b5a3914dbe31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 20:16:48 +0100 Subject: [PATCH 0030/2651] Fix default value --- src/settings/Settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index c83dbab897..3540767a99 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -404,7 +404,7 @@ export const SETTINGS: {[setting: string]: ISetting} = { }, "spell-check-languages": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - default: ["en"], + default: ["en-US"], }, "breadcrumb_rooms": { // not really a setting From 3c2bb6e4f6d19e337d902613adbddf42fcba2f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 20:17:24 +0100 Subject: [PATCH 0031/2651] Cleanup --- src/BasePlatform.ts | 2 ++ .../views/settings/tabs/user/GeneralUserSettingsTab.js | 5 +---- src/languageHandler.tsx | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index 9ac35092a7..2af2ea51c5 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -237,6 +237,8 @@ export default abstract class BasePlatform { setLanguage(preferredLangs: string[]) {} + setSpellCheckLanguages(preferredLangs: string[]) {} + getAvailableSpellCheckLanguages(): Promise | null { return null; } diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 8d06ea3b36..6ed887d749 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -188,10 +188,7 @@ export default class GeneralUserSettingsTab extends React.Component { SettingsStore.setValue("spell-check-languages", null, SettingLevel.DEVICE, languages); this.setState({spellCheckLanguages: languages}) - const plaf = PlatformPeg.get(); - if (plaf) { - plaf.setLanguage(languages); - } + languageHandler.setSpellCheckLanguages(languages); }; _onPasswordChangeError = (err) => { diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index b827e83ded..38d3c8347a 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -349,7 +349,7 @@ export function setLanguage(preferredLangs: string | string[]) { export function setSpellCheckLanguages(preferredLangs: string[]) { const plaf = PlatformPeg.get(); if (plaf) { - plaf.setLanguage(preferredLangs); + plaf.setSpellCheckLanguages(preferredLangs); } } From db5bc0cb7ade92fc056283af639e3c782d384e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 1 Dec 2020 20:36:25 +0100 Subject: [PATCH 0032/2651] Fix formatting --- .../elements/SpellCheckLanguagesDropdown.tsx | 7 ++++--- .../views/settings/SpellCheckSettings.tsx | 17 +++++++++-------- .../tabs/user/GeneralUserSettingsTab.js | 6 +++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx index 5e0fe3132c..53c3f310b7 100644 --- a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx +++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx @@ -33,14 +33,15 @@ interface SpellCheckLanguagesDropdownIProps { className: string, value: string, onOptionChange(language: string), -}; +} interface SpellCheckLanguagesDropdownIState { searchQuery: string, languages: any, } -export default class SpellCheckLanguagesDropdown extends React.Component { +export default class SpellCheckLanguagesDropdown extends React.Component { constructor(props) { super(props); this._onSearchChange = this._onSearchChange.bind(this); @@ -58,7 +59,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component b) return 1; return 0; }); - var langs = []; + const langs = []; languages.forEach((language) => { langs.push({ label: language, diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx index 37476d5f34..bfe0774570 100644 --- a/src/components/views/settings/SpellCheckSettings.tsx +++ b/src/components/views/settings/SpellCheckSettings.tsx @@ -22,12 +22,12 @@ import {_t} from "../../../languageHandler"; interface ExistingSpellCheckLanguageIProps { language: string, onRemoved(language: string), -}; +} interface SpellCheckLanguagesIProps { languages: Array, onLanguagesChange(languages: Array), -}; +} interface SpellCheckLanguagesIState { newLanguage: string, @@ -71,7 +71,7 @@ export default class SpellCheckLanguages extends React.Component; }); - let addButton = ( + const addButton = ( {_t("Add")} @@ -99,12 +99,13 @@ export default class SpellCheckLanguages extends React.Component {existingSpellCheckLanguages} - + {addButton}
); - }; + } } diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 6ed887d749..95a8abbb24 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -22,7 +22,7 @@ import ProfileSettings from "../../ProfileSettings"; import * as languageHandler from "../../../../../languageHandler"; import SettingsStore from "../../../../../settings/SettingsStore"; import LanguageDropdown from "../../../elements/LanguageDropdown"; -import SpellCheckSettings from "../../SpellCheckSettings" +import SpellCheckSettings from "../../SpellCheckSettings"; import AccessibleButton from "../../../elements/AccessibleButton"; import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog"; import PropTypes from "prop-types"; @@ -186,8 +186,8 @@ export default class GeneralUserSettingsTab extends React.Component { _onSpellCheckLanguagesChange = (languages) => { SettingsStore.setValue("spell-check-languages", null, SettingLevel.DEVICE, languages); - this.setState({spellCheckLanguages: languages}) - + this.setState({spellCheckLanguages: languages}); + languageHandler.setSpellCheckLanguages(languages); }; From bab541a652e402c1aede8caa00b22b13a2adb0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 2 Dec 2020 20:14:58 +0100 Subject: [PATCH 0033/2651] Hide spell-check settings if not using Electron --- src/BasePlatform.ts | 8 ++++++++ .../views/settings/tabs/user/GeneralUserSettingsTab.js | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index 2af2ea51c5..54d15675cb 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -128,6 +128,14 @@ export default abstract class BasePlatform { hideUpdateToast(); } + /** + * Return true if platform supports multi-language + * spell-checking, otherwise false. + */ + supportsMultiLanguageSpellCheck(): boolean { + return false; + } + /** * Returns true if the platform supports displaying * notifications, otherwise false. diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 95a8abbb24..4d1210dc40 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -400,6 +400,9 @@ export default class GeneralUserSettingsTab extends React.Component { } render() { + const plaf = PlatformPeg.get(); + const supportsMultiLanguageSpellCheck = plaf.supportsMultiLanguageSpellCheck() ? true : false; + const discoWarning = this.state.requiredPolicyInfo.hasTerms ? Date: Thu, 3 Dec 2020 11:50:08 +0100 Subject: [PATCH 0034/2651] Simplifie --- .../views/settings/tabs/user/GeneralUserSettingsTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 4d1210dc40..febbcc8e36 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -401,7 +401,7 @@ export default class GeneralUserSettingsTab extends React.Component { render() { const plaf = PlatformPeg.get(); - const supportsMultiLanguageSpellCheck = plaf.supportsMultiLanguageSpellCheck() ? true : false; + const supportsMultiLanguageSpellCheck = plaf.supportsMultiLanguageSpellCheck(); const discoWarning = this.state.requiredPolicyInfo.hasTerms ? Date: Thu, 3 Dec 2020 11:50:20 +0100 Subject: [PATCH 0035/2651] Added in if statement --- src/languageHandler.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index 38d3c8347a..985719fce7 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -355,7 +355,9 @@ export function setSpellCheckLanguages(preferredLangs: string[]) { export async function getAvailableSpellCheckLanguages(): Promise { const plaf = PlatformPeg.get(); - return plaf.getAvailableSpellCheckLanguages(); + if (plaf) { + return plaf.getAvailableSpellCheckLanguages(); + } } export function getAllLanguagesFromJson() { From 89bc4435945bfb207355cf5e5e290925f7d7f7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 16 Dec 2020 16:02:27 +0100 Subject: [PATCH 0036/2651] Fix file drop UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 2 +- res/css/structures/_RoomView.scss | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index ad1656efbb..3de68b000d 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -22,7 +22,7 @@ limitations under the License. } .mx_MainSplit > .mx_RightPanel_ResizeWrapper { - padding: 5px; + padding: 0 5px 5px 5px; // margin left to not allow the handle to not encroach on the space for the scrollbar margin-left: 8px; height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 572c7166d2..0a70b027ae 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -23,24 +23,21 @@ limitations under the License. .mx_RoomView_fileDropTarget { min-width: 0px; width: 100%; + height: 100%; + + margin-left: 6.25px; + font-size: $font-18px; text-align: center; pointer-events: none; - padding-left: 12px; - padding-right: 12px; - margin-left: -12px; - border-top-left-radius: 10px; border-top-right-radius: 10px; background-color: $droptarget-bg-color; - border: 2px #e1dddd solid; - border-bottom: none; + position: absolute; - top: 52px; - bottom: 0px; z-index: 3000; } From 41e2ffdf0df43104ef171b690b344a6e22b286f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 16 Dec 2020 19:51:49 +0100 Subject: [PATCH 0037/2651] Added background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 0a70b027ae..9292a400bc 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -39,13 +39,19 @@ limitations under the License. position: absolute; z-index: 3000; + + display: flex; + justify-content: center; + align-items: center; } .mx_RoomView_fileDropTargetLabel { - top: 50%; - width: 100%; - margin-top: -50px; position: absolute; + + border-radius: 10px; + padding: 10px; + + background-color: $menu-bg-color; } .mx_RoomView_auxPanel { From da97d18332c5740499913506b0e059e5b4c7616c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 16 Dec 2020 21:33:05 +0100 Subject: [PATCH 0038/2651] Added a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 9292a400bc..dd63be3a11 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -25,6 +25,7 @@ limitations under the License. width: 100%; height: 100%; + // This is an ugly fix for centering this element margin-left: 6.25px; font-size: $font-18px; From dcb30b72b0ed1adc6fb075ee9cc26ca0338177bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 17 Dec 2020 13:25:22 +0100 Subject: [PATCH 0039/2651] Fix left panel resizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 32 ++++++++++++++++---------- res/css/structures/_RoomView.scss | 12 ++++++---- src/components/structures/RoomView.tsx | 28 +++++++++++----------- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 3de68b000d..6875ef12e0 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -22,22 +22,30 @@ limitations under the License. } .mx_MainSplit > .mx_RightPanel_ResizeWrapper { - padding: 0 5px 5px 5px; - // margin left to not allow the handle to not encroach on the space for the scrollbar - margin-left: 8px; + padding: 0 5px 5px 0px; height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel + + .mx_RightPanel_ResizeHandle { + width: 9px; + } &:hover .mx_RightPanel_ResizeHandle { - // Need to use important to override element style attributes - // set by re-resizable - top: 50% !important; - transform: translate(0, -50%); + &::before { + position: absolute; + left: 6px; + top: 50%; + transform: translate(0, -50%); - height: 64px !important; // to match width of the ones on roomlist - width: 4px !important; - border-radius: 4px !important; + height: 64px; + width: 4px; + border-radius: 4px; - background-color: $primary-fg-color; - opacity: 0.8; + content: ' '; + + background-color: $primary-fg-color; + opacity: 0.8; + + margin-left: -10px; + } } } diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index dd63be3a11..0a12a86c33 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -25,9 +25,6 @@ limitations under the License. width: 100%; height: 100%; - // This is an ugly fix for centering this element - margin-left: 6.25px; - font-size: $font-18px; text-align: center; @@ -120,16 +117,23 @@ limitations under the License. height: 50px; } -.mx_RoomView_body { +.mx_RoomView_container { position: relative; //for .mx_RoomView_auxPanel_fullHeight display: flex; flex-direction: column; +} + +.mx_RoomView_body { + display: flex; + flex-direction: column; flex: 1; min-width: 0; .mx_RoomView_messagePanel, .mx_RoomView_messagePanelSpinner, .mx_RoomView_messagePanelSearchSpinner { order: 2; } + + margin-right: 10px; } .mx_RoomView_body .mx_RoomView_timeline { diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 0ee847fbc9..3d62c06e4b 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2003,22 +2003,24 @@ export default class RoomView extends React.Component { appsShown={this.state.showApps} /> -
+
{auxPanel} -
- {topUnreadMessagesBar} - {jumpToBottom} - {messagePanel} - {searchResultsPanel} -
-
-
-
- {statusBar} +
+
+ {topUnreadMessagesBar} + {jumpToBottom} + {messagePanel} + {searchResultsPanel}
+
+
+
+ {statusBar} +
+
+ {previewBar} + {messageComposer}
- {previewBar} - {messageComposer}
From e70dee08d0ea7b303a51fb807929376b2dad79dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 17 Dec 2020 19:50:59 +0100 Subject: [PATCH 0040/2651] Fix flickering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 42 ++++++++++++++++++++------ 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 3d62c06e4b..67f9663597 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -187,6 +187,7 @@ export interface IState { rejecting?: boolean; rejectError?: Error; hasPinnedWidgets?: boolean; + dragCounter: number; } export default class RoomView extends React.Component { @@ -237,6 +238,7 @@ export default class RoomView extends React.Component { canReply: false, useIRCLayout: SettingsStore.getValue("useIRCLayout"), matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), + dragCounter: 0, }; this.dispatcherRef = dis.register(this.onAction); @@ -525,8 +527,8 @@ export default class RoomView extends React.Component { if (!roomView.ondrop) { roomView.addEventListener('drop', this.onDrop); roomView.addEventListener('dragover', this.onDragOver); - roomView.addEventListener('dragleave', this.onDragLeaveOrEnd); - roomView.addEventListener('dragend', this.onDragLeaveOrEnd); + roomView.addEventListener('dragenter', this.onDragEnter); + roomView.addEventListener('dragleave', this.onDragLeave); } } @@ -1108,6 +1110,31 @@ export default class RoomView extends React.Component { this.updateTopUnreadMessagesBar(); }; + private onDragEnter = ev => { + ev.stopPropagation(); + ev.preventDefault(); + + this.setState({ + dragCounter: this.state.dragCounter + 1, + draggingFile: true, + }); + }; + + private onDragLeave = ev => { + ev.stopPropagation(); + ev.preventDefault(); + + this.setState({ + dragCounter: this.state.dragCounter - 1, + }); + + if (this.state.dragCounter == 0) { + this.setState({ + draggingFile: false, + }); + } + }; + private onDragOver = ev => { ev.stopPropagation(); ev.preventDefault(); @@ -1115,7 +1142,6 @@ export default class RoomView extends React.Component { ev.dataTransfer.dropEffect = 'none'; if (ev.dataTransfer.types.includes("Files") || ev.dataTransfer.types.includes("application/x-moz-file")) { - this.setState({ draggingFile: true }); ev.dataTransfer.dropEffect = 'copy'; } }; @@ -1126,14 +1152,12 @@ export default class RoomView extends React.Component { ContentMessages.sharedInstance().sendContentListToRoom( ev.dataTransfer.files, this.state.room.roomId, this.context, ); - this.setState({ draggingFile: false }); dis.fire(Action.FocusComposer); - }; - private onDragLeaveOrEnd = ev => { - ev.stopPropagation(); - ev.preventDefault(); - this.setState({ draggingFile: false }); + this.setState({ + draggingFile: false, + dragCounter: this.state.dragCounter - 1, + }); }; private injectSticker(url, info, text) { From 044e02b06ad46b417d3aa8fc33f24c1374fdcb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 17 Dec 2020 20:16:53 +0100 Subject: [PATCH 0041/2651] Remove spaces in empty line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 6875ef12e0..f05f24d0d7 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -24,7 +24,7 @@ limitations under the License. .mx_MainSplit > .mx_RightPanel_ResizeWrapper { padding: 0 5px 5px 0px; height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel - + .mx_RightPanel_ResizeHandle { width: 9px; } From 365d252d3f0eb64755f502318c95f855a4404f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 17 Dec 2020 20:25:12 +0100 Subject: [PATCH 0042/2651] Fix removing event listeners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 67f9663597..d910940a73 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -572,8 +572,8 @@ export default class RoomView extends React.Component { const roomView = this.roomView.current; roomView.removeEventListener('drop', this.onDrop); roomView.removeEventListener('dragover', this.onDragOver); - roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd); - roomView.removeEventListener('dragend', this.onDragLeaveOrEnd); + roomView.removeEventListener('dragenter', this.onDragEnter); + roomView.removeEventListener('dragleave', this.onDragLeave); } dis.unregister(this.dispatcherRef); if (this.context) { From 5d7e45e6cf85e14f4143923f7e29642f97965fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 17 Dec 2020 20:29:33 +0100 Subject: [PATCH 0043/2651] Added dragCounter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/contexts/RoomContext.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/contexts/RoomContext.ts b/src/contexts/RoomContext.ts index 082dcc4e6b..1b9097e337 100644 --- a/src/contexts/RoomContext.ts +++ b/src/contexts/RoomContext.ts @@ -42,6 +42,7 @@ const RoomContext = createContext({ canReply: false, useIRCLayout: false, matrixClientIsReady: false, + dragCounter: 0, }); RoomContext.displayName = "RoomContext"; export default RoomContext; From 8aabe1f33077ef95f4414c32b3b625b4297369ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 09:26:09 +0100 Subject: [PATCH 0044/2651] Reorganized elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 114 +++++---------------- src/components/views/elements/ImageView.js | 60 +++++------ 2 files changed, 54 insertions(+), 120 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 0a4ed2a194..77fa597d66 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -22,45 +22,46 @@ limitations under the License. display: flex; width: 100%; height: 100%; - align-items: center; -} - -.mx_ImageView_lhs { - order: 1; - flex: 1 1 10%; - min-width: 60px; - // background-color: #080; - // height: 20px; } .mx_ImageView_content { - order: 2; - /* min-width hack needed for FF */ - min-width: 0px; - height: 90%; - flex: 15 15 0; + width: 100%; + height: 100%; + + display: flex; + flex-direction: column; +} + +.mx_ImageView_imageBox { + overflow: auto; + margin: 0 50px 50px 50px; + flex: 1; display: flex; - align-items: center; - justify-content: center; } .mx_ImageView_content img { - max-width: 100%; + flex: 1; + //max-width: 100%; /* XXX: max-height interacts badly with flex on Chrome and doesn't relayout properly until you refresh */ - max-height: 100%; + //max-height: 100%; /* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */ object-fit: contain; /* background-image: url('$(res)/img/trans.png'); */ pointer-events: all; } -.mx_ImageView_labelWrapper { - position: absolute; - top: 0px; - right: 0px; - height: 100%; - overflow: auto; - pointer-events: all; +.mx_ImageView_panel { + display: flex; + justify-content: space-between; + padding: 50px; +} + +.mx_ImageView_toolbar { + display: flex; +} + +.mx_ImageView_button { + padding: 5px; } .mx_ImageView_label { @@ -68,39 +69,11 @@ limitations under the License. display: flex; justify-content: center; flex-direction: column; - padding-left: 30px; - padding-right: 30px; min-height: 100%; max-width: 240px; color: $lightbox-fg-color; } -.mx_ImageView_cancel { - position: absolute; - // hack for mx_Dialog having a top padding of 40px - top: 40px; - right: 0px; - padding-top: 35px; - padding-right: 35px; - cursor: pointer; -} - -.mx_ImageView_rotateClockwise { - position: absolute; - top: 40px; - right: 70px; - padding-top: 35px; - cursor: pointer; -} - -.mx_ImageView_rotateCounterClockwise { - position: absolute; - top: 40px; - right: 105px; - padding-top: 35px; - cursor: pointer; -} - .mx_ImageView_name { font-size: $font-18px; margin-bottom: 6px; @@ -112,41 +85,6 @@ limitations under the License. opacity: 0.5; } -.mx_ImageView_download { - display: table; - margin-top: 24px; - margin-bottom: 6px; - border-radius: 5px; - background-color: $lightbox-bg-color; - font-size: $font-14px; - padding: 9px; - border: 1px solid $lightbox-border-color; -} - .mx_ImageView_size { font-size: $font-11px; } - -.mx_ImageView_link { - color: $lightbox-fg-color !important; - text-decoration: none !important; -} - -.mx_ImageView_button { - font-size: $font-15px; - opacity: 0.5; - margin-top: 18px; - cursor: pointer; -} - -.mx_ImageView_shim { - height: 30px; -} - -.mx_ImageView_rhs { - order: 3; - flex: 1 1 10%; - min-width: 300px; - // background-color: #800; - // height: 20px; -} diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e39075cedc..a66d2e2e6f 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -153,7 +153,7 @@ export default class ImageView extends React.Component { let mayRedact = false; const showEventMeta = !!this.props.mxEvent; - let eventMeta; + let metadata; if (showEventMeta) { // Figure out the sender, defaulting to mxid let sender = this.props.mxEvent.getSender(); @@ -165,7 +165,7 @@ export default class ImageView extends React.Component { if (member) sender = member.name; } - eventMeta = (
+ metadata = (
{ _t('Uploaded on %(date)s by %(user)s', { date: formatDate(new Date(this.props.mxEvent.getTs())), user: sender, @@ -173,11 +173,13 @@ export default class ImageView extends React.Component {
); } - let eventRedact; + let redactButton; if (mayRedact) { - eventRedact = (
- { _t('Remove') } -
); + redactButton = ( + + { + + ); } const rotationDegrees = this.state.rotationDegrees; @@ -192,40 +194,34 @@ export default class ImageView extends React.Component { }} className="mx_ImageView" > -
-
- -
+
- - { - - - { - - - { - -
-
{ this.getName() }
- { eventMeta } - -
- { _t('Download this file') }
- { sizeRes } -
+ { metadata } + { sizeRes } +
+
+ + { + + + { + + + { - { eventRedact } -
-
+ { redactButton } + + { +
-
-
+
+ +
); From 2040815f661be9c832a629022f01764ae99c8c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 10:20:15 +0100 Subject: [PATCH 0045/2651] Implement zooming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 45 +++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index a66d2e2e6f..0c235d87be 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -46,7 +46,10 @@ export default class ImageView extends React.Component { constructor(props) { super(props); - this.state = { rotationDegrees: 0 }; + this.state = { + rotationDegrees: 0, + zoom: 100, + }; } onKeyDown = (ev) => { @@ -57,6 +60,16 @@ export default class ImageView extends React.Component { } }; + onWheel = (ev) => { + if (ev.ctrlKey) { + ev.stopPropagation(); + ev.preventDefault(); + this.setState({ + zoom: this.state.zoom - ev.deltaY, + }); + } + } + onRedactClick = () => { const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog"); Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, { @@ -98,6 +111,18 @@ export default class ImageView extends React.Component { this.setState({ rotationDegrees }); }; + zoomIn = () => { + this.setState({ + zoom: this.state.zoom + 10, + }); + }; + + zoomOut = () => { + this.setState({ + zoom: this.state.zoom - 10, + }); + } + render() { /* // In theory max-width: 80%, max-height: 80% on the CSS should work @@ -130,12 +155,13 @@ export default class ImageView extends React.Component { let style = {}; let res; + style = { + width: this.state.zoom + "%", + height: this.state.zoom + "%", + }; + if (this.props.width && this.props.height) { - style = { - width: this.props.width, - height: this.props.height, - }; - res = style.width + "x" + style.height + "px"; + res = this.props.width + "x" + this.props.height + "px"; } let size; @@ -190,6 +216,7 @@ export default class ImageView extends React.Component { returnFocus={true} lockProps={{ onKeyDown: this.onKeyDown, + onWheel: this.onWheel, role: "dialog", }} className="mx_ImageView" @@ -204,6 +231,12 @@ export default class ImageView extends React.Component { { sizeRes }
+ + { + + + { + { From 3c306bc54bb81aea6fa18d3f7204c083a053a0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 12:54:55 +0100 Subject: [PATCH 0046/2651] Added icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/download-white.svg | 95 +++++++++++++++++++++ res/img/feather-customised/trash.custom.svg | 87 +++++++++++++++++-- res/img/minus-white.svg | 64 ++++++++++++++ res/img/plus-white.svg | 73 ++++++++++++++++ res/img/trash-red.svg | 89 +++++++++++++++++++ src/components/views/elements/ImageView.js | 8 +- 6 files changed, 406 insertions(+), 10 deletions(-) create mode 100644 res/img/download-white.svg create mode 100644 res/img/minus-white.svg create mode 100644 res/img/plus-white.svg create mode 100644 res/img/trash-red.svg diff --git a/res/img/download-white.svg b/res/img/download-white.svg new file mode 100644 index 0000000000..5c800b350e --- /dev/null +++ b/res/img/download-white.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + Fill 75 + + + + + + Fill 75 + Created with Sketch. + + + + + + + + + + + + + diff --git a/res/img/feather-customised/trash.custom.svg b/res/img/feather-customised/trash.custom.svg index dc1985ddb2..589bb0a4e5 100644 --- a/res/img/feather-customised/trash.custom.svg +++ b/res/img/feather-customised/trash.custom.svg @@ -1,7 +1,82 @@ - - - - - - + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/res/img/minus-white.svg b/res/img/minus-white.svg new file mode 100644 index 0000000000..2921f34980 --- /dev/null +++ b/res/img/minus-white.svg @@ -0,0 +1,64 @@ + + + + + + image/svg+xml + + Fill 75 + + + + + + Fill 75 + Created with Sketch. + + + diff --git a/res/img/plus-white.svg b/res/img/plus-white.svg new file mode 100644 index 0000000000..7759ace50a --- /dev/null +++ b/res/img/plus-white.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + Fill 75 + + + + + + Fill 75 + Created with Sketch. + + + + diff --git a/res/img/trash-red.svg b/res/img/trash-red.svg new file mode 100644 index 0000000000..0b1d201d2e --- /dev/null +++ b/res/img/trash-red.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 0c235d87be..719a17d3cb 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -203,7 +203,7 @@ export default class ImageView extends React.Component { if (mayRedact) { redactButton = ( - { + { ); } @@ -232,10 +232,10 @@ export default class ImageView extends React.Component {
- { + { - { + { { @@ -244,7 +244,7 @@ export default class ImageView extends React.Component { { - { + { { redactButton } From b9f480a825f8f8279d807aa2d10973a58fef78b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 13:13:34 +0100 Subject: [PATCH 0047/2651] Remove flex property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 77fa597d66..5f002c7d7a 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -35,7 +35,6 @@ limitations under the License. .mx_ImageView_imageBox { overflow: auto; margin: 0 50px 50px 50px; - flex: 1; display: flex; } From 2c5f3f31b1bd339c6d40337ddc3bd059fe095edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 13:30:56 +0100 Subject: [PATCH 0048/2651] Fixed Chromium issues - made listner non-passive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 719a17d3cb..6dfd1f78ad 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -52,6 +52,14 @@ export default class ImageView extends React.Component { }; } + componentDidMount() { + this.focusLock.addEventListener('wheel', this.onWheel, { passive: false }); + } + + componentWillUnmount() { + this.focusLock.removeEventListener('wheel', this.onWheel); + } + onKeyDown = (ev) => { if (ev.key === Key.ESCAPE) { ev.stopPropagation(); @@ -216,10 +224,10 @@ export default class ImageView extends React.Component { returnFocus={true} lockProps={{ onKeyDown: this.onKeyDown, - onWheel: this.onWheel, role: "dialog", }} className="mx_ImageView" + ref={ref => this.focusLock = ref} >
From 633221f012961024d2e706f7b7ee0c1fb3cb88f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 13:50:21 +0100 Subject: [PATCH 0049/2651] Center image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 5f002c7d7a..e6ed3684bb 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -40,13 +40,9 @@ limitations under the License. .mx_ImageView_content img { flex: 1; - //max-width: 100%; - /* XXX: max-height interacts badly with flex on Chrome and doesn't relayout properly until you refresh */ - //max-height: 100%; - /* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */ object-fit: contain; - /* background-image: url('$(res)/img/trans.png'); */ pointer-events: all; + margin: auto; } .mx_ImageView_panel { From ae25ff82169048be25dcb37c8ec680b22dfb805d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 19 Dec 2020 15:54:26 +0100 Subject: [PATCH 0050/2651] Switched to scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 5 +++-- src/components/views/elements/ImageView.js | 9 ++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index e6ed3684bb..c87cfd1ece 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -36,13 +36,14 @@ limitations under the License. overflow: auto; margin: 0 50px 50px 50px; display: flex; + height: 100%; } .mx_ImageView_content img { - flex: 1; object-fit: contain; pointer-events: all; - margin: auto; + //margin: auto; + //margin: 0 auto 0 auto; } .mx_ImageView_panel { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 6dfd1f78ad..a42d957daa 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -160,14 +160,8 @@ export default class ImageView extends React.Component { height: displayHeight }; */ - let style = {}; let res; - style = { - width: this.state.zoom + "%", - height: this.state.zoom + "%", - }; - if (this.props.width && this.props.height) { res = this.props.width + "x" + this.props.height + "px"; } @@ -217,7 +211,8 @@ export default class ImageView extends React.Component { } const rotationDegrees = this.state.rotationDegrees; - const effectiveStyle = {transform: `rotate(${rotationDegrees}deg)`, ...style}; + const zoom = this.state.zoom/100; + const effectiveStyle = {transform: `rotate(${rotationDegrees}deg) scale(${zoom})`}; return ( Date: Sun, 20 Dec 2020 09:51:57 +0100 Subject: [PATCH 0051/2651] Added a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index a42d957daa..bc1d8b4d53 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -53,6 +53,8 @@ export default class ImageView extends React.Component { } componentDidMount() { + // We have to use addEventListener() because the listener + // needs to be passive in order to work with Chromium this.focusLock.addEventListener('wheel', this.onWheel, { passive: false }); } From be9b68a4dd3d453548b5e1562019998bd28170de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 10:07:03 +0100 Subject: [PATCH 0052/2651] Use height and width properties for scaling again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 11 ++++++----- src/components/views/elements/ImageView.js | 7 +++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index c87cfd1ece..1fcf1bf543 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -33,17 +33,18 @@ limitations under the License. } .mx_ImageView_imageBox { - overflow: auto; - margin: 0 50px 50px 50px; + overflow: scroll; display: flex; - height: 100%; + flex-grow: 1; +} + +.mainImage { + margin: auto; } .mx_ImageView_content img { object-fit: contain; pointer-events: all; - //margin: auto; - //margin: 0 auto 0 auto; } .mx_ImageView_panel { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index bc1d8b4d53..2feff97fef 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -163,6 +163,10 @@ export default class ImageView extends React.Component { }; */ let res; + const style = { + height: this.state.zoom + "%", + width: this.state.zoom + "%", + }; if (this.props.width && this.props.height) { res = this.props.width + "x" + this.props.height + "px"; @@ -213,8 +217,7 @@ export default class ImageView extends React.Component { } const rotationDegrees = this.state.rotationDegrees; - const zoom = this.state.zoom/100; - const effectiveStyle = {transform: `rotate(${rotationDegrees}deg) scale(${zoom})`}; + const effectiveStyle = {transform: `rotate(${rotationDegrees}deg)`, ...style}; return ( Date: Sun, 20 Dec 2020 12:16:05 +0100 Subject: [PATCH 0053/2651] Added some padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 1fcf1bf543..ec651fcc6a 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -35,6 +35,7 @@ limitations under the License. .mx_ImageView_imageBox { overflow: scroll; display: flex; + padding: 0 50px 50px 50px; flex-grow: 1; } From f9884b1cc75cd7b2cbdb1d15cfa9b9ea364f424c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 17:40:16 +0100 Subject: [PATCH 0054/2651] Implement translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 6 +- src/components/views/elements/ImageView.js | 144 +++++++++++++-------- 2 files changed, 97 insertions(+), 53 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index ec651fcc6a..10553a1c54 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -33,7 +33,7 @@ limitations under the License. } .mx_ImageView_imageBox { - overflow: scroll; + overflow: hidden; display: flex; padding: 0 50px 50px 50px; flex-grow: 1; @@ -41,6 +41,10 @@ limitations under the License. .mainImage { margin: auto; + + &:hover { + cursor: grab; + } } .mx_ImageView_content img { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 2feff97fef..8cc55e40bf 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -47,11 +47,19 @@ export default class ImageView extends React.Component { constructor(props) { super(props); this.state = { - rotationDegrees: 0, + rotation: 0, zoom: 100, + translationX: 0, + translationY: 0, + moving: false, }; } + initX = 0; + initY = 0; + lastX = 0; + lastY = 0; + componentDidMount() { // We have to use addEventListener() because the listener // needs to be passive in order to work with Chromium @@ -74,8 +82,18 @@ export default class ImageView extends React.Component { if (ev.ctrlKey) { ev.stopPropagation(); ev.preventDefault(); + const newZoom =this.state.zoom - ev.deltaY; + + if (newZoom <= 100) { + this.setState({ + zoom: 100, + translationX: 0, + translationY: 0, + }); + return; + } this.setState({ - zoom: this.state.zoom - ev.deltaY, + zoom: newZoom, }); } } @@ -109,65 +127,72 @@ export default class ImageView extends React.Component { return name; } - rotateCounterClockwise = () => { - const cur = this.state.rotationDegrees; + onRotateCounterClockwiseClick = () => { + const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; - this.setState({ rotationDegrees }); + this.setState({ rotation: rotationDegrees }); }; - rotateClockwise = () => { - const cur = this.state.rotationDegrees; + onRotateClockwiseClick = () => { + const cur = this.state.rotation; const rotationDegrees = (cur + 90) % 360; - this.setState({ rotationDegrees }); + this.setState({ rotation: rotationDegrees }); }; - zoomIn = () => { + onZoomInClick = () => { this.setState({ zoom: this.state.zoom + 10, }); }; - zoomOut = () => { + onZoomOutClick = () => { + if (this.state.zoom <= 100) { + this.setState({ + zoom: 100, + translationX: 0, + translationY: 0, + }); + return; + } this.setState({ zoom: this.state.zoom - 10, }); } + onStartMoving = ev => { + ev.stopPropagation(); + ev.preventDefault(); + + if (this.state.zoom <= 100) return false; + + this.setState({moving: true}); + this.initX = ev.pageX - this.lastX; + this.initY = ev.pageY - this.lastY; + } + + onMoving = ev => { + ev.stopPropagation(); + ev.preventDefault(); + + if (!this.state.moving) return false; + + this.lastX = ev.pageX - this.initX; + this.lastY = ev.pageY - this.initY; + this.setState({ + translationX: this.lastX, + translationY: this.lastY, + }); + } + + onEndMoving = ev => { + this.setState({moving: false}); + } + render() { -/* - // In theory max-width: 80%, max-height: 80% on the CSS should work - // but in practice, it doesn't, so do it manually: + let mayRedact = false; + const showEventMeta = !!this.props.mxEvent; - var width = this.props.width || 500; - var height = this.props.height || 500; - - var maxWidth = document.documentElement.clientWidth * 0.8; - var maxHeight = document.documentElement.clientHeight * 0.8; - - var widthFrac = width / maxWidth; - var heightFrac = height / maxHeight; - - var displayWidth; - var displayHeight; - if (widthFrac > heightFrac) { - displayWidth = Math.min(width, maxWidth); - displayHeight = (displayWidth / width) * height; - } else { - displayHeight = Math.min(height, maxHeight); - displayWidth = (displayHeight / height) * width; - } - - var style = { - width: displayWidth, - height: displayHeight - }; -*/ let res; - const style = { - height: this.state.zoom + "%", - width: this.state.zoom + "%", - }; - if (this.props.width && this.props.height) { res = this.props.width + "x" + this.props.height + "px"; } @@ -184,9 +209,6 @@ export default class ImageView extends React.Component { sizeRes = size || res; } - let mayRedact = false; - const showEventMeta = !!this.props.mxEvent; - let metadata; if (showEventMeta) { // Figure out the sender, defaulting to mxid @@ -216,8 +238,16 @@ export default class ImageView extends React.Component { ); } - const rotationDegrees = this.state.rotationDegrees; - const effectiveStyle = {transform: `rotate(${rotationDegrees}deg)`, ...style}; + const rotationDegrees = this.state.rotation + "deg"; + const zoomPercentage = this.state.zoom/100; + const translatePixelsX = this.state.translationX + "px"; + const translatePixelsY = this.state.translationY + "px"; + const style = { + transform: `rotate(${rotationDegrees}) + scale(${zoomPercentage}) + translateX(${translatePixelsX}) + translateY(${translatePixelsY})`, + }; return ( { sizeRes }
- +
From 7dd7aeffedc612827712a0b1ff91a3561f56f016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 18:19:11 +0100 Subject: [PATCH 0055/2651] Remove imageBox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 10 +++------ src/components/views/elements/ImageView.js | 24 ++++++++++------------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 10553a1c54..a2ca9c7927 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -26,21 +26,15 @@ limitations under the License. .mx_ImageView_content { width: 100%; - height: 100%; display: flex; flex-direction: column; -} -.mx_ImageView_imageBox { overflow: hidden; - display: flex; - padding: 0 50px 50px 50px; - flex-grow: 1; } .mainImage { - margin: auto; + //margin: auto; &:hover { cursor: grab; @@ -56,6 +50,8 @@ limitations under the License. display: flex; justify-content: space-between; padding: 50px; + position: absolute; + width: 100%; } .mx_ImageView_toolbar { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 8cc55e40bf..9d747463f9 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -290,19 +290,17 @@ export default class ImageView extends React.Component {
-
- -
+
); From 6758734593ad30e9a766e63ccb23921b43c00c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 19:48:24 +0100 Subject: [PATCH 0056/2651] Remove panel element MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 39 +++++++++------- src/components/views/elements/ImageView.js | 54 +++++++++++----------- 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index a2ca9c7927..0153d372fc 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -28,50 +28,55 @@ limitations under the License. width: 100%; display: flex; - flex-direction: column; + justify-content: center; + align-items: center; overflow: hidden; } .mainImage { - //margin: auto; + object-fit: contain; + pointer-events: all; + + max-width: 100vw; + max-height: 90vh; + min-width: 100px; + min-height: 100px; &:hover { cursor: grab; } } -.mx_ImageView_content img { - object-fit: contain; +.mx_ImageView_panel { + position: absolute; + z-index: 1000; + align-self: flex-start; pointer-events: all; } -.mx_ImageView_panel { - display: flex; - justify-content: space-between; - padding: 50px; - position: absolute; - width: 100%; -} - .mx_ImageView_toolbar { + right: 0; + padding: 50px 50px 0 0; display: flex; -} - -.mx_ImageView_button { - padding: 5px; + } .mx_ImageView_label { + left: 0; + padding: 50px 0 0 50px; text-align: left; display: flex; justify-content: center; flex-direction: column; - min-height: 100%; max-width: 240px; color: $lightbox-fg-color; } +.mx_ImageView_button { + padding: 5px; +} + .mx_ImageView_name { font-size: $font-18px; margin-bottom: 6px; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 9d747463f9..86c6cb8ad5 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -260,35 +260,33 @@ export default class ImageView extends React.Component { ref={ref => this.focusLock = ref} >
-
-
-
- { this.getName() } -
- { metadata } - { sizeRes } -
-
- - { - - - { - - - { - - - { - - - { - - { redactButton } - - { - +
+
+ { this.getName() }
+ { metadata } + { sizeRes } +
+
+ + { + + + { + + + { + + + { + + + { + + { redactButton } + + { +
Date: Sun, 20 Dec 2020 20:00:11 +0100 Subject: [PATCH 0057/2651] Fixed translation issue while the image is rotated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 86c6cb8ad5..0db907003c 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -242,11 +242,15 @@ export default class ImageView extends React.Component { const zoomPercentage = this.state.zoom/100; const translatePixelsX = this.state.translationX + "px"; const translatePixelsY = this.state.translationY + "px"; + /* The order of the values is important! + * First, we translate and only then we rotate, otherwise + * we would apply the translation to an already rotated + * image causing it translate in the wrong direction. */ const style = { - transform: `rotate(${rotationDegrees}) + transform: `translateX(${translatePixelsX}) + translateY(${translatePixelsY}) scale(${zoomPercentage}) - translateX(${translatePixelsX}) - translateY(${translatePixelsY})`, + rotate(${rotationDegrees})`, }; return ( From 776b0e8198e1179ee5f1b7ee9edb6e07d6c14ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:05:27 +0100 Subject: [PATCH 0058/2651] Change comment styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 0db907003c..b6fa9ef35b 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -61,8 +61,8 @@ export default class ImageView extends React.Component { lastY = 0; componentDidMount() { - // We have to use addEventListener() because the listener - // needs to be passive in order to work with Chromium + /* We have to use addEventListener() because the listener + * needs to be passive in order to work with Chromium */ this.focusLock.addEventListener('wheel', this.onWheel, { passive: false }); } From f0abd52130b6f70df4bef144d26afdda05819bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:09:01 +0100 Subject: [PATCH 0059/2651] Remove the need to press ctrl while zooming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 24 ++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index b6fa9ef35b..d40708af4c 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -79,23 +79,21 @@ export default class ImageView extends React.Component { }; onWheel = (ev) => { - if (ev.ctrlKey) { - ev.stopPropagation(); - ev.preventDefault(); - const newZoom =this.state.zoom - ev.deltaY; + ev.stopPropagation(); + ev.preventDefault(); + const newZoom =this.state.zoom - ev.deltaY; - if (newZoom <= 100) { - this.setState({ - zoom: 100, - translationX: 0, - translationY: 0, - }); - return; - } + if (newZoom <= 100) { this.setState({ - zoom: newZoom, + zoom: 100, + translationX: 0, + translationY: 0, }); + return; } + this.setState({ + zoom: newZoom, + }); } onRedactClick = () => { From cbfa6c5f94bc839ce158ee994a2efda81d024508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:15:25 +0100 Subject: [PATCH 0060/2651] Fix some sizing issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 0153d372fc..2c3d881394 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -39,7 +39,7 @@ limitations under the License. pointer-events: all; max-width: 100vw; - max-height: 90vh; + max-height: 80vh; min-width: 100px; min-height: 100px; From 61c5e7e8f17356c849fda70793cd6e5c86f4342c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:15:39 +0100 Subject: [PATCH 0061/2651] Reorder label items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index d40708af4c..b343ec37c2 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -266,8 +266,8 @@ export default class ImageView extends React.Component {
{ this.getName() }
- { metadata } { sizeRes } + { metadata }
From 0dff150bb271985133b551c0b99639fc68461cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:18:21 +0100 Subject: [PATCH 0062/2651] Fix some more sizing issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 2c3d881394..1b38021267 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -39,7 +39,7 @@ limitations under the License. pointer-events: all; max-width: 100vw; - max-height: 80vh; + max-height: 70vh; min-width: 100px; min-height: 100px; From 096fb33397e29e65cf0ec5dea77eb99b8b8c690e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:19:32 +0100 Subject: [PATCH 0063/2651] Always allow moving MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index b343ec37c2..12112db48a 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -161,8 +161,6 @@ export default class ImageView extends React.Component { ev.stopPropagation(); ev.preventDefault(); - if (this.state.zoom <= 100) return false; - this.setState({moving: true}); this.initX = ev.pageX - this.lastX; this.initY = ev.pageY - this.lastY; From 3d62138cbd67fa7beefa9770abf954a35c8286f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:28:19 +0100 Subject: [PATCH 0064/2651] Set max zoom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 12112db48a..82f3386e8d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -91,6 +91,11 @@ export default class ImageView extends React.Component { }); return; } + if (newZoom >= 300) { + this.setState({zoom: 300}); + return; + } + this.setState({ zoom: newZoom, }); @@ -138,6 +143,11 @@ export default class ImageView extends React.Component { }; onZoomInClick = () => { + if (this.state.zoom >= 300) { + this.setState({zoom: 300}); + return; + } + this.setState({ zoom: this.state.zoom + 10, }); From f771b7ac98764135691f64fbddefded6cdb06621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:37:31 +0100 Subject: [PATCH 0065/2651] Added zoom button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/zoom-white.svg | 59 ++++++++++++++++++++++ src/components/views/elements/ImageView.js | 33 +++++++++--- 2 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 res/img/zoom-white.svg diff --git a/res/img/zoom-white.svg b/res/img/zoom-white.svg new file mode 100644 index 0000000000..19379cb881 --- /dev/null +++ b/res/img/zoom-white.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 82f3386e8d..8552b2e381 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -59,6 +59,8 @@ export default class ImageView extends React.Component { initY = 0; lastX = 0; lastY = 0; + minZoom = 100; + maxZoom = 300; componentDidMount() { /* We have to use addEventListener() because the listener @@ -83,16 +85,16 @@ export default class ImageView extends React.Component { ev.preventDefault(); const newZoom =this.state.zoom - ev.deltaY; - if (newZoom <= 100) { + if (newZoom <= this.minZoom) { this.setState({ - zoom: 100, + zoom: this.minZoom, translationX: 0, translationY: 0, }); return; } - if (newZoom >= 300) { - this.setState({zoom: 300}); + if (newZoom >= this.maxZoom) { + this.setState({zoom: this.maxZoom}); return; } @@ -143,8 +145,8 @@ export default class ImageView extends React.Component { }; onZoomInClick = () => { - if (this.state.zoom >= 300) { - this.setState({zoom: 300}); + if (this.state.zoom >= this.maxZoom) { + this.setState({zoom: this.maxZoom}); return; } @@ -154,9 +156,9 @@ export default class ImageView extends React.Component { }; onZoomOutClick = () => { - if (this.state.zoom <= 100) { + if (this.state.zoom <= this.minZoom) { this.setState({ - zoom: 100, + zoom: this.minZoom, translationX: 0, translationY: 0, }); @@ -167,6 +169,18 @@ export default class ImageView extends React.Component { }); } + onZoomClick = () => { + if (this.state.zoom <= this.minZoom) { + this.setState({zoom: this.maxZoom}); + } else { + this.setState({ + zoom: this.minZoom, + translationX: 0, + translationY: 0, + }); + } + } + onStartMoving = ev => { ev.stopPropagation(); ev.preventDefault(); @@ -278,6 +292,9 @@ export default class ImageView extends React.Component { { metadata }
+ + { + { From 6315c8ecefae446a11eb9b031e35b524a1bfa9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:45:33 +0100 Subject: [PATCH 0066/2651] Fix formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 1b38021267..43333a25e6 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -59,7 +59,6 @@ limitations under the License. right: 0; padding: 50px 50px 0 0; display: flex; - } .mx_ImageView_label { From 00bc97b63fde4d1605b8820422d98fa73680e889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 20 Dec 2020 20:45:47 +0100 Subject: [PATCH 0067/2651] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f8ef44763d..cd4285753f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1833,11 +1833,14 @@ "expand": "expand", "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", + "Zoom": "Zoom", + "Zoom in": "Zoom in", + "Zoom out": "Zoom out", "Rotate Left": "Rotate Left", "Rotate counter-clockwise": "Rotate counter-clockwise", "Rotate Right": "Rotate Right", "Rotate clockwise": "Rotate clockwise", - "Download this file": "Download this file", + "Download": "Download", "Information": "Information", "Language Dropdown": "Language Dropdown", "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", @@ -2593,7 +2596,6 @@ "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.", "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Keep a copy of it somewhere secure, like a password manager or even a safe.", "Your recovery key": "Your recovery key", - "Download": "Download", "Your recovery key has been copied to your clipboard, paste it to:": "Your recovery key has been copied to your clipboard, paste it to:", "Your recovery key is in your Downloads folder.": "Your recovery key is in your Downloads folder.", "Print it and store it somewhere safe": "Print it and store it somewhere safe", From 78b3f50bfd4bbe3de053d7b7d994ad779e3002a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= Date: Sun, 20 Dec 2020 23:14:56 +0100 Subject: [PATCH 0068/2651] Use LaTeX delimiters by default, add /tex command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since parsing for $'s as maths delimiters is tricky, switch the default to \(...\) for inline and \[...\] for display maths as it is used in LaTeX. Add /tex command to explicitly parse in TeX mode, which uses $...$ for inline and $$...$$ for display maths. Signed-off-by: Sven Mäder --- src/SlashCommands.tsx | 18 +++++++ src/editor/deserialize.ts | 8 +-- src/editor/serialize.ts | 98 ++++++++++++++++++++++++++++--------- src/i18n/strings/en_EN.json | 1 + 4 files changed, 99 insertions(+), 26 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 79c21c4af5..e9bde933ec 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -48,6 +48,7 @@ import SettingsStore from "./settings/SettingsStore"; import {UIFeature} from "./settings/UIFeature"; import {CHAT_EFFECTS} from "./effects" import CallHandler from "./CallHandler"; +import {markdownSerializeIfNeeded} from './editor/serialize'; // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 interface HTMLInputEvent extends Event { @@ -223,6 +224,23 @@ export const Commands = [ }, category: CommandCategories.messages, }), + new Command({ + command: 'tex', + args: '', + description: _td('Sends a message in TeX mode, using $ and $$ delimiters for maths'), + runFn: function(roomId, args) { + if (SettingsStore.getValue("feature_latex_maths")) { + if (args) { + let html = markdownSerializeIfNeeded(args, {forceHTML: false}, {forceTEX: true}); + return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, html)); + } + return reject(this.getUsage()); + } else { + return reject("Render LaTeX maths in messages needs to be enabled in Labs"); + } + }, + category: CommandCategories.messages, + }), new Command({ command: 'ddg', args: '', diff --git a/src/editor/deserialize.ts b/src/editor/deserialize.ts index 6336b4c46b..a1ee079af5 100644 --- a/src/editor/deserialize.ts +++ b/src/editor/deserialize.ts @@ -136,11 +136,11 @@ function parseElement(n: HTMLElement, partCreator: PartCreator, lastNode: HTMLEl // math nodes are translated back into delimited latex strings if (n.hasAttribute("data-mx-maths")) { const delimLeft = (n.nodeName == "SPAN") ? - (SdkConfig.get()['latex_maths_delims'] || {})['inline_left'] || "$" : - (SdkConfig.get()['latex_maths_delims'] || {})['display_left'] || "$$"; + (SdkConfig.get()['latex_maths_delims'] || {})['inline_left'] || "\\(" : + (SdkConfig.get()['latex_maths_delims'] || {})['display_left'] || "\\["; const delimRight = (n.nodeName == "SPAN") ? - (SdkConfig.get()['latex_maths_delims'] || {})['inline_right'] || "$" : - (SdkConfig.get()['latex_maths_delims'] || {})['display_right'] || "$$"; + (SdkConfig.get()['latex_maths_delims'] || {})['inline_right'] || "\\)" : + (SdkConfig.get()['latex_maths_delims'] || {})['display_right'] || "\\]"; const tex = n.getAttribute("data-mx-maths"); return partCreator.plain(delimLeft + tex + delimRight); } else if (!checkDescendInto(n)) { diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index c1f4da306b..ca798a324e 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -41,24 +41,57 @@ export function mdSerialize(model: EditorModel) { }, ""); } -export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = {}) { - let md = mdSerialize(model); +export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, {forceTEX = false} = {}) { + // copy of raw input to remove unwanted math later + const orig = md; if (SettingsStore.getValue("feature_latex_maths")) { - const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || - "\\$\\$(([^$]|\\\\\\$)*)\\$\\$"; - const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || - "\\$(([^$]|\\\\\\$)*)\\$"; + if (forceTEX) { + // detect math with tex delimiters, inline: $...$, display $$...$$ + // preferably use negative lookbehinds, not supported in all major browsers: + // const displayPattern = "^(?\n\n
\n\n`; - }); + // conditions for display math detection ($$...$$): + // - left delimiter ($$) is not escaped by a backslash + // - pattern starts at the beginning of a line + // - left delimiter is not followed by a space or tab character + // - pattern ends at the end of a line + const displayPattern = "^(?!\\\\)\\$\\$(?![ \\t])(([^$]|\\\\\\$)+?)\\$\\$$"; - md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1) { - const p1e = AllHtmlEntities.encode(p1); - return ``; - }); + // conditions for inline math detection ($...$): + // - left and right delimiters ($) are not escaped by backslashes + // - pattern starts at the beginning of a line or follows a whitespace character + // - left delimiter is not followed by a whitespace character + // - right delimiter is not preseeded by a whitespace character + const inlinePattern = "(^|\\s)(?!\\\\)\\$(?!\\s)(([^$]|\\\\\\$)*[^\\\\\\s\\$](?:\\\\\\$)?)\\$"; + + md = md.replace(RegExp(displayPattern, "gm"), function(m, p1) { + const p1e = AllHtmlEntities.encode(p1); + return `
\n\n
\n\n`; + }); + + md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}`; + }); + } else { + // detect math with latex delimiters, inline: \(...\), display \[...\] + const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || + "^\\\\\\[(.*?)\\\\\\]$"; + const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || + "(^|\\s)\\\\\\((.*?)\\\\\\)"; + + md = md.replace(RegExp(displayPattern, "gms"), function(m, p1) { + const p1e = AllHtmlEntities.encode(p1); + return `
\n\n
\n\n`; + }); + + md = md.replace(RegExp(inlinePattern, "gms"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}`; + }); + } // make sure div tags always start on a new line, otherwise it will confuse // the markdown parser @@ -69,15 +102,30 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = if (!parser.isPlainText() || forceHTML) { // feed Markdown output to HTML parser const phtml = cheerio.load(parser.toHTML(), - { _useHtmlParser2: true, decodeEntities: false }) + { _useHtmlParser2: true, decodeEntities: false }); - // add fallback output for latex math, which should not be interpreted as markdown - phtml('div, span').each(function(i, e) { - const tex = phtml(e).attr('data-mx-maths') - if (tex) { - phtml(e).html(`${tex}`) - } - }); + if (SettingsStore.getValue("feature_latex_maths")) { + // original Markdown without LaTeX replacements + const parserOrig = new Markdown(orig); + const phtmlOrig = cheerio.load(parserOrig.toHTML(), + { _useHtmlParser2: true, decodeEntities: false }); + + // since maths delimiters are handled before Markdown, + // code blocks could contain mangled content. + // replace code blocks with original content + phtml('code').contents('div, span').each(function(i) { + const origData = phtmlOrig('code').contents('div, span')[i].data; + phtml('code').contents('div, span')[i].data = origData; + }); + + // add fallback output for latex math, which should not be interpreted as markdown + phtml('div, span').each(function(i, e) { + const tex = phtml(e).attr('data-mx-maths') + if (tex) { + phtml(e).html(`${tex}`) + } + }); + } return phtml.html(); } // ensure removal of escape backslashes in non-Markdown messages @@ -86,6 +134,12 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = } } +export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = {}) { + let md = mdSerialize(model); + + return markdownSerializeIfNeeded(md, {forceHTML: forceHTML}); +} + export function textSerialize(model: EditorModel) { return model.parts.reduce((text, part) => { switch (part.type) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 2fb70ecdb1..bf6c61414a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -416,6 +416,7 @@ "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message", "Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown", "Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown", + "Sends a message in TeX mode, using $ and $$ delimiters for maths": "Sends a message in TeX mode, using $ and $$ delimiters for maths", "Searches DuckDuckGo for results": "Searches DuckDuckGo for results", "/ddg is not a command": "/ddg is not a command", "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", From 997e08f21e32d61f164cfefb4c397fc48d19de71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 21 Dec 2020 10:07:46 +0100 Subject: [PATCH 0069/2651] Reorganize buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 8552b2e381..4e38b4b4eb 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -292,15 +292,16 @@ export default class ImageView extends React.Component { { metadata }
+ { redactButton } { - - { - { + + { + { @@ -310,7 +311,6 @@ export default class ImageView extends React.Component { { - { redactButton } { From ad5844fcc0b9e585e0f0f5766a33a9e7f716d43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 21 Dec 2020 20:33:03 +0100 Subject: [PATCH 0070/2651] Fix i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 32c3a61f8a..a3345caac5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1839,8 +1839,8 @@ "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", "Zoom": "Zoom", - "Zoom in": "Zoom in", "Zoom out": "Zoom out", + "Zoom in": "Zoom in", "Rotate Left": "Rotate Left", "Rotate counter-clockwise": "Rotate counter-clockwise", "Rotate Right": "Rotate Right", From fb57123e25966912277ac65927304b088b9e7db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= Date: Tue, 22 Dec 2020 12:18:38 +0100 Subject: [PATCH 0071/2651] Improve inline latex regex matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sven Mäder --- src/SlashCommands.tsx | 2 +- src/editor/serialize.ts | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index e9bde933ec..bf190fc450 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -231,7 +231,7 @@ export const Commands = [ runFn: function(roomId, args) { if (SettingsStore.getValue("feature_latex_maths")) { if (args) { - let html = markdownSerializeIfNeeded(args, {forceHTML: false}, {forceTEX: true}); + const html = markdownSerializeIfNeeded(args, {forceHTML: false}, {forceTEX: true}); return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, html)); } return reject(this.getUsage()); diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index ca798a324e..4ef722e334 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -52,18 +52,18 @@ export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, // const displayPattern = "^(? Date: Tue, 22 Dec 2020 13:31:58 +0100 Subject: [PATCH 0072/2651] Fix linting error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sven Mäder --- src/editor/serialize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 4ef722e334..3aafa70fe8 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -144,7 +144,7 @@ export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, } export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = {}) { - let md = mdSerialize(model); + const md = mdSerialize(model); return markdownSerializeIfNeeded(md, {forceHTML: forceHTML}); } From d589c6100069c5ddae0c7372760c63d40ecd84ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:09:14 +0100 Subject: [PATCH 0073/2651] Added send message button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 5 +++++ src/components/views/rooms/MessageComposer.js | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 71c0db947e..897167f745 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -239,6 +239,7 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/call/video-call.svg'); } + .mx_MessageComposer_emoji::before { mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg'); } @@ -247,6 +248,10 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/composer/sticker.svg'); } +.mx_MessageComposer_sendMessage::before { + mask-image: url('$(res)/img/element-icons/call/video-call.svg'); +} + .mx_MessageComposer_formatting { cursor: pointer; margin: 0 11px; diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 4ddff8f4b0..86ad3ddbdd 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -393,6 +393,10 @@ export default class MessageComposer extends React.Component { }); } + sendMessage = () => { + this.messageComposerInput._sendMessage(); + } + render() { const controls = [ this.state.me ? : null, @@ -450,6 +454,16 @@ export default class MessageComposer extends React.Component { ); } } + + if (true) { + controls.push(( + + )); + } } else if (this.state.tombstone) { const replacementRoomId = this.state.tombstone.getContent()['replacement_room']; From c64b2a585f3c2d1e75392657995d6b1813250f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:17:40 +0100 Subject: [PATCH 0074/2651] Added option to disable send button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 2 +- .../views/settings/tabs/user/PreferencesUserSettingsTab.js | 1 + src/settings/Settings.ts | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 86ad3ddbdd..315b1b78c7 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -455,7 +455,7 @@ export default class MessageComposer extends React.Component { } } - if (true) { + if (SettingsStore.getValue("MessageComposerInput.sendButton")) { controls.push(( Date: Sat, 9 Jan 2021 09:18:10 +0100 Subject: [PATCH 0075/2651] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ac18ccb23e..6baccf95de 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -799,6 +799,7 @@ "Show typing notifications": "Show typing notifications", "Use Command + Enter to send a message": "Use Command + Enter to send a message", "Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message", + "Show send message button": "Show send message button", "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", @@ -1412,6 +1413,7 @@ "Send a reply…": "Send a reply…", "Send an encrypted message…": "Send an encrypted message…", "Send a message…": "Send a message…", + "Send message": "Send message", "The conversation continues here.": "The conversation continues here.", "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", "You do not have permission to post to this room": "You do not have permission to post to this room", From 4538274e74938294f840abcae070ac75d052d311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:25:29 +0100 Subject: [PATCH 0076/2651] Added send message icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 2 +- res/img/element-icons/send-message.svg | 54 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 res/img/element-icons/send-message.svg diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 897167f745..8c2a997490 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -249,7 +249,7 @@ limitations under the License. } .mx_MessageComposer_sendMessage::before { - mask-image: url('$(res)/img/element-icons/call/video-call.svg'); + mask-image: url('$(res)/img/element-icons/send-message.svg'); } .mx_MessageComposer_formatting { diff --git a/res/img/element-icons/send-message.svg b/res/img/element-icons/send-message.svg new file mode 100644 index 0000000000..2e74745e21 --- /dev/null +++ b/res/img/element-icons/send-message.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + + From 263f2136502c657c4dcbb07674e965576ad562ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:27:02 +0100 Subject: [PATCH 0077/2651] Remove an empty line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 8c2a997490..8b34318f1d 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -239,7 +239,6 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/call/video-call.svg'); } - .mx_MessageComposer_emoji::before { mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg'); } From 7d120f7183eef575f16d78b1e9b4fdfabf7d2848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:33:11 +0100 Subject: [PATCH 0078/2651] Simplifie svg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/element-icons/send-message.svg | 55 +------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/res/img/element-icons/send-message.svg b/res/img/element-icons/send-message.svg index 2e74745e21..ce35bf8bc8 100644 --- a/res/img/element-icons/send-message.svg +++ b/res/img/element-icons/send-message.svg @@ -1,54 +1,3 @@ - - - - - - image/svg+xml - - - - - - - - + + From 9f1113b3bd47295d1e6f0d2e897bcb93773a06cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 16 Jan 2021 16:35:50 +0100 Subject: [PATCH 0079/2651] Watch setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 315b1b78c7..a18dded04f 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -263,6 +263,7 @@ export default class MessageComposer extends React.Component { tombstone: this._getRoomTombstone(), canSendMessages: this.props.room.maySendMessage(), showCallButtons: SettingsStore.getValue("showCallButtonsInComposer"), + showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), }; @@ -280,6 +281,12 @@ export default class MessageComposer extends React.Component { } }; + onSendButtonChanged = () => { + this.setState({ + showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + }); + } + _onWidgetUpdate = () => { this.setState({hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room)}); }; @@ -292,6 +299,8 @@ export default class MessageComposer extends React.Component { this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); + this.showSendButtonRef = SettingsStore.watchSetting( + "MessageComposerInput.sendButton", null, this.onSendButtonChanged); } _waitForOwnMember() { @@ -317,6 +326,7 @@ export default class MessageComposer extends React.Component { WidgetStore.instance.removeListener(UPDATE_EVENT, this._onWidgetUpdate); ActiveWidgetStore.removeListener('update', this._onActiveWidgetUpdate); dis.unregister(this.dispatcherRef); + SettingsStore.unwatchSetting(this.showSendButtonRef); } _onRoomStateEvents(ev, state) { @@ -455,7 +465,7 @@ export default class MessageComposer extends React.Component { } } - if (SettingsStore.getValue("MessageComposerInput.sendButton")) { + if (this.state.showSendButton) { controls.push(( Date: Sat, 16 Jan 2021 16:37:50 +0100 Subject: [PATCH 0080/2651] Rename setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 6 +++--- .../views/settings/tabs/user/PreferencesUserSettingsTab.js | 2 +- src/settings/Settings.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index a18dded04f..1e43aa6652 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -263,7 +263,7 @@ export default class MessageComposer extends React.Component { tombstone: this._getRoomTombstone(), canSendMessages: this.props.room.maySendMessage(), showCallButtons: SettingsStore.getValue("showCallButtonsInComposer"), - showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), }; @@ -283,7 +283,7 @@ export default class MessageComposer extends React.Component { onSendButtonChanged = () => { this.setState({ - showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), }); } @@ -300,7 +300,7 @@ export default class MessageComposer extends React.Component { MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); this.showSendButtonRef = SettingsStore.watchSetting( - "MessageComposerInput.sendButton", null, this.onSendButtonChanged); + "MessageComposerInput.showSendButton", null, this.onSendButtonChanged); } _waitForOwnMember() { diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js index 31971b7167..eff0824d59 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js @@ -34,7 +34,7 @@ export default class PreferencesUserSettingsTab extends React.Component { 'MessageComposerInput.suggestEmoji', 'sendTypingNotifications', 'MessageComposerInput.ctrlEnterToSend', - `MessageComposerInput.sendButton`, + `MessageComposerInput.showSendButton`, ]; static TIMELINE_SETTINGS = [ diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 50d0f919e6..2d8385240c 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -336,7 +336,7 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: isMac ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"), default: false, }, - "MessageComposerInput.sendButton": { + "MessageComposerInput.showSendButton": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td("Show send message button"), default: false, From c9f5c90047e0140da31050d97d0f831bf50858c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 16 Jan 2021 16:43:47 +0100 Subject: [PATCH 0081/2651] Rename method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 1e43aa6652..9683c4c79e 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -281,7 +281,7 @@ export default class MessageComposer extends React.Component { } }; - onSendButtonChanged = () => { + onShowSendButtonChanged = () => { this.setState({ showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), }); @@ -300,7 +300,7 @@ export default class MessageComposer extends React.Component { MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); this.showSendButtonRef = SettingsStore.watchSetting( - "MessageComposerInput.showSendButton", null, this.onSendButtonChanged); + "MessageComposerInput.showSendButton", null, this.onShowSendButtonChanged); } _waitForOwnMember() { From 90ad3360b628136f4e5dfc69db2c4fd81e07f0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 24 Jan 2021 09:15:11 +0100 Subject: [PATCH 0082/2651] Fixed read receipts? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_EventTile.scss | 8 +------- src/components/views/rooms/EventTile.js | 6 +++--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 429ac7ed4b..e2cff70841 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -258,17 +258,11 @@ $left-gutter: 64px; display: inline-block; width: 14px; height: 14px; - top: 29px; + top: -20px; user-select: none; z-index: 1; } -.mx_EventTile_continuation .mx_EventTile_readAvatars, -.mx_EventTile_info .mx_EventTile_readAvatars, -.mx_EventTile_emote .mx_EventTile_readAvatars { - top: 7px; -} - .mx_EventTile_readAvatars .mx_BaseAvatar { position: absolute; display: inline-block; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 4df74f77ce..7a2047af70 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -950,9 +950,6 @@ export default class EventTile extends React.Component { return (
{ ircTimestamp } -
- { readAvatars } -
{ sender } { ircPadlock }
@@ -971,6 +968,9 @@ export default class EventTile extends React.Component { { reactionsRow } { actionBar }
+
+ { readAvatars } +
{ // The avatar goes after the event tile as it's absolutely positioned to be over the // event tile line, so needs to be later in the DOM so it appears on top (this avoids From 5de92b68d954ba3f997f2d5713d954ee05303b2e Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 27 Jan 2021 11:39:57 +0000 Subject: [PATCH 0083/2651] Show a specific error for hs_disabled --- src/components/structures/LoggedInView.tsx | 2 +- src/components/structures/RoomStatusBar.js | 4 ++++ src/components/structures/auth/Login.tsx | 3 +++ src/components/structures/auth/Registration.tsx | 1 + src/toasts/ServerLimitToast.tsx | 1 + src/utils/ErrorUtils.js | 1 + 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 70ec2b7033..508b7f05e7 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -94,7 +94,7 @@ interface IProps { interface IUsageLimit { // eslint-disable-next-line camelcase - limit_type: "monthly_active_user" | string; + limit_type: "monthly_active_user" | "hs_disabled" | string; // eslint-disable-next-line camelcase admin_contact?: string; } diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index c1c4ad6292..aa4bceba74 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -195,6 +195,10 @@ export default class RoomStatusBar extends React.Component { "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " + "Please contact your service administrator to continue using the service.", ), + 'hs_disabled': _td( + "Your message wasn't sent because this homeserver has been blocked by it's administrator. " + + "Please contact your service administrator to continue using the service.", + ), '': _td( "Your message wasn't sent because this homeserver has exceeded a resource limit. " + "Please contact your service administrator to continue using the service.", diff --git a/src/components/structures/auth/Login.tsx b/src/components/structures/auth/Login.tsx index 606aeb44ab..a9fd363763 100644 --- a/src/components/structures/auth/Login.tsx +++ b/src/components/structures/auth/Login.tsx @@ -218,6 +218,9 @@ export default class LoginComponent extends React.PureComponent 'monthly_active_user': _td( "This homeserver has hit its Monthly Active User limit.", ), + 'hs_blocked': _td( + "This homeserver has been blocked by it's administrator.", + ), '': _td( "This homeserver has exceeded one of its resource limits.", ), diff --git a/src/components/structures/auth/Registration.tsx b/src/components/structures/auth/Registration.tsx index 095f3d3433..f9d338902c 100644 --- a/src/components/structures/auth/Registration.tsx +++ b/src/components/structures/auth/Registration.tsx @@ -276,6 +276,7 @@ export default class Registration extends React.Component { response.data.admin_contact, { 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."), + 'hs_blocked': _td("This homeserver has been blocked by it's administrator."), '': _td("This homeserver has exceeded one of its resource limits."), }, ); diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index d35140be3d..9dbe8c05f1 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -26,6 +26,7 @@ const TOAST_KEY = "serverlimit"; export const showToast = (limitType: string, adminContact?: string, syncError?: boolean) => { const errorText = messageForResourceLimitError(limitType, adminContact, { 'monthly_active_user': _td("Your homeserver has exceeded its user limit."), + 'hs_blocked': _td("This homeserver has been blocked by it's administrator."), '': _td("Your homeserver has exceeded one of its resource limits."), }); const contactText = messageForResourceLimitError(limitType, adminContact, { diff --git a/src/utils/ErrorUtils.js b/src/utils/ErrorUtils.js index f0a4d7c49e..2c6acd5503 100644 --- a/src/utils/ErrorUtils.js +++ b/src/utils/ErrorUtils.js @@ -62,6 +62,7 @@ export function messageForSyncError(err) { err.data.admin_contact, { 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."), + 'hs_blocked': _td("This homeserver has been blocked by its administrator."), '': _td("This homeserver has exceeded one of its resource limits."), }, ); From 27724a93d28d7945e49f94b5fa1158095bd84d8d Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 27 Jan 2021 11:42:36 +0000 Subject: [PATCH 0084/2651] new strings --- src/i18n/strings/en_EN.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8d047ea3f1..e55ab581ca 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -650,6 +650,7 @@ "Unexpected error resolving identity server configuration": "Unexpected error resolving identity server configuration", "The message you are trying to send is too large.": "The message you are trying to send is too large.", "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.", + "This homeserver has been blocked by its administrator.": "This homeserver has been blocked by its administrator.", "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.", "Please contact your service administrator to continue using the service.": "Please contact your service administrator to continue using the service.", "Unable to connect to Homeserver. Retrying...": "Unable to connect to Homeserver. Retrying...", @@ -727,6 +728,7 @@ "Enable desktop notifications": "Enable desktop notifications", "Enable": "Enable", "Your homeserver has exceeded its user limit.": "Your homeserver has exceeded its user limit.", + "This homeserver has been blocked by it's administrator.": "This homeserver has been blocked by it's administrator.", "Your homeserver has exceeded one of its resource limits.": "Your homeserver has exceeded one of its resource limits.", "Contact your server admin.": "Contact your server admin.", "Warning": "Warning", @@ -2471,6 +2473,7 @@ "Filter rooms and people": "Filter rooms and people", "You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.", "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.", + "Your message wasn't sent because this homeserver has been blocked by it's administrator. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has been blocked by it's administrator. Please contact your service administrator to continue using the service.", "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.", "%(count)s of your messages have not been sent.|other": "Some of your messages have not been sent.", "%(count)s of your messages have not been sent.|one": "Your message was not sent.", From c4f0987487c58ed88dacc62ff155dfa140729fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= Date: Fri, 29 Jan 2021 00:11:06 +0100 Subject: [PATCH 0085/2651] Use TeX and LaTeX delimiters by default for serialize --- src/SlashCommands.tsx | 2 +- src/editor/serialize.ts | 71 +++++++++++++++++++++---------------- src/i18n/strings/en_EN.json | 2 +- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index bf190fc450..387b9991db 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -227,7 +227,7 @@ export const Commands = [ new Command({ command: 'tex', args: '', - description: _td('Sends a message in TeX mode, using $ and $$ delimiters for maths'), + description: _td('Sends a message in TeX mode, without restrictions'), runFn: function(roomId, args) { if (SettingsStore.getValue("feature_latex_maths")) { if (args) { diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 3aafa70fe8..61d7878de5 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -47,28 +47,12 @@ export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, if (SettingsStore.getValue("feature_latex_maths")) { if (forceTEX) { - // detect math with tex delimiters, inline: $...$, display $$...$$ - // preferably use negative lookbehinds, not supported in all major browsers: - // const displayPattern = "^(?\n\n
\n\n`; + md = md.replace(RegExp(displayPattern, "gm"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}
\n\n
\n\n`; }); md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1, p2) { @@ -76,24 +60,51 @@ export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, return `${p1}`; }); } else { + // detect math with tex delimiters, inline: $...$, display $$...$$ + // preferably use negative lookbehinds, not supported in all major browsers: + // const displayPattern = "^(?\n\n
\n\n`; + }); + + md = md.replace(RegExp(inlinePatternDollar, "gm"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}`; + }); + // detect math with latex delimiters, inline: \(...\), display \[...\] // conditions for display math detection \[...\]: - // - pattern starts at beginning of line - // - pattern ends at end of line + // - pattern starts at beginning of line or is not prefixed with backslash + // - pattern is not empty const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || - "^\\\\\\[(.*?)\\\\\\]$"; + "(^|[^\\\\])\\\\\\[(?!\\\\\\])(.*?)\\\\\\]"; // conditions for inline math detection \(...\): // - pattern starts at beginning of line or is not prefixed with backslash - // (this allows escaping and requires that multiple consecutive - // patterns are separated by at least one character) + // - pattern is not empty const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || - "(^|[^\\\\])\\\\\\((.*?)\\\\\\)"; + "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)"; - md = md.replace(RegExp(displayPattern, "gms"), function(m, p1) { - const p1e = AllHtmlEntities.encode(p1); - return `
\n\n
\n\n`; + md = md.replace(RegExp(displayPattern, "gms"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}
\n\n
\n\n`; }); md = md.replace(RegExp(inlinePattern, "gms"), function(m, p1, p2) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bf6c61414a..bcae343550 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -416,7 +416,7 @@ "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message", "Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown", "Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown", - "Sends a message in TeX mode, using $ and $$ delimiters for maths": "Sends a message in TeX mode, using $ and $$ delimiters for maths", + "Sends a message in TeX mode, without restrictions": "Sends a message in TeX mode, without restrictions", "Searches DuckDuckGo for results": "Searches DuckDuckGo for results", "/ddg is not a command": "/ddg is not a command", "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", From bcc069771061b7559313ded1f453f91eaf0f283f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= Date: Fri, 29 Jan 2021 13:05:49 +0100 Subject: [PATCH 0086/2651] Remove /tex command --- src/SlashCommands.tsx | 18 ------ src/editor/serialize.ts | 108 +++++++++++++++--------------------- src/i18n/strings/en_EN.json | 1 - 3 files changed, 44 insertions(+), 83 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 387b9991db..79c21c4af5 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -48,7 +48,6 @@ import SettingsStore from "./settings/SettingsStore"; import {UIFeature} from "./settings/UIFeature"; import {CHAT_EFFECTS} from "./effects" import CallHandler from "./CallHandler"; -import {markdownSerializeIfNeeded} from './editor/serialize'; // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 interface HTMLInputEvent extends Event { @@ -224,23 +223,6 @@ export const Commands = [ }, category: CommandCategories.messages, }), - new Command({ - command: 'tex', - args: '', - description: _td('Sends a message in TeX mode, without restrictions'), - runFn: function(roomId, args) { - if (SettingsStore.getValue("feature_latex_maths")) { - if (args) { - const html = markdownSerializeIfNeeded(args, {forceHTML: false}, {forceTEX: true}); - return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, html)); - } - return reject(this.getUsage()); - } else { - return reject("Render LaTeX maths in messages needs to be enabled in Labs"); - } - }, - category: CommandCategories.messages, - }), new Command({ command: 'ddg', args: '', diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 61d7878de5..6b1d97a0ef 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -41,77 +41,63 @@ export function mdSerialize(model: EditorModel) { }, ""); } -export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, {forceTEX = false} = {}) { +export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = {}) { + let md = mdSerialize(model); // copy of raw input to remove unwanted math later const orig = md; if (SettingsStore.getValue("feature_latex_maths")) { - if (forceTEX) { - const displayPattern = "(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$"; - const inlinePattern = "(^|[^\\\\$])\\$(([^$]|\\\\\\$)*([^\\\\\\$]|\\\\\\$))\\$"; + // detect math with tex delimiters, inline: $...$, display $$...$$ + // preferably use negative lookbehinds, not supported in all major browsers: + // const displayPattern = "^(?\n\n
\n\n`; - }); + // conditions for display math detection $$...$$: + // - pattern starts at beginning of line or is not prefixed with backslash or dollar + // - left delimiter ($$) is not escaped by backslash + const displayPatternDollar = "(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$"; - md = md.replace(RegExp(inlinePattern, "gm"), function(m, p1, p2) { - const p2e = AllHtmlEntities.encode(p2); - return `${p1}`; - }); - } else { - // detect math with tex delimiters, inline: $...$, display $$...$$ - // preferably use negative lookbehinds, not supported in all major browsers: - // const displayPattern = "^(?\n\n
\n\n`; + }); - // conditions for inline math detection $...$: - // - pattern starts at beginning of line, follows whitespace character or punctuation - // - pattern is on a single line - // - left and right delimiters ($) are not escaped by backslashes - // - left delimiter is not followed by whitespace character - // - right delimiter is not prefixed with whitespace character - const inlinePatternDollar = "(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$"; + md = md.replace(RegExp(inlinePatternDollar, "gm"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}`; + }); - md = md.replace(RegExp(displayPatternDollar, "gm"), function(m, p1, p2) { - const p2e = AllHtmlEntities.encode(p2); - return `${p1}
\n\n
\n\n`; - }); + // detect math with latex delimiters, inline: \(...\), display \[...\] - md = md.replace(RegExp(inlinePatternDollar, "gm"), function(m, p1, p2) { - const p2e = AllHtmlEntities.encode(p2); - return `${p1}`; - }); + // conditions for display math detection \[...\]: + // - pattern starts at beginning of line or is not prefixed with backslash + // - pattern is not empty + const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || + "(^|[^\\\\])\\\\\\[(?!\\\\\\])(.*?)\\\\\\]"; - // detect math with latex delimiters, inline: \(...\), display \[...\] + // conditions for inline math detection \(...\): + // - pattern starts at beginning of line or is not prefixed with backslash + // - pattern is not empty + const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || + "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)"; - // conditions for display math detection \[...\]: - // - pattern starts at beginning of line or is not prefixed with backslash - // - pattern is not empty - const displayPattern = (SdkConfig.get()['latex_maths_delims'] || {})['display_pattern'] || - "(^|[^\\\\])\\\\\\[(?!\\\\\\])(.*?)\\\\\\]"; + md = md.replace(RegExp(displayPattern, "gms"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}
\n\n
\n\n`; + }); - // conditions for inline math detection \(...\): - // - pattern starts at beginning of line or is not prefixed with backslash - // - pattern is not empty - const inlinePattern = (SdkConfig.get()['latex_maths_delims'] || {})['inline_pattern'] || - "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)"; - - md = md.replace(RegExp(displayPattern, "gms"), function(m, p1, p2) { - const p2e = AllHtmlEntities.encode(p2); - return `${p1}
\n\n
\n\n`; - }); - - md = md.replace(RegExp(inlinePattern, "gms"), function(m, p1, p2) { - const p2e = AllHtmlEntities.encode(p2); - return `${p1}`; - }); - } + md = md.replace(RegExp(inlinePattern, "gms"), function(m, p1, p2) { + const p2e = AllHtmlEntities.encode(p2); + return `${p1}`; + }); // make sure div tags always start on a new line, otherwise it will confuse // the markdown parser @@ -154,12 +140,6 @@ export function markdownSerializeIfNeeded(md: string, {forceHTML = false} = {}, } } -export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = {}) { - const md = mdSerialize(model); - - return markdownSerializeIfNeeded(md, {forceHTML: forceHTML}); -} - export function textSerialize(model: EditorModel) { return model.parts.reduce((text, part) => { switch (part.type) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bcae343550..2fb70ecdb1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -416,7 +416,6 @@ "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message", "Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown", "Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown", - "Sends a message in TeX mode, without restrictions": "Sends a message in TeX mode, without restrictions", "Searches DuckDuckGo for results": "Searches DuckDuckGo for results", "/ddg is not a command": "/ddg is not a command", "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", From ac1f9b4247f7eefacc969bfcbdbf30984c8e15e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20M=C3=A4der?= Date: Fri, 29 Jan 2021 15:49:20 +0100 Subject: [PATCH 0087/2651] Add config keys for alternative patterns --- src/editor/serialize.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 6b1d97a0ef..6655c64347 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -55,7 +55,9 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = // conditions for display math detection $$...$$: // - pattern starts at beginning of line or is not prefixed with backslash or dollar // - left delimiter ($$) is not escaped by backslash - const displayPatternDollar = "(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$"; + const displayPatternAlternative = (SdkConfig.get()['latex_maths_delims'] || + {})['display_pattern_alternative'] || + "(^|[^\\\\$])\\$\\$(([^$]|\\\\\\$)+?)\\$\\$"; // conditions for inline math detection $...$: // - pattern starts at beginning of line, follows whitespace character or punctuation @@ -63,14 +65,16 @@ export function htmlSerializeIfNeeded(model: EditorModel, {forceHTML = false} = // - left and right delimiters ($) are not escaped by backslashes // - left delimiter is not followed by whitespace character // - right delimiter is not prefixed with whitespace character - const inlinePatternDollar = "(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$"; + const inlinePatternAlternative = (SdkConfig.get()['latex_maths_delims'] || + {})['inline_pattern_alternative'] || + "(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$"; - md = md.replace(RegExp(displayPatternDollar, "gm"), function(m, p1, p2) { + md = md.replace(RegExp(displayPatternAlternative, "gm"), function(m, p1, p2) { const p2e = AllHtmlEntities.encode(p2); return `${p1}
\n\n
\n\n`; }); - md = md.replace(RegExp(inlinePatternDollar, "gm"), function(m, p1, p2) { + md = md.replace(RegExp(inlinePatternAlternative, "gm"), function(m, p1, p2) { const p2e = AllHtmlEntities.encode(p2); return `${p1}`; }); From cc38bcf333bc9fdd7d8ebc7d0b4d06330ba7e359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 6 Feb 2021 15:09:21 +0100 Subject: [PATCH 0088/2651] Display room name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/Pill.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index daa4cb70e2..f1527c48b1 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -226,7 +226,7 @@ class Pill extends React.Component { case Pill.TYPE_ROOM_MENTION: { const room = this.state.room; if (room) { - linkText = resource; + linkText = room.name; if (this.props.shouldShowPillAvatar) { avatar =
); } From 0daed986275b34287a9ef8383f500cf07b93b093 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 12:51:17 +0000 Subject: [PATCH 0166/2651] Do not process an older usage event if we've already processed a newer one --- src/components/structures/LoggedInView.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index c76cd7cee7..77c846d816 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -108,6 +108,7 @@ interface IState { }; }; usageLimitEventContent?: IUsageLimit; + usageLimitEventTs?: number; useCompactLayout: boolean; } @@ -339,9 +340,18 @@ class LoggedInView extends React.Component { e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' ); }); + if (this.state.usageLimitEventTs > usageLimitEvent.getTs()) { + // We've processed a newer event than this one, so ignore it. + return; + } const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent(); this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent); - this.setState({ usageLimitEventContent }); + this.setState({ + usageLimitEventContent, + usageLimitEventTs: usageLimitEvent.getTs(), + // This is a fresh toast, we can show toasts again + usageLimitDismissed: false, + }); }; _onPaste = (ev) => { From aa86c1d751087d0f49b624bbc3fc82589d6e69ac Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 12:51:47 +0000 Subject: [PATCH 0167/2651] Ensure that a dismissed usage alert toast stays dismissed --- src/components/structures/LoggedInView.tsx | 19 +++++++++++++++++-- src/toasts/ServerLimitToast.tsx | 7 +++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 77c846d816..60969e3220 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -107,6 +107,7 @@ interface IState { errcode: string; }; }; + usageLimitDismissed: boolean; usageLimitEventContent?: IUsageLimit; usageLimitEventTs?: number; useCompactLayout: boolean; @@ -152,6 +153,7 @@ class LoggedInView extends React.Component { syncErrorData: undefined, // use compact timeline view useCompactLayout: SettingsStore.getValue('useCompactLayout'), + usageLimitDismissed: false, }; // stash the MatrixClient in case we log out before we are unmounted @@ -303,14 +305,27 @@ class LoggedInView extends React.Component { } }; + _onHideToast = () => { + this.setState({ + usageLimitDismissed: true, + }); + } + _calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) { const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED"; if (error) { usageLimitEventContent = syncError.error.data; } - if (usageLimitEventContent) { - showServerLimitToast(usageLimitEventContent.limit_type, usageLimitEventContent.admin_contact, error); + // usageLimitDismissed is true when the user has explicitly hidden the toast + // and it will be reset to false if a *new* usage alert comes in. + if (usageLimitEventContent && this.state.usageLimitDismissed) { + showServerLimitToast( + usageLimitEventContent.limit_type, + this._onHideToast, + usageLimitEventContent.admin_contact, + error, + ); } else { hideServerLimitToast(); } diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index d35140be3d..068d62f9ea 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -23,7 +23,7 @@ import {messageForResourceLimitError} from "../utils/ErrorUtils"; const TOAST_KEY = "serverlimit"; -export const showToast = (limitType: string, adminContact?: string, syncError?: boolean) => { +export const showToast = (limitType: string, onHideToast: () => void, adminContact?: string, syncError?: boolean) => { const errorText = messageForResourceLimitError(limitType, adminContact, { 'monthly_active_user': _td("Your homeserver has exceeded its user limit."), '': _td("Your homeserver has exceeded one of its resource limits."), @@ -38,7 +38,10 @@ export const showToast = (limitType: string, adminContact?: string, syncError?: props: { description: {errorText} {contactText}, acceptLabel: _t("Ok"), - onAccept: hideToast, + onAccept: () => { + hideToast() + onHideToast() + }, }, component: GenericToast, priority: 70, From 84bcdf66f2a02f0fa779a5e80646b5e108614439 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 23 Feb 2021 13:00:05 +0000 Subject: [PATCH 0168/2651] Fix TS check --- src/components/structures/LoggedInView.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 60969e3220..f3cce3ef34 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -336,10 +336,12 @@ class LoggedInView extends React.Component { if (!serverNoticeList) return []; const events = []; + let pinnedEventTs = 0; for (const room of serverNoticeList) { const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", ""); if (!pinStateEvent || !pinStateEvent.getContent().pinned) continue; + pinnedEventTs = pinStateEvent.getTs(); const pinnedEventIds = pinStateEvent.getContent().pinned.slice(0, MAX_PINNED_NOTICES_PER_ROOM); for (const eventId of pinnedEventIds) { @@ -349,21 +351,22 @@ class LoggedInView extends React.Component { } } + if (pinnedEventTs && this.state.usageLimitEventTs > pinnedEventTs) { + // We've processed a newer event than this one, so ignore it. + return; + } + const usageLimitEvent = events.find((e) => { return ( e && e.getType() === 'm.room.message' && e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' ); }); - if (this.state.usageLimitEventTs > usageLimitEvent.getTs()) { - // We've processed a newer event than this one, so ignore it. - return; - } const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent(); this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent); this.setState({ usageLimitEventContent, - usageLimitEventTs: usageLimitEvent.getTs(), + usageLimitEventTs: pinnedEventTs, // This is a fresh toast, we can show toasts again usageLimitDismissed: false, }); From 64945d4ccf7b565afd921130c1a88d58b7e7fb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 23 Feb 2021 19:14:36 +0100 Subject: [PATCH 0169/2651] Add a comment and use rems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_EventTile.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4db16217e7..6f7cd46d51 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -257,7 +257,9 @@ $left-gutter: 64px; display: inline-block; width: 14px; height: 14px; - top: -20px; + // This aligns the avatar with the last line of the + // message. We want to move it one line up - 2.2rem + top: -2.2rem; user-select: none; z-index: 1; } From 3f0e8e4afcb7b9e77ed40448319f29d5c3368fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 23 Feb 2021 19:16:52 +0100 Subject: [PATCH 0170/2651] Delint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_EventTile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 6f7cd46d51..5091d55c08 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -257,7 +257,7 @@ $left-gutter: 64px; display: inline-block; width: 14px; height: 14px; - // This aligns the avatar with the last line of the + // This aligns the avatar with the last line of the // message. We want to move it one line up - 2.2rem top: -2.2rem; user-select: none; From e5d68142c6e35811a37d2ea709167ead99247a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 23 Feb 2021 20:47:42 +0100 Subject: [PATCH 0171/2651] Remove zoom icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/zoom-white.svg | 59 ---------------------- src/components/views/elements/ImageView.js | 3 -- 2 files changed, 62 deletions(-) delete mode 100644 res/img/zoom-white.svg diff --git a/res/img/zoom-white.svg b/res/img/zoom-white.svg deleted file mode 100644 index 19379cb881..0000000000 --- a/res/img/zoom-white.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 4e38b4b4eb..be849d1dde 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -293,9 +293,6 @@ export default class ImageView extends React.Component {
{ redactButton } - - { - { From 35663c35d27e6fc6211ad501375c49a1b8c469d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 23 Feb 2021 20:49:31 +0100 Subject: [PATCH 0172/2651] Reorder the icons according to the design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index be849d1dde..7c40604a88 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -293,18 +293,18 @@ export default class ImageView extends React.Component {
{ redactButton } + + { + + + { + { { - - { - - - { - { From 6cf19e889777a1732182274ae0408dc8a746d7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 23 Feb 2021 21:04:21 +0100 Subject: [PATCH 0173/2651] Update icons according to the design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/cancel-white.svg | 10 --- res/img/download-white.svg | 95 ---------------------- res/img/image-view/close.svg | 4 + res/img/image-view/download.svg | 3 + res/img/image-view/rotate-ccw.svg | 3 + res/img/image-view/rotate-cw.svg | 3 + res/img/image-view/zoom-in.svg | 3 + res/img/image-view/zoom-out.svg | 3 + res/img/minus-white.svg | 64 --------------- res/img/plus-white.svg | 73 ----------------- res/img/rotate-ccw.svg | 1 - res/img/rotate-cw.svg | 1 - src/components/views/elements/ImageView.js | 12 +-- 13 files changed, 25 insertions(+), 250 deletions(-) delete mode 100644 res/img/cancel-white.svg delete mode 100644 res/img/download-white.svg create mode 100644 res/img/image-view/close.svg create mode 100644 res/img/image-view/download.svg create mode 100644 res/img/image-view/rotate-ccw.svg create mode 100644 res/img/image-view/rotate-cw.svg create mode 100644 res/img/image-view/zoom-in.svg create mode 100644 res/img/image-view/zoom-out.svg delete mode 100644 res/img/minus-white.svg delete mode 100644 res/img/plus-white.svg delete mode 100644 res/img/rotate-ccw.svg delete mode 100644 res/img/rotate-cw.svg diff --git a/res/img/cancel-white.svg b/res/img/cancel-white.svg deleted file mode 100644 index 65e14c2fbc..0000000000 --- a/res/img/cancel-white.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - Slice 1 - Created with Sketch. - - - - - \ No newline at end of file diff --git a/res/img/download-white.svg b/res/img/download-white.svg deleted file mode 100644 index 5c800b350e..0000000000 --- a/res/img/download-white.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - image/svg+xml - - Fill 75 - - - - - - Fill 75 - Created with Sketch. - - - - - - - - - - - - - diff --git a/res/img/image-view/close.svg b/res/img/image-view/close.svg new file mode 100644 index 0000000000..f849425264 --- /dev/null +++ b/res/img/image-view/close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/img/image-view/download.svg b/res/img/image-view/download.svg new file mode 100644 index 0000000000..c51deed876 --- /dev/null +++ b/res/img/image-view/download.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/image-view/rotate-ccw.svg b/res/img/image-view/rotate-ccw.svg new file mode 100644 index 0000000000..85ea3198de --- /dev/null +++ b/res/img/image-view/rotate-ccw.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/image-view/rotate-cw.svg b/res/img/image-view/rotate-cw.svg new file mode 100644 index 0000000000..e337f3420e --- /dev/null +++ b/res/img/image-view/rotate-cw.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/image-view/zoom-in.svg b/res/img/image-view/zoom-in.svg new file mode 100644 index 0000000000..c0816d489e --- /dev/null +++ b/res/img/image-view/zoom-in.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/image-view/zoom-out.svg b/res/img/image-view/zoom-out.svg new file mode 100644 index 0000000000..0539e8c81a --- /dev/null +++ b/res/img/image-view/zoom-out.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/minus-white.svg b/res/img/minus-white.svg deleted file mode 100644 index 2921f34980..0000000000 --- a/res/img/minus-white.svg +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - image/svg+xml - - Fill 75 - - - - - - Fill 75 - Created with Sketch. - - - diff --git a/res/img/plus-white.svg b/res/img/plus-white.svg deleted file mode 100644 index 7759ace50a..0000000000 --- a/res/img/plus-white.svg +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - image/svg+xml - - Fill 75 - - - - - - Fill 75 - Created with Sketch. - - - - diff --git a/res/img/rotate-ccw.svg b/res/img/rotate-ccw.svg deleted file mode 100644 index 3924eca040..0000000000 --- a/res/img/rotate-ccw.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/res/img/rotate-cw.svg b/res/img/rotate-cw.svg deleted file mode 100644 index 91021c96d8..0000000000 --- a/res/img/rotate-cw.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 7c40604a88..10e5b083da 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -294,22 +294,22 @@ export default class ImageView extends React.Component {
{ redactButton } - { + { - { + { - { + { - { + { - { + { - { + {
Date: Tue, 23 Feb 2021 19:41:23 -0500 Subject: [PATCH 0174/2651] Vectorize spinners This replaces most of the GIF spinners used throughout the app with an SVG that respects the user's theme. However, spinner.gif is still retained for the room timeline avatar uploader component, since it is more difficult to replace. Signed-off-by: Robin Townsend --- res/css/views/elements/_InlineSpinner.scss | 19 +- res/css/views/elements/_Spinner.scss | 16 ++ res/img/logo-spinner.svg | 141 +++++++++++ res/img/spinner.svg | 235 +++++++----------- .../views/elements/InlineSpinner.js | 26 +- src/components/views/elements/Spinner.js | 28 ++- 6 files changed, 304 insertions(+), 161 deletions(-) create mode 100644 res/img/logo-spinner.svg diff --git a/res/css/views/elements/_InlineSpinner.scss b/res/css/views/elements/_InlineSpinner.scss index 6b91e45923..c850191b93 100644 --- a/res/css/views/elements/_InlineSpinner.scss +++ b/res/css/views/elements/_InlineSpinner.scss @@ -18,7 +18,24 @@ limitations under the License. display: inline; } -.mx_InlineSpinner_spin img { +.mx_InlineSpinner img, .mx_InlineSpinner_icon { margin: 0px 6px; vertical-align: -3px; } + +@keyframes spin { + from { + transform: rotateZ(0deg); + } + to { + transform: rotateZ(360deg); + } +} + +.mx_InlineSpinner_icon { + display: inline-block; + background-color: $primary-fg-color; + mask: url('$(res)/img/spinner.svg'); + mask-size: contain; + animation: 1.1s steps(12, end) infinite spin; +} diff --git a/res/css/views/elements/_Spinner.scss b/res/css/views/elements/_Spinner.scss index 01b4f23c2c..93d5e2d96c 100644 --- a/res/css/views/elements/_Spinner.scss +++ b/res/css/views/elements/_Spinner.scss @@ -26,3 +26,19 @@ limitations under the License. .mx_MatrixChat_middlePanel .mx_Spinner { height: auto; } + +@keyframes spin { + from { + transform: rotateZ(0deg); + } + to { + transform: rotateZ(360deg); + } +} + +.mx_Spinner_icon { + background-color: $primary-fg-color; + mask: url('$(res)/img/spinner.svg'); + mask-size: contain; + animation: 1.1s steps(12, end) infinite spin; +} diff --git a/res/img/logo-spinner.svg b/res/img/logo-spinner.svg new file mode 100644 index 0000000000..08965e982e --- /dev/null +++ b/res/img/logo-spinner.svg @@ -0,0 +1,141 @@ + + + start + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/spinner.svg b/res/img/spinner.svg index 08965e982e..c3680f19d2 100644 --- a/res/img/spinner.svg +++ b/res/img/spinner.svg @@ -1,141 +1,96 @@ - - - start - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js index 73316157f4..2dad9ebe1e 100644 --- a/src/components/views/elements/InlineSpinner.js +++ b/src/components/views/elements/InlineSpinner.js @@ -24,23 +24,29 @@ export default class InlineSpinner extends React.Component { const h = this.props.h || 16; const imgClass = this.props.imgClassName || ""; - let imageSource; + let icon; if (SettingsStore.getValue('feature_new_spinner')) { - imageSource = require("../../../../res/img/spinner.svg"); - } else { - imageSource = require("../../../../res/img/spinner.gif"); - } - - return ( -
+ icon = ( -
+ ); + } else { + icon = ( +
+ ); + } + + return ( +
{ icon }
); } } diff --git a/src/components/views/elements/Spinner.js b/src/components/views/elements/Spinner.js index 4d2dcea90a..43030d01d5 100644 --- a/src/components/views/elements/Spinner.js +++ b/src/components/views/elements/Spinner.js @@ -21,23 +21,31 @@ import {_t} from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; const Spinner = ({w = 32, h = 32, imgClassName, message}) => { - let imageSource; + let icon; if (SettingsStore.getValue('feature_new_spinner')) { - imageSource = require("../../../../res/img/spinner.svg"); - } else { - imageSource = require("../../../../res/img/spinner.gif"); - } - - return ( -
- { message &&
{ message}
 
} + icon = ( + ); + } else { + icon = ( +
+ ); + } + + return ( +
+ { message &&
{ message }
 
} + { icon }
); }; From d85ab382f52297808491f5db72c7d362bd07434d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 07:47:59 +0100 Subject: [PATCH 0175/2651] Reorganize elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 48 +++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 10e5b083da..d37f6ee618 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -284,33 +284,35 @@ export default class ImageView extends React.Component { ref={ref => this.focusLock = ref} >
-
+
+
{ this.getName() }
- { sizeRes } + { sizeRes } { metadata } -
-
- { redactButton } - - { - - - { - - - { - - - { - - - { - - - { - +
+
+ { redactButton } + + { + + + { + + + { + + + { + + + { + + + { + +
Date: Wed, 24 Feb 2021 07:50:10 +0100 Subject: [PATCH 0176/2651] Remove name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index d37f6ee618..3007fe566b 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -124,14 +124,6 @@ export default class ImageView extends React.Component { }); }; - getName() { - let name = this.props.name; - if (name && this.props.link) { - name = { name }; - } - return name; - } - onRotateCounterClockwiseClick = () => { const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; @@ -286,11 +278,8 @@ export default class ImageView extends React.Component {
-
- { this.getName() } -
- { sizeRes } - { metadata } + { sizeRes } + { metadata }
{ redactButton } From 497131874b2c16e3d532558557bec59057ade65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 07:53:33 +0100 Subject: [PATCH 0177/2651] Remove size info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 3007fe566b..e3dbe2a411 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -20,7 +20,6 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {formatDate} from '../../../DateUtils'; import { _t } from '../../../languageHandler'; -import filesize from "filesize"; import AccessibleButton from "./AccessibleButton"; import Modal from "../../../Modal"; import * as sdk from "../../../index"; @@ -204,23 +203,6 @@ export default class ImageView extends React.Component { let mayRedact = false; const showEventMeta = !!this.props.mxEvent; - let res; - if (this.props.width && this.props.height) { - res = this.props.width + "x" + this.props.height + "px"; - } - - let size; - if (this.props.fileSize) { - size = filesize(this.props.fileSize); - } - - let sizeRes; - if (size && res) { - sizeRes = size + ", " + res; - } else { - sizeRes = size || res; - } - let metadata; if (showEventMeta) { // Figure out the sender, defaulting to mxid @@ -278,7 +260,6 @@ export default class ImageView extends React.Component {
- { sizeRes } { metadata }
From 768d26818965d10646e3605c70cabaf7e596f3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 07:54:36 +0100 Subject: [PATCH 0178/2651] Fix css MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 43333a25e6..ee02a1dce8 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -53,6 +53,9 @@ limitations under the License. z-index: 1000; align-self: flex-start; pointer-events: all; + display: flex; + justify-content: space-between; + width: 100%; } .mx_ImageView_toolbar { @@ -76,17 +79,7 @@ limitations under the License. padding: 5px; } -.mx_ImageView_name { - font-size: $font-18px; - margin-bottom: 6px; - word-wrap: break-word; -} - .mx_ImageView_metadata { font-size: $font-15px; opacity: 0.5; } - -.mx_ImageView_size { - font-size: $font-11px; -} From ab79deb88fa828ef1a13a1fecb9e0648b38b68f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 08:11:53 +0100 Subject: [PATCH 0179/2651] Update the looks a bit more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 14 ++++++-- src/components/views/elements/ImageView.js | 38 ++++++++++++---------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index ee02a1dce8..8afd2670a7 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -49,24 +49,32 @@ limitations under the License. } .mx_ImageView_panel { + width: 100%; + height: 68px; position: absolute; z-index: 1000; align-self: flex-start; pointer-events: all; display: flex; justify-content: space-between; - width: 100%; + align-items: center; } .mx_ImageView_toolbar { right: 0; - padding: 50px 50px 0 0; + padding-right: 18px; display: flex; + align-items: center; +} + +.mx_ImageView_toolbar_buttons { + display: flex; + align-items: center; } .mx_ImageView_label { left: 0; - padding: 50px 0 0 50px; + padding-left: 18px; text-align: left; display: flex; justify-content: center; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e3dbe2a411..fd9d84b900 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -227,7 +227,7 @@ export default class ImageView extends React.Component { if (mayRedact) { redactButton = ( - { + { ); } @@ -263,24 +263,26 @@ export default class ImageView extends React.Component { { metadata }
- { redactButton } - - { - - - { - - - { - - - { - - - { - +
+ { redactButton } + + { + + + { + + + { + + + { + + + { + +
- { + {
From 899ce1f605bcebbe46d44c35a6e70bae0155eac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 11:15:59 +0100 Subject: [PATCH 0180/2651] Partially fix overflow issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 14 ++++++++----- src/components/views/elements/ImageView.js | 24 ++++++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 8afd2670a7..b8fb9b81c2 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -27,14 +27,19 @@ limitations under the License. .mx_ImageView_content { width: 100%; + display: flex; + flex-direction: column; +} + +.mx_ImageView_image_wrapper { display: flex; justify-content: center; align-items: center; - + height: 100%; overflow: hidden; } -.mainImage { +.mx_ImageView_image { object-fit: contain; pointer-events: all; @@ -43,6 +48,8 @@ limitations under the License. min-width: 100px; min-height: 100px; + border-radius: 8px; + &:hover { cursor: grab; } @@ -51,7 +58,6 @@ limitations under the License. .mx_ImageView_panel { width: 100%; height: 68px; - position: absolute; z-index: 1000; align-self: flex-start; pointer-events: all; @@ -62,7 +68,6 @@ limitations under the License. .mx_ImageView_toolbar { right: 0; - padding-right: 18px; display: flex; align-items: center; } @@ -74,7 +79,6 @@ limitations under the License. .mx_ImageView_label { left: 0; - padding-left: 18px; text-align: left; display: flex; justify-content: center; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index fd9d84b900..e35c8a3e15 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -286,17 +286,19 @@ export default class ImageView extends React.Component {
- +
+ +
); From 6aac8f1735b8d3bb0bfae0bfc91f8a514178edfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 11:20:28 +0100 Subject: [PATCH 0181/2651] Change padding a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index b8fb9b81c2..943758b80e 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -88,7 +88,7 @@ limitations under the License. } .mx_ImageView_button { - padding: 5px; + padding-left: 28px; } .mx_ImageView_metadata { From 13d766218aeb0f866f45ffe8e7e0b9e91bf93fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 11:59:43 +0100 Subject: [PATCH 0182/2651] Remove redact button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e35c8a3e15..e1babd8bf1 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -200,7 +200,6 @@ export default class ImageView extends React.Component { } render() { - let mayRedact = false; const showEventMeta = !!this.props.mxEvent; let metadata; @@ -210,7 +209,6 @@ export default class ImageView extends React.Component { const cli = MatrixClientPeg.get(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); if (room) { - mayRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId); const member = room.getMember(sender); if (member) sender = member.name; } @@ -223,15 +221,6 @@ export default class ImageView extends React.Component {
); } - let redactButton; - if (mayRedact) { - redactButton = ( - - { - - ); - } - const rotationDegrees = this.state.rotation + "deg"; const zoomPercentage = this.state.zoom/100; const translatePixelsX = this.state.translationX + "px"; @@ -264,14 +253,7 @@ export default class ImageView extends React.Component {
- { redactButton } - - { - - - { - - + { From 8454a2d44098ed5c3c7f509c673b85e323cc90a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 12:52:08 +0100 Subject: [PATCH 0183/2651] Remove padding on lightboxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/_common.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/_common.scss b/res/css/_common.scss index 6e9d252659..9296b67375 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -315,6 +315,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus { max-width: 100%; max-height: 100%; pointer-events: none; + padding: 0; } .mx_Dialog_header { From 3e408b3fcd6c3c8a201f3cb9affbd9bc651ef7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 12:59:40 +0100 Subject: [PATCH 0184/2651] Remove unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e1babd8bf1..0e11eda7d0 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -160,18 +160,6 @@ export default class ImageView extends React.Component { }); } - onZoomClick = () => { - if (this.state.zoom <= this.minZoom) { - this.setState({zoom: this.maxZoom}); - } else { - this.setState({ - zoom: this.minZoom, - translationX: 0, - translationY: 0, - }); - } - } - onStartMoving = ev => { ev.stopPropagation(); ev.preventDefault(); From 7cd8f1135bafc69e2e3aab117e19a9379a6936c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 13:02:25 +0100 Subject: [PATCH 0185/2651] Quit on empty panel click MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 0e11eda7d0..288d3495d3 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -123,19 +123,25 @@ export default class ImageView extends React.Component { }); }; - onRotateCounterClockwiseClick = () => { + onRotateCounterClockwiseClick = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; this.setState({ rotation: rotationDegrees }); }; - onRotateClockwiseClick = () => { + onRotateClockwiseClick = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); const cur = this.state.rotation; const rotationDegrees = (cur + 90) % 360; this.setState({ rotation: rotationDegrees }); }; - onZoomInClick = () => { + onZoomInClick = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); if (this.state.zoom >= this.maxZoom) { this.setState({zoom: this.maxZoom}); return; @@ -146,7 +152,9 @@ export default class ImageView extends React.Component { }); }; - onZoomOutClick = () => { + onZoomOutClick = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); if (this.state.zoom <= this.minZoom) { this.setState({ zoom: this.minZoom, @@ -160,6 +168,10 @@ export default class ImageView extends React.Component { }); } + onPanelClick = (ev) => { + this.props.onFinished(); + } + onStartMoving = ev => { ev.stopPropagation(); ev.preventDefault(); @@ -235,10 +247,7 @@ export default class ImageView extends React.Component { ref={ref => this.focusLock = ref} >
-
-
- { metadata } -
+
From 61cd026d7aad7f51fce7f15d640943292279b119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 13:07:25 +0100 Subject: [PATCH 0186/2651] Improve comment Co-authored-by: J. Ryan Stinnett --- src/components/views/messages/TextualBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 63d287870e..b4535287dd 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -99,7 +99,7 @@ export default class TextualBody extends React.Component { // If there already is a div wrapping the codeblock we want to skip this. // This happens after the codeblock was edited. if (pres[i].parentNode.className == "mx_EventTile_pre_container") continue; - // Add code element if it's missing + // Add code element if it's missing since we depend on it if (pres[i].getElementsByTagName("code").length == 0) { this._addCodeElement(pres[i]); } From 363b753306d10d6949165fdef27e4eedaf4b1193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 13:40:37 +0100 Subject: [PATCH 0187/2651] Avoid innerHTML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/messages/TextualBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 63d287870e..e60ab5b535 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -134,7 +134,7 @@ export default class TextualBody extends React.Component { _addCodeElement(pre) { const code = document.createElement("code"); - code.innerHTML = pre.innerHTML; + code.append(...pre.childNodes); pre.innerHTML = ""; pre.appendChild(code); } From 986950697b964b3575dc81f1db8f7bfbb6965ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 14:10:09 +0100 Subject: [PATCH 0188/2651] Rmove unnecessary code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/messages/TextualBody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 7c18b8c142..04db7bd725 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -135,7 +135,6 @@ export default class TextualBody extends React.Component { _addCodeElement(pre) { const code = document.createElement("code"); code.append(...pre.childNodes); - pre.innerHTML = ""; pre.appendChild(code); } From fafb8d43a37b039dcc8e98a0b2d192e2db05e22d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 14:16:58 +0100 Subject: [PATCH 0189/2651] Fix padding according to the design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 943758b80e..17e2167494 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -64,6 +64,7 @@ limitations under the License. display: flex; justify-content: space-between; align-items: center; + padding: 0 16px 0 32px; } .mx_ImageView_toolbar { From a6bb203a4b2e165b9c5a505213ecfab6b4dc6c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 14:43:33 +0100 Subject: [PATCH 0190/2651] Redo icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 57 ++++++++++++++++++-- src/components/views/elements/ImageView.js | 63 ++++++++++++++++------ 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 17e2167494..ddc51cf583 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -64,10 +64,10 @@ limitations under the License. display: flex; justify-content: space-between; align-items: center; - padding: 0 16px 0 32px; } .mx_ImageView_toolbar { + padding-right: 16px; right: 0; display: flex; align-items: center; @@ -78,18 +78,65 @@ limitations under the License. align-items: center; } -.mx_ImageView_label { +.mx_ImageView_info_wrapper { + padding-left: 32px; left: 0; text-align: left; display: flex; justify-content: center; - flex-direction: column; - max-width: 240px; + flex-direction: row; color: $lightbox-fg-color; + align-items: center; +} + +.mx_ImageView_info { + padding-left: 12px; } .mx_ImageView_button { - padding-left: 28px; + padding-left: 24px; + display: block; + + &::before { + content: ''; + height: 22px; + width: 22px; + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + display: block; + background-color: $icon-button-color; + } +} + +.mx_ImageView_button_rotateCW::before { + mask-image: url('$(res)/img/image-view/rotate-cw.svg'); +} + +.mx_ImageView_button_rotateCCW::before { + mask-image: url('$(res)/img/image-view/rotate-ccw.svg'); +} + +.mx_ImageView_button_zoomOut::before { + mask-image: url('$(res)/img/image-view/zoom-out.svg'); +} + +.mx_ImageView_button_zoomIn::before { + mask-image: url('$(res)/img/image-view/zoom-in.svg'); +} + +.mx_ImageView_button_download::before { + mask-image: url('$(res)/img/image-view/download.svg'); +} + +.mx_ImageView_button_close { + padding-left: 32px; + &::before { + width: 32px; + height: 32px; + mask-image: url('$(res)/img/image-view/close.svg'); + background-color: none; + } } .mx_ImageView_metadata { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 288d3495d3..28a087f77d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -20,11 +20,12 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {formatDate} from '../../../DateUtils'; import { _t } from '../../../languageHandler'; -import AccessibleButton from "./AccessibleButton"; +import AccessibleTooltipButton from "./AccessibleTooltipButton"; import Modal from "../../../Modal"; import * as sdk from "../../../index"; import {Key} from "../../../Keyboard"; import FocusLock from "react-focus-lock"; +import MemberAvatar from "../avatars/MemberAvatar"; export default class ImageView extends React.Component { static propTypes = { @@ -214,10 +215,7 @@ export default class ImageView extends React.Component { } metadata = (
- { _t('Uploaded on %(date)s by %(user)s', { - date: formatDate(new Date(this.props.mxEvent.getTs())), - user: sender, - }) } + { formatDate(new Date(this.props.mxEvent.getTs())) }
); } @@ -236,6 +234,8 @@ export default class ImageView extends React.Component { rotate(${rotationDegrees})`, }; + const event = this.props.mxEvent; + return (
+
+ +
+ { event.sender ? event.sender.name : event.getSender() } + { metadata } +
+
- - { - - - { - - - { + + + + + + + + + + +
- - { -
From 4e87fdcdfef860a303042e7806e110a0de84b195 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 24 Feb 2021 13:40:22 +0000 Subject: [PATCH 0191/2651] Fix object diffing when objects have different keys The object diff optimisation in 32cca0534c5ff7c7a86d854e6a00a4764652d20b is not correct for the case where `b` has some keys that are not in `a`. By ensuring their key arrays are same length, we can preserve optimisation and be correct as well. Fixes https://github.com/vector-im/element-web/issues/16514 --- src/utils/objects.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/objects.ts b/src/utils/objects.ts index 166c31c4c3..e7f4f0f907 100644 --- a/src/utils/objects.ts +++ b/src/utils/objects.ts @@ -89,6 +89,7 @@ export function objectHasDiff(a: O, b: O): boolean { if (a === b) return false; const aKeys = Object.keys(a); const bKeys = Object.keys(b); + if (aKeys.length !== bKeys.length) return true; const possibleChanges = arrayUnion(aKeys, bKeys); // if the amalgamation of both sets of keys has the a different length to the inputs then there must be a change if (possibleChanges.length !== aKeys.length) return true; From b068a4c05504c4b5104a97c99f23f899e7dfb301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 16:28:12 +0100 Subject: [PATCH 0192/2651] Make download into a button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 28a087f77d..8251af1a5d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -169,6 +169,15 @@ export default class ImageView extends React.Component { }); } + onDownloadClick = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); + const a = document.createElement("a"); + a.href = this.props.src; + a.download = this.props.name; + a.click(); + } + onPanelClick = (ev) => { this.props.onFinished(); } @@ -281,13 +290,11 @@ export default class ImageView extends React.Component { title={_t("Zoom in")} onClick={ this.onZoomInClick }> - - + onClick={ this.onDownloadClick }> + Date: Wed, 24 Feb 2021 18:10:50 +0100 Subject: [PATCH 0193/2651] Add more icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/image-view/more.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 res/img/image-view/more.svg diff --git a/res/img/image-view/more.svg b/res/img/image-view/more.svg new file mode 100644 index 0000000000..4f5fa6f9b9 --- /dev/null +++ b/res/img/image-view/more.svg @@ -0,0 +1,3 @@ + + + From 2e6d8e886de46b9407003443291a46c22de60c62 Mon Sep 17 00:00:00 2001 From: b068931cc450442b63f5b3d276ea4297 Date: Wed, 24 Feb 2021 16:00:07 +0000 Subject: [PATCH 0194/2651] Translated using Weblate (German) Currently translated at 99.6% (2754 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index d92aa27e0a..04ec99c9d5 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1045,7 +1045,7 @@ "Unicorn": "Einhorn", "Pig": "Schwein", "Elephant": "Elefant", - "Rabbit": "Kaninchen", + "Rabbit": "Hase", "Panda": "Panda", "Rooster": "Hahn", "Penguin": "Pinguin", @@ -1073,7 +1073,7 @@ "Hat": "Hut", "Glasses": "Brille", "Spanner": "Schraubenschlüssel", - "Santa": "Nikolaus", + "Santa": "Weihnachtsmann", "Thumbs up": "Daumen hoch", "Umbrella": "Regenschirm", "Hourglass": "Sanduhr", @@ -1370,7 +1370,7 @@ "%(num)s days from now": "in %(num)s Tagen", "Show info about bridges in room settings": "Information über Bridges in den Raumeinstellungen anzeigen", "Enable message search in encrypted rooms": "Nachrichtensuche in verschlüsselten Räumen aktivieren", - "Lock": "Sperren", + "Lock": "Schloss", "Later": "Später", "Review": "Überprüfen", "Verify": "Verifizieren", From 20a3b6f4aacba1162bba0bf1b0d943db7e3d50a1 Mon Sep 17 00:00:00 2001 From: libexus Date: Tue, 23 Feb 2021 18:25:20 +0000 Subject: [PATCH 0195/2651] Translated using Weblate (German) Currently translated at 99.6% (2754 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 92 ++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 04ec99c9d5..b44515aaa7 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -35,7 +35,7 @@ "Deactivate Account": "Benutzerkonto deaktivieren", "Failed to send email": "Fehler beim Senden der E-Mail", "Account": "Benutzerkonto", - "Click here to fix": "Zum reparieren hier klicken", + "Click here to fix": "Zum Reparieren hier klicken", "Default": "Standard", "Export E2E room keys": "E2E-Raum-Schlüssel exportieren", "Failed to change password. Is your password correct?": "Passwortänderung fehlgeschlagen. Ist dein Passwort richtig?", @@ -83,7 +83,7 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Server ist nicht verfügbar, überlastet oder du bist auf einen Softwarefehler gestoßen.", "Labs": "Labor", "Unable to add email address": "E-Mail-Adresse konnte nicht hinzugefügt werden", - "Unable to remove contact information": "Die Kontakt-Informationen konnten nicht gelöscht werden", + "Unable to remove contact information": "Die Kontaktinformationen können nicht gelöscht werden", "Unable to verify email address.": "Die E-Mail-Adresse konnte nicht verifiziert werden.", "Unban": "Verbannung aufheben", "unknown error code": "Unbekannter Fehlercode", @@ -311,7 +311,7 @@ "No Microphones detected": "Keine Mikrofone erkannt", "No media permissions": "Keine Medienberechtigungen", "You may need to manually permit %(brand)s to access your microphone/webcam": "Gegebenenfalls kann es notwendig sein, dass du %(brand)s manuell den Zugriff auf dein Mikrofon bzw. deine Webcam gewähren musst", - "Default Device": "Standard-Gerät", + "Default Device": "Standardgerät", "Microphone": "Mikrofon", "Camera": "Kamera", "Export": "Exportieren", @@ -644,7 +644,7 @@ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Um einen Filter zu setzen, ziehe ein Community-Bild auf das Filter-Panel ganz links. Du kannst jederzeit auf einen Avatar im Filter-Panel klicken, um nur die Räume und Personen aus der Community zu sehen.", "Clear filter": "Filter zurücksetzen", "Key request sent.": "Schlüssel-Anfragen gesendet.", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Wenn du einen Fehler via GitHub meldest, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer:innen. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", "Code": "Code", "Opens the Developer Tools dialog": "Öffnet die Entwickler-Werkzeuge", @@ -819,8 +819,8 @@ "Link to selected message": "Link zur ausgewählten Nachricht", "COPY": "KOPIEREN", "Share Message": "Nachricht teilen", - "No Audio Outputs detected": "Keine Ton-Ausgabe erkannt", - "Audio Output": "Ton-Ausgabe", + "No Audio Outputs detected": "Keine Audioausgabe erkannt", + "Audio Output": "Audioausgabe", "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In verschlüsselten Räumen, wie diesem, ist die Link-Vorschau standardmäßig deaktiviert damit dein Heimserver (auf dem die Vorschau erzeugt wird) keine Informationen über Links in diesem Raum bekommt.", "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Wenn jemand eine URL in seine Nachricht einfügt, kann eine URL-Vorschau angezeigt werden, um mehr Informationen über diesen Link zu erhalten, wie z.B. den Titel, die Beschreibung und ein Bild von der Website.", "The email field must not be blank.": "Das E-Mail-Feld darf nicht leer sein.", @@ -874,7 +874,7 @@ "Please review and accept the policies of this homeserver:": "Bitte sieh dir alle Bedingungen dieses Heimservers an und akzeptiere sie:", "Add some now": "Jemanden jetzt hinzufügen", "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Du bist ein:e Administrator:in dieser Community. Du wirst nicht erneut hinzutreten können, wenn du nicht von einem/r anderen Administrator:in eingeladen wirst.", - "Open Devtools": "Öffne Entwickler-Werkzeuge", + "Open Devtools": "Entwicklerwerkzeuge öffnen", "Show developer tools": "Zeige Entwicklerwerkzeuge", "Unable to load! Check your network connectivity and try again.": "Konnte nicht geladen werden! Überprüfe die Netzwerkverbindung und versuche es erneut.", "Delete Backup": "Sicherung löschen", @@ -1006,9 +1006,9 @@ "Profile picture": "Profilbild", "Display Name": "Anzeigename", "Room information": "Rauminformationen", - "Internal room ID:": "Interne Raum ID:", - "Room version": "Raum Version", - "Room version:": "Raum-Version:", + "Internal room ID:": "Interne Raum-ID:", + "Room version": "Raumversion", + "Room version:": "Raumversion:", "Developer options": "Entwickleroptionen", "General": "Allgemein", "Set a new account password...": "Neues Benutzerkonto-Passwort festlegen...", @@ -1103,7 +1103,7 @@ "Timeline": "Chatverlauf", "Autocomplete delay (ms)": "Verzögerung zur Autovervollständigung (ms)", "Roles & Permissions": "Rollen & Berechtigungen", - "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Änderungen daran, wer den Chatverlauf lesen kann werden nur zukünftige Nachrichten in diesem Raum angewendet. Die Sichtbarkeit der existierenden Historie bleibt unverändert.", + "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Änderungen daran, wer den Chatverlauf lesen kann werden nur zukünftige Nachrichten in diesem Raum angewendet. Die Sichtbarkeit des existierenden Verlaufs bleibt unverändert.", "Security & Privacy": "Sicherheit & Datenschutz", "Encryption": "Verschlüsselung", "Once enabled, encryption cannot be disabled.": "Sobald aktiviert, kann die Verschlüsselung nicht mehr deaktiviert werden.", @@ -1208,15 +1208,15 @@ "Change topic": "Ändere das Thema", "Modify widgets": "Ändere Widgets", "Default role": "Standard Rolle", - "Send messages": "Sende Nachrichten", + "Send messages": "Nachrichten senden", "Invite users": "Benutzer:innen einladen", - "Change settings": "Ändere Einstellungen", + "Change settings": "Einstellungen ändern", "Kick users": "Benutzer:innen kicken", "Ban users": "Benutzer:innen verbannen", "Remove messages": "Nachrichten löschen", - "Notify everyone": "Jeden Benachrichtigen", - "Send %(eventType)s events": "Sende %(eventType)s-Ereignisse", - "Select the roles required to change various parts of the room": "Wähle Rollen die benötigt werden um einige Teile des Raumes zu ändern", + "Notify everyone": "Jeden benachrichtigen", + "Send %(eventType)s events": "%(eventType)s-Ereignisse senden", + "Select the roles required to change various parts of the room": "Wähle Rollen, die benötigt werden, um einige Teile des Raumes zu ändern", "Enable encryption?": "Verschlüsselung aktivieren?", "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Sobald aktiviert, kann die Verschlüsselung für einen Raum nicht mehr deaktiviert werden. Nachrichten in einem verschlüsselten Raum können nur noch von Teilnehmern aber nicht mehr vom Server gelesen werden. Einige Bots und Brücken werden vielleicht nicht mehr funktionieren. Erfahre mehr über Verschlüsselung.", "Error updating main address": "Fehler beim Aktualisieren der Hauptadresse", @@ -1301,7 +1301,7 @@ "Multiple integration managers": "Mehrere Integrationsmanager", "Public Name": "Öffentlicher Name", "Identity Server URL must be HTTPS": "Die Identity Server-URL muss HTTPS sein", - "Could not connect to Identity Server": "Verbindung zum Identity Server konnte nicht hergestellt werden", + "Could not connect to Identity Server": "Verbindung zum Identitätsserver konnte nicht hergestellt werden", "Checking server": "Server wird überprüft", "Identity server has no terms of service": "Der Identitätsserver hat keine Nutzungsbedingungen", "Disconnect": "Trennen", @@ -1384,7 +1384,7 @@ "Cannot connect to integration manager": "Verbindung zum Integrationsmanager fehlgeschlagen", "The integration manager is offline or it cannot reach your homeserver.": "Der Integrationsmanager ist offline oder er kann den Heimserver nicht erreichen.", "not stored": "nicht gespeichert", - "Backup has a signature from unknown user with ID %(deviceId)s": "Die Sicherung hat eine Signatur von unbekanntem/r Nutzer!n mit ID %(deviceId)s", + "Backup has a signature from unknown user with ID %(deviceId)s": "Die Sicherung hat eine Signatur von unbekanntem/r Nutzer:in mit ID %(deviceId)s", "Backup key stored: ": "Backup Schlüssel gespeichert: ", "Clear notifications": "Benachrichtigungen löschen", "Disconnect from the identity server and connect to instead?": "Vom Identitätsserver trennen, und stattdessen eine Verbindung zu aufbauen?", @@ -1396,12 +1396,12 @@ "You are still sharing your personal data on the identity server .": "Du teilst deine persönlichen Daten immer noch auf dem Identitätsserver .", "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Wir empfehlen, dass du deine Email Adressen und Telefonnummern vom Identitätsserver löschst, bevor du die Verbindung trennst.", "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Zur Zeit benutzt du keinen Identitätsserver. Trage unten einen Server ein, um Kontakte finden und von anderen gefunden zu werden.", - "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Nutze einen Integrationsmanager (%(serverName)s) um Bots, Widgets und Sticker Packs zu verwalten.", - "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Verwende einen Integrationsmanager um Bots, Widgets und Sticker Packs zu verwalten.", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Nutze einen Integrationsmanager (%(serverName)s), um Bots, Widgets und Stickerpacks zu verwalten.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Verwende einen Integrationsmanager, um Bots, Widgets und Sticker Packs zu verwalten.", "Manage integrations": "Integrationen verwalten", - "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Stimme den Nutzungsbedingungen des Identitätsservers %(serverName)s zu, um dich per Email Adresse und Telefonnummer auffindbar zu machen.", + "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Stimme den Nutzungsbedingungen des Identitätsservers %(serverName)s zu, um dich per E-Mail-Adresse und Telefonnummer auffindbar zu machen.", "Clear cache and reload": "Zwischenspeicher löschen und neu laden", - "Customise your experience with experimental labs features. Learn more.": "Passe deine Erfahrung mit experimentellen Lab Funktionen an. Mehr erfahren.", + "Customise your experience with experimental labs features. Learn more.": "Passe deine Erfahrung mit experimentellen Funktionen an. Mehr erfahren.", "Ignored/Blocked": "Ignoriert/Blockiert", "Something went wrong. Please try again or view your console for hints.": "Etwas ist schief gelaufen. Bitte versuche es erneut oder sieh für weitere Hinweise in deiner Konsole nach.", "Error subscribing to list": "Fehler beim Abonnieren der Liste", @@ -1413,7 +1413,7 @@ "You have not ignored anyone.": "Du hast niemanden ignoriert.", "You are currently ignoring:": "Du ignorierst momentan:", "Unsubscribe": "Deabonnieren", - "View rules": "Regeln betrachten", + "View rules": "Regeln öffnen", "You are currently subscribed to:": "Du abonnierst momentan:", "⚠ These settings are meant for advanced users.": "⚠ Diese Einstellungen sind für fortgeschrittene Nutzer:innen gedacht.", "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Ob du %(brand)s auf einem Gerät verwendest, bei dem Touch das primäre Eingabegerät ist", @@ -1432,9 +1432,9 @@ "Never send encrypted messages to unverified sessions from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen", "Never send encrypted messages to unverified sessions in this room from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen in diesem Raum", "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Durch die Änderung des Passworts werden derzeit alle Ende-zu-Ende-Verschlüsselungsschlüssel in allen Sitzungen zurückgesetzt, sodass der verschlüsselte Chat-Verlauf nicht mehr lesbar ist, es sei denn, du exportierst zuerst deine Raumschlüssel und importierst sie anschließend wieder. In Zukunft wird dies verbessert werden.", - "Delete %(count)s sessions|other": "Lösche %(count)s Sitzungen", + "Delete %(count)s sessions|other": "%(count)s Sitzungen löschen", "Backup is not signed by any of your sessions": "Die Sicherung wurde von keiner deiner Sitzungen unterzeichnet", - "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Dein Passwort wurde erfolgreich geändert. Du erhälst keine Push-Benachrichtigungen zu anderen Sitzungen, bis du dich wieder bei diesen anmeldst", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Dein Passwort wurde erfolgreich geändert. Du erhältst keine Push-Benachrichtigungen zu anderen Sitzungen, bis du dich wieder bei diesen anmeldest", "Notification sound": "Benachrichtigungston", "Set a new custom sound": "Setze einen neuen benutzerdefinierten Ton", "Browse": "Durchsuche", @@ -1455,9 +1455,9 @@ "Notification Autocomplete": "Benachrichtigung Autovervollständigen", "If disabled, messages from encrypted rooms won't appear in search results.": "Wenn deaktiviert, werden Nachrichten von verschlüsselten Räumen nicht in den Ergebnissen auftauchen.", "This user has not verified all of their sessions.": "Diese:r Benutzer:in hat nicht alle seine/ihre Sitzungen verifiziert.", - "You have verified this user. This user has verified all of their sessions.": "Du hast diese/n Nutzer!n verifiziert. Er/Sie hat alle seine/ihre Sitzungen verifiziert.", + "You have verified this user. This user has verified all of their sessions.": "Du hast diese/n Nutzer:in verifiziert. Er/Sie hat alle seine/ihre Sitzungen verifiziert.", "Your key share request has been sent - please check your other sessions for key share requests.": "Deine Schlüsselanfrage wurde gesendet - sieh in deinen anderen Sitzungen nach der Schlüsselanfrage.", - "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Schlüsselanfragen werden automatisch an deine anderen Sitzungen gesendet. Wenn du sie abgelehnt oder ignoriert hast klicke hier, um die Schlüssel erneut anzufordern.", + "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Schlüsselanfragen werden automatisch an deine anderen Sitzungen gesendet. Wenn du sie abgelehnt oder ignoriert hast, klicke hier, um die Schlüssel erneut anzufordern.", "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Wenn deine anderen Sitzungen nicht über den Schlüssel für diese Nachricht verfügen, kannst du die Nachricht nicht entschlüsseln.", "Re-request encryption keys from your other sessions.": "Fordere die Verschlüsselungsschlüssel aus deinen anderen Sitzungen erneut an.", "Room %(name)s": "Raum %(name)s", @@ -1589,12 +1589,12 @@ "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändert eine Ausschluss-Regel für Räume von %(oldGlob)s nach %(newGlob)s, wegen %(reason)s", "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Auf den Server turn.matrix.org zurückgreifen, falls deine Heimserver keine Anruf-Assistenz anbietet (deine IP-Adresse wird während eines Anrufs geteilt)", "Show more": "Mehr zeigen", - "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Diese Sitzung sichert nicht deine Schlüssel, aber du hast eine vorhandene Sicherung, die du wiederherstellen und in Zukunft hinzufügen kannst.", + "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Diese Sitzung sichert deine Schlüssel nicht, aber du hast eine vorhandene Sicherung, die du wiederherstellen und in Zukunft hinzufügen kannst.", "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Verbinde diese Sitzung mit deiner Schlüsselsicherung bevor du dich abmeldest, um den Verlust von Schlüsseln zu vermeiden.", "This backup is trusted because it has been restored on this session": "Dieser Sicherung wird vertraut, da sie während dieser Sitzung wiederhergestellt wurde", "Enable desktop notifications for this session": "Desktop-Benachrichtigungen für diese Sitzung aktivieren", "Enable audible notifications for this session": "Aktiviere die akustischen Benachrichtigungen für diese Sitzung", - "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integrationsmanaager erhalten Konfigurationsdaten und können Widgets modifizieren, Raumeinladungen verschicken und in deinem Namen Einflusslevel setzen.", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integrationsmanager erhalten Konfigurationsdaten und können Widgets modifizieren, Raumeinladungen verschicken und in deinem Namen Berechtigungslevel setzen.", "Read Marker lifetime (ms)": "Gültigkeitsdauer der Gelesen-Markierung (ms)", "Read Marker off-screen lifetime (ms)": "Gültigkeitsdauer der Gelesen-Markierung außerhalb des Bildschirms (ms)", "Session key:": "Sitzungsschlüssel:", @@ -1679,8 +1679,8 @@ "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Bestätige das Löschen dieser Sitzung indem du dich mittels Single Sign-On anmeldest um deine Identität nachzuweisen.", "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Bestätige das Löschen dieser Sitzung indem du dich mittels Single Sign-On anmeldest um deine Identität nachzuweisen.", "Confirm deleting these sessions": "Bestätige das Löschen dieser Sitzungen", - "Click the button below to confirm deleting these sessions.|other": "Klicke den Button um das Löschen dieser Sitzungen zu bestätigen.", - "Click the button below to confirm deleting these sessions.|one": "Klicke den Button um das Löschen dieser Sitzung zu bestätigen.", + "Click the button below to confirm deleting these sessions.|other": "Klicke den Knopf, um das Löschen dieser Sitzungen zu bestätigen.", + "Click the button below to confirm deleting these sessions.|one": "Klicke den Knopf, um das Löschen dieser Sitzung zu bestätigen.", "Clear all data in this session?": "Alle Daten dieser Sitzung löschen?", "Clear all data": "Alle Daten löschen", "Confirm your account deactivation by using Single Sign On to prove your identity.": "Bestätige das Löschen deines Kontos indem du dich mittels Single Sign-On anmeldest um deine Identität nachzuweisen.", @@ -1702,15 +1702,15 @@ "Error adding ignored user/server": "Fehler beim Hinzufügen eines ignorierten Nutzers/Servers", "None": "Keine", "Ban list rules - %(roomName)s": "Verbotslistenregeln - %(roomName)s", - "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Füge hier Benutzer!nnen und Server hinzu, die du ignorieren willst. Verwende Sternchen, damit %(brand)s mit beliebigen Zeichen übereinstimmt. Bspw. würde @bot: * alle Benutzer!nnen ignorieren, die auf einem Server den Namen 'bot' haben.", - "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Ignorieren von Personen erfolgt über Sperrlisten. Wenn eine Sperrliste abonniert wird, werden die von dieser Liste blockierten Benutzer!nnen/Server ausgeblendet.", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Füge hier Benutzer!nnen und Server hinzu, die du ignorieren willst. Verwende Sternchen, damit %(brand)s mit beliebigen Zeichen übereinstimmt. Bspw. würde @bot: * alle Benutzer:innen ignorieren, die auf einem Server den Namen 'bot' haben.", + "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Das Ignorieren von Personen erfolgt über Sperrlisten. Wenn eine Sperrliste abonniert wird, werden die von dieser Liste blockierten Benutzer:innen und Server ausgeblendet.", "Personal ban list": "Persönliche Sperrliste", - "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Deine persönliche Sperrliste enthält alle Benutzer!nnen/Server, von denen du persönlich keine Nachrichten sehen willst. Nachdem du den ersten Benutzer/Server ignoriert hast, wird in der Raumliste \"Meine Sperrliste\" angezeigt - bleibe in diesem Raum, um die Sperrliste aufrecht zu halten.", + "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Deine persönliche Sperrliste enthält alle Benutzer:innen/Server, von denen du persönlich keine Nachrichten sehen willst. Nachdem du den ersten Benutzer/Server ignoriert hast, wird in der Raumliste \"Meine Sperrliste\" angezeigt - bleibe in diesem Raum, um die Sperrliste aufrecht zu halten.", "Server or user ID to ignore": "Zu ignorierende Server- oder Benutzer-ID", "eg: @bot:* or example.org": "z.B. @bot:* oder example.org", "Subscribed lists": "Abonnierte Listen", "Subscribing to a ban list will cause you to join it!": "Eine Verbotsliste abonnieren bedeutet ihr beizutreten!", - "If this isn't what you want, please use a different tool to ignore users.": "Wenn dies nicht das ist, was du willst, verwende ein anderes Tool, um Benutzer!nnen zu ignorieren.", + "If this isn't what you want, please use a different tool to ignore users.": "Wenn dies nicht das ist, was du willst, verwende ein anderes Tool, um Benutzer:innen zu ignorieren.", "Subscribe": "Abonnieren", "Always show the window menu bar": "Fenstermenüleiste immer anzeigen", "Show tray icon and minimize window to it on close": "Taskleistensymbol anzeigen und Fenster beim Schließen dorthin minimieren", @@ -1752,8 +1752,8 @@ "in account data": "in den Kontodaten", "Homeserver feature support:": "Home-Server-Funktionsunterstützung:", "exists": "existiert", - "Delete sessions|other": "Lösche Sitzungen", - "Delete sessions|one": "Lösche Sitzung", + "Delete sessions|other": "Sitzungen löschen", + "Delete sessions|one": "Sitzung löschen", "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Alle Sitzungen einzeln verifizieren, anstatt auch Sitzungen zu vertrauen, die durch Cross-Signing verifiziert sind.", "Securely cache encrypted messages locally for them to appear in search results, using ": "Der Zwischenspeicher für die lokale Suche in verschlüsselten Nachrichten benötigt ", " to store messages from ": " um Nachrichten von ", @@ -1766,7 +1766,7 @@ "Backup has an invalid signature from unverified session ": "Die Sicherung hat eine ungültige Signatur von einer nicht verifizierten Sitzung ", "Your keys are not being backed up from this session.": "Deine Schlüssel werden nicht von dieser Sitzung gesichert.", "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Zur Zeit verwendest du , um Kontakte zu finden und von anderen gefunden zu werden. Du kannst deinen Identitätsserver weiter unten ändern.", - "Invalid theme schema.": "Ungültiges Design Schema.", + "Invalid theme schema.": "Ungültiges Designschema.", "Error downloading theme information.": "Fehler beim herunterladen des Themas.", "Theme added!": "Design hinzugefügt!", "Custom theme URL": "URL des benutzerdefinierten Designs", @@ -1781,11 +1781,11 @@ "Complete": "Abschließen", "Revoke": "Widerrufen", "Share": "Teilen", - "You have not verified this user.": "Du hast diese:n Nutzer!n nicht verifiziert.", - "Everyone in this room is verified": "Jede/r in diesem Raum ist verifiziert", + "You have not verified this user.": "Du hast diese:n Nutzer:in nicht verifiziert.", + "Everyone in this room is verified": "Alle in diesem Raum sind verifiziert", "Mod": "Mod", "Invite only": "Nur auf Einladung", - "Scroll to most recent messages": "Springe zur neusten Nachricht", + "Scroll to most recent messages": "Zur neusten Nachricht springen", "No recent messages by %(user)s found": "Keine neuen Nachrichten von %(user)s gefunden", "Try scrolling up in the timeline to see if there are any earlier ones.": "Versuche nach oben zu scrollen, um zu sehen ob sich dort frühere Nachrichten befinden.", "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Dies kann bei vielen Nachrichten einige Zeit dauern. Bitte lade die Anwendung in dieser Zeit nicht neu.", @@ -2136,7 +2136,7 @@ "Jump to room search": "Springe zur Raumsuche", "Close dialog or context menu": "Schließe Dialog oder Kontextmenü", "Cancel autocomplete": "Deaktiviere Auto-Vervollständigung", - "Unable to revoke sharing for email address": "Das Teilen der E-Mail-Adresse kann nicht widerrufen werden", + "Unable to revoke sharing for email address": "Dem Teilen der E-Mail-Adresse kann nicht widerrufen werden", "Unable to validate homeserver/identity server": "Heimserver/Identitätsserver nicht validierbar", "Without completing security on this session, it won’t have access to encrypted messages.": "Ohne Abschluss der Sicherungseinrichtung in dieser Sitzung wird sie keinen Zugriff auf verschlüsselte Nachrichten erhalten.", "Disable": "Deaktivieren", @@ -2333,7 +2333,7 @@ "Incoming voice call": "Eingehender Sprachanruf", "Incoming video call": "Eingehender Videoanruf", "Incoming call": "Eingehender Anruf", - "There are advanced notifications which are not shown here.": "Erweiterte Benachrichtigungen, werden hier nicht angezeigt.", + "There are advanced notifications which are not shown here.": "Erweiterte Benachrichtigungen werden hier nicht angezeigt.", "Are you sure you want to cancel entering passphrase?": "Bist du sicher, dass du die Eingabe der Passphrase abbrechen möchtest?", "Use your account to sign in to the latest version": "Melde dich mit deinem Account in der neuesten Version an", "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", @@ -2378,7 +2378,7 @@ "A connection error occurred while trying to contact the server.": "Beim Versuch, den Server zu kontaktieren, ist ein Verbindungsfehler aufgetreten.", "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Du hast sie ggf. in einem anderen Client als %(brand)s konfiguriert. Du kannst sie nicht in %(brand)s verändern, aber sie werden trotzdem angewandt.", "Master private key:": "Privater Hauptschlüssel:", - "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Setze den Schriftnamen auf eine in deinem System installierte Schriftart & %(brand)s werden versuchen sie zu verwenden.", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Setze den Schriftnamen auf eine in deinem System installierte Schriftart & %(brand)s wird versuchen, sie zu verwenden.", "Custom Tag": "Benutzerdefinierter Tag", "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "Du bist bereits eingeloggt und kannst loslegen. Allerdings kannst du auch die neuesten Versionen der App für alle Plattformen unter element.io/get-started herunterladen.", "You're all caught up.": "Alles gesichtet.", @@ -2619,8 +2619,8 @@ "Use Command + Enter to send a message": "Benutze Betriebssystemtaste + Enter um eine Nachricht zu senden", "Use Ctrl + Enter to send a message": "Benutze Strg + Enter um eine Nachricht zu senden", "Call Paused": "Anruf pausiert", - "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Verschlüsselte Nachrichten sicher lokal zwischenspeichern um sie in Suchergebnissen finden zu können, benötigt %(size)s um die Nachrichten von den Räumen %(rooms)s zu speichern.", - "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Verschlüsselte Nachrichten sicher lokal zwischenspeichern um sie in Suchergebnissen finden zu können, benötigt %(size)s um die Nachrichten vom Raum %(rooms)s zu speichern.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Verschlüsselte Nachrichten sicher lokal zwischenspeichern, um sie in Suchergebnissen finden zu können. Es werden %(size)s benötigt, um die Nachrichten von den Räumen %(rooms)s zu speichern.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Verschlüsselte Nachrichten sicher lokal zwischenspeichern, um sie in Suchergebnissen finden zu können. Es werden %(size)s benötigt, um die Nachrichten vom Raum %(rooms)s zu speichern.", "Only the two of you are in this conversation, unless either of you invites anyone to join.": "Nur ihr zwei seid in dieser Konversation, außer einer von euch lädt jemanden neues ein.", "This is the beginning of your direct message history with .": "Dies ist der Beginn deiner Direktnachrichtenhistorie mit .", "Topic: %(topic)s (edit)": "Thema: %(topic)s (ändern)", From 28cd3095333cafa9a2294cf770c2474e6355c817 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Tue, 23 Feb 2021 10:47:36 +0000 Subject: [PATCH 0196/2651] Translated using Weblate (German) Currently translated at 99.6% (2754 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index b44515aaa7..3f657e105b 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -909,7 +909,7 @@ "All-uppercase is almost as easy to guess as all-lowercase": "Alles groß zu geschrieben ist fast genauso schnell zu raten, wie alles klein zu schreiben", "Reversed words aren't much harder to guess": "Umgedrehte Worte sind nicht schwerer zu erraten", "Predictable substitutions like '@' instead of 'a' don't help very much": "Vorhersagbare Ersetzungen wie '@' anstelle von 'a' helfen nicht viel", - "Add another word or two. Uncommon words are better.": "Füge ein weiteres Wort hinzu - oder mehr. Ungewöhnliche Worte sind besser.", + "Add another word or two. Uncommon words are better.": "Füge ein weiteres Wort - oder mehr - hinzu. Ungewöhnliche Worte sind besser.", "Repeats like \"aaa\" are easy to guess": "Wiederholungen wie \"aaa\" sind einfach zu erraten", "Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Wiederholungen wie \"abcabcabc\" sind nur leicht schwerer zu raten als \"abc\"", "Sequences like abc or 6543 are easy to guess": "Sequenzen wie \"abc\" oder \"6543\" sind leicht zu raten", @@ -987,7 +987,7 @@ "Enable big emoji in chat": "Aktiviere große Emoji im Chat", "Enable Community Filter Panel": "Community-Filter-Panel aktivieren", "Messages containing my username": "Nachrichten, die meinen Benutzernamen enthalten", - "The other party cancelled the verification.": "Die Gegenstelle hat die Verifizierung abgebrochen.", + "The other party cancelled the verification.": "Die Gegenstelle hat die Überprüfung abgebrochen.", "Verified!": "Verifiziert!", "You've successfully verified this user.": "Du hast diese:n Benutzer:in erfolgreich verifiziert.", "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Sichere Nachrichten mit diesem/r Benutzer:in sind Ende-zu-Ende-verschlüsselt und können nicht von Dritten gelesen werden.", @@ -1111,7 +1111,7 @@ "Ignored users": "Ignorierte Benutzer", "Key backup": "Schlüsselsicherung", "Gets or sets the room topic": "Frage das Thema des Raums ab oder setze es", - "Verify this user by confirming the following emoji appear on their screen.": "Verifiziere diese Nutzer:in, indem du bestätigst, dass folgendes Emoji auf dessen Bildschirm erscheint.", + "Verify this user by confirming the following emoji appear on their screen.": "Verifiziere diese Nutzer:in, indem du bestätigst, dass folgende Emojis auf dessen Bildschirm erscheinen.", "Missing media permissions, click the button below to request.": "Fehlende Medienberechtigungen. Drücke auf den Knopf unten, um sie anzufordern.", "Request media permissions": "Medienberechtigungen anfordern", "Main address": "Primäre Adresse", @@ -2202,7 +2202,7 @@ "I want to help": "Ich möchte helfen", "Your homeserver has exceeded its user limit.": "Dein Heimserver hat das Benutzerlimit erreicht.", "Your homeserver has exceeded one of its resource limits.": "Dein Heimserver hat eine seiner Ressourcengrenzen erreicht.", - "Contact your server admin.": "Kontaktiere deinen Heimserver-Administrator.", + "Contact your server admin.": "Kontaktiere deine Heimserver-Administration.", "Ok": "Ok", "Set password": "Setze Passwort", "To return to your account in future you need to set a password": "Um dein Konto zukünftig wieder verwenden zu können, setze ein Passwort", From 49d8158c7e8eb4660abc2c26a67121b3bcc98e9e Mon Sep 17 00:00:00 2001 From: iaiz Date: Tue, 16 Feb 2021 16:52:11 +0000 Subject: [PATCH 0197/2651] Translated using Weblate (Spanish) Currently translated at 96.4% (2667 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 140 +++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 64de246c0e..cbe7e0a223 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -13,8 +13,8 @@ "A new password must be entered.": "Debes ingresar una contraseña nueva.", "%(senderName)s answered the call.": "%(senderName)s contestó la llamada.", "An error has occurred.": "Un error ha ocurrido.", - "Anyone who knows the room's link, apart from guests": "Cualquier persona que conozca el enlace a esta sala, excepto huéspedes", - "Anyone who knows the room's link, including guests": "Cualquier persona que conozca el enlace a esta sala, incluyendo huéspedes", + "Anyone who knows the room's link, apart from guests": "Cualquier persona que conozca el enlace a esta sala, pero excluir a la gente sin cuenta", + "Anyone who knows the room's link, including guests": "Cualquier persona que conozca el enlace a esta sala, incluyendo gente sin cuenta", "Are you sure?": "¿Estás seguro?", "Are you sure you want to reject the invitation?": "¿Estás seguro que quieres rechazar la invitación?", "Attachment": "Adjunto", @@ -24,7 +24,7 @@ "Banned users": "Usuarios vetados", "Bans user with given id": "Veta al usuario con la ID dada", "Call Timeout": "Tiempo de Espera de Llamada", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "No se puede conectar al servidor base a través de HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o habilitando los scripts inseguros.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "No se ha podido conectar al servidor base a través de HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o activando los scripts inseguros.", "Change Password": "Cambiar contraseña", "%(senderName)s changed their profile picture.": "%(senderName)s cambió su imagen de perfil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha cambiado el nivel de acceso de %(powerLevelDiffText)s.", @@ -215,7 +215,7 @@ "No users have specific privileges in this room": "Ningún usuario tiene permisos específicos en esta sala", "OK": "Vale", "olm version:": "versión de olm:", - "Only people who have been invited": "Solo personas que han sido invitadas", + "Only people who have been invited": "Solo las personas que hayan sido invitadas", "Operation failed": "Falló la operación", "Password": "Contraseña", "Passwords can't be empty": "Las contraseñas no pueden estar en blanco", @@ -278,7 +278,7 @@ "Unable to verify email address.": "No es posible verificar la dirección de correo electrónico.", "Unban": "Quitar Veto", "Unable to capture screen": "No es posible capturar la pantalla", - "Unable to enable Notifications": "No es posible habilitar las Notificaciones", + "Unable to enable Notifications": "No se han podido activar las notificaciones", "unknown caller": "Persona que llama desconocida", "Unnamed Room": "Sala sin nombre", "Uploading %(filename)s and %(count)s others|zero": "Subiendo %(filename)s", @@ -314,14 +314,14 @@ "AM": "AM", "PM": "PM", "The maximum permitted number of widgets have already been added to this room.": "La cantidad máxima de widgets permitida ha sido alcanzada en esta sala.", - "To use it, just wait for autocomplete results to load and tab through them.": "Para utilizarlo, tan solo espera a que se carguen los resultados de autocompletar y navega entre ellos.", + "To use it, just wait for autocomplete results to load and tab through them.": "Para usarlo, tan solo espera a que se carguen los resultados de autocompletar y navega entre ellos.", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s le quitó el veto a %(targetName)s.", "Unmute": "Dejar de silenciar", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nivel de permisos %(powerLevelNumber)s)", "You cannot place VoIP calls in this browser.": "No puedes realizar llamadas VoIP en este navegador.", "You do not have permission to post to this room": "No tienes permiso para publicar en esta sala", - "You have disabled URL previews by default.": "Ha deshabilitado la vista previa de URL por defecto.", - "You have enabled URL previews by default.": "Ha habilitado vista previa de URL por defecto.", + "You have disabled URL previews by default.": "Has desactivado la vista previa de URLs por defecto.", + "You have enabled URL previews by default.": "Has activado las vista previa de URLs por defecto.", "You have no visible notifications": "No tiene notificaciones visibles", "You must register to use this functionality": "Usted debe ser un registrar para usar esta funcionalidad", "You need to be able to invite users to do that.": "Debes ser capaz de invitar usuarios para realizar esa acción.", @@ -374,7 +374,7 @@ "Sunday": "Domingo", "Guests can join": "Los invitados se pueden unir", "Failed to add tag %(tagName)s to room": "Error al añadir la etiqueta %(tagName)s a la sala", - "Notification targets": "Objetivos de notificación", + "Notification targets": "Destinos de notificaciones", "Failed to set direct chat tag": "Error al establecer la etiqueta de conversación directa", "Today": "Hoy", "Files": "Archivos", @@ -388,7 +388,7 @@ "Leave": "Salir", "Uploaded on %(date)s by %(user)s": "Subido el %(date)s por %(user)s", "Send Custom Event": "Enviar evento personalizado", - "All notifications are currently disabled for all targets.": "Las notificaciones están deshabilitadas para todos los objetivos.", + "All notifications are currently disabled for all targets.": "Las notificaciones están desactivadas para todos los objetivos.", "Failed to send logs: ": "Error al enviar registros: ", "Forget": "Olvidar", "World readable": "Legible por todo el mundo", @@ -409,19 +409,19 @@ "An error occurred whilst saving your email notification preferences.": "Se ha producido un error al guardar las preferencias de notificación por email.", "Explore Room State": "Explorar Estado de la Sala", "Source URL": "URL de Origen", - "Messages sent by bot": "Mensajes enviados por bot", + "Messages sent by bot": "Mensajes enviados por bots", "Filter results": "Filtrar resultados", "Members": "Miembros", "No update available.": "No hay actualizaciones disponibles.", - "Noisy": "Ruidoso", + "Noisy": "Sonoro", "Collecting app version information": "Recolectando información de la versión de la aplicación", "Keywords": "Palabras clave", - "Enable notifications for this account": "Habilitar notificaciones para esta cuenta", + "Enable notifications for this account": "Activar notificaciones para esta cuenta", "Invite to this community": "Invitar a esta comunidad", "Messages containing keywords": "Mensajes que contienen palabras clave", "Error saving email notification preferences": "Error al guardar las preferencias de notificación por email", "Tuesday": "Martes", - "Enter keywords separated by a comma:": "Introduzca palabras clave separadas por una coma:", + "Enter keywords separated by a comma:": "Escribe palabras clave separadas por una coma:", "Search…": "Buscar…", "You have successfully set a password and an email address!": "¡Has establecido una nueva contraseña y dirección de correo electrónico!", "Remove %(name)s from the directory?": "¿Eliminar a %(name)s del directorio?", @@ -448,14 +448,14 @@ "Send": "Enviar", "Send logs": "Enviar registros", "All messages": "Todos los mensajes", - "Call invitation": "Invitación a la llamada", + "Call invitation": "Cuando me inviten a una llamada", "Thank you!": "¡Gracias!", "Downloading update...": "Descargando actualizaciones...", "State Key": "Clave de estado", "Failed to send custom event.": "Ha fallado el envio del evento personalizado.", "What's new?": "¿Qué hay de nuevo?", "Notify me for anything else": "Notificarme para cualquier otra cosa", - "When I'm invited to a room": "Cuando soy invitado a una sala", + "When I'm invited to a room": "Cuando me inviten a una sala", "Can't update user notification settings": "No se puede actualizar los ajustes de notificaciones del usuario", "Notify for all other messages/rooms": "Notificar para todos los demás mensajes/salas", "Unable to look up room ID from server": "No se puede buscar el ID de la sala desde el servidor", @@ -469,7 +469,7 @@ "Reply": "Responder", "Show message in desktop notification": "Mostrar mensaje en la notificación del escritorio", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Los registros de depuración contienen datos de uso de la aplicación como nombre de usuario, ID o alias de las salas o grupos que hayas visitado (y nombres de usuario de otros usuarios). No contienen mensajes.", - "Unhide Preview": "Mostrar Vista Previa", + "Unhide Preview": "Mostrar vista previa", "Unable to join network": "No se puede unir a la red", "Sorry, your browser is not able to run %(brand)s.": "¡Lo sentimos! Su navegador no puede ejecutar %(brand)s.", "Messages in group chats": "Mensajes en conversaciones grupales", @@ -478,12 +478,12 @@ "Low Priority": "Prioridad baja", "%(brand)s does not know how to join a room on this network": "%(brand)s no sabe cómo unirse a una sala en esta red", "Set Password": "Establecer contraseña", - "Off": "Desactivado", + "Off": "Apagado", "Mentions only": "Solo menciones", "Failed to remove tag %(tagName)s from room": "Error al eliminar la etiqueta %(tagName)s de la sala", "Wednesday": "Miércoles", "You can now return to your account after signing out, and sign in on other devices.": "Ahora puedes regresar a tu cuenta después de cerrar tu sesión, e iniciar sesión en otros dispositivos.", - "Enable email notifications": "Habilitar notificaciones por email", + "Enable email notifications": "Activar notificaciones por correo", "Event Type": "Tipo de Evento", "No rooms to show": "No hay salas para mostrar", "Download this file": "Descargar este archivo", @@ -493,7 +493,7 @@ "Developer Tools": "Herramientas de desarrollo", "View Source": "Ver fuente", "Event Content": "Contenido del Evento", - "Unable to fetch notification target list": "No se puede obtener la lista de objetivos de notificación", + "Unable to fetch notification target list": "No se puede obtener la lista de destinos de notificación", "Quote": "Citar", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "En su navegador actual, la apariencia y comportamiento de la aplicación puede ser completamente incorrecta, y algunas de las características podrían no funcionar. Si aún desea probarlo puede continuar, pero ¡no podremos ofrecer soporte por cualquier problema que pudiese tener!", "Checking for an update...": "Comprobando actualizaciones...", @@ -540,8 +540,8 @@ "Automatically replace plain text Emoji": "Reemplazar automáticamente texto por Emojis", "Mirror local video feed": "Clonar transmisión de video local", "Send analytics data": "Enviar datos de análisis de estadísticas", - "Enable inline URL previews by default": "Habilitar vistas previas de URL en línea por defecto", - "Enable URL previews for this room (only affects you)": "Activar vista previa de URL en esta sala (sólo le afecta a ud.)", + "Enable inline URL previews by default": "Activar vistas previas de URLs en línea por defecto", + "Enable URL previews for this room (only affects you)": "Activar vista previa de URL en esta sala (te afecta a ti)", "Enable URL previews by default for participants in this room": "Activar vista previa de URL por defecto para los participantes en esta sala", "Enable widget screenshots on supported widgets": "Activar capturas de pantalla de widget en los widgets soportados", "Drop file here to upload": "Soltar aquí el fichero a subir", @@ -593,21 +593,21 @@ "Members only (since the point in time of selecting this option)": "Solo miembros (desde el momento en que se selecciona esta opción)", "Members only (since they were invited)": "Solo miembros (desde que fueron invitados)", "Members only (since they joined)": "Solo miembros (desde que se unieron)", - "You don't currently have any stickerpacks enabled": "Actualmente no tienes ningún paquete de pegatinas habilitado", + "You don't currently have any stickerpacks enabled": "Actualmente no tienes ningún paquete de pegatinas activado", "Stickerpack": "Paquete de pegatinas", "Hide Stickers": "Ocultar Pegatinas", "Show Stickers": "Mostrar Pegatinas", "Invalid community ID": "ID de comunidad inválida", "'%(groupId)s' is not a valid community ID": "'%(groupId)s' no es una ID de comunidad válida", "Flair": "Insignia", - "Showing flair for these communities:": "Mostrar insignias de estas comunidades:", + "Showing flair for these communities:": "Mostrar insignias de las siguientes comunidades:", "This room is not showing flair for any communities": "Esta sala no está mostrando insignias para ninguna comunidad", "New community ID (e.g. +foo:%(localDomain)s)": "Nueva ID de comunidad (ej. +foo:%(localDomain)s)", "URL previews are enabled by default for participants in this room.": "La vista previa de URL se activa por defecto en los participantes de esta sala.", "URL previews are disabled by default for participants in this room.": "La vista previa se desactiva por defecto para los participantes de esta sala.", "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "En salas cifradas como ésta, la vista previa de las URL se desactiva por defecto para asegurar que el servidor base (donde se generan) no puede recopilar información de los enlaces que veas en esta sala.", "URL Previews": "Vista previa de URL", - "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Cuando alguien pone una URL en su mensaje, una vista previa se mostrará para ofrecer información sobre el enlace, tal como título, descripción, y una imagen del sitio Web.", + "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Cuando alguien incluye una URL en su mensaje, se mostrará una vista previa para ofrecer información sobre el enlace, que incluirá el título, descripción, y una imagen del sitio web.", "Error decrypting audio": "Error al descifrar el sonido", "Error decrypting image": "Error al descifrar imagen", "Error decrypting video": "Error al descifrar video", @@ -927,14 +927,14 @@ "Custom user status messages": "Mensajes de estado de usuario personalizados", "Group & filter rooms by custom tags (refresh to apply changes)": "Agrupa y filtra salas por etiquetas personalizadas (refresca para aplicar cambios)", "Render simple counters in room header": "Muestra contadores simples en la cabecera de la sala", - "Enable Emoji suggestions while typing": "Habilitar sugerencia de Emojis mientras se teclea", + "Enable Emoji suggestions while typing": "Activar sugerencias de emojis al escribir", "Show a placeholder for removed messages": "Mostrar una marca para los mensaje borrados", "Show join/leave messages (invites/kicks/bans unaffected)": "Mostrar mensajes de entrada/salida (no afecta a invitaciones/expulsiones/baneos)", "Show avatar changes": "Mostrar cambios de avatar", "Show display name changes": "Muestra cambios en los nombres", "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Mostrar un recordatorio para habilitar 'Recuperación Segura de Mensajes' en sala cifradas", "Show avatars in user and room mentions": "Mostrar avatares en menciones a usuarios y salas", - "Enable big emoji in chat": "Habilitar emojis grandes en el chat", + "Enable big emoji in chat": "Activar emojis grandes en el chat", "Send typing notifications": "Enviar notificaciones de tecleo", "Allow Peer-to-Peer for 1:1 calls": "Permitir conexión de pares en llamadas individuales", "Prompt before sending invites to potentially invalid matrix IDs": "Pedir confirmación antes de enviar invitaciones a IDs de matrix que parezcan inválidas", @@ -1033,7 +1033,7 @@ "Profile picture": "Foto de perfil", "Display Name": "Nombre a mostrar", "Internal room ID:": "ID de Sala Interna:", - "Open Devtools": "Abrir Devtools", + "Open Devtools": "Abrir devtools", "General": "General", "Room Addresses": "Direcciones de sala", "Set a new account password...": "Establecer una nueva contraseña para la cuenta...", @@ -1050,11 +1050,11 @@ "Preferences": "Opciones", "Room list": "Lista de salas", "Autocomplete delay (ms)": "Retardo autocompletado (ms)", - "Roles & Permissions": "Roles & Permisos", + "Roles & Permissions": "Roles y permisos", "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Los cambios que se hagan sobre quien puede leer el historial se aplicarán solo a nuevos mensajes en esta sala. La visibilidad del historial actual no cambiará.", "Security & Privacy": "Seguridad y privacidad", "Encryption": "Cifrado", - "Once enabled, encryption cannot be disabled.": "Después de activarlo, el cifrado no se puede desactivar.", + "Once enabled, encryption cannot be disabled.": "Una vez activado, el cifrado no se puede desactivar.", "Encrypted": "Cifrado", "Ignored users": "Usuarios ignorados", "Bulk options": "Opciones generales", @@ -1088,7 +1088,7 @@ "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s cambió la regla para unirse a %(rule)s", "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s cambió el acceso para invitados a %(rule)s", "Use a longer keyboard pattern with more turns": "Usa un patrón de tecleo largo con más vueltas", - "Enable Community Filter Panel": "Habilitar el Panel de Filtro de Comunidad", + "Enable Community Filter Panel": "Activar el panel de filtro de comunidad", "Verify this user by confirming the following emoji appear on their screen.": "Verifica este usuario confirmando que los siguientes emojis aparecen en su pantalla.", "Your %(brand)s is misconfigured": "Tu %(brand)s tiene un error de configuración", "Whether or not you're logged in (we don't record your username)": "Hayas o no iniciado sesión (no guardamos tu nombre de usuario)", @@ -1107,9 +1107,9 @@ "%(senderName)s made no change.": "%(senderName)s no hizo ningún cambio.", "Sends the given message coloured as a rainbow": "Envía el mensaje coloreado como un arcoiris", "Sends the given emote coloured as a rainbow": "Envía el emoji coloreado como un arcoiris", - "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s ha habilitado las insignias para %(groups)s en esta sala.", - "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s ha deshabilitado las insignias para %(groups)s en esta sala.", - "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s ha habilitado las insignias para %(newGroups)s y las ha deshabilitado para %(oldGroups)s en esta sala.", + "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s ha activado las insignias para %(groups)s en esta sala.", + "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s ha desactivado las insignias para %(groups)s en esta sala.", + "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s ha activado las insignias para %(newGroups)s y las ha desactivado para %(oldGroups)s en esta sala.", "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s ha revocado la invitación para que %(targetDisplayName)s se una a la sala.", "Cannot reach homeserver": "No se puede conectar con el servidor", "Ensure you have a stable internet connection, or get in touch with the server admin": "Asegúrate de tener conexión a internet, o contacta con el administrador del servidor", @@ -1162,7 +1162,7 @@ "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s hizo una llamada de vídeo (no soportada por este navegador)", "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", "Try out new ways to ignore people (experimental)": "Pruebe nuevas formas de ignorar a usuarios (experimental)", - "Match system theme": "Utilizar el mismo tema que el sistema", + "Match system theme": "Usar el mismo tema que el sistema", "Show previews/thumbnails for images": "Mostrar vistas previas para las imágenes", "When rooms are upgraded": "Cuando las salas son actualizadas", "My Ban List": "Mi lista de baneos", @@ -1236,8 +1236,8 @@ "Suggestions": "Sugerencias", "Recently Direct Messaged": "Enviado Mensaje Directo recientemente", "Go": "Ir", - "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Has usado %(brand)s anteriormente en %(host)s con carga diferida de usuarios habilitada. En esta versión la carga diferida está deshabilitada. Como el caché local no es compatible entre estas dos configuraciones, %(brand)s necesita resincronizar tu cuenta.", - "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si la otra versión de %(brand)s esta todavía abierta en otra pestaña, por favor, ciérrala, ya que usar %(brand)s en el mismo host con la opción de carga diferida habilitada y deshabilitada simultáneamente causará problemas.", + "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Has usado %(brand)s anteriormente en %(host)s con carga diferida de usuarios activada. En esta versión la carga diferida está desactivada. Como el caché local no es compatible entre estas dos configuraciones, %(brand)s tiene que resincronizar tu cuenta.", + "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si la otra versión de %(brand)s esta todavía abierta en otra pestaña, por favor, ciérrala, ya que usar %(brand)s en el mismo host con la opción de carga diferida activada y desactivada simultáneamente causará problemas.", "Incompatible local cache": "Caché local incompatible", "Clear cache and resync": "Limpiar la caché y resincronizar", "I don't want my encrypted messages": "No quiero mis mensajes cifrados", @@ -1348,7 +1348,7 @@ "Show typing notifications": "Mostrar notificaciones de escritura", "Never send encrypted messages to unverified sessions from this session": "No enviar nunca mensajes cifrados a sesiones sin verificar desde esta sesión", "Never send encrypted messages to unverified sessions in this room from this session": "No enviar nunca mensajes cifrados a sesiones sin verificar en esta sala desde esta sesión", - "Enable message search in encrypted rooms": "Habilitar la búsqueda de mensajes en salas cifradas", + "Enable message search in encrypted rooms": "Activar la búsqueda de mensajes en salas cifradas", "How fast should messages be downloaded.": "Con qué rapidez deben ser descargados los mensajes.", "Verify this session by completing one of the following:": "Verifica esta sesión completando uno de los siguientes:", "Scan this unique code": "Escanea este código único", @@ -1376,7 +1376,7 @@ "Sounds": "Sonidos", "Notification sound": "Sonido de notificación", "Set a new custom sound": "Usar un nuevo sonido personalizado", - "Browse": "Navegar", + "Browse": "Seleccionar", "Change room avatar": "Cambiar avatar de sala", "Change room name": "Cambiar nombre de sala", "Change main address for the room": "Cambiar la dirección principal para la sala", @@ -1400,7 +1400,7 @@ "Notify everyone": "Notificar a todos", "Send %(eventType)s events": "Enviar eventos %(eventType)s", "Select the roles required to change various parts of the room": "Selecciona los roles requeridos para cambiar varias partes de la sala", - "Enable encryption?": "¿Habilitar cifrado?", + "Enable encryption?": "¿Activar cifrado?", "Your email address hasn't been verified yet": "Tu dirección de email no ha sido verificada", "Verify the link in your inbox": "Verifica el enlace en tu bandeja de entrada", "Complete": "Completar", @@ -1411,8 +1411,8 @@ "Backup key stored: ": "Clave de seguridad almacenada: ", "Your keys are not being backed up from this session.": "No se está haciendo una copia de seguridad de tus claves en esta sesión.", "Clear notifications": "Limpiar notificaciones", - "Enable desktop notifications for this session": "Habilitar notificaciones de escritorio para esta sesión", - "Enable audible notifications for this session": "Habilitar notificaciones sonoras para esta sesión", + "Enable desktop notifications for this session": "Activar notificaciones de escritorio para esta sesión", + "Enable audible notifications for this session": "Activar notificaciones sonoras para esta sesión", "Checking server": "Comprobando servidor", "Change identity server": "Cambiar servidor de identidad", "Disconnect from the identity server and connect to instead?": "¿Desconectarse del servidor de identidad y conectarse a ?", @@ -1525,7 +1525,7 @@ "Backup has a valid signature from unverified session ": "La copia de seguridad tiene una firma de válida de sesión no verificada ", "Backup has an invalid signature from verified session ": "La copia de seguridad tiene una firma de no válida de sesión verificada ", "Backup has an invalid signature from unverified session ": "La copia de seguridad tiene una firma de no válida de sesión no verificada ", - "Upgrade to your own domain": "Actualizar a su propio dominio", + "Upgrade to your own domain": "Contratar el uso de un dominio personalizado", "Identity Server URL must be HTTPS": "La URL del servidor de identidad debe ser tipo HTTPS", "Not a valid Identity Server (status code %(code)s)": "No es un servidor de identidad válido (código de estado %(code)s)", "Could not connect to Identity Server": "No se ha podido conectar al servidor de identidad", @@ -1559,7 +1559,7 @@ "Subscribe": "Suscribir", "Always show the window menu bar": "Siempre mostrar la barra de menú de la ventana", "Show tray icon and minimize window to it on close": "Mostrar el icono en el Área de Notificación y minimizar la ventana al cerrarla", - "Composer": "Compositor", + "Composer": "Editor", "Timeline": "Línea de tiempo", "Read Marker lifetime (ms)": "Permanencia del marcador de lectura (en ms)", "Read Marker off-screen lifetime (ms)": "Permanencia del marcador de lectura fuera de la pantalla (en ms)", @@ -1641,12 +1641,12 @@ "Please enter a name for the room": "Por favor, introduzca un nombre para la sala", "This room is private, and can only be joined by invitation.": "Esta sala es privada, y sólo se puede acceder a ella por invitación.", "Enable end-to-end encryption": "Activar el cifrado de extremo a extremo", - "You can’t disable this later. Bridges & most bots won’t work yet.": "No puedes deshabilitar esto después. Los puentes y la mayoría de los bots no funcionarán todavía.", + "You can’t disable this later. Bridges & most bots won’t work yet.": "No puedes desactivar esto después. Los puentes y la mayoría de los bots no funcionarán todavía.", "Create a public room": "Crear una sala pública", "Create a private room": "Crear una sala privada", "Topic (optional)": "Tema (opcional)", "Make this room public": "Convierte esta sala en pública", - "Hide advanced": "Ocultar opciones avanzadas", + "Hide advanced": "Ocultar ajustes avanzados", "Show advanced": "Mostrar ajustes avanzados", "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Evitar que usuarios de otros servidores Matrix se unan a esta sala (¡Este ajuste no puede ser cambiada más tarde!)", "Server did not require any authentication": "El servidor no requirió ninguna autenticación", @@ -1663,10 +1663,10 @@ "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Verificar que este usuario marcará su sesión como de confianza, y también que marcará su sesión como de confianza para él.", "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verifique este dispositivo para marcarlo como confiable. Confiar en este dispositivo le da a usted y a otros usuarios tranquilidad adicional cuando utilizan mensajes cifrados de extremo a extremo.", "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "La verificación de este dispositivo lo marcará como de confianza. Los usuarios que te han verificado confiarán en este dispositivo.", - "Integrations are disabled": "Las integraciones están deshabilitadas", - "Enable 'Manage Integrations' in Settings to do this.": "Habilita 'Gestionar Integraciones' en Ajustes para hacer esto.", + "Integrations are disabled": "Las integraciones están desactivadas", + "Enable 'Manage Integrations' in Settings to do this.": "Activa «Gestionar integraciones» en ajustes para hacer esto.", "Integrations not allowed": "Integraciones no están permitidas", - "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Su %(brand)s no le permite utilizar un \"Administrador de Integración\" para hacer esto. Por favor, contacte con un administrador.", + "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "%(brand)s no utilizar un \"gestor de integración\" para hacer esto. Por favor, contacta con un administrador.", "Failed to invite the following users to chat: %(csvUsers)s": "Error invitando a los siguientes usuarios al chat: %(csvUsers)s", "We couldn't create your DM. Please check the users you want to invite and try again.": "No se ha podido crear el mensaje directo. Por favor, comprueba los usuarios que quieres invitar e inténtalo de nuevo.", "Start a conversation with someone using their name, username (like ) or email address.": "Iniciar una conversación con alguien usando su nombre, nombre de usuario (como ) o dirección de correo electrónico.", @@ -1677,7 +1677,7 @@ "a key signature": "un firma de clave", "%(brand)s encountered an error during upload of:": "%(brand)s encontró un error durante la carga de:", "End": "Fin", - "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Una vez habilitado, el cifrado de una sala no puede deshabilitarse. Los mensajes enviados a una sala cifrada no pueden ser vistos por el servidor, sólo lo verán los participantes de la sala. Habilitar el cifrado puede hacer que muchos bots y bridges no funcionen correctamente. Aprende más de cifrado", + "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Una vez activado, el cifrado de una sala no puede desactivarse. Los mensajes enviados a una sala cifrada no pueden ser vistos por el servidor, solo lo verán los participantes de la sala. Activar el cifrado puede hacer que muchos bots y bridges no funcionen correctamente. Más información sobre el cifrado", "Joining room …": "Uniéndose a sala …", "Loading …": "Cargando …", "Rejecting invite …": "Rechazando invitación …", @@ -1762,7 +1762,7 @@ "Published Addresses": "Direcciones publicadas", "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Las direcciones publicadas pueden ser usadas por cualquier usuario en cualquier servidor para unirse a tu salas. Para publicar una dirección, primero hay que establecerla como una dirección local.", "Other published addresses:": "Otras direcciones publicadas:", - "No other published addresses yet, add one below": "No tiene direcciones publicadas todavía, agregue una más abajo", + "No other published addresses yet, add one below": "Todavía no hay direcciones publicadas, puedes añadir una más abajo", "New published address (e.g. #alias:server)": "Nueva dirección publicada (p.ej.. #alias:server)", "Local Addresses": "Direcciones locales", "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Establecer las direcciones de esta sala para que los usuarios puedan encontrarla a través de tu servidor base (%(localDomain)s)", @@ -1925,7 +1925,7 @@ "Resend edit": "Reenviar la edición", "Resend %(unsentCount)s reaction(s)": "Reenviar %(unsentCount)s reacción(es)", "Resend removal": "Reenviar la eliminación", - "Share Permalink": "Compartir Permalink", + "Share Permalink": "Compartir enlace", "Report Content": "Reportar contenido", "Notification settings": "Configuración de notificaciones", "Clear status": "Borrar estado", @@ -2004,10 +2004,10 @@ "%(brand)s failed to get the public room list.": "%(brand)s no logró obtener la lista de salas públicas.", "The homeserver may be unavailable or overloaded.": "Es posible el servidor de base no esté disponible o esté sobrecargado.", "Preview": "Ver", - "View": "Vista", + "View": "Ver", "Find a room…": "Encuentre una sala…", - "Find a room… (e.g. %(exampleRoom)s)": "Encontrar una sala una sala... (ej.: %(exampleRoom)s)", - "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Si no puedes encontrar la sala que buscas, pide que te inviten a ella o crea una nueva.", + "Find a room… (e.g. %(exampleRoom)s)": "Encuentra una sala... (ej.: %(exampleRoom)s)", + "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Si no encuentras la sala que buscas, pide que te inviten a ella o crea una nueva.", "Explore rooms": "Explorar salas", "Jump to first invite.": "Salte a la primera invitación.", "Add room": "Añadir sala", @@ -2100,10 +2100,10 @@ "This session is encrypting history using the new recovery method.": "Esta sesión está cifrando el historial usando el nuevo método de recuperación.", "Change notification settings": "Cambiar los ajustes de notificaciones", "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipo de comunidades v2. Requiere un servidor compatible. Altamente experimental - usar con precuación.", - "Font size": "Tamaño de la fuente", - "Use custom size": "Utilizar un tamaño personalizado", + "Font size": "Tamaño del texto", + "Use custom size": "Usar un tamaño personalizado", "Use a more compact ‘Modern’ layout": "Usar un diseño más 'moderno' y compacto", - "Use a system font": "Utilizar una fuente del sistema", + "Use a system font": "Usar una fuente del sistema", "System font name": "Nombre de la fuente", "Enable experimental, compact IRC style layout": "Activar el diseño experimental de IRC compacto", "Uploading logs": "Subiendo registros", @@ -2123,11 +2123,11 @@ "Message layout": "Diseño del mensaje", "Compact": "Compacto", "Modern": "Moderno", - "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Inserta el nombre de la fuente instalada en tu sistema y %(brand)s intentara utilizarla.", - "Customise your appearance": "Personaliza tu apariencia", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Introduce el nombre de la fuente instalada en tu sistema y %(brand)s intentará utilizarla.", + "Customise your appearance": "Personaliza la apariencia", "Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta esta %(brand)s sesión.", "Please verify the room ID or address and try again.": "Por favor, verifica la ID o dirección de esta sala e inténtalo de nuevo.", - "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "El administrador del servidor base ha deshabilitado el cifrado de extremo a extremo en salas privadas y mensajes directos.", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "El administrador del servidor base ha desactivado el cifrado de extremo a extremo en salas privadas y mensajes directos.", "To link to this room, please add an address.": "Para vincular esta sala, por favor añade una dirección.", "The authenticity of this encrypted message can't be guaranteed on this device.": "La autenticidad de este mensaje cifrado no puede ser garantizada en este dispositivo.", "No recently visited rooms": "No hay salas visitadas recientemente", @@ -2144,7 +2144,7 @@ "New spinner design": "Nuevo diseño de ruleta", "Show message previews for reactions in DMs": "Mostrar vistas previas de mensajes para reacciones en DM", "Show message previews for reactions in all rooms": "Mostrar vistas previas de mensajes para reacciones en todas las salas", - "Enable advanced debugging for the room list": "Habilite la depuración avanzada para la lista de salas", + "Enable advanced debugging for the room list": "Activar la depuración avanzada para la lista de salas", "IRC display name width": "Ancho del nombre de visualización de IRC", "Unknown caller": "Llamador desconocido", "Cross-signing is ready for use.": "La firma cruzada está lista para su uso.", @@ -2220,7 +2220,7 @@ "Send %(count)s invites|other": "Enviar %(count)s invitaciones", "Send %(count)s invites|one": "Enviar invitación a %(count)s", "Invite people to join %(communityName)s": "Invita a personas a unirse %(communityName)s", - "There was an error creating your community. The name may be taken or the server is unable to process your request.": "Hubo un error al crear tu comunidad. El nombre puede ser tomado o el servidor no puede procesar su solicitud.", + "There was an error creating your community. The name may be taken or the server is unable to process your request.": "Ha ocurrido un error al crear la comunidad. El nombre puede que ya esté siendo usado o el servidor no puede procesar la solicitud.", "Community ID: +:%(domain)s": "ID de comunidad: +:%(domain)s", "Use this when referencing your community to others. The community ID cannot be changed.": "Use esto cuando haga referencia a su comunidad con otras. La identificación de la comunidad no se puede cambiar.", "You can change this later if needed.": "Puede cambiar esto más tarde si es necesario.", @@ -2235,7 +2235,7 @@ "Create a room in %(communityName)s": "Crea una sala en %(communityName)s", "Block anyone not part of %(serverName)s from ever joining this room.": "Bloquea a cualquier persona que no sea parte de %(serverName)s para que no se una a esta sala.", "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Anteriormente usaste una versión más nueva de %(brand)s con esta sesión. Para volver a utilizar esta versión con cifrado de extremo a extremo, deberá cerrar sesión y volver a iniciar sesión.", - "There was an error updating your community. The server is unable to process your request.": "Hubo un error al actualizar tu comunidad. El servidor no puede procesar su solicitud.", + "There was an error updating your community. The server is unable to process your request.": "Ha ocurrido un error al actualizar tu comunidad. El servidor no puede procesar la solicitud.", "Update community": "Actualizar comunidad", "To continue, use Single Sign On to prove your identity.": "Para continuar, utilice el inicio de sesión único para demostrar su identidad.", "Confirm to continue": "Confirmar para continuar", @@ -2246,10 +2246,10 @@ "Server isn't responding": "El servidor no responde", "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Su servidor no responde a algunas de sus solicitudes. A continuación se presentan algunas de las razones más probables.", "The server (%(serverName)s) took too long to respond.": "El servidor (%(serverName)s) tardó demasiado en responder.", - "Your firewall or anti-virus is blocking the request.": "Su firewall o antivirus está bloqueando la solicitud.", - "A browser extension is preventing the request.": "Una extensión del navegador impide la solicitud.", + "Your firewall or anti-virus is blocking the request.": "Tu firewall o antivirus está bloqueando la solicitud.", + "A browser extension is preventing the request.": "Una extensión del navegador está impidiendo que se haga la solicitud.", "The server is offline.": "El servidor está desconectado.", - "The server has denied your request.": "El servidor ha denegado su solicitud.", + "The server has denied your request.": "El servidor ha rechazado la solicitud.", "Your area is experiencing difficulties connecting to the internet.": "Su área está experimentando dificultades para conectarse a Internet.", "A connection error occurred while trying to contact the server.": "Se produjo un error de conexión al intentar contactar con el servidor.", "The server is not configured to indicate what the problem is (CORS).": "El servidor no está configurado para indicar cuál es el problema (CORS).", @@ -2396,7 +2396,7 @@ "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Si hizo esto accidentalmente, puede configurar Mensajes seguros en esta sesión que volverá a cifrar el historial de mensajes de esta sesión con un nuevo método de recuperación.", "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si no eliminó el método de recuperación, es posible que un atacante esté intentando acceder a su cuenta. Cambie la contraseña de su cuenta y configure un nuevo método de recuperación inmediatamente en Configuración.", "If disabled, messages from encrypted rooms won't appear in search results.": "Si está desactivado, los mensajes de las salas cifradas no aparecerán en los resultados de búsqueda.", - "Disable": "Inhabilitar", + "Disable": "Desactivar", "Not currently indexing messages for any room.": "Actualmente no indexa mensajes para ninguna sala.", "Currently indexing: %(currentRoom)s": "Actualmente indexando: %(currentRoom)s", "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s está almacenando en caché de forma segura los mensajes cifrados localmente para que aparezcan en los resultados de búsqueda:", @@ -2419,8 +2419,8 @@ "Toggle Quote": "Alternar Entrecomillar", "New line": "Nueva línea", "Navigate recent messages to edit": "Navegar por mensajes recientes para editar", - "Jump to start/end of the composer": "Saltar al inicio / final del compositor", - "Navigate composer history": "Navegar por el historial del compositor", + "Jump to start/end of the composer": "Saltar al inicio o final del editor", + "Navigate composer history": "Navegar por el historial del editor", "Cancel replying to a message": "Cancelar la respuesta a un mensaje", "Toggle microphone mute": "Alternar silencio del micrófono", "Toggle video on/off": "Activar/desactivar video", From 69b7daae449793504a3cc3401397b8cd1e79c1b1 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Wed, 24 Feb 2021 09:49:01 +0000 Subject: [PATCH 0198/2651] Translated using Weblate (French) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 122 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 3bb86d2c63..b98edea1b1 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2547,7 +2547,7 @@ "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n'importe qui dans cette communauté.", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n'importe qui.", "Start a new chat": "Commencer une nouvelle discussion", - "Add a photo so people know it's you.": "Ajoutez une photo pour que les gens savent que c'est vous", + "Add a photo so people know it's you.": "Ajoutez une photo pour que les gens sachent qu’il s’agit de vous.", "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s ou %(usernamePassword)s", "Decide where your account is hosted": "Décidez où votre compte est hébergé", "Go to Home View": "Revenir à la page d'accueil", @@ -2820,11 +2820,11 @@ "British Indian Ocean Territory": "Territoire britannique de l'océan Indien", "Brazil": "Brésil", "Bouvet Island": "Île Bouvet", - "Botswana": "", + "Botswana": "Botswana", "Bosnia": "Bosnie-Herzegovine", - "Bolivia": "", - "Bhutan": "", - "Bermuda": "", + "Bolivia": "Bolivie", + "Bhutan": "Bhoutan", + "Bermuda": "Bermudes", "with state key %(stateKey)s": "avec la ou les clés d'état %(stateKey)s", "with an empty state key": "avec une clé d'état vide", "See when anyone posts a sticker to your active room": "Voir quand n'importe qui envoye un sticker dans le salon actuel", @@ -2837,7 +2837,7 @@ "See when the topic changes in this room": "Voir quand le sujet change dans ce salon", "See when the topic changes in your active room": "Voir quand le sujet change dans le salon actuel", "Change the name of your active room": "Changer le nom du salon actuel", - "See when the name changes in this room": "Traquer quand le nom change dans ce salon", + "See when the name changes in this room": "Suivre quand le nom de ce salon change", "Change the name of this room": "Changer le nom de ce salon", "Change the topic of your active room": "Changer le sujet dans le salon actuel", "Change the topic of this room": "Changer le sujet de ce salon", @@ -2935,5 +2935,113 @@ "See general files posted to your active room": "Voir les fichiers postés dans votre salon actuel", "See general files posted to this room": "Voir les fichiers postés dans ce salon", "Send general files as you in your active room": "Envoie des fichiers en tant que vous dans votre salon actuel", - "Send general files as you in this room": "Envoie des fichiers en tant que vous dans ce salon" + "Send general files as you in this room": "Envoie des fichiers en tant que vous dans ce salon", + "Search (must be enabled)": "Recherche (si activée)", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Cette session a détecté que votre phrase de passe et clé de sécurité pour les messages sécurisés ont été supprimées.", + "A new Security Phrase and key for Secure Messages have been detected.": "Une nouvelle phrase de passe et clé pour les messages sécurisés ont été détectées.", + "Make a copy of your Security Key": "Faire une copie de votre Clé de Sécurité", + "Confirm your Security Phrase": "Confirmez votre phrase de passe", + "Secure your backup with a Security Phrase": "Protégez votre sauvegarde avec une Clé de Sécurité", + "Your Security Key is in your Downloads folder.": "Votre Clé de Sécurité est dans le répertoire Téléchargements.", + "Your Security Key has been copied to your clipboard, paste it to:": "Votre Clé de Sécurité a été copiée dans votre presse-papier, copiez la pour :", + "Your Security Key": "Votre Clé de Sécurité", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Votre Clé de Sécurité est un filet de sécurité. Vous pouvez l’utiliser pour retrouver l’accès à vos messages chiffrés si vous oubliez votre phrase de passe.", + "Repeat your Security Phrase...": "Répétez votre phrase de passe…", + "Please enter your Security Phrase a second time to confirm.": "Merci de saisir votre phrase de passe une seconde fois pour confirmer.", + "Set up with a Security Key": "Configurer avec une Clé de Sécurité", + "Great! This Security Phrase looks strong enough.": "Super ! Cette phrase de passe a l’air assez solide.", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Nous avons stocké une copie chiffrée de vos clés sur notre serveur. Sécurisez vos sauvegardes avec une phrase de passe.", + "Use Security Key": "Utiliser la Clé de Sécurité", + "Use Security Key or Phrase": "Utilisez votre Clé de Sécurité ou phrase de passe", + "You have no visible notifications.": "Vous n’avez aucune notification visible.", + "Upgrade to pro": "Mettre à jour vers pro", + "Great, that'll help people know it's you": "Super, ceci aidera des personnes à confirmer qu’il s’agit bien de vous", + "

HTML for your community's page

\n

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

\n

\n You can even add images with Matrix URLs \n

\n": "

HTML pour votre page de communauté

\n

\n Utilisez la description longue pour présenter la communauté aux nouveaux membres\n ou pour diffuser des liens importants\n

\n

\n Vous pouvez même ajouter des images avec des URL Matrix \n

\n", + "Use email to optionally be discoverable by existing contacts.": "Utiliser une adresse e-mail pour pouvoir être découvert par des contacts existants.", + "Use email or phone to optionally be discoverable by existing contacts.": "Utiliser une adresse e-mail ou un numéro de téléphone pour pouvoir être découvert par des contacts existants.", + "Add an email to be able to reset your password.": "Ajouter une adresse e-mail pour pouvoir réinitialiser votre mot de passe.", + "Forgot password?": "Mot de passe oublié ?", + "That phone number doesn't look quite right, please check and try again": "Ce numéro de téléphone ne semble pas correct, merci de vérifier et réessayer", + "Enter email address": "Saisir l’adresse e-mail", + "Enter phone number": "Saisir le numéro de téléphone", + "Something went wrong in confirming your identity. Cancel and try again.": "Une erreur s’est produite lors de la vérification de votre identité. Annulez et réessayez.", + "Open the link in the email to continue registration.": "Ouvrez le lien dans l’e-mail pour poursuivre l’inscription.", + "A confirmation email has been sent to %(emailAddress)s": "Un e-mail de confirmation a été envoyé à %(emailAddress)s", + "Hold": "Mettre en pause", + "Resume": "Reprendre", + "If you've forgotten your Security Key you can ": "Si vous avez oublié votre Clé de Sécurité, vous pouvez ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre Clé de Sécurité.", + "Not a valid Security Key": "Clé de Sécurité invalide", + "This looks like a valid Security Key!": "Ça ressemble à une Clé de Sécurité !", + "Enter Security Key": "Saisir la clé de sécurité", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Si vous avez oublié votre phrase de passe vous pouvez utiliser votre Clé de Sécurité ou définir de nouvelles options de récupération", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre phrase de passe.", + "Enter Security Phrase": "Saisir la phrase de passe", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "La sauvegarde n’a pas pu être déchiffrée avec cette phrase de passe : merci de vérifier que vous avez saisi la bonne phrase de passe.", + "Incorrect Security Phrase": "Phrase de passe incorrecte", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "La sauvegarde n’a pas pu être déchiffrée avec cette Clé de Sécurité : merci de vérifier que vous avez saisi la bonne Clé de Sécurité.", + "Security Key mismatch": "Pas de correspondance entre les Clés de Sécurité", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Impossible d’accéder à l’espace de stockage sécurisé. Merci de vérifier que vous avez saisi la bonne phrase de passe.", + "Invalid Security Key": "Clé de Sécurité invalide", + "Wrong Security Key": "Mauvaise Clé de Sécurité", + "Remember this": "Mémoriser ceci", + "The widget will verify your user ID, but won't be able to perform actions for you:": "Ce widget vérifiera votre identifiant d’utilisateur, mais ne pourra pas effectuer des actions en votre nom :", + "Allow this widget to verify your identity": "Autoriser ce widget à vérifier votre identité", + "Decline All": "Tout refuser", + "Approve": "Approuver", + "This widget would like to:": "Le widget voudrait :", + "Approve widget permissions": "Approuver les permissions du widget", + "We recommend you change your password and Security Key in Settings immediately": "Nous vous recommandons de changer votre mot de passe et Clé de Sécurité dans les Paramètres immédiatement", + "Minimize dialog": "Réduire la modale", + "Maximize dialog": "Maximiser la modale", + "%(hostSignupBrand)s Setup": "Configuration de %(hostSignupBrand)s", + "You should know": "Vous devriez connaître", + "Privacy Policy": "Politique de confidentialité", + "Cookie Policy": "Politique de gestion des cookies", + "Learn more in our , and .": "Consultez nos , et .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Continuer permettra temporairement au processus de configuration de %(hostSignupBrand)s d’accéder à votre compte pour récupérer les adresses email vérifiées. Les données ne sont pas stockées.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Impossible de vous connecter à votre serveur d’accueil. Merci de fermer cette modale et de réessayer.", + "Abort": "Annuler", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Êtes-vous sûr de vouloir annuler la création de cet hôte ? Le process ne pourra pas être repris.", + "Confirm abort of host creation": "Confirmer l’annulation de la création de cet hôte", + "There was an error finding this widget.": "Erreur lors de la récupération de ce widget.", + "Windows": "Windows", + "Screens": "Écrans", + "Share your screen": "Partager votre écran", + "Set my room layout for everyone": "Définir ma disposition de salon pour tout le monde", + "Open dial pad": "Ouvrir le pavé de numérotation", + "Start a Conversation": "Démarrer une conversation", + "Recently visited rooms": "Salons visités récemment", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Sauvegardez vos clés de chiffrement et les données de votre compte au casoù vous perdiez l’accès à vos sessions. Vos clés seront sécurisés avec une Clé de Sécurité unique.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Mettre en cache localement et de manière sécurisée les messages chiffrés pour qu’ils apparaissent dans les résultats de recherche, en utilisant %(size)s pour stocker les messages de %(rooms)s salons.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Mettre en cache localement et de manière sécurisée les messages chiffrés pour qu’ils apparaissent dans les résultats de recherche, en utilisant %(size)s pour stocker les messages de %(rooms)s salons.", + "Channel: ": "Canal : ", + "Workspace: ": "Espace de travail : ", + "Dial pad": "Pavé de numérotation", + "There was an error looking up the phone number": "Erreur lors de la recherche de votre numéro de téléphone", + "Unable to look up phone number": "Impossible de trouver votre numéro de téléphone", + "Use Ctrl + F to search": "Utilisez Control + F pour rechercher", + "Use Command + F to search": "Utilisez Commande + F pour rechercher", + "Show line numbers in code blocks": "Afficher les numéros de ligne dans les blocs de code", + "Expand code blocks by default": "Dérouler les blocs de code par défaut", + "Show stickers button": "Afficher le bouton stickers", + "Use app": "Utiliser l’application", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web est expérimental sur téléphone. Pour une meilleure expérience et bénéficier des dernières fonctionnalités, utilisez notre application native gratuite.", + "Use app for a better experience": "Utilisez une application pour une meilleure expérience", + "See text messages posted to your active room": "Voir les messages textuels dans le salon actif", + "See text messages posted to this room": "Voir les messages textuels envoyés dans ce salon", + "Send text messages as you in your active room": "Envoyez des messages textuels en tant que vous-même dans le salon actif", + "Send text messages as you in this room": "Envoyez des messages textuels en tant que vous-même dans ce salon", + "See when the name changes in your active room": "Suivre les changements de nom dans le salon actif", + "Change which room, message, or user you're viewing": "Changer le salon, message, ou la personne que vous visualisez", + "Change which room you're viewing": "Changer le salon que vous visualisez", + "Remain on your screen while running": "Restez sur votre écran pendant l’exécution", + "%(senderName)s has updated the widget layout": "%(senderName)s a mis à jour la disposition du widget", + "Converts the DM to a room": "Transformer le message privé en salon", + "Converts the room to a DM": "Transformer le salon en message privé", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil a rejeté la demande de connexion. Ceci pourrait être dû à une connexion qui prend trop de temps. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil n’est pas accessible, nous n’avons pas pu vous connecter. Merci de réessayer. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", + "Try again": "Réessayez", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Nous avons demandé à votre navigateur de mémoriser votre serveur d’accueil, mais il semble l’avoir oublié. Rendez-vous à la page de connexion et réessayez.", + "We couldn't log you in": "Impossible de vous déconnecter" } From a5cdc79f94047e31abc8d8ceb50a6d3ba12aa634 Mon Sep 17 00:00:00 2001 From: Maxime Corteel Date: Mon, 22 Feb 2021 12:18:39 +0000 Subject: [PATCH 0199/2651] Translated using Weblate (French) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index b98edea1b1..c942cae520 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -862,7 +862,7 @@ "Upgrade this room to version %(version)s": "Mettre à niveau ce salon vers la version %(version)s", "Forces the current outbound group session in an encrypted room to be discarded": "Force la session de groupe sortante actuelle dans un salon chiffré à être rejetée", "Unable to connect to Homeserver. Retrying...": "Impossible de se connecter au serveur d'accueil. Reconnexion...", - "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s à défini l'adresse principale pour ce salon comme %(address)s.", + "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s a défini l'adresse principale pour ce salon comme %(address)s.", "%(senderName)s removed the main address for this room.": "%(senderName)s a supprimé l'adresse principale de ce salon.", "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s utilise maintenant 3 à 5 fois moins de mémoire, en ne chargeant les informations des autres utilisateurs que quand elles sont nécessaires. Veuillez patienter pendant que l'on se resynchronise avec le serveur !", "Updating %(brand)s": "Mise à jour de %(brand)s", @@ -970,7 +970,7 @@ "Invite anyway": "Inviter quand même", "Whether or not you're logged in (we don't record your username)": "Si vous êtes connecté ou pas (votre nom d'utilisateur n'est pas enregistré)", "Upgrades a room to a new version": "Met à niveau un salon vers une nouvelle version", - "Sets the room name": "Défini le nom du salon", + "Sets the room name": "Définit le nom du salon", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s a mis à niveau ce salon.", "%(displayName)s is typing …": "%(displayName)s est en train d'écrire…", "%(names)s and %(count)s others are typing …|other": "%(names)s et %(count)s autres sont en train d'écrire…", @@ -1085,7 +1085,7 @@ "Recovery Method Removed": "Méthode de récupération supprimée", "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n'avez pas supprimé la méthode de récupération, un attaquant peut être en train d'essayer d'accéder à votre compte. Modifiez le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les réglages.", "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Le fichier \"%(fileName)s\" dépasse la taille limite autorisée par ce serveur pour les téléchargements", - "Gets or sets the room topic": "Récupère ou défini le sujet du salon", + "Gets or sets the room topic": "Récupère ou définit le sujet du salon", "This room has no topic.": "Ce salon n'a pas de sujet.", "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s a rendu le salon public à tous ceux qui en connaissent le lien.", "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s a rendu le salon disponible sur invitation seulement.", @@ -2894,7 +2894,7 @@ "Homeserver": "Serveur d'accueil", "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Vous pouvez utiliser les options de serveur personnalisés pour vous connecter à d'autres serveurs Matrix en spécifiant une URL de serveur d'accueil différente. Celà vous permet d'utiliser Element avec un compte Matrix existant sur un serveur d'accueil différent.", "Server Options": "Options serveur", - "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Quand les gens joignent, vous pouvez les vérifiez dans leur profil, tappez juste sur leur avatar.", + "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Quand les gens joignent, vous pouvez les vérifier dans leur profil, tapez simplement sur leur avatar.", "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Vérifiez %(displayName)s dans leur profil - tapez sur leur avatar.", "Role": "Rôle", "Use the + to make a new room or explore existing ones below": "Utilisez le + pour créer un nouveau salon ou explorer les existantes ci-dessous", From 23b16b62f205ae23b5234196970c3f629f412619 Mon Sep 17 00:00:00 2001 From: MusiCode1 Date: Sun, 21 Feb 2021 20:59:15 +0000 Subject: [PATCH 0200/2651] Translated using Weblate (Hebrew) Currently translated at 98.5% (2723 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/he/ --- src/i18n/strings/he.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 30ca524699..1dd492767e 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -2774,5 +2774,16 @@ "Workspace: ": "סביבת עבודה: ", "Use Ctrl + F to search": "השתמש ב- Ctrl + F כדי לחפש", "Use Command + F to search": "השתמש ב- Command + F כדי לחפש", - "Change which room, message, or user you're viewing": "שנה את החדר, ההודעה או המשתמש שאתה צופה בו" + "Change which room, message, or user you're viewing": "שנה את החדר, ההודעה או המשתמש שאתה צופה בו", + "Expand code blocks by default": "הרחב את בלוקי הקוד כברירת מחדל", + "Show stickers button": "הצג את לחצן הסטיקרים", + "Use app": "השתמש באפליקציה", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web הוא ניסיוני במובייל. לקבלת חוויה טובה יותר והתכונות העדכניות ביותר, השתמש באפליקציה המקורית החינמית שלנו.", + "Use app for a better experience": "השתמש באפליקציה לחוויה טובה יותר", + "Converts the DM to a room": "המר את ה- DM לחדר שיחוח", + "Converts the room to a DM": "המר את החדר ל- DM", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "לא ניתן היה להגיע לשרת הבית שלך ולא היה ניתן להתחבר. נסה שוב. אם זה נמשך, אנא פנה למנהל שרת הבית שלך.", + "Try again": "נסה שוב", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "ביקשנו מהדפדפן לזכור באיזה שרת בית אתה משתמש כדי לאפשר לך להיכנס, אך למרבה הצער הדפדפן שלך שכח אותו. עבור לדף הכניסה ונסה שוב.", + "We couldn't log you in": "לא הצלחנו להתחבר אליך" } From fb083d13ad6bafc3b804c7a75c30de16c558f6e8 Mon Sep 17 00:00:00 2001 From: Men770 Date: Thu, 11 Feb 2021 08:55:30 +0000 Subject: [PATCH 0201/2651] Translated using Weblate (Hebrew) Currently translated at 98.5% (2723 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/he/ --- src/i18n/strings/he.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 1dd492767e..dda9902e72 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -46,7 +46,7 @@ "Unpin Message": "שחרר צימוד הודעה", "Online": "מקוון", "Register": "רשום", - "Rooms": "חדרי שיחוח", + "Rooms": "חדרים", "Add rooms to this community": "הוסף חדר שיחוח לקהילה זו", "OK": "בסדר", "Operation failed": "פעולה נכשלה", From 44153f9cfb53747764f0a5a16e3c52577998becc Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 12 Feb 2021 14:45:14 +0000 Subject: [PATCH 0202/2651] Translated using Weblate (Hungarian) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 20f39d61bc..398dd04ec2 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -3058,5 +3058,7 @@ "Learn more in our , and .": "Tudjon meg többet innen: , és .", "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Folytatva %(hostSignupBrand)s beállítási folyamat ideiglenes hozzáférést kap a fiókadatok elérésére az ellenőrzött e-mail cím megszerzésének érdekében. Ezt az adat nincs elmenetve.", "Failed to connect to your homeserver. Please close this dialog and try again.": "A matrix szerverhez való csatlakozás nem sikerült. Zárja be ezt az ablakot és próbálja újra.", - "Abort": "Megszakítás" + "Abort": "Megszakítás", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Biztos benne, hogy meg kívánja szakítani a gazdagép létrehozásának a folyamatát? A folyamat nem folytatható.", + "Confirm abort of host creation": "Erősítse meg a gazdagép készítés megszakítását" } From 376c675593531c4582d0c8da948e7fdb6ac56f78 Mon Sep 17 00:00:00 2001 From: jelv Date: Mon, 15 Feb 2021 11:48:18 +0000 Subject: [PATCH 0203/2651] Translated using Weblate (Dutch) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 639 ++++++++++++++++++++++++++++----------- 1 file changed, 470 insertions(+), 169 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 82b8cd39d5..101d997d9c 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -24,7 +24,7 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met de gegeven ID", "Call Timeout": "Oproeptime-out", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan geen verbinding maken met de thuisserver via HTTP wanneer er een HTTPS-URL in uw browserbalk staat. Gebruik HTTPS of schakel onveilige scripts in.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan geen verbinding maken met de homeserver via HTTP wanneer er een HTTPS-URL in uw browserbalk staat. Gebruik HTTPS of schakel onveilige scripts in.", "Change Password": "Wachtwoord veranderen", "%(senderName)s changed their profile picture.": "%(senderName)s heeft een nieuwe profielfoto ingesteld.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s heeft het machtsniveau van %(powerLevelDiffText)s gewijzigd.", @@ -87,10 +87,10 @@ "olm version:": "olm-versie:", "Password": "Wachtwoord", "Passwords can't be empty": "Wachtwoorden kunnen niet leeg zijn", - "Permissions": "Toestemmingen", + "Permissions": "Rechten", "Phone": "Telefoonnummer", "Private Chat": "Privégesprek", - "Privileged Users": "Bevoorrechte gebruikers", + "Privileged Users": "Bevoegde gebruikers", "Profile": "Profiel", "Public Chat": "Openbaar gesprek", "Reason": "Reden", @@ -124,7 +124,7 @@ "%(weekDayName)s %(time)s": "%(weekDayName)s, %(time)s", "Set a display name:": "Stel een weergavenaam in:", "Upload an avatar:": "Upload een avatar:", - "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 uw verbinding, zorg ervoor dat het SSL-certificaat van de thuisserver vertrouwd is en dat er geen browserextensies verzoeken blokkeren.", + "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 homeserver - controleer uw verbinding, zorg ervoor dat het SSL-certificaat van de homeserver vertrouwd is en dat er geen browserextensies verzoeken blokkeren.", "Cryptography": "Cryptografie", "Current password": "Huidig wachtwoord", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de gespreksnaam verwijderd.", @@ -143,14 +143,14 @@ "Deops user with given id": "Ontmachtigt gebruiker met de gegeven ID", "Default": "Standaard", "Displays action": "Toont actie", - "Emoji": "Emoticons", + "Emoji": "Emoji", "%(senderName)s ended the call.": "%(senderName)s heeft opgehangen.", "Enter passphrase": "Voer wachtwoord in", "Error decrypting attachment": "Fout bij het ontsleutelen van de bijlage", "Error: Problem communicating with the given homeserver.": "Fout: probleem bij communicatie met de gegeven thuisserver.", "Existing Call": "Bestaande oproep", "Export": "Wegschrijven", - "Export E2E room keys": "E2E-gesprekssleutels wegschrijven", + "Export E2E room keys": "E2E-gesprekssleutels exporteren", "Failed to ban user": "Verbannen van gebruiker is mislukt", "Failed to change power level": "Wijzigen van machtsniveau is mislukt", "Failed to fetch avatar URL": "Ophalen van avatar-URL is mislukt", @@ -181,7 +181,7 @@ "Identity Server is": "Identiteitsserver is", "I have verified my email address": "Ik heb mijn e-mailadres geverifieerd", "Import": "Inlezen", - "Import E2E room keys": "E2E-gesprekssleutels inlezen", + "Import E2E room keys": "E2E-gesprekssleutels 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", @@ -202,7 +202,7 @@ "Last seen": "Laatst gezien", "Leave room": "Gesprek verlaten", "%(targetName)s left the room.": "%(targetName)s heeft het gesprek verlaten.", - "Logout": "Afmelden", + "Logout": "Uitloggen", "Low priority": "Lage prioriteit", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s heeft de toekomstige gespreksgeschiedenis zichtbaar gemaakt voor alle gespreksleden, vanaf het moment dat ze uitgenodigd zijn.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s heeft de toekomstige gespreksgeschiedenis zichtbaar gemaakt voor alle gespreksleden, vanaf het moment dat ze toegetreden zijn.", @@ -222,7 +222,7 @@ "Failed to kick": "Uit het gesprek zetten is mislukt", "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP-vergadering aangevraagd.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", - "Return to login screen": "Terug naar het aanmeldscherm", + "Return to login screen": "Terug naar het loginscherm", "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s heeft geen toestemming u meldingen te sturen - controleer uw browserinstellingen", "%(brand)s was not given permission to send notifications - please try again": "%(brand)s kreeg geen toestemming u meldingen te sturen - probeer het opnieuw", "%(brand)s version:": "%(brand)s-versie:", @@ -230,7 +230,7 @@ "Room Colour": "Gesprekskleur", "%(roomName)s does not exist.": "%(roomName)s bestaat niet.", "%(roomName)s is not accessible at this time.": "%(roomName)s is op dit moment niet toegankelijk.", - "Rooms": "Groepsgesprekken", + "Rooms": "Groepen", "Save": "Opslaan", "Search failed": "Zoeken mislukt", "Searches DuckDuckGo for results": "Zoekt op DuckDuckGo voor resultaten", @@ -248,7 +248,7 @@ "Kicks user with given id": "Stuurt de gebruiker met de gegeven ID uit het gesprek", "%(senderName)s set a profile picture.": "%(senderName)s heeft een profielfoto ingesteld.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s heeft %(displayName)s als weergavenaam aangenomen.", - "Show timestamps in 12 hour format (e.g. 2:30pm)": "Tijd in 12-uursformaat weergeven (bv. 2:30pm)", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Tijd in 12-uursformaat tonen (bv. 2:30pm)", "Signed Out": "Afgemeld", "Sign in": "Aanmelden", "Sign out": "Afmelden", @@ -265,7 +265,7 @@ "This phone number is already in use": "Dit telefoonnummer is al in gebruik", "This room": "Dit gesprek", "This room is not accessible by remote Matrix servers": "Dit gesprek is niet toegankelijk vanaf externe Matrix-servers", - "To use it, just wait for autocomplete results to load and tab through them.": "Om het te gebruiken, wacht u tot de automatisch aangevulde resultaten geladen zijn en tabt u erdoorheen.", + "To use it, just wait for autocomplete results to load and tab through them.": "Om het te gebruiken, wacht u tot de autoaanvullen resultaten geladen zijn en tabt u erdoorheen.", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "U heeft gepoogd een gegeven punt in de tijdslijn van dit gesprek te laden, maar u bent niet bevoegd het desbetreffende bericht te zien.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Geprobeerd een gegeven punt in de tijdslijn van dit gesprek te laden, maar kon dit niet vinden.", "Unable to add email address": "Kan e-mailadres niet toevoegen", @@ -312,8 +312,8 @@ "You have no visible notifications": "U heeft geen zichtbare meldingen", "You must register to use this functionality": "U dient u te registreren om deze functie te gebruiken", "You need to be able to invite users to do that.": "Dit vereist de bevoegdheid gebruikers uit te nodigen.", - "You need to be logged in.": "Hiervoor dient u aangemeld te zijn.", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Zo te zien is uw e-mailadres op deze thuisserver niet aan een Matrix-ID gekoppeld.", + "You need to be logged in.": "Hiervoor dient u ingelogd te zijn.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Zo te zien is uw e-mailadres op deze homeserver niet aan een Matrix-ID gekoppeld.", "You seem to be in a call, are you sure you want to quit?": "Het ziet er naar uit dat u in gesprek bent, weet u zeker dat u wilt afsluiten?", "You seem to be uploading files, are you sure you want to quit?": "Het ziet er naar uit dat u bestanden aan het uploaden bent, weet u zeker dat u wilt afsluiten?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "U zult deze veranderingen niet terug kunnen draaien, daar u de gebruiker tot uw eigen niveau promoveert.", @@ -328,7 +328,7 @@ "Active call": "Actieve oproep", "Please select the destination room for this message": "Selecteer het bestemmingsgesprek voor dit bericht", "New Password": "Nieuw wachtwoord", - "Start automatically after system login": "Automatisch starten na systeemaanmelding", + "Start automatically after system login": "Automatisch starten na systeemlogin", "Analytics": "Statistische gegevens", "Options": "Opties", "%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s verzamelt anonieme analysegegevens die het mogelijk maken de toepassing te verbeteren.", @@ -405,7 +405,7 @@ "Create": "Aanmaken", "Featured Rooms:": "Prominente gesprekken:", "Featured Users:": "Prominente gebruikers:", - "Automatically replace plain text Emoji": "Tekst automatisch vervangen door emoticons", + "Automatically replace plain text Emoji": "Tekst automatisch vervangen door emoji", "Failed to upload image": "Uploaden van afbeelding is mislukt", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s-widget toegevoegd door %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s-widget verwijderd door %(senderName)s", @@ -440,7 +440,7 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", "Enable inline URL previews by default": "Inline URL-voorvertoning standaard inschakelen", "Enable URL previews for this room (only affects you)": "URL-voorvertoning in dit gesprek inschakelen (geldt alleen voor u)", - "Enable URL previews by default for participants in this room": "URL-voorvertoning standaard voor alle deelnemers aan dit gesprek inschakelen", + "Enable URL previews by default for participants in this room": "URL-voorvertoning voor alle deelnemers aan dit gesprek standaard inschakelen", "%(senderName)s sent an image": "%(senderName)s heeft een afbeelding gestuurd", "%(senderName)s sent a video": "%(senderName)s heeft een video gestuurd", "%(senderName)s uploaded a file": "%(senderName)s heeft een bestand geüpload", @@ -484,10 +484,10 @@ "'%(groupId)s' is not a valid community ID": "‘%(groupId)s’ is geen geldige gemeenschaps-ID", "Flair": "Badge", "Showing flair for these communities:": "Badges voor deze gemeenschappen weergeven:", - "This room is not showing flair for any communities": "Dit gesprek geeft geen badges voor gemeenschappen weer", + "This room is not showing flair for any communities": "Dit gesprek geeft geen gemeenschapsbadges weer", "New community ID (e.g. +foo:%(localDomain)s)": "Nieuwe gemeenschaps-ID (bv. +foo:%(localDomain)s)", - "URL previews are enabled by default for participants in this room.": "URL-voorvertoningen zijn voor leden van dit gesprek standaard ingeschakeld.", - "URL previews are disabled by default for participants in this room.": "URL-voorvertoningen zijn voor leden van dit gesprek standaard uitgeschakeld.", + "URL previews are enabled by default for participants in this room.": "URL-voorvertoningen zijn voor deelnemers van dit gesprek standaard ingeschakeld.", + "URL previews are disabled by default for participants in this room.": "URL-voorvertoningen zijn voor deelnemers van dit gesprek standaard uitgeschakeld.", "An email has been sent to %(emailAddress)s": "Er is een e-mail naar %(emailAddress)s verstuurd", "A text message has been sent to %(msisdn)s": "Er is een sms naar %(msisdn)s verstuurd", "Remove from community": "Verwijderen uit gemeenschap", @@ -607,7 +607,7 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "Failed to load %(groupId)s": "Laden van %(groupId)s is mislukt", "Old cryptography data detected": "Oude cryptografiegegevens gedetecteerd", - "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van %(brand)s gevonden, die problemen veroorzaakt hebben met de eind-tot-eind-versleuteling in de oude versie. Onlangs vanuit de oude versie verzonden eind-tot-eind-versleutelde berichten zijn mogelijk onontsleutelbaar in deze versie. Ook kunnen berichten die met deze versie uitgewisseld zijn falen. Mocht u problemen ervaren, meld u dan opnieuw aan. Schrijf uw sleutels weg en lees ze weer in om uw berichtgeschiedenis te behouden.", + "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van %(brand)s gevonden, die problemen veroorzaakt hebben met de eind-tot-eind-versleuteling in de oude versie. Onlangs vanuit de oude versie verzonden eind-tot-eind-versleutelde berichten zijn mogelijk onontsleutelbaar in deze versie. Ook kunnen berichten die met deze versie uitgewisseld zijn falen. Mocht u problemen ervaren, log dan opnieuw in. Exporteer uw sleutels en importeer ze weer om uw berichtgeschiedenis te behouden.", "Your Communities": "Uw gemeenschappen", "Error whilst fetching joined communities": "Er is een fout opgetreden bij het ophalen van de gemeenschappen waarvan u lid bent", "Create a new community": "Maak een nieuwe gemeenschap aan", @@ -620,8 +620,8 @@ "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is belangrijk voor ons, dus we verzamelen geen persoonlijke of identificeerbare gegevens voor onze gegevensanalyse.", "Learn more about how we use analytics.": "Lees meer over hoe we uw gegevens gebruiken.", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Er is een e-mail naar %(emailAddress)s verstuurd. Klik hieronder van zodra u de koppeling erin hebt gevolgd.", - "Please note you are logging into the %(hs)s server, not matrix.org.": "Merk op dat u zich aanmeldt bij de %(hs)s-server, niet matrix.org.", - "This homeserver doesn't offer any login flows which are supported by this client.": "Deze thuisserver heeft geen aanmeldmethodes die door deze cliënt worden ondersteund.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Let op dat u inlogt bij de %(hs)s-server, niet matrix.org.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Deze homeserver heeft geen loginmethodes die door deze cliënt worden ondersteund.", "Ignores a user, hiding their messages from you": "Negeert een gebruiker, waardoor de berichten ervan onzichtbaar voor u worden", "Stops ignoring a user, showing their messages going forward": "Stopt het negeren van een gebruiker, hierdoor worden de berichten van de gebruiker weer zichtbaar", "Notify the whole room": "Laat dit aan het hele groepsgesprek weten", @@ -633,16 +633,16 @@ "Your language of choice": "De door u gekozen taal", "Which officially provided instance you are using, if any": "Welke officieel aangeboden instantie u eventueel gebruikt", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Of u de tekstverwerker al dan niet in de modus voor opgemaakte tekst gebruikt", - "Your homeserver's URL": "De URL van uw thuisserver", + "Your homeserver's URL": "De URL van uw homeserver", "In reply to ": "Als antwoord op ", "This room is not public. You will not be able to rejoin without an invite.": "Dit is geen openbaar gesprek. Slechts op uitnodiging zult u opnieuw kunnen toetreden.", "were unbanned %(count)s times|one": "zijn ontbannen", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s heeft %(displayName)s als weergavenaam aangenomen.", "Key request sent.": "Sleutelverzoek verstuurd.", - "Did you know: you can use communities to filter your %(brand)s experience!": "Wist u dat: u gemeenschappen kunt gebruiken om uw %(brand)s-beleving te filteren!", + "Did you know: you can use communities to filter your %(brand)s experience!": "Tip: u kunt gemeenschappen gebruiken om uw %(brand)s-beleving te filteren!", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Versleep een gemeenschapsavatar naar het filterpaneel helemaal links op het scherm om een filter in te stellen. Daarna kunt u op de avatar in het filterpaneel klikken wanneer u zich wilt beperken tot de gesprekken en mensen uit die gemeenschap.", "Clear filter": "Filter wissen", - "Failed to set direct chat tag": "Instellen van tweegesprekslabel is mislukt", + "Failed to set direct chat tag": "Instellen van direct gespreklabel is mislukt", "Failed to remove tag %(tagName)s from room": "Verwijderen van %(tagName)s-label van gesprek is mislukt", "Failed to add tag %(tagName)s to room": "Toevoegen van %(tagName)s-label aan gesprek is mislukt", "Stickerpack": "Stickerpakket", @@ -658,7 +658,7 @@ "Who can join this community?": "Wie kan er tot deze gemeenschap toetreden?", "Everyone": "Iedereen", "Leave this community": "Deze gemeenschap verlaten", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Voor het oplossen van in GitHub gemelde problemen helpen foutopsporingslogboeken ons enorm. Deze bevatten wel gebruiksgegevens (waaronder uw gebruikersnaam, de ID’s of bijnamen van de gesprekken en groepen die u heeft bezocht, en de namen van andere gebruikers), maar geen berichten.", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Voor het oplossen van, via GitHub, gemelde problemen helpen foutopsporingslogboeken ons enorm. Deze bevatten wel gebruiksgegevens (waaronder uw gebruikersnaam, de ID’s of bijnamen van de gesprekken en groepen die u heeft bezocht, en de namen van andere gebruikers), maar geen berichten.", "Submit debug logs": "Foutopsporingslogboeken indienen", "Opens the Developer Tools dialog": "Opent het dialoogvenster met ontwikkelaarsgereedschap", "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", @@ -686,7 +686,7 @@ "Resend": "Opnieuw versturen", "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", - "Messages in one-to-one chats": "Berichten in een-op-een chats", + "Messages in one-to-one chats": "Berichten in één-op-één gesprekken", "Unavailable": "Niet beschikbaar", "View Decrypted Source": "Ontsleutelde bron bekijken", "Failed to update keywords": "Bijwerken van trefwoorden is mislukt", @@ -697,14 +697,14 @@ "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", "Explore Room State": "Gesprekstoestand verkennen", "Source URL": "Bron-URL", - "Messages sent by bot": "Berichten verzonden door een robot", + "Messages sent by bot": "Berichten verzonden door een bot", "Filter results": "Resultaten filteren", "Members": "Leden", "No update available.": "Geen update beschikbaar.", "Noisy": "Lawaaierig", "Collecting app version information": "App-versieinformatie wordt verzameld", "Keywords": "Trefwoorden", - "Enable notifications for this account": "Meldingen inschakelen voor deze account", + "Enable notifications for this account": "Meldingen voor dit account inschakelen", "Invite to this community": "Uitnodigen in deze gemeenschap", "Messages containing keywords": "Berichten die trefwoorden bevatten", "Room not found": "Gesprek niet gevonden", @@ -730,7 +730,7 @@ "Collecting logs": "Logboeken worden verzameld", "You must specify an event type!": "U dient een gebeurtenistype op te geven!", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", - "Invite to this room": "Uitnodigen tot dit gesprek", + "Invite to this room": "Uitnodigen voor dit gesprek", "Send logs": "Logboeken versturen", "All messages": "Alle berichten", "Call invitation": "Oproep-uitnodiging", @@ -750,7 +750,7 @@ "Forward Message": "Bericht doorsturen", "Back": "Terug", "Reply": "Beantwoorden", - "Show message in desktop notification": "Bericht tonen in bureaubladmelding", + "Show message in desktop notification": "Bericht in bureaubladmelding tonen", "Unhide Preview": "Voorvertoning weergeven", "Unable to join network": "Kon niet toetreden tot dit netwerk", "Sorry, your browser is not able to run %(brand)s.": "Sorry, uw browser werkt niet met %(brand)s.", @@ -788,12 +788,12 @@ "Your device resolution": "De resolutie van uw apparaat", "Missing roomId.": "roomId ontbreekt.", "Always show encryption icons": "Versleutelingspictogrammen altijd tonen", - "Send analytics data": "Statistische gegevens (analytics) versturen", + "Send analytics data": "Statistische gegevens versturen", "Enable widget screenshots on supported widgets": "Widget-schermafbeeldingen inschakelen op ondersteunde widgets", "Muted Users": "Gedempte gebruikers", "Popout widget": "Widget in nieuw venster openen", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Kan de gebeurtenis waarop gereageerd was niet laden. Wellicht bestaat die niet, of heeft u geen toestemming die te bekijken.", - "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Dit zal uw account voorgoed onbruikbaar maken. U zult zich niet meer kunnen aanmelden, en niemand anders zal zich met dezelfde gebruikers-ID kunnen registreren. Hierdoor zal uw account alle gesprekken waaraan ze deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. Deze stap is onomkeerbaar.", + "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Dit zal uw account voorgoed onbruikbaar maken. U zult niet meer kunnen inloggen, en niemand anders zal zich met dezelfde gebruikers-ID kunnen registreren. Hierdoor zal uw account alle gesprekken waaraan u deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. Deze stap is onomkeerbaar.", "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Het sluiten van uw account maakt op zich niet dat wij de door u verstuurde berichten vergeten. Als u wilt dat wij uw berichten vergeten, vink dan het vakje hieronder aan.", "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "De zichtbaarheid van berichten in Matrix is zoals bij e-mails. Het vergeten van uw berichten betekent dat berichten die u heeft verstuurd niet meer gedeeld worden met nieuwe of ongeregistreerde gebruikers, maar geregistreerde gebruikers die al toegang hebben tot deze berichten zullen alsnog toegang hebben tot hun eigen kopie ervan.", "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Vergeet bij het sluiten van mijn account alle door mij verstuurde berichten (Let op: hierdoor zullen gebruikers een onvolledig beeld krijgen van gesprekken)", @@ -805,9 +805,9 @@ "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Het legen van de opslag van uw browser zal het probleem misschien verhelpen, maar zal u ook afmelden en uw gehele versleutelde gespreksgeschiedenis onleesbaar maken.", "Collapse Reply Thread": "Reactieketting dichtvouwen", "Can't leave Server Notices room": "Kan servermeldingsgesprek niet verlaten", - "This room is used for important messages from the Homeserver, so you cannot leave it.": "Dit gesprek is bedoeld voor belangrijke berichten van de thuisserver, dus u kunt het niet verlaten.", + "This room is used for important messages from the Homeserver, so you cannot leave it.": "Dit gesprek is bedoeld voor belangrijke berichten van de homeserver, dus u kunt het niet verlaten.", "Terms and Conditions": "Gebruiksvoorwaarden", - "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "Om de %(homeserverDomain)s-thuisserver te blijven gebruiken, zult u de gebruiksvoorwaarden moeten bestuderen en aanvaarden.", + "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "Om de %(homeserverDomain)s-homeserver te blijven gebruiken, zult u de gebruiksvoorwaarden moeten bestuderen en aanvaarden.", "Review terms and conditions": "Gebruiksvoorwaarden lezen", "Call in Progress": "Lopend gesprek", "A call is currently being placed!": "Er wordt al een oproep gemaakt!", @@ -820,7 +820,7 @@ "Share Link to User": "Koppeling naar gebruiker delen", "Share room": "Gesprek delen", "System Alerts": "Systeemmeldingen", - "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In versleutelde gesprekken zoals deze zijn URL-voorvertoningen standaard uitgeschakeld, om te voorkomen dat uw thuisserver (waar de voorvertoningen worden gemaakt) informatie kan verzamelen over de koppelingen die u hier ziet.", + "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In versleutelde gesprekken zoals deze zijn URL-voorvertoningen standaard uitgeschakeld, om te voorkomen dat uw homeserver (waar de voorvertoningen worden gemaakt) informatie kan verzamelen over de koppelingen die u hier ziet.", "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Als iemand een URL in een bericht invoegt, kan er een URL-voorvertoning weergegeven worden met meer informatie over de koppeling, zoals de titel, omschrijving en een afbeelding van de website.", "The email field must not be blank.": "Het e-mailveld mag niet leeg zijn.", "The phone number field must not be blank.": "Het telefoonnummerveld mag niet leeg zijn.", @@ -840,20 +840,20 @@ "Audio Output": "Geluidsuitgang", "Ignored users": "Genegeerde gebruikers", "Bulk options": "Bulkopties", - "This homeserver has hit its Monthly Active User limit.": "Deze thuisserver heeft zijn limiet voor maandelijks actieve gebruikers bereikt.", - "This homeserver has exceeded one of its resource limits.": "Deze thuisserver heeft één van zijn systeembronlimieten overschreden.", - "Whether or not you're logged in (we don't record your username)": "Of u al dan niet aangemeld bent (we slaan uw gebruikersnaam niet op)", - "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Het bestand ‘%(fileName)s’ is groter dan de uploadlimiet van de thuisserver", + "This homeserver has hit its Monthly Active User limit.": "Deze homeserver heeft zijn limiet voor maandelijks actieve gebruikers bereikt.", + "This homeserver has exceeded one of its resource limits.": "Deze homeserver heeft één van zijn systeembronlimieten overschreden.", + "Whether or not you're logged in (we don't record your username)": "Of u al dan niet ingelogd bent (we slaan uw gebruikersnaam niet op)", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Het bestand ‘%(fileName)s’ is groter dan de uploadlimiet van de homeserver", "Unable to load! Check your network connectivity and try again.": "Laden mislukt! Controleer uw netwerktoegang en probeer het nogmaals.", "Failed to invite users to the room:": "Kon de volgende gebruikers hier niet uitnodigen:", "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Plakt ¯\\_(ツ)_/¯ vóór een bericht zonder opmaak", "Upgrades a room to a new version": "Actualiseert het gesprek tot een nieuwe versie", - "Changes your display nickname in the current room only": "Stelt uw weergavenaam enkel in het huidige gesprek in", + "Changes your display nickname in the current room only": "Stelt uw weergavenaam alleen in het huidige gesprek in", "Gets or sets the room topic": "Verkrijgt het onderwerp van het gesprek of stelt het in", "This room has no topic.": "Dit gesprek heeft geen onderwerp.", "Sets the room name": "Stelt de gespreksnaam in", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s heeft dit gesprek bijgewerkt.", - "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s heeft het gesprek toegankelijk gemaakt voor iedereen die de verwijzing kent.", + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s heeft het gesprek toegankelijk gemaakt voor iedereen die de koppeling kent.", "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s heeft het gesprek enkel op uitnodiging toegankelijk gemaakt.", "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s heeft de toegangsregel veranderd naar ‘%(rule)s’", "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s heeft gasten toegestaan het gesprek te betreden.", @@ -869,12 +869,12 @@ "%(names)s and %(count)s others are typing …|one": "%(names)s en nog iemand zijn aan het typen…", "%(names)s and %(lastPerson)s are typing …": "%(names)s en %(lastPerson)s zijn aan het typen…", "Please contact your service administrator to continue using the service.": "Gelieve contact op te nemen met uw systeembeheerder om deze dienst te blijven gebruiken.", - "Unable to connect to Homeserver. Retrying...": "Kon geen verbinding met de thuisserver maken. Nieuwe poging…", + "Unable to connect to Homeserver. Retrying...": "Kon geen verbinding met de homeserver maken. Nieuwe poging…", "Unrecognised address": "Adres niet herkend", "You do not have permission to invite people to this room.": "U bent niet bevoegd anderen tot dit gesprek uit te nodigen.", "User %(userId)s is already in the room": "De gebruiker %(userId)s is al aanwezig", - "User %(user_id)s does not exist": "Er bestaat geen gebruiker ‘%(user_id)s’", - "User %(user_id)s may or may not exist": "Er bestaat mogelijk geen gebruiker ‘%(user_id)s’", + "User %(user_id)s does not exist": "Er bestaat geen gebruiker %(user_id)s", + "User %(user_id)s may or may not exist": "Er bestaat mogelijk geen gebruiker %(user_id)s", "The user must be unbanned before they can be invited.": "De gebruiker kan niet uitgenodigd worden voordat diens ban teniet is gedaan.", "Unknown server error": "Onbekende serverfout", "Use a few words, avoid common phrases": "Gebruik enkele woorden - maar geen bekende uitdrukkingen", @@ -905,28 +905,28 @@ "Straight rows of keys are easy to guess": "Zo’n aaneengesloten rijtje toetsen is eenvoudig te raden", "Short keyboard patterns are easy to guess": "Korte patronen op het toetsenbord worden gemakkelijk geraden", "There was an error joining the room": "Er is een fout opgetreden bij het betreden van het gesprek", - "Sorry, your homeserver is too old to participate in this room.": "Helaas - uw thuisserver is te oud voor dit gesprek.", - "Please contact your homeserver administrator.": "Gelieve contact op te nemen met de beheerder van uw thuisserver.", + "Sorry, your homeserver is too old to participate in this room.": "Helaas - uw homeserver is te oud voor dit gesprek.", + "Please contact your homeserver administrator.": "Gelieve contact op te nemen met de beheerder van uw homeserver.", "Custom user status messages": "Aangepaste gebruikersstatusberichten", "Group & filter rooms by custom tags (refresh to apply changes)": "Gesprekken groeperen en filteren volgens eigen labels (herlaad om de verandering te zien)", "Render simple counters in room header": "Eenvoudige tellers bovenaan het gesprek tonen", "Enable Emoji suggestions while typing": "Emoticons voorstellen tijdens het typen", - "Show a placeholder for removed messages": "Vulling tonen voor verwijderde berichten", + "Show a placeholder for removed messages": "Verwijderde berichten vulling tonen", "Show join/leave messages (invites/kicks/bans unaffected)": "Berichten over toe- en uittredingen tonen (dit heeft geen effect op uitnodigingen, berispingen of verbanningen)", "Show avatar changes": "Veranderingen van avatar tonen", "Show display name changes": "Veranderingen van weergavenamen tonen", "Show read receipts sent by other users": "Door andere gebruikers verstuurde leesbevestigingen tonen", "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Herinnering tonen om veilig berichtherstel in te schakelen in versleutelde gesprekken", - "Show avatars in user and room mentions": "Avatars tonen wanneer gebruikers of gesprekken vermeld worden", - "Enable big emoji in chat": "Grote emoticons in gesprekken inschakelen", + "Show avatars in user and room mentions": "Vermelde gebruikers- of gesprekkenavatars tonen", + "Enable big emoji in chat": "Grote emoji in gesprekken inschakelen", "Send typing notifications": "Typmeldingen versturen", "Enable Community Filter Panel": "Gemeenschapsfilterpaneel inschakelen", - "Allow Peer-to-Peer for 1:1 calls": "Peer-to-peer toestaan voor tweegesprekken", - "Prompt before sending invites to potentially invalid matrix IDs": "Bevestiging vragen voordat uitnodigingen naar mogelijk ongeldige Matrix-ID’s worden verstuurd", + "Allow Peer-to-Peer for 1:1 calls": "Peer-to-peer voor één-op-één oproepen toestaan", + "Prompt before sending invites to potentially invalid matrix IDs": "Uitnodigingen naar mogelijk ongeldige Matrix-ID’s bevestigen", "Show developer tools": "Ontwikkelgereedschap tonen", "Messages containing my username": "Berichten die mijn gebruikersnaam bevatten", "Messages containing @room": "Berichten die ‘@room’ bevatten", - "Encrypted messages in one-to-one chats": "Versleutelde berichten in een-op-een chats", + "Encrypted messages in one-to-one chats": "Versleutelde berichten in één-op-één gesprekken", "Encrypted messages in group chats": "Versleutelde berichten in groepsgesprekken", "The other party cancelled the verification.": "De tegenpartij heeft de verificatie geannuleerd.", "Verified!": "Geverifieerd!", @@ -998,7 +998,7 @@ "Anchor": "Anker", "Headphones": "Koptelefoon", "Folder": "Map", - "Pin": "Speld", + "Pin": "Vastmaken", "Yes": "Ja", "No": "Nee", "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "We hebben u een e-mail gestuurd om uw adres te verifiëren. Gelieve de daarin gegeven aanwijzingen op te volgen en dan op de knop hieronder te klikken.", @@ -1007,7 +1007,7 @@ "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Weet u het zeker? U zult uw versleutelde berichten verliezen als uw sleutels niet correct geback-upt zijn.", "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Versleutelde berichten zijn beveiligd met eind-tot-eind-versleuteling. Enkel de ontvanger(s) en u hebben de sleutels om deze berichten te lezen.", "Unable to load key backup status": "Kan sleutelback-upstatus niet laden", - "Restore from Backup": "Herstellen uit back-up", + "Restore from Backup": "Uit back-up herstellen", "Back up your keys before signing out to avoid losing them.": "Maak een back-up van uw sleutels vooraleer u zich afmeldt om ze niet te verliezen.", "Backing up %(sessionsRemaining)s keys...": "%(sessionsRemaining)s sleutels worden geback-upt…", "All keys backed up": "Alle sleutels zijn geback-upt", @@ -1037,19 +1037,19 @@ "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "Klik hier voor hulp bij het gebruiken van %(brand)s, of begin een gesprek met onze robot met de knop hieronder.", "Help & About": "Hulp & Info", "Bug reporting": "Foutmeldingen", - "FAQ": "VGV", + "FAQ": "FAQ", "Versions": "Versies", "Preferences": "Instellingen", "Composer": "Opsteller", "Timeline": "Tijdslijn", "Room list": "Gesprekslijst", - "Autocomplete delay (ms)": "Vertraging voor automatisch aanvullen (ms)", + "Autocomplete delay (ms)": "Vertraging voor autoaanvullen (ms)", "Accept all %(invitedRooms)s invites": "Alle %(invitedRooms)s de uitnodigingen aannemen", "Key backup": "Sleutelback-up", - "Security & Privacy": "Veiligheid & privacy", + "Security & Privacy": "Veiligheid & Privacy", "Missing media permissions, click the button below to request.": "Mediatoestemmingen ontbreken, klik op de knop hieronder om deze aan te vragen.", "Request media permissions": "Mediatoestemmingen verzoeken", - "Voice & Video": "Spraak & video", + "Voice & Video": "Spraak & Video", "Room information": "Gespreksinformatie", "Internal room ID:": "Interne gespreks-ID:", "Room version": "Gespreksversie", @@ -1061,7 +1061,7 @@ "Change room name": "Gespreksnaam wijzigen", "Change main address for the room": "Hoofdadres voor het gesprek wijzigen", "Change history visibility": "Zichtbaarheid van geschiedenis wijzigen", - "Change permissions": "Toestemmingen wijzigen", + "Change permissions": "Rechten wijzigen", "Change topic": "Onderwerp wijzigen", "Modify widgets": "Widgets aanpassen", "Default role": "Standaardrol", @@ -1073,8 +1073,8 @@ "Remove messages": "Berichten verwijderen", "Notify everyone": "Iedereen melden", "Send %(eventType)s events": "%(eventType)s-gebeurtenissen versturen", - "Roles & Permissions": "Rollen & toestemmingen", - "Select the roles required to change various parts of the room": "Selecteer de rollen vereist om verschillende delen van het gesprek te wijzigen", + "Roles & Permissions": "Rollen & rechten", + "Select the roles required to change various parts of the room": "Selecteer de vereiste rollen om verschillende delen van het gesprek te wijzigen", "Enable encryption?": "Versleuteling inschakelen?", "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Gespreksversleuteling is onomkeerbaar. Berichten in versleutelde gesprekken zijn niet leesbaar voor de server; enkel voor de gespreksdeelnemers. Veel robots en overbruggingen werken niet correct in versleutelde gesprekken. Lees meer over versleuteling.", "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Wijzigingen aan wie de geschiedenis kan lezen gelden enkel voor toekomstige berichten in dit gesprek. De zichtbaarheid van de bestaande geschiedenis blijft ongewijzigd.", @@ -1108,9 +1108,9 @@ "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "Kan geen profielen voor de Matrix-ID’s hieronder vinden - wilt u ze toch uitnodigen?", "Invite anyway and never warn me again": "Alsnog uitnodigen en mij nooit meer waarschuwen", "Invite anyway": "Alsnog uitnodigen", - "Before submitting logs, you must create a GitHub issue to describe your problem.": "Vooraleer u logboeken indient, dient u uw probleem te melden op GitHub.", + "Before submitting logs, you must create a GitHub issue to describe your problem.": "Voor u logboeken indient, dient u uw probleem te melden op GitHub.", "Unable to load commit detail: %(msg)s": "Kan commitdetail niet laden: %(msg)s", - "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Schrijf om uw gespreksgeschiedenis niet te verliezen vóór het afmelden uw gesprekssleutels weg. Dat moet vanuit de nieuwere versie van %(brand)s", + "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Om uw gespreksgeschiedenis niet te verliezen vóór het uitloggen dient u uw veiligheidssleutel te exporteren. Dat moet vanuit de nieuwere versie van %(brand)s", "Incompatible Database": "Incompatibele database", "Continue With Encryption Disabled": "Verdergaan met versleuteling uitgeschakeld", "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifieer deze gebruiker om hem/haar als vertrouwd te markeren. Gebruikers vertrouwen geeft u extra gemoedsrust bij het gebruik van eind-tot-eind-versleutelde berichten.", @@ -1158,9 +1158,9 @@ "Set status": "Status instellen", "Set a new status...": "Stel een nieuwe status in…", "Hide": "Verbergen", - "This homeserver would like to make sure you are not a robot.": "Deze thuisserver wil graag weten of u geen robot bent.", - "Please review and accept all of the homeserver's policies": "Gelieve het beleid van de thuisserver door te nemen en te aanvaarden", - "Please review and accept the policies of this homeserver:": "Gelieve het beleid van deze thuisserver door te nemen en te aanvaarden:", + "This homeserver would like to make sure you are not a robot.": "Deze homeserver wil graag weten of u geen robot bent.", + "Please review and accept all of the homeserver's policies": "Gelieve het beleid van de homeserver door te nemen en te aanvaarden", + "Please review and accept the policies of this homeserver:": "Gelieve het beleid van deze homeserver door te nemen en te aanvaarden:", "Your Modular server": "Uw Modular-server", "Enter the location of your Modular homeserver. It may use your own domain name or be a subdomain of modular.im.": "Voer de locatie van uw Modular-thuisserver in. Deze kan uw eigen domeinnaam gebruiken, of een subdomein van modular.im zijn.", "Server Name": "Servernaam", @@ -1186,9 +1186,9 @@ "Couldn't load page": "Kon pagina niet laden", "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "U bent een beheerder van deze gemeenschap. U zult niet opnieuw kunnen toetreden zonder een uitnodiging van een andere beheerder.", "Want more than a community? Get your own server": "Wilt u meer dan een gemeenschap? Verkrijg uw eigen server", - "This homeserver does not support communities": "Deze thuisserver biedt geen ondersteuning voor gemeenschappen", - "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Uw bericht is niet verstuurd omdat deze thuisserver zijn limiet voor maandelijks actieve gebruikers heeft bereikt. Gelieve contact op te nemen met uw dienstbeheerder om de dienst te blijven gebruiken.", - "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Uw bericht is niet verstuurd omdat deze thuisserver een systeembronlimiet heeft overschreden. Gelieve contact op te nemen met uw dienstbeheerder om de dienst te blijven gebruiken.", + "This homeserver does not support communities": "Deze homeserver biedt geen ondersteuning voor gemeenschappen", + "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Uw bericht is niet verstuurd omdat deze homeserver zijn limiet voor maandelijks actieve gebruikers heeft bereikt. Neem contact op met uw dienstbeheerder om de dienst te blijven gebruiken.", + "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Uw bericht is niet verstuurd omdat deze homeserver een systeembronlimiet heeft overschreden. Neem contact op met uw dienstbeheerder om de dienst te blijven gebruiken.", "Guest": "Gast", "Could not load user profile": "Kon gebruikersprofiel niet laden", "Your Matrix account on %(serverName)s": "Uw Matrix-account op %(serverName)s", @@ -1196,15 +1196,15 @@ "Sign in instead": "Aanmelden", "Your password has been reset.": "Uw wachtwoord is opnieuw ingesteld.", "Set a new password": "Stel een nieuw wachtwoord in", - "Invalid homeserver discovery response": "Ongeldig thuisserverontdekkingsantwoord", + "Invalid homeserver discovery response": "Ongeldig homeserver-ontdekkingsantwoord", "Invalid identity server discovery response": "Ongeldig identiteitsserverontdekkingsantwoord", "General failure": "Algemene fout", - "This homeserver does not support login using email address.": "Deze thuisserver biedt geen ondersteuning voor aanmelden met e-mailadres.", + "This homeserver does not support login using email address.": "Deze homeserver biedt geen ondersteuning voor inloggen met e-mailadres.", "Please contact your service administrator to continue using this service.": "Gelieve contact op te nemen met uw dienstbeheerder om deze dienst te blijven gebruiken.", - "Failed to perform homeserver discovery": "Ontdekken van thuisserver is mislukt", - "Sign in with single sign-on": "Aanmelden met enkele aanmelding", + "Failed to perform homeserver discovery": "Ontdekken van homeserver is mislukt", + "Sign in with single sign-on": "Aanmelden met eenmalige aanmelding", "Create account": "Account aanmaken", - "Registration has been disabled on this homeserver.": "Registratie is uitgeschakeld op deze thuisserver.", + "Registration has been disabled on this homeserver.": "Registratie is uitgeschakeld op deze homeserver.", "Unable to query for supported registration methods.": "Kan ondersteunde registratiemethoden niet opvragen.", "Create your account": "Maak uw account aan", "Keep going...": "Doe verder…", @@ -1239,7 +1239,7 @@ "You cannot modify widgets in this room.": "U kunt de widgets in dit gesprek niet aanpassen.", "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s heeft de uitnodiging aan %(targetDisplayName)s toe te treden tot het gesprek ingetrokken.", "Upgrade this room to the recommended room version": "Werk dit gesprek bij tot de aanbevolen versie", - "This room is running room version , which this homeserver has marked as unstable.": "Dit gesprek draait op groepsgespreksversie , die door deze thuisserver als onstabiel is gemarkeerd.", + "This room is running room version , which this homeserver has marked as unstable.": "Dit gesprek draait op groepsgespreksversie , die door deze homeserver als onstabiel is gemarkeerd.", "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Bijwerken zal de huidige versie van dit gesprek sluiten, en onder dezelfde naam een bijgewerkte versie starten.", "Failed to revoke invite": "Intrekken van uitnodiging is mislukt", "Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Kon de uitnodiging niet intrekken. De server ondervindt mogelijk een tijdelijk probleem, of u heeft niet het recht de uitnodiging in te trekken.", @@ -1250,9 +1250,9 @@ "A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Een widget op %(widgetUrl)s wil uw identiteit nagaan. Staat u dit toe, dan zal de widget wel uw gebruikers-ID kunnen nagaan, maar niet als u kunnen handelen.", "Remember my selection for this widget": "Onthoud mijn keuze voor deze widget", "Deny": "Weigeren", - "%(brand)s failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.": "%(brand)s kon de protocollijst niet ophalen van de thuisserver. Mogelijk is de thuisserver te oud om derdepartijnetwerken te ondersteunen.", + "%(brand)s failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.": "%(brand)s kon de protocollijst niet ophalen van de homeserver. Mogelijk is de homeserver te oud om derde-partij-netwerken te ondersteunen.", "%(brand)s failed to get the public room list.": "%(brand)s kon de lijst met openbare gesprekken niet verkrijgen.", - "The homeserver may be unavailable or overloaded.": "De thuisserver is mogelijk onbereikbaar of overbelast.", + "The homeserver may be unavailable or overloaded.": "De homeserver is mogelijk onbereikbaar of overbelast.", "You have %(count)s unread notifications in a prior version of this room.|other": "U heeft %(count)s ongelezen meldingen in een vorige versie van dit gesprek.", "You have %(count)s unread notifications in a prior version of this room.|one": "U heeft %(count)s ongelezen meldingen in een vorige versie van dit gesprek.", "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Of u de icoontjes voor recente gesprekken (boven de gesprekkenlijst) al dan niet gebruikt", @@ -1285,9 +1285,9 @@ "Unbans user with given ID": "Ontbant de gebruiker met de gegeven ID", "Sends the given message coloured as a rainbow": "Verstuurt het gegeven bericht in regenboogkleuren", "Sends the given emote coloured as a rainbow": "Verstuurt de gegeven emoticon in regenboogkleuren", - "No homeserver URL provided": "Geen thuisserver-URL opgegeven", - "Unexpected error resolving homeserver configuration": "Onverwachte fout bij het controleren van de thuisserverconfiguratie", - "The user's homeserver does not support the version of the room.": "De thuisserver van de gebruiker biedt geen ondersteuning voor de gespreksversie.", + "No homeserver URL provided": "Geen homeserver-URL opgegeven", + "Unexpected error resolving homeserver configuration": "Onverwachte fout bij het controleren van de homeserverconfiguratie", + "The user's homeserver does not support the version of the room.": "De homeserver van de gebruiker biedt geen ondersteuning voor de gespreksversie.", "Show hidden events in timeline": "Verborgen gebeurtenissen op de tijdslijn weergeven", "When rooms are upgraded": "Wanneer gesprekken bijgewerkt worden", "this room": "dit gesprek", @@ -1326,14 +1326,14 @@ "Unable to validate homeserver/identity server": "Kan thuis-/identiteitsserver niet valideren", "Sign in to your Matrix account on ": "Meld u met uw Matrix-account op aan", "Use an email address to recover your account": "Gebruik een e-mailadres om uw account te herstellen", - "Enter email address (required on this homeserver)": "Voer een e-mailadres in (vereist op deze thuisserver)", + "Enter email address (required on this homeserver)": "Voer een e-mailadres in (vereist op deze homeserver)", "Doesn't look like a valid email address": "Dit lijkt geen geldig e-mailadres", "Enter password": "Voer wachtwoord in", "Password is allowed, but unsafe": "Wachtwoord is toegestaan, maar onveilig", "Nice, strong password!": "Dit is een sterk wachtwoord!", "Passwords don't match": "Wachtwoorden komen niet overeen", "Other users can invite you to rooms using your contact details": "Andere gebruikers kunnen u in gesprekken uitnodigen op basis van uw contactgegevens", - "Enter phone number (required on this homeserver)": "Voer telefoonnummer in (vereist op deze thuisserver)", + "Enter phone number (required on this homeserver)": "Voer telefoonnummer in (vereist op deze homeserver)", "Doesn't look like a valid phone number": "Dit lijkt geen geldig telefoonnummer", "Enter username": "Voer gebruikersnaam in", "Some characters not allowed": "Sommige tekens zijn niet toegestaan", @@ -1343,7 +1343,7 @@ "Your Matrix account on ": "Uw Matrix-account op ", "Failed to get autodiscovery configuration from server": "Ophalen van auto-ontdekkingsconfiguratie van server is mislukt", "Invalid base_url for m.homeserver": "Ongeldige base_url voor m.homeserver", - "Homeserver URL does not appear to be a valid Matrix homeserver": "De thuisserver-URL lijkt geen geldige Matrix-thuisserver", + "Homeserver URL does not appear to be a valid Matrix homeserver": "De homeserver-URL lijkt geen geldige Matrix-homeserver", "Invalid base_url for m.identity_server": "Ongeldige base_url voor m.identity_server", "Identity server URL does not appear to be a valid identity server": "De identiteitsserver-URL lijkt geen geldige identiteitsserver", "Low bandwidth mode": "Lagebandbreedtemodus", @@ -1353,7 +1353,7 @@ "Reset": "Opnieuw instellen", "Set a new custom sound": "Stel een nieuw aangepast geluid in", "Browse": "Bladeren", - "Cannot reach homeserver": "Kan thuisserver niet bereiken", + "Cannot reach homeserver": "Kan homeserver niet bereiken", "Ensure you have a stable internet connection, or get in touch with the server admin": "Zorg dat u een stabiele internetverbinding heeft, of neem contact op met de systeembeheerder", "Your %(brand)s is misconfigured": "Uw %(brand)s is onjuist geconfigureerd", "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Vraag uw %(brand)s-beheerder uw configuratie na te kijken op onjuiste of dubbele items.", @@ -1362,12 +1362,12 @@ "Cannot reach identity server": "Kan identiteitsserver niet bereiken", "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "U kunt zich registreren, maar sommige functies zullen pas beschikbaar zijn wanneer de identiteitsserver weer online is. Als u deze waarschuwing blijft zien, controleer dan uw configuratie of neem contact op met een serverbeheerder.", "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "U kunt uw wachtwoord opnieuw instellen, maar sommige functies zullen pas beschikbaar komen wanneer de identiteitsserver weer online is. Als u deze waarschuwing blijft zien, controleer dan uw configuratie of neem contact op met een serverbeheerder.", - "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "U kunt zich aanmelden, maar sommige functies zullen pas beschikbaar zijn wanneer de identiteitsserver weer online is. Als u deze waarschuwing blijft zien, controleer dan uw configuratie of neem contact op met een systeembeheerder.", - "Log in to your new account.": "Meld u aan met uw nieuwe account.", - "You can now close this window or log in to your new account.": "U kunt dit venster nu sluiten, of u met uw nieuwe account aanmelden.", + "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "U kunt inloggen, maar sommige functies zullen pas beschikbaar zijn wanneer de identiteitsserver weer online is. Als u deze waarschuwing blijft zien, controleer dan uw configuratie of neem contact op met een systeembeheerder.", + "Log in to your new account.": "Login met uw nieuwe account.", + "You can now close this window or log in to your new account.": "U kunt dit venster nu sluiten, of login met uw nieuwe account.", "Registration Successful": "Registratie geslaagd", "Upload all": "Alles versturen", - "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Uw nieuwe account (%(newAccountId)s) is geregistreerd, maar u bent reeds aangemeld met een andere account (%(loggedInUserId)s).", + "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Uw nieuwe account (%(newAccountId)s) is geregistreerd, maar u bent al ingelogd met een andere account (%(loggedInUserId)s).", "Continue with previous account": "Doorgaan met vorige account", "Loading room preview": "Gespreksweergave wordt geladen", "Edited at %(date)s. Click to view edits.": "Bewerkt op %(date)s. Klik om de bewerkingen te bekijken.", @@ -1382,11 +1382,11 @@ "Changes your avatar in all rooms": "Verandert uw avatar in alle gesprekken", "Removing…": "Bezig met verwijderen…", "Clear all data": "Alle gegevens wissen", - "Your homeserver doesn't seem to support this feature.": "Uw thuisserver biedt geen ondersteuning voor deze functie.", + "Your homeserver doesn't seem to support this feature.": "Uw homeserver biedt geen ondersteuning voor deze functie.", "Resend edit": "Bewerking opnieuw versturen", "Resend %(unsentCount)s reaction(s)": "%(unsentCount)s reactie(s) opnieuw versturen", "Resend removal": "Verwijdering opnieuw versturen", - "Failed to re-authenticate due to a homeserver problem": "Opnieuw aanmelden is mislukt wegens een probleem met de thuisserver", + "Failed to re-authenticate due to a homeserver problem": "Opnieuw aanmelden is mislukt wegens een probleem met de homeserver", "Failed to re-authenticate": "Opnieuw aanmelden is mislukt", "Enter your password to sign in and regain access to your account.": "Voer uw wachtwoord in om u aan te melden en toegang tot uw account te herkrijgen.", "Forgotten your password?": "Wachtwoord vergeten?", @@ -1401,7 +1401,7 @@ "Service": "Dienst", "Summary": "Samenvatting", "Sign in and regain access to your account.": "Meld u aan en herkrijg toegang tot uw account.", - "You cannot sign in to your account. Please contact your homeserver admin for more information.": "U kunt zich niet aanmelden met uw account. Neem voor meer informatie contact op met de beheerder van uw thuisserver.", + "You cannot sign in to your account. Please contact your homeserver admin for more information.": "U kunt zich niet aanmelden met uw account. Neem voor meer informatie contact op met de beheerder van uw homeserver.", "This account has been deactivated.": "Deze account is gesloten.", "Messages": "Berichten", "Actions": "Acties", @@ -1433,7 +1433,7 @@ "Command Help": "Hulp bij opdrachten", "No identity server is configured: add one in server settings to reset your password.": "Er is geen identiteitsserver geconfigureerd: voeg er één toe in de serverinstellingen om uw wachtwoord opnieuw in te stellen.", "Call failed due to misconfigured server": "Oproep mislukt door verkeerd geconfigureerde server", - "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Vraag uw thuisserverbeheerder (%(homeserverDomain)s) een TURN-server te configureren teneinde oproepen betrouwbaar te doen werken.", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Vraag uw homeserverbeheerder (%(homeserverDomain)s) een TURN-server te configureren voor de betrouwbaarheid van de oproepen.", "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "U kunt ook de publieke server op turn.matrix.org gebruiken, maar dit zal minder betrouwbaar zijn, en zal uw IP-adres met die server delen. U kunt dit ook beheren in de Instellingen.", "Try using turn.matrix.org": "Probeer turn.matrix.org te gebruiken", "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Sta de terugvalserver voor oproepbijstand turn.matrix.org toe wanneer uw homeserver er geen aanbiedt (uw IP-adres wordt gedeeld gedurende een oproep)", @@ -1461,7 +1461,7 @@ "You are still sharing your personal data on the identity server .": "U deelt nog steeds uw persoonlijke gegevens op de identiteitsserver .", "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "We raden u aan uw e-mailadressen en telefoonnummers van de identiteitsserver te verwijderen vooraleer u de verbinding verbreekt.", "Disconnect anyway": "Verbinding toch verbreken", - "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Mocht u om bekenden te zoeken en zelf vindbaar te zijn niet willen gebruiken, voer dan hieronder een andere identiteitsserver in.", + "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Mocht u, om bekenden te zoeken en zelf vindbaar te zijn, niet willen gebruiken, voer dan hieronder een andere identiteitsserver in.", "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Een identiteitsserver is niet verplicht, maar zonder identiteitsserver zult u geen bekenden op e-mailadres of telefoonnummer kunnen zoeken, noch door hen vindbaar zijn.", "Do not use an identity server": "Geen identiteitsserver gebruiken", "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Aanvaard de gebruiksvoorwaarden van de identiteitsserver (%(serverName)s) om vindbaar te zijn op e-mailadres of telefoonnummer.", @@ -1482,7 +1482,7 @@ "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Bij een groot aantal berichten kan dit even duren. Herlaad uw cliënt niet gedurende deze tijd.", "Remove %(count)s messages|other": "%(count)s berichten verwijderen", "Deactivate user?": "Gebruiker deactiveren?", - "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Deze gebruiker deactiveren zal hem/haar afmelden en verhinderen dat hij/zij zich weer aanmeldt. Bovendien zal hij/zij alle gesprekken waaraan hij/zij deelneemt verlaten. Deze actie is onherroepelijk. Weet u zeker dat u deze gebruiker wilt deactiveren?", + "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Deze gebruiker deactiveren zal deze gebruiker uitloggen en verhinderen dat de gebruiker weer inlogt. Bovendien zal de gebruiker alle gesprekken waaraan de gebruiker deelneemt verlaten. Deze actie is onherroepelijk. Weet u zeker dat u deze gebruiker wilt deactiveren?", "Deactivate user": "Gebruiker deactiveren", "Remove recent messages": "Recente berichten verwijderen", "Bold": "Vet", @@ -1498,8 +1498,8 @@ "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Gebruik een identiteitsserver om uit te nodigen op e-mailadres. Gebruik de standaardserver (%(defaultIdentityServerName)s) of beheer de server in de Instellingen.", "Use an identity server to invite by email. Manage in Settings.": "Gebruik een identiteitsserver om anderen uit te nodigen via e-mail. Beheer de server in de Instellingen.", "Please fill why you're reporting.": "Gelieve aan te geven waarom u deze melding indient.", - "Report Content to Your Homeserver Administrator": "Inhoud melden aan de beheerder van uw thuisserver", - "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Dit bericht melden zal zijn unieke ‘gebeurtenis-ID’ versturen naar de beheerder van uw thuisserver. Als de berichten in dit gesprek versleuteld zijn, zal de beheerder van uw thuisserver het bericht niet kunnen lezen, noch enige bestanden of afbeeldingen zien.", + "Report Content to Your Homeserver Administrator": "Inhoud melden aan de beheerder van uw homeserver", + "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Dit bericht melden zal zijn unieke ‘gebeurtenis-ID’ versturen naar de beheerder van uw homeserver. Als de berichten in dit gesprek versleuteld zijn, zal de beheerder van uw homeserver het bericht niet kunnen lezen, noch enige bestanden of afbeeldingen zien.", "Send report": "Rapport versturen", "Report Content": "Inhoud melden", "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Stel een e-mailadres voor accountherstel in. Gebruik eventueel een e-mailadres of telefoonnummer om vindbaar te zijn voor bestaande contacten.", @@ -1515,7 +1515,7 @@ "Find a room… (e.g. %(exampleRoom)s)": "Zoek een gesprek… (bv. %(exampleRoom)s)", "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Als u het gesprek dat u zoekt niet kunt vinden, vraag dan een uitnodiging, of Maak een nieuw gesprek aan.", "Explore rooms": "Gesprekken ontdekken", - "Show previews/thumbnails for images": "Toon miniaturen voor afbeeldingen", + "Show previews/thumbnails for images": "Miniaturen voor afbeeldingen tonen", "Clear cache and reload": "Cache wissen en herladen", "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "U staat op het punt 1 bericht door %(user)s te verwijderen. Dit is onherroepelijk. Wilt u doorgaan?", "Remove %(count)s messages|one": "1 bericht verwijderen", @@ -1537,12 +1537,12 @@ "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Verhinder gebruikers op andere Matrix-thuisservers de toegang tot dit gesprek (Deze instelling kan later niet meer aangepast worden!)", "To continue you need to accept the terms of this service.": "Om door te gaan dient u de dienstvoorwaarden te aanvaarden.", "Document": "Document", - "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Publieke sleutel van captcha ontbreekt in thuisserverconfiguratie. Gelieve dit te melden aan de beheerder van uw thuisserver.", - "Community Autocomplete": "Gemeenschappen automatisch aanvullen", - "Emoji Autocomplete": "Emoji’s automatisch aanvullen", - "Notification Autocomplete": "Meldingen automatisch voltooien", - "Room Autocomplete": "Gesprekken automatisch aanvullen", - "User Autocomplete": "Gebruikers automatisch aanvullen", + "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Publieke sleutel van captcha ontbreekt in homeserverconfiguratie. Meld dit aan de beheerder van uw homeserver.", + "Community Autocomplete": "Gemeenschappen autoaanvullen", + "Emoji Autocomplete": "Emoji autoaanvullen", + "Notification Autocomplete": "Meldingen autoaanvullen", + "Room Autocomplete": "Gesprekken autoaanvullen", + "User Autocomplete": "Gebruikers autoaanvullen", "Add Email Address": "E-mailadres toevoegen", "Add Phone Number": "Telefoonnummer toevoegen", "Your email address hasn't been verified yet": "Uw e-mailadres is nog niet geverifieerd", @@ -1605,9 +1605,9 @@ "Try out new ways to ignore people (experimental)": "Nieuwe manieren om mensen te negeren uitproberen (nog in ontwikkeling)", "Show info about bridges in room settings": "Toon bruginformatie in gespreksinstellingen", "Match system theme": "Aanpassen aan systeemthema", - "Never send encrypted messages to unverified sessions from this session": "Zend vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies", - "Never send encrypted messages to unverified sessions in this room from this session": "Zend vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies in dit gesprek", - "Enable message search in encrypted rooms": "Sta zoeken in versleutelde gesprekken toe", + "Never send encrypted messages to unverified sessions from this session": "Vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies versturen", + "Never send encrypted messages to unverified sessions in this room from this session": "Vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies in dit gesprek versturen", + "Enable message search in encrypted rooms": "Zoeken in versleutelde gesprekken inschakelen", "How fast should messages be downloaded.": "Ophaalfrequentie van berichten.", "My Ban List": "Mijn banlijst", "This is your list of users/servers you have blocked - don't leave the room!": "Dit is de lijst van door u geblokkeerde servers/gebruikers. Verlaat dit gesprek niet!", @@ -1632,7 +1632,7 @@ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Momenteel stelt een wachtwoordswijziging alle berichtsleutels in alle sessies opnieuw in, en maakt zo oude versleutelde berichten onleesbaar - tenzij u uw sleutels eerst wegschrijft, en na afloop weer inleest. Dit zal verbeterd worden.", "in memory": "in het geheugen", "not found": "niet gevonden", - "Your homeserver does not support session management.": "Uw thuisserver ondersteunt geen sessiebeheer.", + "Your homeserver does not support session management.": "Uw homeserver ondersteunt geen sessiebeheer.", "Unable to load session list": "Kan sessielijst niet laden", "Delete %(count)s sessions|other": "%(count)s sessies verwijderen", "Delete %(count)s sessions|one": "%(count)s sessie verwijderen", @@ -1653,10 +1653,10 @@ "Enable": "Inschakelen", "Connecting to integration manager...": "Verbinding maken met de integratiebeheerder…", "Cannot connect to integration manager": "Kan geen verbinding maken met de integratiebeheerder", - "The integration manager is offline or it cannot reach your homeserver.": "De integratiebeheerder is offline of kan uw thuisserver niet bereiken.", + "The integration manager is offline or it cannot reach your homeserver.": "De integratiebeheerder is offline of kan uw homeserver niet bereiken.", "This session is backing up your keys. ": "Deze sessie maakt back-ups van uw sleutels. ", "not stored": "niet opgeslagen", - "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Uw wachtwoord is gewijzigd. U zult geen pushmeldingen op uw andere sessies meer ontvangen, totdat u zichzelf daarop opnieuw aanmeldt", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Uw wachtwoord is gewijzigd. U zult geen pushmeldingen op uw andere sessies meer ontvangen, totdat u zichzelf daar opnieuw inlogt", "Ignored/Blocked": "Genegeerd/geblokkeerd", "Error adding ignored user/server": "Fout bij het toevoegen van een genegeerde gebruiker/server", "Something went wrong. Please try again or view your console for hints.": "Er is iets fout gegaan. Probeer het opnieuw of bekijk de console om voor meer informatie.", @@ -1681,8 +1681,8 @@ "Subscribing to a ban list will cause you to join it!": "Wanneer u zich abonneert op een banlijst zal u eraan worden toegevoegd!", "If this isn't what you want, please use a different tool to ignore users.": "Als u dit niet wilt kunt u een andere methode gebruiken om gebruikers te negeren.", "Subscribe": "Abonneren", - "Enable desktop notifications for this session": "Bureaubladmeldingen inschakelen voor deze sessie", - "Enable audible notifications for this session": "Meldingen met geluid inschakelen voor deze sessie", + "Enable desktop notifications for this session": "Bureaubladmeldingen voor deze sessie inschakelen", + "Enable audible notifications for this session": "Meldingen met geluid voor deze sessie inschakelen", "You should:": "U zou best:", "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "uw browserextensies bekijken voor extensies die mogelijk de identiteitsserver blokkeren (zoals Privacy Badger)", "contact the administrators of identity server ": "contact opnemen met de beheerders van de identiteitsserver ", @@ -1711,7 +1711,7 @@ "Mod": "Mod", "rooms.": "gesprekken.", "Recent rooms": "Actuele gesprekken", - "Direct Messages": "Directe Berichten", + "Direct Messages": "Direct gesprek", "If disabled, messages from encrypted rooms won't appear in search results.": "Dit moet aan staan om te kunnen zoeken in versleutelde gesprekken.", "Indexed rooms:": "Geïndexeerde gesprekken:", "Cross-signing and secret storage are enabled.": "Kruiselings ondertekenen en sleutelopslag zijn ingeschakeld.", @@ -1745,9 +1745,9 @@ "Your keys are not being backed up from this session.": "Uw sleutels worden niet geback-upt van deze sessie.", "Clear notifications": "Meldingen wissen", "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "U moet uw persoonlijke informatie van de identiteitsserver verwijderen voordat u zich ontkoppelt. Helaas kan de identiteitsserver op dit moment niet worden bereikt. Mogelijk is hij offline.", - "Your homeserver does not support cross-signing.": "Uw thuisserver biedt geen ondersteuning voor kruiselings ondertekenen.", - "Homeserver feature support:": "Functies ondersteund door thuisserver:", - "exists": "bestaat", + "Your homeserver does not support cross-signing.": "Uw homeserver biedt geen ondersteuning voor kruiselings ondertekenen.", + "Homeserver feature support:": "Homeserver ondersteund deze functies:", + "exists": "aanwezig", "Sign In or Create Account": "Meld u aan of maak een account aan", "Use your account or create a new one to continue.": "Gebruik uw bestaande account of maak een nieuwe aan om verder te gaan.", "Create Account": "Account aanmaken", @@ -1794,8 +1794,8 @@ "For extra security, verify this user by checking a one-time code on both of your devices.": "Als extra beveiliging kunt u deze gebruiker verifiëren door een eenmalige code op uw toestellen te controleren.", "Your messages are not secure": "Uw berichten zijn niet veilig", "One of the following may be compromised:": "Eén van volgende onderdelen kan gecompromitteerd zijn:", - "Your homeserver": "Uw thuisserver", - "The homeserver the user you’re verifying is connected to": "De thuisserver waarmee de gebruiker die u tracht te verifiëren verbonden is", + "Your homeserver": "Uw homeserver", + "The homeserver the user you’re verifying is connected to": "De homeserver waarmee de gebruiker die u probeert te verifiëren verbonden is", "Yours, or the other users’ internet connection": "De internetverbinding van uzelf of de andere gebruiker", "Yours, or the other users’ session": "De sessie van uzelf of de andere gebruiker", "Not Trusted": "Niet vertrouwd", @@ -1810,7 +1810,7 @@ "%(count)s sessions|other": "%(count)s sessies", "%(count)s sessions|one": "%(count)s sessie", "Hide sessions": "Sessies verbergen", - "Direct message": "Tweegesprek", + "Direct message": "Direct gesprek", "%(role)s in %(roomName)s": "%(role)s in %(roomName)s", "This client does not support end-to-end encryption.": "Deze cliënt biedt geen ondersteuning voor eind-tot-eind-versleuteling.", "Messages in this room are not end-to-end encrypted.": "De berichten in dit gesprek worden niet eind-tot-eind-versleuteld.", @@ -1846,7 +1846,7 @@ "Reactions": "Reacties", " reacted with %(content)s": " heeft gereageerd met %(content)s", "Frequently Used": "Vaak gebruikt", - "Smileys & People": "Emoticons en personen", + "Smileys & People": "Smileys & mensen", "Animals & Nature": "Dieren en natuur", "Food & Drink": "Eten en drinken", "Activities": "Activiteiten", @@ -1875,7 +1875,7 @@ "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Het verwijderen van sleutels voor kruiselings ondertekenen is onherroepelijk. Iedereen waarmee u geverifieerd heeft zal beveiligingswaarschuwingen te zien krijgen. U wilt dit hoogstwaarschijnlijk niet doen, tenzij u alle apparaten heeft verloren waarmee u kruiselings kon ondertekenen.", "Clear cross-signing keys": "Sleutels voor kruiselings ondertekenen wissen", "Clear all data in this session?": "Alle gegevens in deze sessie verwijderen?", - "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Het verwijderen van alle gegevens in deze sessie is onherroepelijk. Versleutelde berichten zullen verloren gaan, tenzij u een back-up van hun sleutels heeft.", + "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Het verwijderen van alle gegevens in deze sessie is onherroepelijk. Versleutelde berichten zullen verloren gaan, tenzij u een back-up van de sleutels heeft.", "Verify session": "Sessie verifiëren", "Session name": "Sessienaam", "Session key": "Sessiesleutel", @@ -1888,7 +1888,7 @@ "Integrations not allowed": "Integraties niet toegestaan", "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Uw %(brand)s laat u geen integratiebeheerder gebruiken om dit te doen. Neem contact op met een beheerder.", "Failed to invite the following users to chat: %(csvUsers)s": "Het uitnodigen van volgende gebruikers voor gesprek is mislukt: %(csvUsers)s", - "We couldn't create your DM. Please check the users you want to invite and try again.": "Uw tweegesprek kon niet aangemaakt worden. Controleer de gebruikers die u wilt uitnodigen en probeer het opnieuw.", + "We couldn't create your DM. Please check the users you want to invite and try again.": "Uw direct gesprek kon niet aangemaakt worden. Controleer de gebruikers die u wilt uitnodigen en probeer het opnieuw.", "Something went wrong trying to invite the users.": "Er is een fout opgetreden bij het uitnodigen van de gebruikers.", "We couldn't invite those users. Please check the users you want to invite and try again.": "Deze gebruikers konden niet uitgenodigd worden. Controleer de gebruikers die u wilt uitnodigen en probeer het opnieuw.", "Failed to find the following users": "Kon volgende gebruikers niet vinden", @@ -1937,10 +1937,10 @@ "Without completing security on this session, it won’t have access to encrypted messages.": "Als u de beveiliging van deze sessie niet vervolledigt, zal ze geen toegang hebben tot uw versleutelde berichten.", "Go Back": "Terugkeren", "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Door uw wachtwoord te wijzigen stelt u alle eind-tot-eind-versleutelingssleutels op al uw sessies opnieuw in, waardoor uw versleutelde gespreksgeschiedenis onleesbaar wordt. Stel sleutelback-up in of schrijf uw gesprekssleutels van een andere sessie weg vooraleer u een nieuw wachtwoord instelt.", - "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "U bent afgemeld bij al uw sessies en zult geen pushberichten meer ontvangen. Meld u op elk apparaat opnieuw aan om meldingen opnieuw in te schakelen.", + "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "U bent uitgelogd bij al uw sessies en zult geen pushberichten meer ontvangen. Meld u op elk apparaat opnieuw aan om meldingen opnieuw in te schakelen.", "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Herwin toegang tot uw account en herstel de tijdens deze sessie opgeslagen versleutelingssleutels, zonder welke sommige van uw beveiligde berichten in al uw sessies onleesbaar zijn.", "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Let op: uw persoonlijke gegevens (waaronder versleutelingssleutels) zijn nog steeds opgeslagen in deze sessie. Wis ze wanneer u klaar bent met deze sessie, of wanneer u zich wilt aanmelden met een andere account.", - "Command Autocomplete": "Opdrachten automatisch aanvullen", + "Command Autocomplete": "Opdrachten autoaanvullen", "DuckDuckGo Results": "DuckDuckGo-resultaten", "Enter your account password to confirm the upgrade:": "Voer uw accountwachtwoord in om het bijwerken te bevestigen:", "Restore your key backup to upgrade your encryption": "Herstel uw sleutelback-up om uw versleuteling bij te werken", @@ -1955,8 +1955,8 @@ "Your recovery key is in your Downloads folder.": "Uw herstelsleutel bevindt zich in uw Downloads-map.", "Upgrade your encryption": "Werk uw versleuteling bij", "Make a copy of your recovery key": "Maak een kopie van uw herstelsleutel", - "Unable to set up secret storage": "Kan geheime opslag niet instellen", - "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Zonder veilig berichtherstel in te stellen zult u uw versleutelde berichtgeschiedenis niet kunnen herstellen als u zich afmeldt of een andere sessie gebruikt.", + "Unable to set up secret storage": "Kan sleutelopslag niet instellen", + "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Zonder veilig berichtherstel in te stellen zult u uw versleutelde berichtgeschiedenis niet kunnen herstellen als u uitlogt of een andere sessie gebruikt.", "Create key backup": "Sleutelback-up aanmaken", "This session is encrypting history using the new recovery method.": "Deze sessie versleutelt uw geschiedenis aan de hand van de nieuwe herstelmethode.", "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Deze sessie heeft gedetecteerd dat uw herstelwachtwoord en -sleutel voor beveiligde berichten verwijderd zijn.", @@ -1970,19 +1970,19 @@ "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Bekijk eerst het beveiligingsopenbaarmakingsbeleid van Matrix.org als u een probleem met de beveiliging van Matrix wilt melden.", "Not currently indexing messages for any room.": "Er worden momenteel voor geen enkel gesprek berichten geïndexeerd.", "%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s van %(totalRooms)s", - "Where you’re logged in": "Waar u aangemeld bent", + "Where you’re logged in": "Waar u ingelogd bent", "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Beheer hieronder de namen van uw sessies en meld ze af. Of verifieer ze in uw gebruikersprofiel.", - "Use Single Sign On to continue": "Ga verder met Eenmalige Aanmelding", - "Confirm adding this email address by using Single Sign On to prove your identity.": "Bevestig uw identiteit met Eenmalige Aanmelding om dit emailadres toe te voegen.", - "Single Sign On": "Eenmalige Aanmelding", + "Use Single Sign On to continue": "Ga verder met eenmalige aanmelding", + "Confirm adding this email address by using Single Sign On to prove your identity.": "Bevestig uw identiteit met uw eenmalige aanmelding om dit e-mailadres toe te voegen.", + "Single Sign On": "Eenmalige aanmelding", "Confirm adding email": "Bevestig toevoegen van het e-mailadres", "Click the button below to confirm adding this email address.": "Klik op de knop hieronder om dit e-mailadres toe te voegen.", - "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bevestig uw identiteit met Eenmalige Aanmelding om dit telefoonnummer toe te voegen.", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bevestig uw identiteit met uw eenmalige aanmelding om dit telefoonnummer toe te voegen.", "Confirm adding phone number": "Bevestig toevoegen van het telefoonnummer", "Click the button below to confirm adding this phone number.": "Klik op de knop hieronder om het toevoegen van dit telefoonnummer te bevestigen.", "If you cancel now, you won't complete your operation.": "Als u de operatie afbreekt kunt u haar niet voltooien.", - "Review where you’re logged in": "Kijk na waar u aangemeld bent", - "New login. Was this you?": "Nieuwe aanmelding - was u dat?", + "Review where you’re logged in": "Kijk na waar u ingelogd bent", + "New login. Was this you?": "Nieuwe login - was u dat?", "%(name)s is requesting verification": "%(name)s verzoekt om verificatie", "Sends a message as html, without interpreting it as markdown": "Stuurt een bericht als HTML, zonder markdown toe te passen", "Failed to set topic": "Kon onderwerp niet instellen", @@ -2003,12 +2003,12 @@ "Manually Verify by Text": "Handmatig middels een tekst", "Interactively verify by Emoji": "Interactief middels emojis", "Support adding custom themes": "Sta maatwerkthema's toe", - "Opens chat with the given user": "Start een tweegesprek met die gebruiker", + "Opens chat with the given user": "Start een gesprek met die gebruiker", "Sends a message to the given user": "Zendt die gebruiker een bericht", "Font scaling": "Lettergrootte", "Verify all your sessions to ensure your account & messages are safe": "Controleer al uw sessies om zeker te zijn dat uw account & berichten veilig zijn", - "Verify the new login accessing your account: %(name)s": "Verifieer de nieuwe aanmelding op uw account: %(name)s", - "Confirm your account deactivation by using Single Sign On to prove your identity.": "Bevestig uw intentie deze account te sluiten door met Single Sign On uw identiteit te bewijzen.", + "Verify the new login accessing your account: %(name)s": "Verifieer de nieuwe login op uw account: %(name)s", + "Confirm your account deactivation by using Single Sign On to prove your identity.": "Bevestig de deactivering van uw account door gebruik te maken van eenmalige aanmelding om uw identiteit te bewijzen.", "Are you sure you want to deactivate your account? This is irreversible.": "Weet u zeker dat u uw account wil sluiten? Dit is onomkeerbaar.", "Confirm account deactivation": "Bevestig accountsluiting", "Room name or address": "Gespreksnaam of -adres", @@ -2017,8 +2017,8 @@ "Help us improve %(brand)s": "Help ons %(brand)s nog beter te maken", "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Stuur anonieme gebruiksinformatie waarmee we %(brand)s kunnen verbeteren. Dit plaatst een cookie.", "I want to help": "Ik wil helpen", - "Your homeserver has exceeded its user limit.": "Uw thuisserver heeft het maximaal aantal gebruikers overschreden.", - "Your homeserver has exceeded one of its resource limits.": "Uw thuisserver heeft een van zijn limieten overschreden.", + "Your homeserver has exceeded its user limit.": "Uw homeserver heeft het maximaal aantal gebruikers overschreden.", + "Your homeserver has exceeded one of its resource limits.": "Uw homeserver heeft een van zijn limieten overschreden.", "Ok": "Oké", "Light": "Helder", "Dark": "Donker", @@ -2312,20 +2312,20 @@ "Are you sure you want to cancel entering passphrase?": "Weet u zeker, dat u het invoeren van uw wachtwoord wilt afbreken?", "Vatican City": "Vaticaanstad", "Taiwan": "Taiwan", - "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Uw thuisserver wees uw aanmeldingspoging af. Dit kan zijn doordat het te lang heeft geduurd. Probeer het opnieuw. Als dit probleem zich blijft voordoen, neem contact op met de beheerder van uw thuisserver.", - "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Uw thuisserver was onbereikbaar en kon u niet aanmelden, probeer het opnieuw. Wanneer dit probleem zich blijft voordoen, neem contact op met de beheerder van uw thuisserver.", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Uw homeserver wees uw inlogpoging af. Dit kan zijn doordat het te lang heeft geduurd. Probeer het opnieuw. Als dit probleem zich blijft voordoen, neem contact op met de beheerder van uw homeserver.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Uw homeserver was onbereikbaar en kon u niet inloggen, probeer het opnieuw. Wanneer dit probleem zich blijft voordoen, neem contact op met de beheerder van uw homeserver.", "Try again": "Probeer opnieuw", - "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "De browser is verzocht uw thuisserver te onthouden die u gebruikt om zich aan te melden, maar is deze vergeten. Ga naar de aanmeldpagina en probeer het opnieuw.", - "We couldn't log you in": "We konden u niet aanmelden", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "De browser is verzocht uw homeserver te onthouden die u gebruikt om zich aan te melden, maar is deze vergeten. Ga naar de aanmeldpagina en probeer het opnieuw.", + "We couldn't log you in": "We konden u niet inloggen", "Room Info": "Gespreksinfo", - "Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org is de grootste openbare thuisserver van de wereld, dus het is een goede plek voor vele.", - "Explore Public Rooms": "Verken openbare groepsgesprekken", + "Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org is de grootste openbare homeserver van de wereld, dus het is een goede plek voor vele.", + "Explore Public Rooms": "Verken openbare groepen", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Privégesprekken zijn alleen zichtbaar en toegankelijk met een uitnodiging. Openbare gesprekken zijn zichtbaar en toegankelijk voor iedereen in deze gemeenschap.", "This room is public": "Dit gesprek is openbaar", - "Show previews of messages": "Toon voorvertoning van berichten", + "Show previews of messages": "Voorvertoning van berichten inschakelen", "Show message previews for reactions in all rooms": "Toon berichtvoorbeelden voor reacties in alle gesprekken", - "Explore public rooms": "Verken openbare groepsgesprekken", - "Leave Room": "Verlaat gesprek", + "Explore public rooms": "Verken openbare groepen", + "Leave Room": "Gesprek verlaten", "Room options": "Gesprekopties", "Start a conversation with someone using their name, email address or username (like ).": "Start een gesprek met iemand door hun naam, emailadres of gebruikersnaam (zoals ) te typen.", "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Berichten hier zijn eind-tot-eind versleuteld. Verifieer %(displayName)s op hun profiel - klik op hun avatar.", @@ -2349,7 +2349,7 @@ "Show rooms with unread messages first": "Gesprekken met ongelezen berichten als eerste tonen", "%(count)s results|one": "%(count)s resultaten", "%(count)s results|other": "%(count)s resultaten", - "Explore all public rooms": "Verken alle openbare groepsgesprekken", + "Explore all public rooms": "Verken alle openbare groepen", "Start a new chat": "Een nieuw gesprek beginnen", "Can't see what you’re looking for?": "Niet kunnen vinden waar u naar zocht?", "Custom Tag": "Aangepast label", @@ -2359,11 +2359,11 @@ "Hide Widgets": "Widgets verbergen", "This is the start of .": "Dit is het begin van .", "%(displayName)s created this room.": "%(displayName)s heeft dit gesprek aangemaakt.", - "You created this room.": "U heeft dit gesprek aangemaakt.", + "You created this room.": "U heeft dit gesprek gemaakt.", "Topic: %(topic)s ": "Onderwerp: %(topic)s ", "Topic: %(topic)s (edit)": "Onderwerp: %(topic)s (bewerken)", - "This is the beginning of your direct message history with .": "Dit is het begin van de geschiedenis van uw tweegesprek met .", - "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "De beheerder van uw server heeft eind-tot-eindversleuteling standaard uitgeschakeld in alle privégesprekken en tweegesprekken.", + "This is the beginning of your direct message history with .": "Dit is het begin van de geschiedenis van uw direct gesprek met .", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "De beheerder van uw server heeft eind-tot-eind-versleuteling standaard uitgeschakeld in alle privégesprekken en directe gesprekken.", "Scroll to most recent messages": "Spring naar meest recente bericht", "The authenticity of this encrypted message can't be guaranteed on this device.": "De echtheid van dit versleutelde bericht kan op dit apparaat niet worden gegarandeerd.", "To link to this room, please add an address.": "Voeg een adres toe om naar deze kamer te verwijzen.", @@ -2392,10 +2392,10 @@ "Click the button below to confirm deleting these sessions.|one": "Bevestig het verwijderen van deze sessie door op de knop hieronder te drukken.", "Click the button below to confirm deleting these sessions.|other": "Bevestig het verwijderen van deze sessies door op de knop hieronder te drukken.", "Confirm deleting these sessions": "Bevestig dat u deze sessies wilt verwijderen", - "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Bevestig uw identiteit met Eenmalige Aanmelding om deze sessies te verwijderen.", - "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Bevestig uw identiteit met Eenmalige Aanmelding om deze sessies te verwijderen.", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Bevestig uw identiteit met uw eenmalige aanmelding om deze sessies te verwijderen.", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Bevestig uw identiteit met uw eenmalige aanmelding om deze sessies te verwijderen.", "not found locally": "lokaal niet gevonden", - "cached locally": "Lokaal opgeslagen", + "cached locally": "lokaal opgeslagen", "not found in storage": "Niet gevonden in de opslag", "Channel: ": "Kanaal: ", "From %(deviceName)s (%(deviceId)s)": "Van %(deviceName)s %(deviceId)s", @@ -2414,16 +2414,16 @@ "Voice Call": "Spraakoproep", "Video Call": "Video-oproep", "sends snowfall": "Stuur sneeuwvlokken", - "sends confetti": "Stuur confetti", + "sends confetti": "verstuurt confetti", "sends fireworks": "Stuur vuurwerk", "Downloading logs": "Logboeken downloaden", "Uploading logs": "Logboeken versturen", "Use Ctrl + Enter to send a message": "Gebruik Ctrl + Enter om een bericht te sturen", "Use Command + Enter to send a message": "Gebruik Command (⌘) + Enter om een bericht te sturen", - "Use Ctrl + F to search": "Gebruik Ctrl + F om te zoeken", - "Use Command + F to search": "Gebruik Command (⌘) + F om te zoeken", - "Use a more compact ‘Modern’ layout": "Gebruik een meer compacte 'Moderne' indeling", - "Use custom size": "Gebruik aangepaste grootte", + "Use Ctrl + F to search": "Ctrl + F om te zoeken gebruiken", + "Use Command + F to search": "Command (⌘) + F om te zoeken gebruiken", + "Use a more compact ‘Modern’ layout": "Compacte 'Modern'-layout inschakelen", + "Use custom size": "Aangepaste lettergrootte gebruiken", "Font size": "Lettergrootte", "Enable advanced debugging for the room list": "Geavanceerde foutopsporing voor de gesprekkenlijst inschakelen", "Render LaTeX maths in messages": "Weergeef LaTeX-wiskundenotatie in berichten", @@ -2478,8 +2478,8 @@ "Looks good": "Ziet er goed uit", "Enter a server name": "Geef een servernaam", "Continue with %(provider)s": "Doorgaan met %(provider)s", - "Homeserver": "Thuisserver", - "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "U kunt de aangepaste serverinstellingen gebruiken om u aan te melden bij andere Matrix-servers, door een andere thuisserver-URL in te voeren. Dit laat u toe Element te gebruiken met een bestaande Matrix-account bij een andere thuisserver.", + "Homeserver": "Homeserver", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "U kunt de aangepaste serverinstellingen gebruiken om u aan te melden bij andere Matrix-servers, door een andere homeserver-URL in te voeren. Dit laat u toe Element te gebruiken met een bestaande Matrix-account bij een andere homeserver.", "Server Options": "Serverinstellingen", "This address is already in use": "Dit adres is al in gebruik", "This address is available to use": "Dit adres kan worden gebruikt", @@ -2492,7 +2492,7 @@ "Use the Desktop app to search encrypted messages": "Gebruik de Desktop-toepassing om alle versleutelde berichten te zien", "Categories": "Categorieën", "Can't load this message": "Dit bericht kan niet geladen worden", - "Click to view edits": "Druk om wijzigingen te weergeven", + "Click to view edits": "Klik om bewerkingen te zien", "Edited at %(date)s": "Bewerkt op %(date)s", "Message deleted on %(date)s": "Bericht verwijderd op %(date)s", "Message deleted by %(name)s": "Bericht verwijderd door %(name)s", @@ -2517,7 +2517,7 @@ "You can only pin up to %(count)s widgets|other": "U kunt maar %(count)s widgets vastzetten", "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "In versleutelde gesprekken zijn uw berichten beveiligd, enkel de ontvanger en u hebben de unieke sleutels om ze te ontsleutelen.", "Waiting for you to accept on your other session…": "Wachten totdat u uw uitnodiging in uw andere sessie aanneemt…", - "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Stel een adres in zodat gebruikers dit gesprek via uw thuisserver (%(localDomain)s) kunnen vinden", + "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Stel een adres in zodat gebruikers dit gesprek via uw homeserver (%(localDomain)s) kunnen vinden", "Local Addresses": "Lokale adressen", "Local address": "Lokaal adres", "The server has denied your request.": "De server heeft uw verzoek afgewezen.", @@ -2549,9 +2549,9 @@ "Manually verify all remote sessions": "Handmatig alle externe sessies verifiëren", "System font name": "Systeemlettertypenaam", "Use a system font": "Gebruik een systeemlettertype", - "Show line numbers in code blocks": "Toon regelnummers in codeblokken", + "Show line numbers in code blocks": "Regelnummers in codeblokken tonen", "Expand code blocks by default": "Standaard codeblokken uitvouwen", - "Show stickers button": "Toon stickers-knop", + "Show stickers button": "Stickers-knop tonen", "Offline encrypted messaging using dehydrated devices": "Offline versleutelde berichten met gebruik van uitgedroogde apparaten", "Show message previews for reactions in DMs": "Toon berichtvoorbeelden voor reacties in DM's", "New spinner design": "Nieuw laadicoonontwerp", @@ -2595,7 +2595,7 @@ "See messages posted to this room": "Zie berichten verstuurd naar dit gesprek", "Send messages as you in your active room": "Stuur berichten als uzelf in uw actieve gesprek", "Send messages as you in this room": "Stuur berichten als uzelf in dit gesprek", - "End": "Beëindigen", + "End": "End", "The %(capability)s capability": "De %(capability)s mogelijkheid", "See %(eventType)s events posted to your active room": "Stuur %(eventType)s gebeurtenissen verstuurd in uw actieve gesprek", "Send %(eventType)s events as you in your active room": "Stuur %(eventType)s gebeurtenissen als uzelf in uw actieve gesprek", @@ -2648,6 +2648,307 @@ "Feedback sent": "Feedback verstuurd", "Workspace: ": "Werkplaats: ", "Your firewall or anti-virus is blocking the request.": "Uw firewall of antivirussoftware blokkeert de aanvraag.", - "Show chat effects": "Toon gesprekseffecten", - "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Stel de naam in van een lettertype dat op uw systeem is geïnstalleerd en %(brand)s zal proberen het te gebruiken." + "Show chat effects": "Gesprekseffecten tonen", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Stel de naam in van een lettertype dat op uw systeem is geïnstalleerd en %(brand)s zal proberen het te gebruiken.", + "Toggle this dialog": "Dit dialoogvenster in- of uitschakelen", + "Toggle right panel": "Rechterpaneel in- of uitschakelen", + "Toggle the top left menu": "Het menu linksboven in- of uitschakelen", + "Toggle video on/off": "Video in- of uitschakelen", + "Toggle microphone mute": "Microfoon dempen in- of uitschakelen", + "Toggle Quote": "Quote in- of uitschakelen", + "Toggle Italics": "Cursief in- of uitschakelen", + "Toggle Bold": "Vetgedrukt in- of uitschakelen", + "Go to Home View": "Ga naar welkomscherm", + "Activate selected button": "Geselecteerde knop activeren", + "Close dialog or context menu": "Dialoogvenster of contextmenu sluiten", + "Previous/next room or DM": "Vorige/volgende gesprek", + "Previous/next unread room or DM": "Vorige/volgende ongelezen gesprek", + "Clear room list filter field": "Gespreklijst filter wissen", + "Expand room list section": "Gespreklijst selectie uitvouwen", + "Collapse room list section": "Gespreklijst selectie invouwen", + "Select room from the room list": "Gesprek uit de gespreklijst selecteren", + "Navigate up/down in the room list": "Omhoog/omlaag in de gespreklijst navigeren", + "Jump to room search": "Ga naar gesprek zoeken", + "Search (must be enabled)": "Zoeken (moet zijn ingeschakeld)", + "Upload a file": "Bestand uploaden", + "Jump to oldest unread message": "Ga naar het oudste ongelezen bericht", + "Dismiss read marker and jump to bottom": "Verlaat de leesmarkering en spring naar beneden", + "Scroll up/down in the timeline": "Omhoog/omlaag in de tijdlijn scrollen", + "Cancel replying to a message": "Antwoord op bericht annuleren", + "Navigate composer history": "Berichtveldgeschiedenis navigeren", + "Jump to start/end of the composer": "Ga naar begin/eind van de berichtveld", + "Navigate recent messages to edit": "Navigeer recente berichten om te bewerken", + "New line": "Nieuwe regel", + "Page Up": "Page Up", + "Page Down": "Page Down", + "Esc": "Esc", + "Enter": "Enter", + "Space": "Spatie", + "Ctrl": "Ctrl", + "Super": "Super", + "Shift": "Shift", + "Alt Gr": "Alt Gr", + "Alt": "Alt", + "Cancel autocomplete": "Autoaanvullen annuleren", + "Move autocomplete selection up/down": "Autoaanvullen selectie omhoog/omlaag verplaatsen", + "Autocomplete": "Autoaanvullen", + "Room List": "Gespreklijst", + "Calls": "Oproepen", + "Navigation": "Navigatie", + "Currently indexing: %(currentRoom)s": "Momenteel indexeren: %(currentRoom)s", + "Enter your recovery passphrase a second time to confirm it.": "Voer uw herstel wachtwoord een tweede keer in om te bevestigen.", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Deze sessie heeft ontdekt dat uw veiligheidszin en sleutel voor versleutelde berichten zijn verwijderd.", + "A new Security Phrase and key for Secure Messages have been detected.": "Er is een nieuwe veiligheidszin en sleutel voor versleutelde berichten gedetecteerd.", + "Save your Security Key": "Uw veiligheidssleutel opslaan", + "Confirm Security Phrase": "Veiligheidszin bevestigen", + "Set a Security Phrase": "Een veiligheidszin instellen", + "You can also set up Secure Backup & manage your keys in Settings.": "U kunt ook een beveiligde back-up instellen en uw sleutels beheren via instellingen.", + "Secure Backup": "Beveiligde back-up", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Geen toegang tot sleutelopslag. Controleer of u de juiste veiligheidszin hebt ingevoerd.", + "Secret storage:": "Sleutelopslag:", + "Unable to query secret storage status": "Kan status sleutelopslag niet opvragen", + "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Bewaar uw veiligheidssleutel op een veilige plaats, zoals in een wachtwoordmanager of een kluis, aangezien deze wordt gebruikt om uw versleutelde gegevens te beveiligen.", + "Confirm your recovery passphrase": "Bevestig uw herstel wachtwoord", + "Use a different passphrase?": "Gebruik een ander wachtwoord?", + "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Voer een veiligheidszin in die alleen u kent, aangezien deze wordt gebruikt om uw gegevens te versleutelen. Om veilig te zijn, moet u het wachtwoord van uw account niet opnieuw gebruiken.", + "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Bescherm uw server tegen toegangsverlies tot versleutelde berichten en gegevens door een back-up te maken van de versleutelingssleutels.", + "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Gebruik een veiligheidszin die alleen u kent, en sla optioneel een veiligheidssleutel op om te gebruiken als back-up.", + "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Wij maken een veiligheidssleutel voor u aan die u ergens veilig kunt opbergen, zoals in een wachtwoordmanager of een kluis.", + "Generate a Security Key": "Genereer een veiligheidssleutel", + "Make a copy of your Security Key": "Maak een kopie van uw veiligheidssleutel", + "Confirm your Security Phrase": "Bevestig uw veiligheidszin", + "Secure your backup with a Security Phrase": "Beveilig uw back-up met een veiligheidszin", + "Your Security Key is in your Downloads folder.": "Uw veiligheidssleutel staat in uw Downloads-map.", + "Your Security Key has been copied to your clipboard, paste it to:": "Uw veiligheidssleutel is gekopieerd naar uw klembord, plak het in:", + "Your Security Key": "Uw veiligheidssleutel", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Uw veiligheidssleutel is een vangnet - u kunt hem gebruiken om de toegang tot uw versleutelde berichten te herstellen als u uw veiligheidszin bent vergeten.", + "Repeat your Security Phrase...": "Herhaal uw veiligheidszin...", + "Please enter your Security Phrase a second time to confirm.": "Voer uw veiligheidszin een tweede keer in om te bevestigen.", + "Set up with a Security Key": "Instellen met een veiligheidssleutel", + "Great! This Security Phrase looks strong enough.": "Geweldig. Deze veiligheidszin ziet er sterk genoeg uit.", + "Enter a Security Phrase": "Veiligheidszin invoeren", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Wij bewaren een versleutelde kopie van uw sleutels op onze server. Beveilig uw back-up met een veiligheidszin.", + "or another cross-signing capable Matrix client": "of een andere Matrix-client die kruislings kan ondertekenen", + "%(brand)s Android": "%(brand)s Android", + "%(brand)s iOS": "%(brand)s iOS", + "%(brand)s Desktop": "%(brand)s Desktop", + "%(brand)s Web": "%(brand)s Web", + "This requires the latest %(brand)s on your other devices:": "Dit vereist de nieuwste %(brand)s op uw andere toestellen:", + "Use Security Key": "Gebruik veiligheidssleutel", + "Use Security Key or Phrase": "Gebruik veiligheidssleutel of -zin", + "Decide where your account is hosted": "Kies waar uw account wordt gehost", + "Host account on": "Host uw account op", + "Already have an account? Sign in here": "Heeft u al een account? Aanmelden", + "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s of %(usernamePassword)s", + "Continue with %(ssoButtons)s": "Ga verder met %(ssoButtons)s", + "That username already exists, please try another.": "Die gebruikersnaam bestaat al, probeer een andere.", + "New? Create account": "Nieuw? Maak een account aan", + "If you've joined lots of rooms, this might take a while": "Als u zich bij veel gesprekken heeft aangesloten, kan dit een tijdje duren", + "Signing In...": "Aanmelden...", + "Syncing...": "Synchroniseren...", + "There was a problem communicating with the homeserver, please try again later.": "Er was een communicatieprobleem met de homeserver, probeer het later opnieuw.", + "Community and user menu": "Gemeenschaps- en gebruikersmenu", + "User menu": "Gebruikersmenu", + "Switch theme": "Thema wisselen", + "Community settings": "Gemeenschapsinstellingen", + "User settings": "Gebruikersinstellingen", + "Security & privacy": "Veiligheid & privacy", + "New here? Create an account": "Nieuw hier? Maak een account", + "Got an account? Sign in": "Heeft u een account? Aanmelden", + "Failed to find the general chat for this community": "De algemene chat voor deze gemeenschap werd niet gevonden", + "Filter rooms and people": "Gespreken en personen filteren", + "Explore rooms in %(communityName)s": "Ontdek de gesprekken van %(communityName)s", + "delete the address.": "het adres verwijderen.", + "Delete the room address %(alias)s and remove %(name)s from the directory?": "Het gespreksadres %(alias)s en %(name)s uit de catalogus verwijderen?", + "You have no visible notifications.": "U hebt geen zichtbare meldingen.", + "You’re all caught up": "U bent helemaal bij", + "Self-verification request": "Verzoek om zelfverificatie", + "You do not have permission to create rooms in this community.": "U hebt geen toestemming om gesprekken te maken in deze gemeenschap.", + "Cannot create rooms in this community": "Kan geen gesprek maken in deze gemeenschap", + "Upgrade to pro": "Upgrade naar pro", + "Now, let's help you get started": "Laten we u helpen om te beginnen", + "Welcome %(name)s": "Welkom %(name)s", + "Add a photo so people know it's you.": "Voeg een foto toe zodat mensen weten dat u het bent.", + "Great, that'll help people know it's you": "Geweldig, dat zal mensen helpen te weten dat u het bent", + "

HTML for your community's page

\n

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

\n

\n You can even add images with Matrix URLs \n

\n": "

HTML voor de pagina van uw gemeenschap

\n

\nGebruik de lange beschrijving om nieuwe deelnemers voor te stellen aan de gemeenschap, of verspreid enkele belangrijke links\n

\n

\nU kunt zelfs afbeeldingen toevoegen met Matrix URL's \n

\n", + "Create community": "Gemeenschap aanmaken", + "Attach files from chat or just drag and drop them anywhere in a room.": "Voeg bestanden toe vanuit het gesprek of sleep ze in een gesprek.", + "No files visible in this room": "Geen bestanden zichtbaar in dit gesprek", + "Sign in with SSO": "Aanmelden met SSO", + "Use email to optionally be discoverable by existing contacts.": "Gebruik e-mail om optioneel ontdekt te worden door bestaande contacten.", + "Use email or phone to optionally be discoverable by existing contacts.": "Gebruik e-mail of telefoon om optioneel ontdekt te kunnen worden door bestaande contacten.", + "Add an email to be able to reset your password.": "Voeg een e-mail toe om uw wachtwoord te kunnen resetten.", + "Forgot password?": "Wachtwoord vergeten?", + "That phone number doesn't look quite right, please check and try again": "Dat telefoonnummer ziet er niet goed uit, controleer het en probeer het opnieuw", + "Enter phone number": "Telefoonnummer invoeren", + "Enter email address": "E-mailadres invoeren", + "Something went wrong in confirming your identity. Cancel and try again.": "Er is iets misgegaan bij het bevestigen van uw identiteit. Annuleer en probeer het opnieuw.", + "Open the link in the email to continue registration.": "Open de link in de e-mail om verder te gaan met de registratie.", + "A confirmation email has been sent to %(emailAddress)s": "Er is een bevestigingsmail verzonden naar %(emailAddress)s", + "Away": "Afwezig", + "Move right": "Ga naar rechts", + "Move left": "Ga naar links", + "Revoke permissions": "Machtigingen intrekken", + "Take a picture": "Neem een foto", + "Hold": "Vasthouden", + "Resume": "Hervatten", + "If you've forgotten your Security Key you can ": "Als u uw veiligheidssleutel bent vergeten, kunt u ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Ga naar uw veilige berichtengeschiedenis en stel veilige berichten in door uw veiligheidssleutel in te voeren.", + "Not a valid Security Key": "Geen geldige veiligheidssleutel", + "This looks like a valid Security Key!": "Dit lijkt op een geldige veiligheidssleutel!", + "Enter Security Key": "Veiligheidssleutel invoeren", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Als u uw veiligheidszin bent vergeten, kunt u uw veiligheidssleutel gebruiken of nieuwe herstelopties instellen", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Ga naar uw veilige berichtengeschiedenis en stel veilige berichten in door uw veiligheidszin in te voeren.", + "Enter Security Phrase": "Voer veiligheidszin in", + "Successfully restored %(sessionCount)s keys": "Succesvol %(sessionCount)s sleutels hersteld", + "Keys restored": "Sleutels hersteld", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "Back-up kon niet worden gedecodeerd met deze veiligheidszin: controleer of u de juiste veiligheidszin hebt ingevoerd.", + "Incorrect Security Phrase": "Onjuiste veiligheidszin", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "Back-up kon niet worden ontcijferd met deze veiligheidssleutel: controleer of u de juiste veiligheidssleutel hebt ingevoerd.", + "Security Key mismatch": "Verkeerde veiligheidssleutel", + "%(completed)s of %(total)s keys restored": "%(completed)s van %(total)s sleutels hersteld", + "Fetching keys from server...": "Sleutels ophalen van server...", + "Restoring keys from backup": "Sleutels herstellen vanaf back-up", + "Unable to set up keys": "Kan geen sleutels instellen", + "Click the button below to confirm setting up encryption.": "Klik op de knop hieronder om het instellen van de versleuting te bevestigen.", + "Confirm encryption setup": "Bevestig versleuting instelling", + "Use your Security Key to continue.": "Gebruik uw veiligheidssleutel om verder te gaan.", + "Security Key": "Veiligheidssleutel", + "Enter your Security Phrase or to continue.": "Voer uw veiligheidszin in of om verder te gaan.", + "Security Phrase": "Veiligheidszin", + "Invalid Security Key": "Ongeldige veiligheidssleutel", + "Wrong Security Key": "Verkeerde veiligheidssleutel", + "Looks good!": "Ziet er goed uit!", + "Wrong file type": "Verkeerd bestandstype", + "Remember this": "Onthoud dit", + "The widget will verify your user ID, but won't be able to perform actions for you:": "De widget zal uw gebruikers-ID verifiëren, maar zal geen acties voor u kunnen uitvoeren:", + "Allow this widget to verify your identity": "Sta deze widget toe om uw identiteit te verifiëren", + "Decline All": "Alles weigeren", + "Approve": "Goedkeuren", + "This widget would like to:": "Deze widget zou willen:", + "Approve widget permissions": "Machtigingen voor widgets goedkeuren", + "Use your preferred Matrix homeserver if you have one, or host your own.": "Gebruik de Matrix-homeserver van uw voorkeur als u er een hebt, of host uw eigen.", + "We call the places where you can host your account ‘homeservers’.": "Wij noemen de plaatsen waar u uw account kunt hosten 'homeservers'.", + "Unable to validate homeserver": "Kan homeserver niet valideren", + "Recent changes that have not yet been received": "Recente wijzigingen die nog niet zijn ontvangen", + "The server is not configured to indicate what the problem is (CORS).": "De server is niet geconfigureerd om aan te geven wat het probleem is (CORS).", + "A connection error occurred while trying to contact the server.": "Er is een verbindingsfout opgetreden tijdens het contact maken met de server.", + "Your area is experiencing difficulties connecting to the internet.": "Uw regio ondervindt problemen bij de verbinding met het internet.", + "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Uw server reageert niet op sommige van uw verzoeken. Hieronder staan enkele van de meest waarschijnlijke redenen.", + "We recommend you change your password and Security Key in Settings immediately": "Wij raden u aan uw wachtwoord en veiligheidssleutel in de instellingen onmiddellijk te wijzigen", + "Data on this screen is shared with %(widgetDomain)s": "Gegevens op dit scherm worden gedeeld met %(widgetDomain)s", + "Modal Widget": "Modale widget", + "Confirm this user's session by comparing the following with their User Settings:": "Bevestig de sessie van deze gebruiker door het volgende te vergelijken met zijn gebruikersinstellingen:", + "Cancelled signature upload": "Geannuleerde ondertekening upload", + "%(brand)s encountered an error during upload of:": "%(brand)s is een fout tegengekomen tijdens het uploaden van:", + "a key signature": "een sleutel ondertekening", + "a device cross-signing signature": "een apparaat kruiselings ondertekenen ondertekening", + "a new cross-signing key signature": "een nieuwe kruiselings ondertekenen ondertekening", + "a new master key signature": "een nieuwe hoofdsleutel ondertekening", + "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "Dit zal ze niet uitnodigen voor %(communityName)s. Als u iemand wilt uitnodigen voor %(communityName)s, klik hier", + "Failed to transfer call": "Gesprek niet doorverbonden", + "A call can only be transferred to a single user.": "Een oproep kan slechts naar één gebruiker worden doorverbonden.", + "Learn more in our , and .": "Meer informatie vindt u in onze , en .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Door tijdelijk door te gaan, krijgt het installatieproces van %(hostSignupBrand)s toegang tot uw account om geverifieerde e-mailadressen op te halen. Deze gegevens worden niet opgeslagen.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Kan geen verbinding maken met uw homeserver. Sluit dit dialoogvenster en probeer het opnieuw.", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Weet u zeker dat u het aanmaken van de host wilt afbreken? Het proces kan niet worden voortgezet.", + "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "PRO TIP: Als u een bug start, stuur ons dan debug logs om ons te helpen het probleem op te sporen.", + "There was an error updating your community. The server is unable to process your request.": "Er is een fout opgetreden bij het updaten van uw gemeenschap. De server is niet in staat om uw verzoek te verwerken.", + "There was an error finding this widget.": "Er is een fout opgetreden bij het vinden van deze widget.", + "Server did not return valid authentication information.": "Server heeft geen geldige verificatiegegevens teruggestuurd.", + "Server did not require any authentication": "Server heeft geen authenticatie nodig", + "There was a problem communicating with the server. Please try again.": "Er was een communicatie probleem met de server. Probeer het opnieuw.", + "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "U zou dit kunnen uitschakelen als dit gesprek gebruikt zal worden om samen te werken met externe teams die hun eigen homeserver hebben. Dit kan later niet meer veranderd worden.", + "Verify other session": "Verifier andere sessies", + "About homeservers": "Over homeservers", + "Learn more": "Lees verder", + "Other homeserver": "Andere homeserver", + "Sign into your homeserver": "Login op uw homeserver", + "Specify a homeserver": "Specificeer een homeserver", + "Invalid URL": "Ongeldige URL", + "Upload completed": "Upload voltooid", + "Maximize dialog": "Maximaliseer dialoog", + "%(hostSignupBrand)s Setup": "%(hostSignupBrand)s Installatie", + "You should know": "U moet weten", + "Privacy Policy": "Privacystatement", + "Cookie Policy": "Cookiebeleid", + "Abort": "Annuleren", + "Confirm abort of host creation": "Bevestig het annuleren van de host creatie", + "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "U zou dit kunnen aanzetten als dit gesprek alleen gebruikt zal worden voor samenwerking met interne teams op uw homeserver. Dit kan later niet meer veranderd worden.", + "You can’t disable this later. Bridges & most bots won’t work yet.": "U kunt dit later niet uitschakelen. Bruggen en de meeste bots zullen nog niet werken.", + "There was an error creating your community. The name may be taken or the server is unable to process your request.": "Er is een fout opgetreden bij het aanmaken van uw gemeenschap. De naam kan bezet zijn of de server is niet in staat om uw aanvraag te verwerken.", + "Preparing to download logs": "Klaarmaken om logs te downloaden", + "Matrix rooms": "Matrix-gesprekken", + "%(networkName)s rooms": "%(networkName)s gesprekken", + "Enter the name of a new server you want to explore.": "Voer de naam in van een nieuwe server die u wilt verkennen.", + "Remove server": "Server verwijderen", + "All rooms": "Alle gesprekken", + "Windows": "Windows", + "Screens": "Schermen", + "Share your screen": "Uw scherm delen", + "Submit logs": "Logs versturen", + "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Berichten in dit gesprek zijn eind-tot-eind-versleuteld. Als mensen deelnemen, kan u ze verifiëren in hun profiel, tik gewoon op hun avatar.", + "In encrypted rooms, verify all users to ensure it’s secure.": "Controleer alle gebruikers in versleutelde gesprekken om er zeker van te zijn dat het veilig is.", + "Verify all users in a room to ensure it's secure.": "Controleer alle gebruikers in een gesprek om er zeker van te zijn dat hij veilig is.", + "%(count)s people|one": "%(count)s persoon", + "Add widgets, bridges & bots": "Widgets, bruggen & bots toevoegen", + "Edit widgets, bridges & bots": "Widgets, bruggen & bots bewerken", + "Set my room layout for everyone": "Stel mijn gesprekindeling in voor iedereen", + "New published address (e.g. #alias:server)": "Nieuw gepubliceerd adres (b.v. #alias:server)", + "No other published addresses yet, add one below": "Nog geen andere gepubliceerde adressen, voeg er hieronder een toe", + "Other published addresses:": "Andere gepubliceerde adressen:", + "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Gepubliceerde adressen kunnen door iedereen op elke server gebruikt worden om aan je groep deel te nemen. Om een adres te publiceren moet het eerste ingesteld worden als lokaaladres.", + "Published Addresses": "Gepubliceerde adressen", + "Mentions & Keywords": "Vermeldingen & Trefwoorden", + "Use the + to make a new room or explore existing ones below": "Gebruik de + om een nieuw gesprek te starten of ontdek de bestaande groepen hieronder", + "Open dial pad": "Kiestoetsen openen", + "Recently visited rooms": "Onlangs geopende gesprekken", + "Add a photo, so people can easily spot your room.": "Voeg een foto toe, zodat mensen je gemakkelijk kunnen herkennen in het gesprek.", + "Only the two of you are in this conversation, unless either of you invites anyone to join.": "Alleen u beiden nemen deel aan dit gesprek, tenzij een van u beiden iemand uitnodigt om deel te nemen.", + "Emoji picker": "Emoji kiezer", + "Room ID or address of ban list": "Gesprek-ID of het adres van de banlijst", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Voeg hier gebruikers en servers toe die u wilt negeren. Gebruik asterisken om %(brand)s met alle tekens te laten overeenkomen. Bijvoorbeeld, @bot:* zou alle gebruikers negeren die de naam 'bot' hebben op elke server.", + "Please verify the room ID or address and try again.": "Controleer het gesprek-ID of het adres en probeer het opnieuw.", + "Message layout": "Berichtlayout", + "Custom theme URL": "Aangepaste thema-URL", + "Error downloading theme information.": "Fout bij het downloaden van de thema-informatie.", + "Invalid theme schema.": "Ongeldig themaschema.", + "Hey you. You're the best!": "Hey. U bent de beste!", + "Backup key cached:": "Back-up sleutel cached:", + "Backup key stored:": "Back-up sleutel bewaard:", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Maak een back-up van uw encryptiesleutels met uw accountgegevens voor het geval u de toegang tot uw sessies verliest. Uw sleutels worden beveiligd met een unieke veiligheidssleutel.", + "well formed": "goed gevormd", + "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s kan versleutelde berichten niet veilig lokaal opslaan in een webbrowser. Gebruik %(brand)s Desktop om versleutelde berichten in zoekresultaten te laten verschijnen.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Veilig lokaal opslaan van versleutelde berichten zodat ze in de zoekresultaten verschijnen, gebruik %(size)s voor het opslaan van berichten uit %(rooms)s gesprek.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Veilig lokaal opslaan van versleutelde berichten zodat ze in de zoekresultaten verschijnen, gebruik %(size)s voor het opslaan van berichten uit %(rooms)s gesprekken.", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Elke sessie die door een gebruiker wordt gebruikt, afzonderlijk verifiëren om deze als vertrouwd aan te merken, waarbij geen vertrouwen wordt gesteld in kruiselings ondertekende apparaten.", + "User signing private key:": "Gebruiker ondertekening privésleutel:", + "Master private key:": "Hoofd privésleutel:", + "Self signing private key:": "Zelfondertekenende privésleutel:", + "Cross-signing is not set up.": "Kruiselings ondertekenen is niet ingesteld.", + "Cross-signing is ready for use.": "Kruiselings ondertekenen is klaar voor gebruik.", + "Your server isn't responding to some requests.": "Uw server reageert niet op sommige verzoeken.", + "Dial pad": "Kiestoetsen", + "%(name)s on hold": "%(name)s in de wacht", + "%(peerName)s held the call": "%(peerName)s heeft de oproep in de wacht", + "You held the call Resume": "U heeft een oproep in de wacht Hervat", + "You held the call Switch": "U heeft een oproep in de wacht Wissel", + "Sends the given message with snowfall": "Verstuur het bericht met sneeuwval", + "Sends the given message with fireworks": "Verstuur het bericht met vuurwerk", + "Sends the given message with confetti": "Verstuur het bericht met confetti", + "IRC display name width": "Breedte IRC-weergavenaam", + "Enable experimental, compact IRC style layout": "Compacte IRC-layout (experimenteel) inschakelen", + "Minimize dialog": "Dialoog minimaliseren", + "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Als u nu annuleert, kunt u versleutelde berichten en gegevens verliezen als u geen toegang meer heeft tot uw login.", + "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Bevestig uw identiteit door deze login te verifiëren vanuit een van uw andere sessies, waardoor u toegang krijgt tot uw versleutelde berichten.", + "Verify this login": "Controleer deze login", + "To continue, use Single Sign On to prove your identity.": "Om verder te gaan, gebruik uw eenmalige aanmelding om uw identiteit te bewijzen.", + "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Plakt ( ͡° ͜ʖ ͡°) vóór een bericht zonder opmaak", + "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "Plakt ┬──┬ ノ( ゜-゜ノ) vóór een bericht zonder opmaak", + "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Plakt (╯°□°)╯︵ ┻━┻ vóór een bericht zonder opmaak", + "Liberate your communication": "Bevrijd uw communicatie", + "Create a Group Chat": "Maak een groepsgesprek aan", + "Send a Direct Message": "Start een direct gesprek", + "Welcome to %(appName)s": "Welkom bij %(appName)s", + "Add a topic to help people know what it is about.": "Stel een gespreksonderwerp in zodat mensen weten waar het over gaat." } From 5cd6426645167c42c473cd30e1ebd3f1cbfc97ba Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Sun, 21 Feb 2021 19:45:05 +0000 Subject: [PATCH 0204/2651] Translated using Weblate (Russian) Currently translated at 99.7% (2757 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 76 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 7a889ed084..a72eef2c58 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -2635,7 +2635,7 @@ "Server Options": "Параметры сервера", "Decline All": "Отклонить все", "Homeserver": "Домашний сервер", - "Approve": "Одобрить", + "Approve": "Согласиться", "Approve widget permissions": "Одобрить разрешения виджета", "Send stickers into your active room": "Отправить стикеры в активную комнату", "Remain on your screen while running": "Оставаться на экране во время работы", @@ -2985,5 +2985,77 @@ "Unable to look up phone number": "Невозможно найти номер телефона", "Change which room, message, or user you're viewing": "Измените комнату, сообщение или пользователя, которого вы просматриваете", "Channel: ": "Канал: ", - "Workspace: ": "Рабочая область: " + "Workspace: ": "Рабочая область: ", + "Search (must be enabled)": "Поиск (должен быть включен)", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Этот сеанс обнаружил, что ваша секретная фраза и ключ безопасности для защищенных сообщений были удалены.", + "A new Security Phrase and key for Secure Messages have been detected.": "Обнаружены новая секретная фраза и ключ безопасности для защищенных сообщений.", + "Make a copy of your Security Key": "Сделайте копию своего ключа безопасности", + "Confirm your Security Phrase": "Подтвердите секретную фразу", + "Secure your backup with a Security Phrase": "Защитите свою резервную копию с помощью секретной фразы", + "Your Security Key is in your Downloads folder.": "Ваш ключ безопасности находится в папке Загрузки.", + "Your Security Key has been copied to your clipboard, paste it to:": "Ваш ключ безопасности был скопирован в буфер обмена, вставьте его в:", + "Your Security Key": "Ваш ключ безопасности", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Ваш ключ безопасности является защитной сеткой - вы можете использовать его для восстановления доступа к своим зашифрованным сообщениям, если вы забыли секретную фразу.", + "Repeat your Security Phrase...": "Повторите секретную фразу…", + "Please enter your Security Phrase a second time to confirm.": "Пожалуйста, введите секретную фразу второй раз для подтверждения.", + "Set up with a Security Key": "Настройка с помощью ключа безопасности", + "Great! This Security Phrase looks strong enough.": "Отлично! Эта контрольная фраза выглядит достаточно сильной.", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Мы будем хранить зашифрованную копию ваших ключей на нашем сервере. Защитите свою резервную копию с помощью секретной фразы.", + "Use Security Key": "Используйте ключ безопасности", + "Use Security Key or Phrase": "Используйте ключ безопасности или секретную фразу", + "Upgrade to pro": "Перейти на Pro", + "Allow this widget to verify your identity": "Разрешите этому виджету проверить ваш идентификатор", + "Something went wrong in confirming your identity. Cancel and try again.": "Что-то пошло не так при вашей идентификации. Отмените последнее действие и попробуйте еще раз.", + "If you've forgotten your Security Key you can ": "Если вы забыли свой ключ безопасности, вы можете ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Получите доступ к своей истории защищенных сообщений и настройте безопасный обмен сообщениями, введя ключ безопасности.", + "Not a valid Security Key": "Неправильный ключ безопасности", + "This looks like a valid Security Key!": "Похоже, это правильный ключ безопасности!", + "Enter Security Key": "Введите ключ безопасности", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Если вы забыли секретную фразу, вы можете использовать ключ безопасности или настроить новые параметры восстановления", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Получите доступ к своей истории защищенных сообщений и настройте безопасный обмен сообщениями, введя секретную фразу.", + "Enter Security Phrase": "Введите секретную фразу", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "Не удалось расшифровать резервную копию с помощью этой секретной фразы: убедитесь, что вы ввели правильную секретную фразу.", + "Incorrect Security Phrase": "Неверная секретная фраза", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "Не удалось расшифровать резервную копию с помощью этого ключа безопасности: убедитесь, что вы ввели правильный ключ безопасности.", + "Security Key mismatch": "Ключ безопасности не подходит", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Невозможно получить доступ к секретному хранилищу. Убедитесь, что вы ввели правильную секретную фразу.", + "Invalid Security Key": "Неверный ключ безопасности", + "Wrong Security Key": "Неправильный ключ безопасности", + "Remember this": "Запомнить это", + "The widget will verify your user ID, but won't be able to perform actions for you:": "Виджет проверит ваш идентификатор пользователя, но не сможет выполнять за вас действия:", + "We recommend you change your password and Security Key in Settings immediately": "Мы рекомендуем вам немедленно сменить пароль и ключ безопасности в настройках", + "Minimize dialog": "Свернуть диалог", + "Maximize dialog": "Развернуть диалог", + "%(hostSignupBrand)s Setup": "%(hostSignupBrand)s Настройка", + "You should know": "Вы должны знать", + "Privacy Policy": "Политика конфиденциальности", + "Cookie Policy": "Политика использования файлов cookie", + "Learn more in our , and .": "Дополнительную информацию можно найти на страницах , и .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Продолжая процесс настройки %(hostSignupBrand)s, вы предоставите доступ к вашей учётной записи для получения проверенных адресов электронной почты. Эти данные не сохраняются.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Не удалось подключиться к домашнему серверу. Закройте это диалоговое окно и попробуйте ещё раз.", + "Abort": "Отмена", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Вы уверены, что хотите прервать создание хоста? Процесс не может быть продолжен.", + "Confirm abort of host creation": "Подтвердите отмену создания хоста", + "Windows": "Окна", + "Screens": "Экраны", + "Share your screen": "Поделитесь своим экраном", + "Set my room layout for everyone": "Установить мой макет комнаты для всех", + "Recently visited rooms": "Недавно посещённые комнаты", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Сделайте резервную копию ключей шифрования с данными вашей учетной записи на случай, если вы потеряете доступ к своим сеансам. Ваши ключи будут защищены уникальным ключом безопасности.", + "Use Ctrl + F to search": "Нажмите Ctrl + F для поиска", + "Use Command + F to search": "Нажмите Command (⌘) + F для поиска", + "Show line numbers in code blocks": "Показывать номера строк в блоках кода", + "Expand code blocks by default": "По умолчанию отображать блоки кода целиком", + "Show stickers button": "Показать кнопку стикеров", + "Use app": "Использовать приложение", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web - экспериментальная версия на мобильных устройствах. Для лучшего опыта и новейших функций используйте наше бесплатное приложение.", + "Use app for a better experience": "Используйте приложение для лучшего опыта", + "%(senderName)s has updated the widget layout": "%(senderName)s обновил макет виджета", + "Converts the DM to a room": "Преобразовать ЛС в комнату", + "Converts the room to a DM": "Преобразовать комнату в ЛС", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Ваш домашний сервер не позволил вам войти в систему. Это могло произойти из-за того, что вход занял слишком много времени. Пожалуйста, попробуйте снова через пару минут. Если ситуация по-прежнему не меняется, обратитесь к администратору домашнего сервера за дополнительной информацией.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Ваш домашний сервер был недоступен, и мы не смогли войти в систему. Пожалуйста, попробуйте снова через пару минут. Если ситуация по-прежнему не меняется, обратитесь к администратору домашнего сервера за дополнительной информацией.", + "Try again": "Попробовать ещё раз", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Мы попросили браузер запомнить, какой домашний сервер вы используете для входа в систему, но, к сожалению, ваш браузер забыл об этом. Перейдите на страницу входа и попробуйте ещё раз.", + "We couldn't log you in": "Нам не удалось войти в систему" } From 940bfdf21f22bbf53798b054623d042a7ecae4c2 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 17 Feb 2021 19:59:18 +0000 Subject: [PATCH 0205/2651] Translated using Weblate (Swedish) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index ae523205d5..916de9ecce 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -2983,5 +2983,18 @@ "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Din hemserver kunde inte nås så du kunde inte loggas in. Vänligen försök igen. Om det här fortsätter, vänligen kontakta administratören för din hemserver.", "Try again": "Försök igen", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Vi bad webbläsaren att komma ihåg vilken hemserver du använder för att logga in, men tyvärr har din webbläsare glömt det. Gå till inloggningssidan och försök igen.", - "We couldn't log you in": "Vi kunde inte logga in dig" + "We couldn't log you in": "Vi kunde inte logga in dig", + "Upgrade to pro": "Uppgradera till pro", + "Minimize dialog": "Minimera dialog", + "Maximize dialog": "Maximera dialog", + "%(hostSignupBrand)s Setup": "inställning av %(hostSignupBrand)s", + "You should know": "Du behöver veta", + "Privacy Policy": "sekretesspolicy", + "Cookie Policy": "kakpolicy", + "Learn more in our , and .": "Läs mer i våran , och .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Om du fortsätter så tillåts inställningsprocessen för %(hostSignupBrand)s att temporärt komma åt din konto för att hämta verifierade e-postadresser. Den här datan lagras inte.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Misslyckades att ansluta till din hemserver. Vänligen stäng den här dialogrutan och försök igen.", + "Abort": "Avbryt", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Är du säker på att du vill avbryta skapande av värden? Processen kan inte fortsättas.", + "Confirm abort of host creation": "Bekräfta avbrytning av värdskapande" } From 4a038ec2f4a1b333c43725e5c194245881a39338 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 19 Feb 2021 01:48:12 +0000 Subject: [PATCH 0206/2651] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index c1fc44dc05..b11ff2274f 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2828,7 +2828,7 @@ "United States": "美國", "United Kingdom": "英國", "%(creator)s created this DM.": "%(creator)s 建立了此直接訊息。", - "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "此聊天適中的訊息為端到端加密。當人們加入,您可以在他們的個人檔案中驗證他們,只要點擊他們的大頭照就可以了。", + "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "此聊天室中的訊息為端到端加密。當人們加入,您可以在他們的個人檔案中驗證他們,只要點擊他們的大頭照就可以了。", "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "此處的訊息為端到端加密。請在他們的個人檔案中驗證 %(displayName)s,只要點擊他們的大頭照就可以了。", "This is the start of .": "這是 的開頭。", "Add a photo, so people can easily spot your room.": "新增圖片,這樣人們就可以輕鬆發現您的聊天室。", @@ -3055,5 +3055,18 @@ "Share your screen": "分享您的畫面", "Recently visited rooms": "最近造訪過的聊天室", "Show line numbers in code blocks": "在程式碼區塊中顯示行號", - "Expand code blocks by default": "預設展開程式碼區塊" + "Expand code blocks by default": "預設展開程式碼區塊", + "Upgrade to pro": "升級到專業版", + "Minimize dialog": "最小化對話框", + "Maximize dialog": "最大化對話框", + "%(hostSignupBrand)s Setup": "%(hostSignupBrand)s 設定", + "You should know": "您應該知道", + "Privacy Policy": "隱私權政策", + "Cookie Policy": "Cookie 政策", + "Learn more in our , and .": "在我們的 取得更多資訊。", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "暫時繼續進行讓 %(hostSignupBrand)s 設定流程可以存取您的帳號來擷取已驗證的電子郵件地址。此資料未儲存。", + "Failed to connect to your homeserver. Please close this dialog and try again.": "無法連線到您的家伺服器。請關閉對話框並再試一次。", + "Abort": "中止", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "您確定您想要中止主機建立嗎?流程將無法繼續。", + "Confirm abort of host creation": "確認中止主機建立" } From 83e1a7a70781c026c62c03dd8f2652125e44da9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 18:13:12 +0100 Subject: [PATCH 0207/2651] Add more button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 4 ++++ src/components/views/elements/ImageView.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index ddc51cf583..bb99454152 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -129,6 +129,10 @@ limitations under the License. mask-image: url('$(res)/img/image-view/download.svg'); } +.mx_ImageView_button_more::before { + mask-image: url('$(res)/img/image-view/more.svg'); +} + .mx_ImageView_button_close { padding-left: 32px; &::before { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 8251af1a5d..cd104cce37 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -295,6 +295,10 @@ export default class ImageView extends React.Component { title={_t("Download")} onClick={ this.onDownloadClick }>
+ Date: Wed, 10 Feb 2021 19:44:20 +0000 Subject: [PATCH 0208/2651] Translated using Weblate (Ukrainian) Currently translated at 53.9% (1490 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index f07bd8b05b..adb830c123 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -1596,5 +1596,6 @@ "Re-request encryption keys from your other sessions.": "Повторно запитати ключі шифрування з інших сеансів.", "Enable encryption?": "Увімкнути шифрування?", "Enable room encryption": "Увімкнути шифрування кімнати", - "Encryption": "Шифрування" + "Encryption": "Шифрування", + "Try again": "Спробувати ще раз" } From 1f538607f474d0f38a0b19549f5ee714f6aee546 Mon Sep 17 00:00:00 2001 From: vejetaryenvampir Date: Wed, 17 Feb 2021 22:42:40 +0000 Subject: [PATCH 0209/2651] Translated using Weblate (Turkish) Currently translated at 83.4% (2307 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/tr/ --- src/i18n/strings/tr.json | 97 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 5cedd8f322..c5316ee2df 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -2279,7 +2279,7 @@ "See %(eventType)s events posted to this room": "Bu odaya gönderilen %(eventType)s türü etkinlikleri gör", "with state key %(stateKey)s": "%(stateKey)s durum anahtarı ile", "Verify all users in a room to ensure it's secure.": "Güvenli olduğuna emin olmak için odadaki tüm kullanıcıları onaylayın.", - "No recent messages by %(user)s found": "", + "No recent messages by %(user)s found": "%(user)s kullanıcısın hiç yeni ileti yok", "Show %(count)s more|one": "%(count)s adet daha fazla göster", "Show %(count)s more|other": "%(count)s adet daha fazla göster", "Activity": "Aktivite", @@ -2424,5 +2424,98 @@ "Add a new server...": "Yeni sunucu ekle...", "Preparing to download logs": "Loglar indirilmeye hazırlanıyor", "Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Hatırlatma:Tarayıcınız desteklenmiyor, deneyiminiz öngörülemiyor.", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Hata ayıklama günlükleri, kullanıcı adınız, ziyaret ettiğiniz oda veya grupların kimlikleri veya takma adları ve diğer kullanıcıların kullanıcı adları dahil olmak üzere uygulama kullanım verilerini içerir. Mesaj içermezler." + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Hata ayıklama günlükleri, kullanıcı adınız, ziyaret ettiğiniz oda veya grupların kimlikleri veya takma adları ve diğer kullanıcıların kullanıcı adları dahil olmak üzere uygulama kullanım verilerini içerir. Mesaj içermezler.", + "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Bir oda için şifreleme bir kez etkinleştirildiğinde geri alınamaz. Şifrelenmiş bir odada gönderilen iletiler yalnızca ve yalnızca odadaki kullanıcılar tarafından görülebilir. Şifrelemeyi etkinleştirmek bir çok bot'un ve köprülemenin doğru çalışmasını etkileyebilir. Şifrelemeyle ilgili daha fazla bilgi edinmek için.", + "Link this email with your account in Settings to receive invites directly in %(brand)s.": "Doğrudan %(brand)s uygulamasından davet isteği almak için bu e-posta adresini Ayarlardan kendi hesabınıza bağlayın.", + "Failed to remove '%(roomName)s' from %(groupId)s": "", + "This client does not support end-to-end encryption.": "Bu istemci uçtan uca şifrelemeyi desteklemiyor.", + "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Bu kullanıcı etkisizleştirmek onu bir daha oturum açmasını engeller.Ek olarak da bulundukları bütün odalardan atılırlar. Bu eylem geri dönüştürülebilir. Bu kullanıcıyı etkisizleştirmek istediğinize emin misiniz?", + "Disinvite this user from community?": "Bu kullanıcının bu topluluğa davetini iptal et?", + "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Çok sayıda ileti için bu biraz sürebilir. Lütfen bu sürede kullandığınız istemciyi yenilemeyin.", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "%(user)s kullanıcısından %(count)s sayıda ileti silmek üzeresiniz. Bu işlem geri döndürülemez. Sürdürmek istiyor musunuz?", + "Remove recent messages by %(user)s": "%(user)s kullanıcısından en son iletileri kaldır", + "Try scrolling up in the timeline to see if there are any earlier ones.": "Daha önceden kalma iletilerin var olup olmadığını kontrol etmek için zaman çizelgesinde yukarı doğru kaydırın.", + "Set my room layout for everyone": "Oda düzenimi herkes için ayarla", + "Yours, or the other users’ internet connection": "Sizin ya da diğer kullanıcıların internet bağlantısı", + "The homeserver the user you’re verifying is connected to": "Doğruladığınız kullanıcının bağlı olduğunu ana sunucu:", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Fazladan güvenlik sağlamak için bu kullanıcıyı cihazlarınızdaki tek kezlik kod ile doğrulayın.", + "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Şifrelenmiş odalarda iletileriniz şifreledir ve yalnızca sizde ve gönderdiğiniz kullanıcılarda iletileri açmak için anahtarlar vardır.", + "Messages in this room are not end-to-end encrypted.": "Bu odadaki iletiler uçtan uca şifreli değildir.", + "Messages in this room are end-to-end encrypted.": "Bu odadaki iletiler uçtan uca şifrelenmiştir.", + "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "İletileriniz şifreledir ve yalnızca sizde ve gönderdiğiniz kullanıcılarda iletileri açmak için anahtarlar vardır.", + "Waiting for %(displayName)s to accept…": "%(displayName)s kullanıcısın onaylaması için bekleniliyor…", + "Waiting for you to accept on your other session…": "Diğer oturumunuzda onaylamanız için bekleniliyor…", + "URL previews are disabled by default for participants in this room.": "URL ön izlemeleri, bu odadaki kullanıcılar için varsayılan olarak devre dışı bıraktırılmıştır.", + "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Adanın alternatif adresini güncellerken bir hata oluştu. Bu eylem, sunucu tarafından izin verilmemiş olabilir ya da geçici bir sorun oluşmuş olabilir.", + "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "Odanın ana adresini güncellerken bir sorun oluştu. Bu eylem, sunucu tarafından izin verilmemiş olabilir ya da geçici bir sorun oluşmuş olabilir.", + "Hint: Begin your message with // to start it with a slash.": "İpucu: İletilerinizi eğik çizgi ile başlatmak için // ile başlayın.", + "You can use /help to list available commands. Did you mean to send this as a message?": "/help yazarak var olan komutları listeleyebilirsiniz. Yoksa bunu bir ileti olarak mı göndermek istemiştiniz?", + "This room is running room version , which this homeserver has marked as unstable.": "Bu oda, oda sürümünü kullanmaktadır ve ana sunucunuz tarafından tutarsız olarak işaretlenmiştir.", + "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Bu odayı güncellerseniz bu oda kapanacak ve yerine aynı adlı, güncellenmiş bir oda geçecek.", + "Favourited": "Beğenilenler", + "Mentions & Keywords": "Değinilmeler & Anahtar Sözcükler", + "Share this email in Settings to receive invites directly in %(brand)s.": "Doğrdan %(brand)s uygulamasından davet isteği almak için Ayarlardan bu e-posta adresini paylaşın.", + "Use an identity server in Settings to receive invites directly in %(brand)s.": "Doğrudan %(brand)s uygulamasından davet isteği almak için Ayarlardan bir kimlik sunucusu belirleyin.", + "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Bu davet, %(roomName)s odasına %(email)s e-posta adresi üzerinden yollanmıştır ve sizinle ilgili değildir", + "Recently visited rooms": "En son ziyaret edilmiş odalar", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Eğer diğer oturumlarınızın bu iletiyi açacak anahtarı yoksa deşifreleyemezsiniz.", + "Discovery options will appear once you have added a phone number above.": "Bulunulabilirlik seçenekleri, yukarıya bir telefon numarası ekleyince ortaya çıkacaktır.", + "Discovery options will appear once you have added an email above.": "Bulunulabilirlik seçenekleri, yukarıya bir e-posta adresi ekleyince ortaya çıkacaktır.", + "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Geçmişi kimin okuyabileceğini değiştirmek yalnızca odadaki yeni iletileri etkiler. Var olan geçmiş değişmeden kalacaktır.", + "To link to this room, please add an address.": "Bu odaya bağlamak için lütfen bir adres ekleyin.", + "Remove messages sent by others": "Diğerleri tarafından gönderilen iletileri kaldır", + "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Odanın güç düzeyi gereksinimlerini değiştirirken bir hata ile karşılaşıldı. Yeterince yetkiniz olduğunuzdan emin olup yeniden deyin.", + "This room isn’t bridging messages to any platforms. Learn more.": "Bu oda, iletileri hiçbir platforma köprülemiyor. Daha fazla bilgi için.", + "This room is bridging messages to the following platforms. Learn more.": "Bu oda, iletileri sözü edilen platformlara köprülüyor. Daha fazla bilgi için.", + "A session's public name is visible to people you communicate with": "Bir oturumun halka açık adı iletişim kurduğunuz kişilerce görülebilir", + "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Aşağıdan oturumlarınızın adlarını düzenleyin veya oturumlarızdan çıkın ya da oturumlarınızı Kullanıcı Profilinden doğrulayın.", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Sunucu yönetinciniz varsayılan olarak odalarda ve doğrudandan iletilerde uçtan uca şifrelemeyi kapadı.", + "Read Marker lifetime (ms)": "Okundu iminin gösterim süresi (ms)", + "Read Marker off-screen lifetime (ms)": "Okundu iminin ekran dışındaki gösterim süresi (ms)", + "Composer": "Yazan", + "Room ID or address of ban list": "Engelleme listesinin oda kimliği ya da adresi", + "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Kişisel engelleme listeniz, ileti almak istemediğiniz kullanıcı veya sunucuları bulundurur. İlk engellemenizde oda listenizde \"My Ban List\" adlı bir oda oluşturulacaktır. Engelleme listesinin yürürlüğünü sürdürmesini istiyorsanız o odada kalın.", + "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Kullanıcıları engelleme, hangi kullanıcıları engelleyeceğini belirleyen kurallar bulunduran bir engelleme listesi kullanılarak gerçekleşir. Bir engelleme listesine abone olmak, o listeden engellenen kullanıcıların veya sunucuların sizden gizlenmesi demektir.", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Görmezden gelmek istediğiniz kullanıcıları ya da sunucuları buraya ekleyin. %(brand)s uygulamasının herhangi bir karakteri eşleştirmesini istiyorsanız yıldız imi kullanın. Örneğin @fobar:*, \"foobar\" adlı kullanıcıların hepsini bütün sunucularda görmezden gelir.", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Eğer GitHub aracılığıyla bir hata bildirdiyseniz hata kayıtları sorunu bulmamızda bize yardımcı olabilir. Hata kayıtları kullanıcı adınızı, daha önceden bulunmuş olduğunuz odaların veya grupların kimliklerini veya takma adlarını ve diğer kullanıcıların adlarını içerir. Hata kayıtları ileti içermez.", + "Please verify the room ID or address and try again.": "Lütfen oda kimliğini ya da adresini doğrulayıp yeniden deneyin.", + "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "%(brand)s uygulamasına yardımcı olmak için buraya tıklayın ya da aşağıdaki tuşları kullanarak bot'umuzla sohbet edin.", + "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Başkaları tarafından e-posta adresi ya da telefon numarası ile bulunabilmek için %(serverName)s kimlik sunucusunun Kullanım Koşullarını kabul edin.", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Parolanız başarıyla değişmiştir. Diğer oturumlarınızda yeniden oturum açmadığınız sürece anlık bildirim almayacaksınız", + "Flair": "Özel Yetenek", + "Appearance Settings only affect this %(brand)s session.": "Dış Görünüş Ayarları yalnızca bu %(brand)s oturumunu etkileyecek.", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Sisteminizde bulunan bir font adı belirtiniz. %(brand)s sizin için onu kullanmaya çalışacak.", + "Invalid theme schema.": "Geçersiz tema taslağı.", + "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Bir kimlik sunucusu kullanmak isteğe bağlıdır. Eğer bir tane kullanmak istemezseniz başkaları tarafından bulunamayabilir ve başkalarını e-posta adresi ya da telefon numarası ile davet edemeyebilirsiniz.", + "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Kimlik sunucunuz ile bağlantıyı keserseniz başkaları tarafından bulunamayabilir ve başkalarını e-posta adresi ya da telefon numarası ile davet edemeyebilirsiniz.", + "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Şu anda herhangi bir kimlik sunucusu kullanmıyorsunuz. Başkalarını bulmak ve başkaları tarafından bulunabilmek için aşağıya bir kimlik sunucusu ekleyin.", + "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Eğer kimlik sunucusunu kullanarak başkalarını bulmak ve başkalarını tarafından bulunabilmek istemiyorsanız aşağıya bir başka kimlik sunucusu giriniz.", + "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Şu anda kimlik sunucusunu kullanarak başkalarını buluyorsunuz ve başkalarını tarafından bulunabiliyorsunuz. Aşağıdan kimlik sunucunuzu değiştirebilirsiniz.", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "kimlik sunucunuza erişimi engelleyen herhangi bir eklenti (Privacy Badger gibi) için tarayıcınızı kontrol ediniz", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Bağlantınızı kesmeden önce kişisel verilerinizi kimlik sunucusundan silmelisiniz. Ne yazık ki kimlik sunucusu şu anda çevrim dışı ya da bir nedenden ötürü erişilemiyor.", + "Disconnect from the identity server and connect to instead?": " kimlik sunucusundan bağlantı kesilip kimlik sunucusuna bağlanılsın mı?", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Olası bir oturuma erişememe durumunu önlemek için şifreleme anahtarlarınızı hesap verilerinizle yedekleyin. Anahtarlarınız eşsiz bir güvenlik anahtarı ile güvenlenecektir.", + "well formed": "uygun biçimlendirilmiş", + "Master private key:": "Ana gizli anahtar", + "Cross-signing is not set up.": "Çapraz imzalama ayarlanmamış.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Hesabınız gizli belleğinde çapraz imzalama kimliği barındırıyor ancak bu oturumda daha kullanılmış değil.", + "Cross-signing is ready for use.": "Çapraz imzalama zaten kullanılıyor.", + "Channel: ": "Kanal: ", + "Workspace: ": "Çalışma alanı: ", + "Unable to look up phone number": "Telefon numarasına bakılamadı", + "There was an error looking up the phone number": "Telefon numarasına bakarken bir hata oluştu", + "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "", + "Use Ctrl + F to search": "Arama yapmak için Ctrl + F", + "Use Command + F to search": "Arama yapmak için Command + F", + "Show line numbers in code blocks": "Kod bloklarında satır sayısını göster", + "Expand code blocks by default": "Varsayılan olarak kod bloklarını genişlet", + "Show stickers button": "Çıkartma tuşunu göster", + "Use app": "Uygulamayı kullan", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web arayüzü mobil üzerinde daha tamamlanmadı. En yeni özellikler ve daha iyi bir deneyim için özgür yazılım mobil uygulamamızı kullanın.", + "Use app for a better experience": "Daha iyi bir deneyim için uygulamayı kullanın", + "%(senderName)s has updated the widget layout": "%(senderName)s widget düzenini güncelledi", + "Remain on your screen while running": "Uygulama çalışırken lütfen başka uygulamaya geçmeyin", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Ana sunucunuza erişilemedi ve oturum açmanıza izin verilmedi. Lütfen yeniden deneyin. Eğer hata devam ederse ana sunucunuzun yöneticisine bildirin.", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Ana sunucunuz oturum açma isteğinizi reddetti. Bunun nedeni bağlantı yavaşlığı olabilir. Lütfen yeniden deneyin. Eğer hata devam ederse ana sunucunuzun yöneticisine bildirin.", + "Try again": "Yeniden deneyin" } From 9efebc66bf3948012f39c10400761b2ace18f2d7 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Mon, 22 Feb 2021 18:44:54 +0000 Subject: [PATCH 0210/2651] Translated using Weblate (Esperanto) Currently translated at 98.7% (2729 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 161 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 748d265c89..3f99a68187 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -370,10 +370,10 @@ "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)saliĝis kaj foriris", "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s%(count)s-foje aliĝis kaj foriris", "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)saliĝis kaj foriris", - "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s%(count)s-foje foriris kaj realiĝis", - "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sforiris kaj realiĝis", - "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s%(count)s-foje foriris kaj realiĝis", - "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sforiris kaj realiĝis", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s%(count)s-foje foriris kaj re-aliĝis", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s foriris kaj re-aliĝis", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s %(count)s-foje foriris kaj re-aliĝis", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s foriris kaj re-aliĝis", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s%(count)s-foje rifuzis inviton", "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)srifuzis inviton", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s%(count)s-foje rifuzis inviton", @@ -1081,10 +1081,10 @@ "Account management": "Administrado de kontoj", "This event could not be displayed": "Ĉi tiu okazo ne povis montriĝi", "Please install Chrome, Firefox, or Safari for the best experience.": "Bonvolu instali foliumilon Chrome, Firefox, aŭ Safari, por la plej bona sperto.", - "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Vi estas administranto de tiu ĉi komunumo. Sen invito de alia administranto vi ne povos realiĝi.", + "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Vi estas administranto de tiu ĉi komunumo. Sen invito de alia administranto vi ne povos re-aliĝi.", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Ŝanĝoj al viaj komunumaj nomo kaj profilbildo eble ne montriĝos al aliaj uzantoj ĝis 30 minutoj.", "Who can join this community?": "Kiu povas aliĝi al tiu ĉi komunumo?", - "This room is not public. You will not be able to rejoin without an invite.": "Ĉi tiu ĉambro ne estas publika. Vi ne povos realiĝi sen invito.", + "This room is not public. You will not be able to rejoin without an invite.": "Ĉi tiu ĉambro ne estas publika. Vi ne povos re-aliĝi sen invito.", "Can't leave Server Notices room": "Ne eblas eliri el ĉambro « Server Notices »", "Revoke invite": "Nuligi inviton", "Invited by %(sender)s": "Invitita de %(sender)s", @@ -2859,5 +2859,152 @@ "Call failed because webcam or microphone could not be accessed. Check that:": "Voko malsukcesis, ĉar retfilmilo aŭ mikrofono ne povis uziĝi. Kontrolu, ke:", "Unable to access webcam / microphone": "Ne povas aliri retfilmilon / mikrofonon", "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "Voko malsukcesis, ĉar mikrofono ne estis uzebla. Kontrolu, ĉu mikrofono estas ĝuste konektita kaj agordita.", - "Unable to access microphone": "Ne povas aliri mikrofonon" + "Unable to access microphone": "Ne povas aliri mikrofonon", + "Invite by email": "Inviti per retpoŝto", + "Minimize dialog": "Minimumigi interagujon", + "Maximize dialog": "Maksimumigi interagujon", + "Privacy Policy": "Politiko pri privateco", + "Cookie Policy": "Politiko pri kuketoj", + "There was an error finding this widget.": "Eraris serĉado de tiu ĉi fenestraĵo.", + "Active Widgets": "Aktivaj fenestraĵoj", + "Reason (optional)": "Kialo (malnepra)", + "Continue with %(provider)s": "Daŭrigi per %(provider)s", + "Homeserver": "Hejmservilo", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Vi povas uzi la proprajn elekteblojn de servilo por saluti aliajn servilojn de Matrix, specifigante la URL-on de alia hejmservilo. Tio ebligas uzi Elementon kun jama konto de Matrix ĉe alia hejmservilo.", + "Server Options": "Elektebloj de servilo", + "Windows": "Fenestroj", + "Screens": "Ekranoj", + "Share your screen": "Vidigu vian ekranon", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Sekure kaŝmemori ĉifritajn mesaĝojn loke por ke ili aperu inter serĉrezultoj, uzante %(size)s por deponi mesaĝojn el %(rooms)s ĉambroj.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Sekure kaŝmemori ĉifritajn mesaĝojn loke por ke ili aperu inter serĉrezultoj, uzante %(size)s por deponi mesaĝojn el %(rooms)s ĉambroj.", + "Channel: ": "Kanalo: ", + "Remain on your screen while running": "Resti sur via ekrano rulante", + "Remain on your screen when viewing another room, when running": "Resti sur via ekrano rulante, dum rigardo al alia ĉambro", + "Go to Home View": "Iri al ĉefpaĝo", + "Search (must be enabled)": "Serĉi (devas esti ŝaltita)", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Tiu ĉi salutaĵo trovis, ke viaj Sekureca frazo kaj ŝlosilo por Sekuraj mesaĝoj foriĝis.", + "A new Security Phrase and key for Secure Messages have been detected.": "Novaj Sekureca frazo kaj ŝlosilo por Sekuraj mesaĝoj troviĝis.", + "Make a copy of your Security Key": "Faru kopion de via Sekureca ŝlosilo", + "Confirm your Security Phrase": "Konfirmu vian Sekurecan frazon", + "Secure your backup with a Security Phrase": "Sekurigu vian savkopion per Sekureca frazo", + "Your Security Key is in your Downloads folder.": "Via Sekureca ŝlosilo estas en via dosierujo kun Elŝutoj.", + "Your Security Key has been copied to your clipboard, paste it to:": "Via Sekureca ŝlosilo kopiiĝis al via tondujo, algluu ĝin al:", + "Your Security Key": "Via Sekureca ŝlosilo", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Via Sekureca ŝlosilo estas speco de asekuro – vi povas uzi ĝin por rehavi aliron al viaj ĉifritaj mesaĝoj, se vi forgesas vian Sekurecan frazon.", + "Repeat your Security Phrase...": "Ripetu vian Sekurecan frazon…", + "Please enter your Security Phrase a second time to confirm.": "Bonvolu enigi vian Sekurecan frazon je dua fojo por konfirmi.", + "Set up with a Security Key": "Agordi per Sekureca ŝlosilo", + "Great! This Security Phrase looks strong enough.": "Bonege! La Sekureca frazo ŝajnas sufiĉe forta.", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Ni konservos ĉifritan kopion de viaj ŝlosiloj en nia servilo. Sekurigu vian savkopion per Sekureca frazo.", + "Use Security Key": "Uzi Sekurecan ŝlosilon", + "Use Security Key or Phrase": "Uzu Sekurecan ŝlosilon aŭ frazon", + "Decide where your account is hosted": "Decidu, kie via konto gastiĝos", + "Host account on": "Gastigi konton ĉe", + "Already have an account? Sign in here": "Ĉu vi jam havas konton? Salutu tie ĉi", + "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s aŭ %(usernamePassword)s", + "Continue with %(ssoButtons)s": "Daŭrigi per %(ssoButtons)s", + "That username already exists, please try another.": "Tiu uzantonomo jam ekzistas, bonvolu provi alian.", + "New? Create account": "Ĉu vi novas? Kreu konton", + "There was a problem communicating with the homeserver, please try again later.": "Eraris komunikado kun la hejmservilo, bonvolu reprovi poste.", + "New here? Create an account": "Ĉu vi novas? Kreu konton", + "Got an account? Sign in": "Ĉu vi havas konton? Salutu", + "Filter rooms and people": "Filtri ĉambrojn kaj personojn", + "You have no visible notifications.": "Vi havas neniujn videblajn sciigojn.", + "Upgrade to pro": "Gradaltigu al profesionala versio", + "Now, let's help you get started": "Nun, ni helpos al vi komenci", + "Welcome %(name)s": "Bonvenu, %(name)s", + "Add a photo so people know it's you.": "Aldonu foton, por ke oni vin rekonu.", + "Great, that'll help people know it's you": "Bonege, tio helpos al aliuloj scii, ke temas pri vi", + "Use email to optionally be discoverable by existing contacts.": "Uzu retpoŝtadreson por laŭplaĉe esti trovebla de jamaj kontaktoj.", + "Use email or phone to optionally be discoverable by existing contacts.": "Uzu retpoŝtadreson aŭ telefonnumeron por laŭplaĉe esti trovebla de jamaj kontaktoj.", + "Add an email to be able to reset your password.": "Aldonu retpoŝtadreson por ebligi rehavon de via pasvorto.", + "Forgot password?": "Ĉu forgesis pasvorton?", + "That phone number doesn't look quite right, please check and try again": "Tiu telefonnumero ne ŝajnas ĝusta, bonvolu kontroli kaj reprovi", + "Enter phone number": "Enigu telefonnumeron", + "Enter email address": "Enigu retpoŝtadreson", + "Something went wrong in confirming your identity. Cancel and try again.": "Io misokazis dum konfirmado de via identeco. Nuligu kaj reprovu.", + "Open the link in the email to continue registration.": "Por daŭrigi la registriĝon, malfermu la ligilon senditan en la retletero.", + "A confirmation email has been sent to %(emailAddress)s": "Konfirma retletero sendiĝis al %(emailAddress)s", + "Hold": "Paŭzigi", + "Resume": "Daŭrigi", + "If you've forgotten your Security Key you can ": "Se vi forgesis vian Sekurecan ŝlosilon, vi povas ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Aliru vian historion de sekuraj mesaĝoj kaj agordu sekurajn mesaĝojn per enigo de via Sekureca ŝlosio.", + "Not a valid Security Key": "Tio ne estas valida Sekureca ŝlosilo", + "This looks like a valid Security Key!": "Tio ĉi ŝajnas esti valida Sekureca ŝlosilo!", + "Enter Security Key": "Enigu Sekurecan ŝlosilon", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Se vi forgesis vian Sekurecan frazon, vi povas uzi vian Sekurecan ŝlosilonagordi novajn elekteblojn de rehavo", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Aliru vian historion de sekuraj mesaĝoj kaj agordu sekurigitajn mesaĝojn per enigo de via Sekureca frazo.", + "Enter Security Phrase": "Enigu Sekurecan frazon", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "Ne povis malĉifri savkopion per ĉi tiu Sekureca frazo: bonvolu kontroli, ĉu vi enigis la ĝustan Sekurecan frazon.", + "Incorrect Security Phrase": "Malĝusta Sekureca frazo", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "Ne povis malĉifri savkopion per ĉi tiu Sekureca ŝlosilo: bonvolu kontroli, ĉu vi enigis la ĝustan Sekurecan ŝlosilon.", + "Security Key mismatch": "Malakordo de Sekureca ŝlosilo", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Ne povas akiri sekretandeponejon. Bonvolu kontroli, ĉu vi enigis la ĝustan Sekurecan frazon.", + "Invalid Security Key": "Nevalida Sekureca ŝlosilo", + "Wrong Security Key": "Malĝusta Sekureca ŝlosilo", + "Remember this": "Memoru ĉi tion", + "The widget will verify your user ID, but won't be able to perform actions for you:": "Ĉi tiu fenestraĵo kontrolos vian identigilon de uzanto, sed ne povos fari agojn por vi:", + "Allow this widget to verify your identity": "Permesu al ĉi tiu fenestraĵo kontroli vian identecon", + "Decline All": "Rifuzi ĉion", + "Approve": "Aprobi", + "This widget would like to:": "Ĉi tiu fenestraĵo volas:", + "Approve widget permissions": "Aprobi rajtojn de fenestraĵo", + "About homeservers": "Pri hejmserviloj", + "Learn more": "Ekscii plion", + "Use your preferred Matrix homeserver if you have one, or host your own.": "Uzu vian preferatan hejmservilon de Matrix se vi havas iun, aŭ gastigu vian propran.", + "Other homeserver": "Alia hejmservilo", + "We call the places where you can host your account ‘homeservers’.": "La lokojn, kie via konto povas gastiĝi, ni nomas «hejmserviloj».", + "Sign into your homeserver": "Salutu vian hejmservilon", + "Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org estas la plej granda publika hejmservilo en la mondo, kaj estas do bona loko por multaj.", + "Specify a homeserver": "Specifu hejmservilon", + "%(hostSignupBrand)s Setup": "Agordoj de %(hostSignupBrand)s", + "You should know": "Vi sciu", + "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Mesaĝoj en ĉi tiu ĉambro estas tutvoje ĉifrataj. Kiam oni aliĝas, vi povas kontroli ĝin per ĝia profilo; simple tuŝetu ĝian profilbildon.", + "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Mesaĝoj ĉi tie estas tutvoje ĉifritaj. Kontrolu uzanton %(displayName)s per ĝia profilo – tuŝetu ĝian profilbildon.", + "Role": "Rolo", + "Use the + to make a new room or explore existing ones below": "Uzu la simbolon + por krei novan ĉambron aŭ esplori jam ekzistantajn sube", + "Start a new chat": "Komenci novan babilon", + "Start a Conversation": "Komenci interparolon", + "Recently visited rooms": "Freŝe vizititiaj ĉambroj", + "This is the start of .": "Jen la komenco de .", + "Add a photo, so people can easily spot your room.": "Aldonu foton, por ke oni facile trovu vian ĉambron.", + "%(displayName)s created this room.": "%(displayName)s kreis ĉi tiun ĉambron.", + "You created this room.": "Vi kreis ĉi tiun ĉambron.", + "Add a topic to help people know what it is about.": "Aldonu temon, por ke oni sciu, pri kio temas.", + "Topic: %(topic)s ": "Temo: %(topic)s ", + "Topic: %(topic)s (edit)": "Temo: %(topic)s (redakti)", + "This is the beginning of your direct message history with .": "Jen la komenco de historio de viaj rektaj mesaĝoj kun .", + "Only the two of you are in this conversation, unless either of you invites anyone to join.": "Nur vi du partoprenas ĉi tiun interparolon, se neniu el vi invitos aliulon.", + "There was an error looking up the phone number": "Eraris trovado de la telefonnumero", + "Unable to look up phone number": "Ne povas trovi telefonnumeron", + "sends snowfall": "sendas neĝadon", + "Sends the given message with snowfall": "Sendas la mesaĝon kun neĝado", + "sends fireworks": "sendas artfajraĵon", + "Sends the given message with fireworks": "Sendas la mesaĝon kun artfajraĵo", + "sends confetti": "sendas konfetojn", + "Sends the given message with confetti": "Sendas la mesaĝon kun konfetoj", + "Show chat effects": "Montri efektojn de babilujo", + "Show line numbers in code blocks": "Montri numerojn de linioj en kodujoj", + "Expand code blocks by default": "Implicite etendi kodujojn", + "Show stickers button": "Butono por montri glumarkojn", + "Use app": "Uzu aplikaĵon", + "Use app for a better experience": "Uzu aplikaĵon por pli bona sperto", + "Don't miss a reply": "Ne preterpasu respondon", + "See emotes posted to your active room": "Vidi mienojn afiŝitajn al via aktiva ĉambro", + "See emotes posted to this room": "Vidi mienojn afiŝitajn al ĉi tiu ĉambro", + "Send emotes as you in your active room": "Sendi mienon kiel vi en via aktiva ĉambro", + "Send emotes as you in this room": "Sendi mienon kiel vi en ĉi tiu ĉambro", + "See text messages posted to your active room": "Vidi tekstajn mesaĝojn afiŝitajn al via aktiva ĉambro", + "See text messages posted to this room": "Vidi tekstajn mesaĝojn afiŝitajn al ĉi tiu ĉambro", + "Send text messages as you in your active room": "Sendi tekstajn mesaĝojn kiel vi en via aktiva ĉambro", + "Send text messages as you in this room": "Sendi tekstajn mesaĝojn kiel vi en ĉi tiu ĉambro", + "Change which room, message, or user you're viewing": "Ŝanĝu, kiun ĉambron, mesaĝon, aŭ uzanton vi rigardas", + "%(senderName)s has updated the widget layout": "%(senderName)s ĝisdatigis la aranĝon de la fenestrajoj", + "Converts the DM to a room": "Igas la ĉambron nerekta", + "Converts the room to a DM": "Igas la ĉambron rekta", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Via hejmservilo rifuzis vian saluton. Eble tio okazis, ĉar ĝi simple daŭris tro longe. Bonvolu reprovi. Se tio daŭros, bonvolu kontakti la administranton de via hejmservilo.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Via hejmservilo estis neatingebla kaj ne povis vin salutigi. Bonvolu reprovi. Se tio daŭros, bonvolu kontakti la administranton de via hejmservilo.", + "Try again": "Reprovu", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Ni petis la foliumilon memori, kiun hejmservilon vi uzas por saluti, sed domaĝe, via foliumilo forgesis. Iru al la saluta paĝo kaj reprovu.", + "We couldn't log you in": "Ni ne povis salutigi vin" } From 0ae194981a18aa6806d78b6eaa4ed155e726bd6c Mon Sep 17 00:00:00 2001 From: random Date: Mon, 15 Feb 2021 10:54:08 +0000 Subject: [PATCH 0211/2651] Translated using Weblate (Italian) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index a280709430..2764863e77 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -3045,5 +3045,25 @@ "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Il tuo homeserver è irraggiungibile e non ha potuto farti accedere. Riprova. Se il problema persiste, contatta l'amministratore dell'homeserver.", "Try again": "Riprova", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Abbiamo chiesto al browser di ricordare quale homeserver usi per farti accedere, ma sfortunatamente l'ha dimenticato. Vai alla pagina di accesso e riprova.", - "We couldn't log you in": "Non abbiamo potuto farti accedere" + "We couldn't log you in": "Non abbiamo potuto farti accedere", + "Upgrade to pro": "Aggiorna a Pro", + "Minimize dialog": "Riduci finestra", + "Maximize dialog": "Espandi finestra", + "%(hostSignupBrand)s Setup": "Configurazione di %(hostSignupBrand)s", + "You should know": "Dovresti sapere", + "Privacy Policy": "Informativa sulla privacy", + "Cookie Policy": "Informativa sui cookie", + "Learn more in our , and .": "Maggiori informazioni nella nostra , e .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Continuando permetti temporaneamente al processo di configurazione di %(hostSignupBrand)s di accedere al tuo account per rilevare gli indirizzi email verificati. Questi dati non vengono memorizzati.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Connessione al tuo homeserver fallita. Chiudi questo messaggio e riprova.", + "Abort": "Annulla", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Vuoi veramente annullare la creazione dell'host? Il processo non può essere continuato.", + "Confirm abort of host creation": "Conferma annullamento creazione host", + "Windows": "Finestre", + "Screens": "Schermi", + "Share your screen": "Condividi lo schermo", + "Recently visited rooms": "Stanze visitate di recente", + "Show line numbers in code blocks": "Mostra numeri di riga nei blocchi di codice", + "Expand code blocks by default": "Espandi blocchi di codice in modo predefinito", + "Show stickers button": "Mostra pulsante adesivi" } From dbae13324c1ae9ba66b13e1b26aa16cf5acb4c9b Mon Sep 17 00:00:00 2001 From: Andrejs Date: Thu, 11 Feb 2021 20:24:53 +0000 Subject: [PATCH 0212/2651] Translated using Weblate (Latvian) Currently translated at 47.7% (1321 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index a05bb81544..d294b38d82 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -166,7 +166,7 @@ "No results": "Nav rezultātu", "No users have specific privileges in this room": "Šajā istabā nav lietotāju ar īpašām privilēģijām", "OK": "Labi", - "olm version:": "Olm versija:", + "olm version:": "olm versija:", "Only people who have been invited": "Vienīgi uzaicināti cilvēki", "Operation failed": "Darbība neizdevās", "Password": "Parole", @@ -306,7 +306,7 @@ "Tue": "O.", "Wed": "T.", "Thu": "C.", - "Fri": "P.", + "Fri": "Pk.", "Sat": "S.", "Jan": "Jan.", "Feb": "Feb.", @@ -344,7 +344,7 @@ "Import room keys": "Importēt istabas atslēgas", "File to import": "Importējamais fails", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība ļauj Tev uz lokālo failu eksportēt atslēgas priekš tām ziņām, kuras Tu saņēmi šifrētās istabās. Tu varēsi importēt šo failu citā Matrix klientā, lai tajā būtu iespējams lasīt šīs ziņas atšifrētas.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētā datne ļaus ikvienam, kurš to spēj to nolasīt, atšifrēt jebkuras jūsu šifrētās ziņas. Tādēļ ievērojiet piesardzību un glabājiet šo datni drošā vietā. Lai palīdzētu to nodrošināt, zemāk ievadiet frāzveida paroli eksportējamo datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu frāzveida paroli.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails ļaus ikvienam, kurš to spēj to nolasīt, atšifrēt jebkuras jūsu šifrētās ziņas. Tādēļ ievērojiet piesardzību un glabājiet šo failu drošā vietā. Lai palīdzētu to nodrošināt, zemāk ievadiet frāzveida paroli eksportējamo datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu frāzveida paroli.", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļaus Tev importēt šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no cita Matrix klienta. Tas ļaus Tev atšifrēt čata vēsturi.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar frāzveida paroli. Tā ir jāievada šeit, lai atšifrētu failu.", "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", @@ -361,7 +361,7 @@ "Please check your email to continue registration.": "Lūdzu pārbaudi savu epastu lai turpinātu reģistrāciju.", "Token incorrect": "Nepareizs autentifikācijas tokens", "Please enter the code it contains:": "Lūdzu, ievadiet tajā ietverto kodu:", - "powered by Matrix": "Tiek darbināta ar Matrix", + "powered by Matrix": "tiek darbināta ar Matrix", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ja Tu nenorādīsi epasta adresi, tev nebūs iespējams izmantot paroles atiestatīšanu. Vai to vēlies?", "Error decrypting audio": "Kļūda atšifrējot audio", "Error decrypting image": "Kļūda atšifrējot attēlu", @@ -654,7 +654,7 @@ "Uploading report": "Augšuplādē atskaiti", "Sunday": "Svētdiena", "Notification targets": "Paziņojumu adresāti", - "Today": "šodien", + "Today": "Šodien", "You are not receiving desktop notifications": "Darbvirsmas paziņojumi netiek saņemti", "Friday": "Piektdiena", "Update": "Atjaunināt", @@ -976,7 +976,7 @@ "Forgot password?": "Aizmirsi paroli?", "No homeserver URL provided": "Nav iestatīts bāzes servera URL", "Cannot reach homeserver": "Neizdodas savienoties ar bāzes serveri", - "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Datne '%(fileName)s pārsniedz augšupielādējamas datnes izmēra limitu šajā bāzes serverī", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Fails '%(fileName)s pārsniedz augšupielādējama faila izmēra limitu šajā bāzes serverī", "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Lūdzu, jautājiet sava bāzes servera administratoram (%(homeserverDomain)s) sakonfigurēt TURN serveri, lai zvani strādātu stabili.", "Join millions for free on the largest public server": "Pievienojieties bez maksas miljoniem lietotāju lielākajā publiskajā serverī", "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Jūs varat pielāgot servera parametrus, lai pierakstītos citos Matrix bāzes serveros, norādot atbilstošu bāzes servera URL. Tas ļauj jums izmantot Element ar eksistējošu Matrix kontu uz cita bāzes servera.", @@ -1185,7 +1185,7 @@ "Room Settings - %(roomName)s": "Istabas iestatījumi - %(roomName)s", "Room settings": "Istabas iestatījumi", "Share room": "Dalīties ar istabu", - "Show files": "Rādīt datnes", + "Show files": "Rādīt failus", "Help & About": "Palīdzība un par lietotni", "About homeservers": "Par bāzes serveriem", "About": "Detaļas", From 489d341d041fa65b696b18a41bc9d75947eaef57 Mon Sep 17 00:00:00 2001 From: Kaede Date: Mon, 22 Feb 2021 00:28:34 +0000 Subject: [PATCH 0213/2651] Translated using Weblate (Japanese) Currently translated at 50.5% (1398 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 215921704d..bab9d94935 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -393,7 +393,7 @@ "%(senderName)s sent a video": "%(senderName)s が動画を送信しました", "%(senderName)s uploaded a file": "%(senderName)s がファイルをアップロードしました", "Options": "オプション", - "Key request sent.": "キーリクエストが送信されました。", + "Key request sent.": "鍵リクエストが送信されました。", "Please select the destination room for this message": "このメッセージを送り先部屋を選択してください", "Disinvite": "招待拒否", "Kick": "追放する", @@ -825,8 +825,8 @@ "Account": "アカウント", "Access Token:": "アクセストークン:", "click to reveal": "クリックすると表示されます", - "Homeserver is": "ホームサーバーは", - "Identity Server is": "アイデンティティ・サーバー", + "Homeserver is": "ホームサーバー:", + "Identity Server is": "ID サーバー:", "%(brand)s version:": "%(brand)s のバージョン:", "olm version:": "olm のバージョン:", "Failed to send email": "メールを送信できませんでした", @@ -1526,5 +1526,12 @@ "Please view existing bugs on Github first. No match? Start a new one.": "まず、Github で既知のバグを確認してください。また掲載されていない新しいバグを発見した場合は報告してください。", "Report a bug": "バグの報告", "Update %(brand)s": "%(brand)s の更新", - "New version of %(brand)s is available": "%(brand)s の新バージョンが利用可能です" + "New version of %(brand)s is available": "%(brand)s の新バージョンが利用可能です", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "あなたの他のセッションがこのメッセージの鍵を持っていない場合、このメッセージを復号することはできません。", + "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "鍵共有リクエストは自動的にあなたの他のセッションに送信されます。他のセッションで鍵共有リクエストを拒否または却下した場合は、ここをクリックしてこのセッションの鍵を再度リクエストしてください。", + "Your key share request has been sent - please check your other sessions for key share requests.": "鍵共有リクエストが送信されました。あなたの他のセッションで鍵共有リクエストをご確認ください。", + "Re-request encryption keys from your other sessions.": "あなたの他のセッションに暗号鍵を再リクエストする。", + "Block anyone not part of %(serverName)s from ever joining this room.": "%(serverName)s 以外からの参加をブロック", + "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "プライベートな部屋は招待者のみが参加できます。公開された部屋は誰でも検索・参加できます。", + "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Matrix 関連のセキュリティ問題を報告するには、Matrix.org の Security Disclosure Policy をご覧ください。" } From ba12c274ce88bdb52273d3ff0144e0a7237df6de Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Thu, 18 Feb 2021 21:41:40 +0000 Subject: [PATCH 0214/2651] Translated using Weblate (Czech) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 864c6208fa..3ee9c73399 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -771,7 +771,7 @@ "System Alerts": "Systémová varování", "Muted Users": "Umlčení uživatelé", "Only room administrators will see this warning": "Toto varování uvidí jen správci místnosti", - "You don't currently have any stickerpacks enabled": "Momentálně nemáte aktívní žádné balíčky s nálepkami", + "You don't currently have any stickerpacks enabled": "Momentálně nemáte aktivní žádné balíčky s nálepkami", "Stickerpack": "Balíček s nálepkami", "Hide Stickers": "Skrýt nálepky", "Show Stickers": "Zobrazit nálepky", @@ -1589,10 +1589,10 @@ "Custom (%(level)s)": "Vlastní (%(level)s)", "Error upgrading room": "Chyba při upgrade místnosti", "Double check that your server supports the room version chosen and try again.": "Zkontrolujte, že váš server opravdu podporuje zvolenou verzi místnosti.", - "%(senderName)s placed a voice call.": "%(senderName)s spustil hovor.", - "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s spustil hovor. (není podporováno tímto prohlížečem)", - "%(senderName)s placed a video call.": "%(senderName)s spustil videohovor.", - "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s spustil videohovor. (není podporováno tímto prohlížečem)", + "%(senderName)s placed a voice call.": "%(senderName)s zahájil(a) hovor.", + "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s zahájil(a) hovor. (není podporováno tímto prohlížečem)", + "%(senderName)s placed a video call.": "%(senderName)s zahájil(a) videohovor.", + "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s zahájil(a) videohovor. (není podporováno tímto prohlížečem)", "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s odstranil(a) pravidlo blokující uživatele odpovídající %(glob)s", "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s odstranil pravidlo blokující místnosti odpovídající %(glob)s", "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s odstranil pravidlo blokující servery odpovídající %(glob)s", @@ -2295,7 +2295,7 @@ "Attach files from chat or just drag and drop them anywhere in a room.": "Připojte soubory z chatu nebo je jednoduše přetáhněte kamkoli do místnosti.", "No files visible in this room": "V této místnosti nejsou viditelné žádné soubory", "Show files": "Zobrazit soubory", - "%(count)s people|other": "%(count)s lidí", + "%(count)s people|other": "%(count)s osob", "About": "O", "You’re all caught up": "Vše vyřízeno", "You have no visible notifications in this room.": "V této místnosti nemáte žádná viditelná oznámení.", @@ -2356,7 +2356,7 @@ "delete the address.": "smazat adresu.", "Delete the room address %(alias)s and remove %(name)s from the directory?": "Smazat adresu místnosti %(alias)s a odebrat %(name)s z adresáře?", "Self-verification request": "Požadavek na sebeověření", - "%(creator)s created this DM.": "%(creator)s vytvořil tuto přímou zprávu.", + "%(creator)s created this DM.": "%(creator)s vytvořil(a) tuto přímou zprávu.", "You do not have permission to create rooms in this community.": "Nemáte oprávnění k vytváření místností v této skupině.", "Cannot create rooms in this community": "V této skupině nelze vytvořit místnosti", "Great, that'll help people know it's you": "Skvělé, to pomůže lidem zjistit, že jste to vy", @@ -2644,7 +2644,7 @@ "Enter name": "Zadejte jméno", "Ignored attempt to disable encryption": "Ignorovaný pokus o deaktivaci šifrování", "Show chat effects": "Zobrazit efekty chatu", - "%(count)s people|one": "%(count)s člověk", + "%(count)s people|one": "%(count)s osoba", "Takes the call in the current room off hold": "Zruší podržení hovoru v aktuální místnosti", "Places the call in the current room on hold": "Podrží hovor v aktuální místnosti", "Zimbabwe": "Zimbabwe", From 997e9cc6b9932738cc9942171ee30d55cbfd6c51 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Mon, 15 Feb 2021 19:57:00 +0000 Subject: [PATCH 0215/2651] Translated using Weblate (Finnish) Currently translated at 94.8% (2621 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 46 +++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 1c518a681e..74fd5f5a9a 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -411,7 +411,7 @@ "Unban this user?": "Poista tämän käyttäjän porttikielto?", "Ban this user?": "Anna porttikielto tälle käyttäjälle?", "Unignore": "Huomioi käyttäjä jälleen", - "Ignore": "Jätä käyttäjä huomioimatta", + "Ignore": "Sivuuta", "Jump to read receipt": "Hyppää lukukuittaukseen", "Mention": "Mainitse", "Invite": "Kutsu", @@ -512,7 +512,7 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Huomaa että olet kirjautumassa palvelimelle %(hs)s, etkä palvelimelle matrix.org.", "Upload an avatar:": "Lataa profiilikuva:", "Deops user with given id": "Poistaa tunnuksen mukaiselta käyttäjältä ylläpito-oikeudet", - "Ignores a user, hiding their messages from you": "Jättää käyttäjän huomioimatta, jotta hänen viestejään ei näytetä sinulle", + "Ignores a user, hiding their messages from you": "Sivuuttaa käyttäjän, eli hänen viestejään ei näytetä sinulle", "Stops ignoring a user, showing their messages going forward": "Lopettaa käyttäjän huomiotta jättämisen, jotta hänen viestinsä näytetään sinulle", "Notify the whole room": "Ilmoita koko huoneelle", "Room Notification": "Huoneilmoitus", @@ -521,7 +521,7 @@ "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s %(day)s. %(monthName)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s %(day)s. %(monthName)s %(fullYear)s %(time)s", - "Ignored user": "Estetty käyttäjä", + "Ignored user": "Sivuutettu käyttäjä", "Unignored user": "Sallittu käyttäjä", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s tasolta %(fromPowerLevel)s tasolle %(toPowerLevel)s", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s muutti %(powerLevelDiffText)s:n oikeustasoa.", @@ -1047,7 +1047,7 @@ "Bug reporting": "Virheiden raportointi", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Jos olet ilmoittanut virheestä Githubin kautta, debug-lokit voivat auttaa meitä ongelman jäljittämisessä. Debug-lokit sisältävät sovelluksen käyttödataa sisältäen käyttäjätunnuksen, vierailemiesi huoneiden tai ryhmien tunnukset tai aliakset ja muiden käyttäjien käyttäjätunnukset. Debug-lokit eivät sisällä viestejä.", "Autocomplete delay (ms)": "Automaattisen täydennyksen viive (ms)", - "Ignored users": "Hiljennetyt käyttäjät", + "Ignored users": "Sivuutetut käyttäjät", "Bulk options": "Massatoimintoasetukset", "Key backup": "Avainvarmuuskopio", "Missing media permissions, click the button below to request.": "Mediaoikeuksia puuttuu. Klikkaa painikkeesta pyytääksesi oikeuksia.", @@ -1591,7 +1591,7 @@ "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Voit käyttää identiteettipalvelinta lähettääksesi sähköpostikutsuja. Klikkaa Jatka käyttääksesi oletuspalvelinta (%(defaultIdentityServerName)s) tai syötä eri palvelin asetuksissa.", "Use an identity server to invite by email. Manage in Settings.": "Voit käyttää identiteettipalvelinta sähköpostikutsujen lähettämiseen.", "Multiple integration managers": "Useita integraatiolähteitä", - "Try out new ways to ignore people (experimental)": "Kokeile uusia tapoja käyttäjien huomiotta jättämiseen (kokeellinen)", + "Try out new ways to ignore people (experimental)": "Kokeile uusia tapoja käyttäjien sivuuttamiseen (kokeellinen)", "Match system theme": "Käytä järjestelmän teemaa", "Decline (%(counter)s)": "Hylkää (%(counter)s)", "Connecting to integration manager...": "Yhdistetään integraatioiden lähteeseen...", @@ -1602,25 +1602,25 @@ "Manage integrations": "Hallitse integraatioita", "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integraatioiden lähteet vastaanottavat asetusdataa ja voivat muokata sovelmia, lähettää kutsuja huoneeseen ja asettaa oikeustasoja puolestasi.", "Discovery": "Käyttäjien etsintä", - "Ignored/Blocked": "Jätetty huomiotta/estetty", - "Error adding ignored user/server": "Ongelma huomiotta jätetyn käyttäjän/palvelimen lisäämisessä", + "Ignored/Blocked": "Sivuutettu/estetty", + "Error adding ignored user/server": "Virhe sivuutetun käyttäjän/palvelimen lisäämisessä", "Error subscribing to list": "Virhe listalle liityttäessä", - "Error removing ignored user/server": "Ongelma huomiotta jätetyn käyttäjän/palvelimen poistamisessa", + "Error removing ignored user/server": "Virhe sivuutetun käyttäjän/palvelimen poistamisessa", "Error unsubscribing from list": "Virhe listalta poistuttaessa", "Ban list rules - %(roomName)s": "Estolistan säännöt - %(roomName)s", "Server rules": "Palvelinehdot", "User rules": "Käyttäjäehdot", - "You have not ignored anyone.": "Et ole jättänyt ketään huomiotta.", + "You have not ignored anyone.": "Et ole sivuuttanut ketään.", "You are currently ignoring:": "Jätät tällä hetkellä huomiotta:", "You are not subscribed to any lists": "Et ole liittynyt yhteenkään listaan", "You are currently subscribed to:": "Olet tällä hetkellä liittynyt:", "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Käyttäjien huomiotta jättäminen tapahtuu estolistojen kautta, joissa on tieto siitä, kenet pitää estää. Estolistalle liittyminen tarkoittaa, että ne käyttäjät/palvelimet, jotka tämä lista estää, eivät näy sinulle.", "Personal ban list": "Henkilökohtainen estolista", "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Henkilökohtainen estolistasi sisältää kaikki käyttäjät/palvelimet, joilta et henkilökohtaisesti halua nähdä viestejä. Sen jälkeen, kun olet estänyt ensimmäisen käyttäjän/palvelimen, huonelistaan ilmestyy uusi huone nimeltä ”Tekemäni estot” (englanniksi ”My Ban List”). Pysy tässä huoneessa, jotta estolistasi pysyy voimassa.", - "Server or user ID to ignore": "Huomiotta jätettävä palvelin tai käyttäjätunnus", + "Server or user ID to ignore": "Sivuutettava palvelin tai käyttäjätunnus", "Subscribed lists": "Tilatut listat", "Subscribing to a ban list will cause you to join it!": "Estolistan käyttäminen saa sinut liittymään listalle!", - "If this isn't what you want, please use a different tool to ignore users.": "Jos tämä ei ole mitä haluat, käytä eri työkalua käyttäjien huomiotta jättämiseen.", + "If this isn't what you want, please use a different tool to ignore users.": "Jos et halua tätä, käytä eri työkalua käyttäjien sivuuttamiseen.", "Integration Manager": "Integraatioiden lähde", "Read Marker lifetime (ms)": "Viestin luetuksi merkkaamisen kesto (ms)", "Click the link in the email you received to verify and then click continue again.": "Klikkaa lähettämässämme sähköpostissa olevaa linkkiä vahvistaaksesi tunnuksesi. Klikkaa sen jälkeen tällä sivulla olevaa painiketta ”Jatka”.", @@ -1636,7 +1636,7 @@ "Messages in this room are not end-to-end encrypted.": "Tämän huoneen viestit eivät ole päästä päähän -salattuja.", "Messages in this room are end-to-end encrypted.": "Tämän huoneen viestit ovat päästä päähän -salattuja.", "Verify": "Varmenna", - "You have ignored this user, so their message is hidden. Show anyways.": "Olet jättänyt tämän käyttäjän huomiotta, joten hänen viestit ovat piilotettu. Näytä käyttäjän viestit.", + "You have ignored this user, so their message is hidden. Show anyways.": "Olet sivuuttanut tämän käyttäjän, joten hänen viestinsä on piilotettu. Näytä silti.", "You verified %(name)s": "Varmensit käyttäjän %(name)s", "You cancelled verifying %(name)s": "Peruutit käyttäjän %(name)s varmennuksen", "%(name)s cancelled verifying": "%(name)s peruutti varmennuksen", @@ -2054,7 +2054,7 @@ "Encrypted by an unverified session": "Salattu varmentamattoman istunnon toimesta", "Encrypted by a deleted session": "Salattu poistetun istunnon toimesta", "Create room": "Luo huone", - "Reject & Ignore user": "Hylkää ja jätä käyttäjä huomiotta", + "Reject & Ignore user": "Hylkää ja sivuuta käyttäjä", "Start Verification": "Aloita varmennus", "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Viestisi ovat turvattu, ja vain sinulla ja vastaanottajalla on avaimet viestien lukemiseen.", "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Salausta käyttävissä huoneissa viestisi on turvattu, ja vain sinulla ja vastaanottajilla on yksityiset avaimet viestien lukemiseen.", @@ -2737,7 +2737,7 @@ "Show message previews for reactions in DMs": "Näytä reaktioille esikatselu yksityisviesteissä", "Show message previews for reactions in all rooms": "Näytä reaktioille esikatselu kaikissa huoneissa", "New spinner design": "Uusi kehrääjä tyyli", - "Render LaTeX maths in messages": "Suorita LaTeX-matematiikkaa viesteissä", + "Render LaTeX maths in messages": "Piirrä LaTeX-matematiikka viesteissä", "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", "Downloading logs": "Ladataan lokeja", "Uploading logs": "Lähetetään lokeja", @@ -2854,5 +2854,21 @@ "Converts the room to a DM": "Muuntaa huoneen yksityisviestiksi", "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Kotipalvelimesi hylkäsi kirjautumisyrityksesi. Syynä saattaa olla, että asiat tapahtuvat liian hitaasti. Yritä uudelleen. Mikäli ongelma jatkuu, ota yhteyttä kotipalvelimesi ylläpitäjään.", "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Kotipalvelintasi ei tavoitettu eikä sinua siksi kirjattu sisään. Yritä uudelleen. Mikäli ongelma jatkuu, ota yhteyttä kotipalvelimesi ylläpitäjään.", - "Try again": "Yritä uudelleen" + "Try again": "Yritä uudelleen", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Lisää tähän käyttäjät ja palvelimet, jotka haluat sivuuttaa. Asteriski täsmää mihin tahansa merkkiin. Esimerkiksi @bot:* sivuuttaa kaikki käyttäjät, joiden nimessä on \"bot\".", + "Show stickers button": "Näytä tarrapainike", + "Expand code blocks by default": "Laajenna koodilohkot oletuksena", + "Show line numbers in code blocks": "Näytä rivinumerot koodilohkoissa", + "Recently visited rooms": "Hiljattain vieraillut huoneet", + "Screens": "Näytöt", + "Share your screen": "Jaa näyttösi", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Voit kirjautua muille Matrix-palvelimille antamalla eri kotipalvelimen URL-osoitteen palvelinasetuksissa. Näin voit käyttää Elementiä eri kotipalvelimella olevan Matrix-tilin kanssa.", + "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Voi olla paikallaan poistaa tämä käytöstä, jos huonetta käyttävät myös ulkoiset tiimit joilla on oma kotipalvelimensa. Asetusta ei voi muuttaa myöhemmin.", + "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Voi olla paikallaan ottaa tämä käyttöön, jos huonetta käyttävät vain sisäiset tiimit kotipalvelimellasi. Asetusta ei voi muuttaa myöhemmin.", + "Learn more in our , and .": "Lue lisää: , ja .", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Kotipalvelimeesi yhdistäminen ei onnistunut. Sulje tämä ikkuna ja yritä uudelleen.", + "Privacy Policy": "Tietosuojakäytäntö", + "Cookie Policy": "Evästekäytäntö", + "Recent changes that have not yet been received": "Tuoreet muutokset, joita ei ole vielä otettu vastaan", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Pyysimme selainta muistamaan kirjautumista varten mitä kotipalvelinta käytät, mutta selain on unohtanut sen. Mene kirjautumissivulle ja yritä uudelleen." } From 9fc8d30550c44738c293c10bf841f9397b9843c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Fri, 12 Feb 2021 19:35:15 +0000 Subject: [PATCH 0216/2651] Translated using Weblate (Slovak) Currently translated at 65.5% (1813 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 317 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 293 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 454d86cb64..0ee0c6cbc3 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -548,7 +548,7 @@ "The phone number entered looks invalid": "Zdá sa, že zadané telefónne číslo je neplatné", "Error: Problem communicating with the given homeserver.": "Chyba: Nie je možné komunikovať so zadaným domovským serverom.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", - "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vášho pripojenia na internet. Uistite sa že certifikát domovského servera je dôveryhodný a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", "Set a display name:": "Nastaviť zobrazované meno:", "Upload an avatar:": "Nahrať obrázok:", @@ -573,7 +573,7 @@ "Passphrases must match": "Heslá sa musia zhodovať", "Passphrase must not be empty": "Heslo nesmie byť prázdne", "Export room keys": "Exportovať kľúče miestností", - "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tento proces vás prevedie exportom kľúčov určených na dešifrovanie správ, ktoré ste dostali v šifrovaných miestnostiach do lokálneho súboru. Tieto kľúče zo súboru môžete neskôr importovať do iného Matrix klienta, aby ste v ňom mohli dešifrovať vaše šifrované správy.", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tento proces vás prevedie exportom kľúčov určených na dešifrovanie správ, ktoré ste dostali v šifrovaných miestnostiach do lokálneho súboru. Tieto kľúče zo súboru môžete neskôr importovať do iného Matrix klienta, aby ste v ňom mohli dešifrovať vaše šifrované správy.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Tento súbor umožní komukoľvek, kto má ku nemu prístup, dešifrovať všetky vami viditeľné šifrované správy, mali by ste teda byť opatrní a tento súbor si bezpečne uchovať. Aby bolo toto pre vás jednoduchšie, nižšie zadajte heslo, ktorým budú údaje v súbore zašifrované. Importovať údaje zo súboru bude možné len po zadaní tohoto istého hesla.", "Enter passphrase": "Zadajte (dlhé) heslo", "Confirm passphrase": "Potvrďte heslo", @@ -613,7 +613,7 @@ "This room is not showing flair for any communities": "V tejto miestnosti nie je zobrazená príslušnosť k žiadnym komunitám", "Display your community flair in rooms configured to show it.": "Zobrazovať vašu príslušnosť ku komunite v miestnostiach, ktoré sú nastavené na zobrazovanie tejto príslušnosti.", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", - "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Túto zmenu nebudete môcť vrátiť späť pretože znižujete vašu vlastnú úroveň moci. Ak ste jediný poverený používateľ v miestnosti, nebudete môcť znovu získať úroveň, akú máte teraz.", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Túto zmenu nebudete môcť vrátiť späť, pretože znižujete vašu vlastnú úroveň moci. Ak ste jediný privilegovaný používateľ v miestnosti, nebudete môcť získať vašu súčasnú úroveň znovu.", "Send an encrypted reply…": "Odoslať šifrovanú odpoveď…", "Send an encrypted message…": "Odoslať šifrovanú správu…", "Replying": "Odpoveď", @@ -727,7 +727,7 @@ "You must specify an event type!": "Musíte nastaviť typ udalosti!", "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", "All Rooms": "Vo všetkych miestnostiach", - "State Key": "State Key", + "State Key": "Stavový kľúč", "Wednesday": "Streda", "Quote": "Citovať", "Send logs": "Zahrnúť záznamy", @@ -963,7 +963,7 @@ "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Ak ste si nenastavili nový spôsob obnovenia, je možné, že útočník sa pokúša dostať k vášmu účtu. Radšej si ihneď zmeňte vaše heslo a nastavte si nový spôsob obnovenia v Nastaveniach.", "Set up Secure Messages": "Nastaviť bezpečné obnovenie správ", "Go to Settings": "Otvoriť nastavenia", - "Whether or not you're logged in (we don't record your username)": "Či ste alebo nie ste prihlásení (nezaznamenávame vaše meno používateľa)", + "Whether or not you're logged in (we don't record your username)": "Či ste alebo nie ste prihlásení (nezaznamenávame vaše používateľské meno)", "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Veľkosť súboru „%(fileName)s“ prekračuje limit veľkosti súboru nahrávania na tento domovský server", "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Pridá znaky ¯\\_(ツ)_/¯ pred správy vo formáte obyčajného textu", "Upgrades a room to a new version": "Aktualizuje miestnosť na novšiu verziu", @@ -1289,7 +1289,7 @@ "Double check that your server supports the room version chosen and try again.": "Uistite sa, že domovský server podporuje zvolenú verziu miestnosti a skúste znovu.", "Changes the avatar of the current room": "Zmení obrázok miestnosti", "Use an identity server": "Použiť server totožností", - "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Aby ste mohli používateľov pozývať zadaním emailovej adresy, je potrebné nastaviť adresu servera totožností. Klepnutím na tlačidlo pokračovať použijete predvolený server (%(defaultIdentityServerName)s) a zmeniť to môžete v nastaveniach.", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Aby ste mohli používateľov pozývať zadaním emailovej adresy, je potrebné nastaviť adresu servera totožností. Klepnutím na tlačidlo pokračovať použijete predvolený server (%(defaultIdentityServerName)s) a zmeniť to môžete v nastaveniach.", "Use an identity server to invite by email. Manage in Settings.": "Server totožností sa použije na pozývanie používateľov zadaním emailovej adresy. Spravujte v nastaveniach.", "%(senderName)s placed a voice call.": "%(senderName)s uskutočnil telefonát.", "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s uskutočnil telefonát. (Nepodporované týmto prehliadačom)", @@ -1371,27 +1371,27 @@ "Discovery": "Objaviť", "Deactivate account": "Deaktivovať účet", "Clear cache and reload": "Vymazať vyrovnávaciu pamäť a načítať znovu", - "Customise your experience with experimental labs features. Learn more.": "Prispôsobte si zážitok s používania aktivovaním experimentálnych vlastností. Zistiť viac.", + "Customise your experience with experimental labs features. Learn more.": "Prispôsobte si zážitok z používania aktivovaním experimentálnych vlastností. Zistiť viac.", "Ignored/Blocked": "Ignorovaní / Blokovaní", "Error adding ignored user/server": "Chyba pri pridávaní ignorovaného používateľa / servera", "Something went wrong. Please try again or view your console for hints.": "Niečo sa nepodarilo. Prosím, skúste znovu neskôr alebo si prečítajte ďalšie usmernenia zobrazením konzoly.", "Error subscribing to list": "Chyba pri prihlasovaní sa do zoznamu", "Error removing ignored user/server": "Chyba pri odstraňovaní ignorovaného používateľa / servera", - "Use Single Sign On to continue": "Pokračovať pomocou Jednotného prihlásenia", - "Confirm adding this email address by using Single Sign On to prove your identity.": "Potvrďte pridanie tejto adresy pomocou Jednotného prihlásenia.", - "Single Sign On": "Jednotné prihlásenie", + "Use Single Sign On to continue": "Pokračovať pomocou Single Sign On", + "Confirm adding this email address by using Single Sign On to prove your identity.": "Potvrďte pridanie tejto adresy pomocou Single Sign On.", + "Single Sign On": "Single Sign On", "Confirm adding email": "Potvrdiť pridanie emailu", - "Click the button below to confirm adding this email address.": "Kliknutím na tlačítko potvrdíte pridanie emailovej adresy.", - "Confirm adding this phone number by using Single Sign On to prove your identity.": "Potvrďte pridanie telefónneho čísla pomocou Jednotného prihlásenia.", + "Click the button below to confirm adding this email address.": "Kliknutím na tlačidlo nižšie potvrdíte pridanie emailovej adresy.", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "Potvrďte pridanie telefónneho čísla pomocou Single Sign On.", "Confirm adding phone number": "Potvrdiť pridanie telefónneho čísla", - "Click the button below to confirm adding this phone number.": "Kliknutím na tlačítko potvrdíte pridanie telefónneho čísla.", + "Click the button below to confirm adding this phone number.": "Kliknutím na tlačidlo nižšie potvrdíte pridanie telefónneho čísla.", "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Či používate %(brand)s na zariadení, ktorého hlavným vstupným mechanizmom je dotyk (mobil, tablet,...)", "Whether you're using %(brand)s as an installed Progressive Web App": "Či používate %(brand)s ako nainštalovanú Progresívnu Webovú Aplikáciu", "Your user agent": "Identifikátor vášho prehliadača", "If you cancel now, you won't complete verifying the other user.": "Pokiaľ teraz proces zrušíte, nedokončíte overenie druhého používateľa.", "If you cancel now, you won't complete verifying your other session.": "Pokiaľ teraz proces zrušíte, nedokončíte overenie vašej druhej relácie.", "If you cancel now, you won't complete your operation.": "Pokiaľ teraz proces zrušíte, nedokončíte ho.", - "Cancel entering passphrase?": "Zrušiť zadávanie (dlhého) hesla.", + "Cancel entering passphrase?": "Želáte si zrušiť zadávanie hesla?", "Setting up keys": "Príprava kľúčov", "Verify this session": "Overiť túto reláciu", "Enter recovery passphrase": "Zadajte (dlhé) heslo pre obnovu zálohy", @@ -1439,7 +1439,7 @@ "Interactively verify by Emoji": "Interaktívne overte pomocou emoji", "Done": "Hotovo", "a few seconds ago": "pred pár sekundami", - "about a minute ago": "približne pred minutou", + "about a minute ago": "približne pred minútou", "about an hour ago": "približne pred hodinou", "about a day ago": "približne deň dozadu", "a few seconds from now": "o pár sekúnd", @@ -1474,7 +1474,7 @@ "Failed to re-authenticate": "Opätovná autentifikácia zlyhala", "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Znovuzískajte prístup k vášmu účtu a obnovte šifrovacie kľúče uložené v tejto relácií. Bez nich nebudete môcť čítať všetky vaše šifrované správy vo všetkých reláciach.", "Font scaling": "Škálovanie písma", - "Show info about bridges in room settings": "Zobraziť informácie o mostoch v Nastaveniach miestnosti", + "Show info about bridges in room settings": "Zobraziť informácie o mostoch v nastaveniach miestnosti", "Font size": "Veľkosť písma", "Show typing notifications": "Posielať oznámenia, keď píšete", "Never send encrypted messages to unverified sessions from this session": "Nikdy neposielať šifrované správy neovereným reláciam z tejto relácie", @@ -1519,7 +1519,7 @@ "To be secure, do this in person or use a trusted way to communicate.": "Aby ste si boli istý, urobte to osobne alebo použite dôveryhodný spôsob komunikácie.", "Lock": "Zámok", "If you can't scan the code above, verify by comparing unique emoji.": "Pokiaľ nemôžete kód vyššie skenovať, overte sa porovnaním jedinečnej kombinácie emoji.", - "Verify by comparing unique emoji.": "Overenie porovnaním jedinečnej kombinácie emoji", + "Verify by comparing unique emoji.": "Overenie porovnaním jedinečnej kombinácie emotikonov.", "Verify by emoji": "Overte pomocou emoji", "Compare emoji": "Porovnajte emoji", "Verify all your sessions to ensure your account & messages are safe": "Overte všetky vaše relácie, aby ste si boli istý, že sú vaše správy a účet bezpečné", @@ -1528,7 +1528,7 @@ "Upgrade": "Upgradovať", "Verify": "Overiť", "Verify yourself & others to keep your chats safe": "Overte seba a ostatných, aby vaše komunikácie boli bezpečné", - "Other users may not trust it": "Ostatný používatelia jej nemusia veriť", + "Other users may not trust it": "Ostatní používatelia jej nemusia veriť", "Verify the new login accessing your account: %(name)s": "Overte nové prihlásenie na váš účet: %(name)s", "From %(deviceName)s (%(deviceId)s)": "Od %(deviceName)s (%(deviceId)s)", "This bridge was provisioned by .": "Tento most poskytuje .", @@ -1545,7 +1545,7 @@ "unexpected type": "neočakávaný typ", "in memory": "v pamäti", "Self signing private key:": "Samo-podpísané súkromné kľúče:", - "cached locally": "cachenuté lokálne", + "cached locally": "uložené do lokálnej vyrovnávacej pamäťe", "not found locally": "nenájdené lokálne", "User signing private key:": "Používateľom podpísané súkromné kľúče:", "Session backup key:": "Kľúč na zálohu relácie:", @@ -1595,7 +1595,7 @@ "Restart": "Reštartovať", "Upgrade your %(brand)s": "Upgradujte svoj %(brand)s", "A new version of %(brand)s is available!": "Nová verzia %(brand)su je dostupná!", - "Which officially provided instance you are using, if any": "Ktorú oficiálne poskytovanú inštanciu používate, pokiaľ nejakú", + "Which officially provided instance you are using, if any": "Ktorú oficiálne poskytovanú inštanciu používate, ak nejakú", "Use your account to sign in to the latest version": "Použite svoj účet na prihlásenie sa do najnovšej verzie", "We’re excited to announce Riot is now Element": "Sme nadšený oznámiť, že Riot je odteraz Element", "Riot is now Element!": "Riot je odteraz Element!", @@ -1669,7 +1669,7 @@ "Incoming video call": "Prichádzajúci video hovor", "Incoming call": "Prichádzajúci hovor", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Vytvorte si filter, potiahnite avatara komunity do panelu filtrov na ľavý okraj obrazovky. Môžete kliknúť na avatara v paneli filtorv, aby ste videli len miestnosti a ľudí patriacich do danej komunity.", - "%(num)s minutes ago": "pred %(num)s minútami", + "%(num)s minutes ago": "pred %(num)s min", "%(num)s hours ago": "pred %(num)s hodinami", "%(num)s days ago": "pred %(num)s dňami", "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s nemôže bezpečne cachovať šiforvané správy lokálne pomocou prehlliadača. Použite %(brand)s Desktop na zobrazenie výsledkov vyhľadávania šiforavných správ.", @@ -1775,10 +1775,10 @@ "%(num)s hours from now": "o %(num)s hodín", "%(num)s days from now": "o %(num)s dní", "The person who invited you already left the room.": "Osoba ktorá Vás pozvala už opustila miestnosť.", - "The person who invited you already left the room, or their server is offline.": "Osoba ktorá Vás pozvala už opustila miestnosť, alebo je ich server offline.", + "The person who invited you already left the room, or their server is offline.": "Osoba, ktorá Vás pozvala už opustila miestnosť, alebo je jej server offline.", "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", "Change notification settings": "Upraviť nastavenia upozornení", - "Enable advanced debugging for the room list": "Zapnúť pokročilé ladenie pre zoznam miestností", + "Enable advanced debugging for the room list": "Zapnúť pokročilé nástroje ladenia pre zoznam miestností", "Securely cache encrypted messages locally for them to appear in search results, using ": "Bezpečne uchovávať šifrované správy na tomto zariadení, aby sa v nich dalo vyhľadávať pomocou ", " to store messages from ": " na uchovanie správ z ", "rooms.": "miestnosti.", @@ -1811,5 +1811,274 @@ "Security": "Zabezpečenie", "Send a Direct Message": "Poslať priamu správu", "User menu": "Používateľské menu", - "Toggle Italics": "Prepnúť kurzíva" + "Toggle Italics": "Prepnúť kurzíva", + "Zimbabwe": "Zimbabwe", + "Zambia": "Zambia", + "Yemen": "Jemen", + "Western Sahara": "Západná Sahara", + "Wallis & Futuna": "Wallis a Futuna", + "Vietnam": "Vietnam", + "Venezuela": "Venezuela", + "Vatican City": "Vatikán", + "Vanuatu": "Vanuatu", + "Uzbekistan": "Uzbekistan", + "Uruguay": "Uruguaj", + "United Arab Emirates": "Spojené Arabské Emiráty", + "Ukraine": "Ukrajina", + "Uganda": "Uganda", + "U.S. Virgin Islands": "Americké Panenské ostrovy", + "Tuvalu": "Tuvalu", + "Turks & Caicos Islands": "Ostrovy Turks a Caicos", + "Turkmenistan": "Turkménsko", + "Turkey": "Turecko", + "Tunisia": "Tunisko", + "Trinidad & Tobago": "Trinidad a Tobago", + "Tonga": "Tonga", + "Tokelau": "Tokelau", + "Togo": "Togo", + "Timor-Leste": "Východný Timor", + "Thailand": "Thajsko", + "Tanzania": "Tanzánia", + "Tajikistan": "Tadžikistan", + "Taiwan": "Taiwan", + "São Tomé & Príncipe": "Svätý Tomáš a Princov ostrov", + "Syria": "Sýria", + "Switzerland": "Švajčiarsko", + "Sweden": "Švédsko", + "Swaziland": "Svazijsko", + "Svalbard & Jan Mayen": "Špicbergy a Jan Mayen", + "Suriname": "Surinam", + "Sudan": "Sudán", + "St. Vincent & Grenadines": "Svätý Vincent a Grenadíny", + "St. Pierre & Miquelon": "Svätý Pierre a Miquelon", + "St. Martin": "Svätý Martin", + "St. Lucia": "Svätá Lucia", + "St. Kitts & Nevis": "Svätý Krištof a Nevis", + "St. Helena": "Svätá Helena", + "St. Barthélemy": "Svätý Bartolomej", + "Sri Lanka": "Srí Lanka", + "Spain": "Španielsko", + "South Sudan": "Južný Sudán", + "South Korea": "Južná Kórea", + "South Georgia & South Sandwich Islands": "Južná Georgia a Južné sendvičové ostrovy", + "South Africa": "Južná Afrika", + "Somalia": "Somálsko", + "Solomon Islands": "Šalamúnove ostrovy", + "Slovenia": "Slovinsko", + "Slovakia": "Slovensko", + "Sint Maarten": "Sint Maarten", + "Singapore": "Singapur", + "Sierra Leone": "Sierra Leone", + "Seychelles": "Seychely", + "Serbia": "Srbsko", + "Senegal": "Senegal", + "Saudi Arabia": "Saudská Arábia", + "San Marino": "San Maríno", + "Samoa": "Samoa", + "Réunion": "Réunion", + "Rwanda": "Rwanda", + "Russia": "Rusko", + "Romania": "Rumunsko", + "Qatar": "Katar", + "Puerto Rico": "Portoriko", + "Portugal": "Portugalsko", + "Poland": "Poľsko", + "Pitcairn Islands": "Pitcairnove ostrovy", + "Philippines": "Filipíny", + "Peru": "Peru", + "Paraguay": "Paraguaj", + "Papua New Guinea": "Papua-Nová Guinea", + "Panama": "Panama", + "Palestine": "Palestína", + "Palau": "Palau", + "Pakistan": "Pakistan", + "Oman": "Omán", + "Norway": "Nórsko", + "Northern Mariana Islands": "Severné Mariány", + "North Korea": "Severná Kórea", + "Norfolk Island": "Ostrov Norfolk", + "Niue": "Niue", + "Nigeria": "Nigéria", + "Niger": "Niger", + "Nicaragua": "Nikaragua", + "New Zealand": "Nový Zéland", + "New Caledonia": "Nová Kaledónia", + "Netherlands": "Holandsko", + "Nepal": "Nepál", + "Nauru": "Nauru", + "Namibia": "Namíbia", + "Myanmar": "Mjanmarsko", + "Mozambique": "Mozambik", + "Morocco": "Maroko", + "Montserrat": "Montserrat", + "Montenegro": "Čierna Hora", + "Mongolia": "Mongolsko", + "Monaco": "Monako", + "Moldova": "Moldavsko", + "Micronesia": "Mikronézia", + "Mexico": "Mexiko", + "Mayotte": "Mayotte", + "Mauritius": "Maurícius", + "Mauritania": "Mauretánia", + "Martinique": "Martinik", + "Marshall Islands": "Maršalove ostrovy", + "Malta": "Malta", + "Mali": "Mali", + "Maldives": "Maledivy", + "Malaysia": "Malajzia", + "Malawi": "Malawi", + "Madagascar": "Madagaskar", + "Macedonia": "Macedónsko", + "Macau": "Macao", + "Luxembourg": "Luxembursko", + "Lithuania": "Litva", + "Liechtenstein": "Lichtenštajnsko", + "Libya": "Líbya", + "Liberia": "Libéria", + "Lesotho": "Lesotho", + "Lebanon": "Libanon", + "Latvia": "Lotyšsko", + "Laos": "Laos", + "Kyrgyzstan": "Kirgizsko", + "Kuwait": "Kuvajt", + "Kosovo": "Kosovo", + "Kiribati": "Kiribati", + "Kenya": "Keňa", + "Kazakhstan": "Kazachstan", + "Jordan": "Jordánsko", + "Jersey": "Jersey", + "Japan": "Japonsko", + "Jamaica": "Jamajka", + "Italy": "Taliansko", + "Israel": "Izrael", + "Isle of Man": "Ostrov Man", + "Ireland": "Írsko", + "Iraq": "Irak", + "Iran": "Irán", + "Indonesia": "Indonézia", + "India": "India", + "Iceland": "Island", + "Hungary": "Maďarsko", + "Hong Kong": "Hongkong", + "Honduras": "Honduras", + "Heard & McDonald Islands": "Teritórium Heardovho ostrova a Macdonaldových ostrovov", + "Haiti": "Haiti", + "Guyana": "Guyana", + "Guinea-Bissau": "Guinea-Bissau", + "Guinea": "Guinea", + "Guernsey": "Guernsey", + "Guatemala": "Guatemala", + "Guam": "Guam", + "Guadeloupe": "Guadeloupe", + "Grenada": "Grenada", + "Greenland": "Grónsko", + "Greece": "Grécko", + "Gibraltar": "Gibraltár", + "Ghana": "Ghana", + "Germany": "Nemecko", + "Georgia": "Gruzínsko", + "Gambia": "Gambia", + "Gabon": "Gabon", + "French Southern Territories": "Francúzske južné územia", + "French Polynesia": "Francúzska Polynézia", + "French Guiana": "Francúzska Guiana", + "France": "Francúzsko", + "Finland": "Fínsko", + "Fiji": "Fidži", + "Faroe Islands": "Faerské ostrovy", + "Falkland Islands": "Falklandské ostrovy", + "Ethiopia": "Etiópia", + "Estonia": "Estónsko", + "Eritrea": "Eritrea", + "Equatorial Guinea": "Rovníková Guinea", + "El Salvador": "El Salvador", + "Egypt": "Egypt", + "Ecuador": "Ekvádor", + "Dominican Republic": "Dominikánska republika", + "Dominica": "Dominika", + "Djibouti": "Džibuti", + "Denmark": "Dánsko", + "Côte d’Ivoire": "Pobrežie Slonoviny", + "Czech Republic": "Česká republika", + "Cyprus": "Cyprus", + "Curaçao": "Curaçao", + "Cuba": "Kuba", + "Croatia": "Chorvátsko", + "Costa Rica": "Kostarika", + "Cook Islands": "Cookove ostrovy", + "Congo - Kinshasa": "Kongo (Kinshasa)", + "Congo - Brazzaville": "Kongo (Brazzaville)", + "Comoros": "Komory", + "Colombia": "Kolumbia", + "Cocos (Keeling) Islands": "Kokosové ostrovy", + "Christmas Island": "Vianočný ostrov", + "China": "Čína", + "Chile": "Čile", + "Chad": "Čad", + "Central African Republic": "Stredoafrická republika", + "Cayman Islands": "Kajmanské ostrovy", + "Caribbean Netherlands": "Karibské Holandsko", + "Cape Verde": "Kapverdy", + "Canada": "Kanada", + "Cameroon": "Kamerun", + "Cambodia": "Kambodža", + "Burundi": "Burundi", + "Burkina Faso": "Burkina Faso", + "Bulgaria": "Bulharsko", + "Brunei": "Brunej", + "British Virgin Islands": "Britské Panenské ostrovy", + "British Indian Ocean Territory": "Britské indickooceánske územie", + "Brazil": "Brazília", + "Bouvet Island": "Bouvetov ostrov", + "Botswana": "Botswana", + "Bosnia": "Bosna", + "Bolivia": "Bolívia", + "Bhutan": "Bhután", + "Bermuda": "Bermudy", + "Benin": "Benin", + "Belize": "Belize", + "Belgium": "Belgicko", + "Belarus": "Bielorusko", + "Barbados": "Barbados", + "Bangladesh": "Bangladéš", + "Bahrain": "Bahrajn", + "Bahamas": "Bahamy", + "Azerbaijan": "Azerbajdžan", + "Austria": "Rakúsko", + "Australia": "Austrália", + "Aruba": "Aruba", + "Armenia": "Arménsko", + "Argentina": "Argentína", + "Antigua & Barbuda": "Antigua a Barbuda", + "Antarctica": "Antarktída", + "Anguilla": "Anguilla", + "Angola": "Angola", + "Andorra": "Andorra", + "American Samoa": "Americká Samoa", + "Algeria": "Alžírsko", + "Albania": "Albánsko", + "Åland Islands": "Alandské ostrovy", + "Afghanistan": "Afganistan", + "United States": "Spojené Štáty", + "United Kingdom": "Spojené Kráľovstvo", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Domáci server odmietol váš pokus o prihlásenie. Môže to byť spôsobené tým, že požiadavky trvajú príliš dlho. Prosím skúste znova. Ak to bude pokračovať, kontaktujte svojho správcu domovského servera.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Váš domovský server bol nedosiahnuteľný a nemohol vás prihlásiť. Skúste to znova. Ak to bude pokračovať, kontaktujte svojho správcu domovského servera.", + "Try again": "Skúste to znova", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Požiadali sme prehliadač, aby si pamätal, aký domovský server používate na prihlásenie, ale váš prehliadač ho, bohužiaľ, zabudol. Prejdite na prihlasovaciu stránku a skúste to znova.", + "We couldn't log you in": "Nemohli sme vás prihlásiť", + "This will end the conference for everyone. Continue?": "Týmto sa konferencia ukončí pre všetkých. Chcete pokračovať?", + "End conference": "Koniec konferencie", + "You've reached the maximum number of simultaneous calls.": "Dosiahli ste maximálny počet súčasných hovorov.", + "Too Many Calls": "Príliš veľa hovorov", + "No other application is using the webcam": "Webkameru nepoužíva žiadna iná aplikácia", + "Permission is granted to use the webcam": "Udeľuje sa povolenie na používanie webkamery", + "A microphone and webcam are plugged in and set up correctly": "Mikrofón a webkamera sú pripojené a správne nastavené", + "Call failed because webcam or microphone could not be accessed. Check that:": "Hovor zlyhal, pretože nebolo možné získať prístup k webkamere alebo mikrofónu. Skontrolujte, či:", + "Unable to access webcam / microphone": "Nie je možné získať prístup k webkamere / mikrofónu", + "Unable to access microphone": "Nie je možné získať prístup k mikrofónu", + "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "Hovor zlyhal, pretože nebolo možné získať prístup k mikrofónu. Skontrolujte, či je mikrofón pripojený a správne nastavený.", + "The call was answered on another device.": "Hovor bol prijatý na inom zariadení.", + "The call could not be established": "Hovor nemohol byť realizovaný", + "The other party declined the call.": "Druhá strana odmietla hovor.", + "Call Declined": "Hovor odmietnutý" } From 134d18554a9ec899dc92d036c66b1492533d9b2b Mon Sep 17 00:00:00 2001 From: XoseM Date: Fri, 12 Feb 2021 04:17:11 +0000 Subject: [PATCH 0217/2651] Translated using Weblate (Galician) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 006412fb88..b309f12245 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -3052,5 +3052,18 @@ "Share your screen": "Compartir a túa pantalla", "Recently visited rooms": "Salas visitadas recentemente", "Show line numbers in code blocks": "Mostrar números de liña nos bloques de código", - "Expand code blocks by default": "Por omsión despregar bloques de código" + "Expand code blocks by default": "Por omsión despregar bloques de código", + "Upgrade to pro": "Mellorar a pro", + "Minimize dialog": "Minimizar ventá", + "Maximize dialog": "Maximizar ventá", + "%(hostSignupBrand)s Setup": "Configurar %(hostSignupBrand)s", + "You should know": "Deberías saber", + "Privacy Policy": "Política de Privacidade", + "Cookie Policy": "Política de Cookies", + "Learn more in our , and .": "Aprende máis na nosa , e .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Ao continuar de xeito temporal permitirás que %(hostSignupBrand)s complete o acceso á túa conta para obter os enderezos de email verificados. Os datos non se almacenan.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Fallou a conexión co teu servidor de inicio. Pecha esta información e inténtao outra vez.", + "Abort": "Abortar", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Tes a certeza de querer cancelar a creación do servidor? O proceso non pode ser completado.", + "Confirm abort of host creation": "Corfirma que cancelas a creación do servidor" } From 041f74eaafb58f1ca8c95dbac5221b4499ba8813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Slobodan=20Simi=C4=87?= Date: Mon, 22 Feb 2021 08:36:41 +0000 Subject: [PATCH 0218/2651] Translated using Weblate (Serbian) Currently translated at 50.6% (1401 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 74 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 3ca12d2fd1..ca79955f72 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -1001,7 +1001,7 @@ "Show rooms with unread notifications first": "Прво прикажи собе са непрочитаним обавештењима", "Enable experimental, compact IRC style layout": "Омогући пробни, збијенији распоред у IRC стилу", "Got It": "Разумем", - "Light bulb": "Сијалица", + "Light bulb": "сијалица", "Algorithm: ": "Алгоритам: ", "Go back": "Назад", "Hey you. You're the best!": "Хеј! Само напред!", @@ -1438,5 +1438,75 @@ "Changes your display nickname in the current room only": "Мења ваше приказно име само у тренутној соби", "Try again": "Покушај поново", "We couldn't log you in": "Не могу да вас пријавим", - "Double check that your server supports the room version chosen and try again.": "Добро проверите да ли сервер подржава изабрану верзију собе и пробајте поново." + "Double check that your server supports the room version chosen and try again.": "Добро проверите да ли сервер подржава изабрану верзију собе и пробајте поново.", + "a few seconds from now": "за неколико секунди", + "The message you are trying to send is too large.": "Порука коју покушавате да пошаљете је предугачка.", + "Pin": "чиода", + "Folder": "фасцикла", + "Headphones": "слушалице", + "Anchor": "сидро", + "Bell": "звоно", + "Trumpet": "труба", + "Guitar": "гитара", + "Ball": "лопта", + "Trophy": "трофеј", + "Rocket": "ракета", + "Aeroplane": "авион", + "Bicycle": "бицикл", + "Train": "воз", + "Flag": "застава", + "Telephone": "телефон", + "Hammer": "чекић", + "Key": "кључ", + "Lock": "катанац", + "Scissors": "маказе", + "Paperclip": "спајалица", + "Pencil": "оловка", + "Book": "књига", + "Gift": "поклон", + "Clock": "сат", + "Hourglass": "пешчаник", + "Umbrella": "кишобран", + "Thumbs up": "палац горе", + "Santa": "Мраз", + "Spanner": "кључ", + "Glasses": "наочаре", + "Hat": "шешир", + "Robot": "робот", + "Smiley": "смајли", + "Heart": "срце", + "Cake": "торта", + "Pizza": "пица", + "Corn": "кукуруз", + "Strawberry": "јагода", + "Apple": "јабука", + "Banana": "банана", + "Fire": "ватра", + "Cloud": "облак", + "Moon": "месец", + "Globe": "глобус", + "Mushroom": "печурка", + "Cactus": "кактус", + "Tree": "дрво", + "Flower": "цвет", + "Butterfly": "лептир", + "Octopus": "октопод", + "Fish": "риба", + "Turtle": "корњача", + "Penguin": "пингвин", + "Rooster": "петао", + "Panda": "панда", + "Rabbit": "зец", + "Elephant": "слон", + "Pig": "прасе", + "Unicorn": "једнорог", + "Horse": "коњ", + "Lion": "лав", + "Cat": "мачка", + "Dog": "пас", + "To be secure, do this in person or use a trusted way to communicate.": "Да будете сигурни, ово обавите лично или путем поузданог начина комуникације.", + "They don't match": "Не поклапају се", + "They match": "Поклапају се", + "Cancelling…": "Отказујем…", + "Show stickers button": "Прикажи дугме за налепнице" } From 03589af8ad3208cd88683d986685cdb457345d62 Mon Sep 17 00:00:00 2001 From: Fake Mail Date: Thu, 11 Feb 2021 22:13:10 +0000 Subject: [PATCH 0219/2651] Translated using Weblate (Bulgarian) Currently translated at 93.3% (2581 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 317 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 309 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index e4010e8b64..8c6ea60a8d 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -851,7 +851,7 @@ "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Съобщението Ви не бе изпратено, защото този сървър е някой от лимитите си. Моля, свържете се с администратора на услугата за да продължите да я използвате.", "Please contact your service administrator to continue using this service.": "Моля, свържете се с администратора на услугата за да продължите да я използвате.", "Sorry, your homeserver is too old to participate in this room.": "Съжаляваме, вашият сървър е прекалено стар за да участва в тази стая.", - "Please contact your homeserver administrator.": "Моля, свържете се се със сървърния администратор.", + "Please contact your homeserver administrator.": "Моля, свържете се със сървърния администратор.", "Legal": "Юридически", "Unable to connect to Homeserver. Retrying...": "Неуспешно свързване със сървъра. Опитване отново...", "This room has been replaced and is no longer active.": "Тази стая е била заменена и вече не е активна.", @@ -1612,11 +1612,11 @@ "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s премахна правилото блокиращо достъпа до стаи отговарящи на %(glob)s", "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s премахна правилото блокиращо достъпа до сървъри отговарящи на %(glob)s", "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s премахна правилото блокиращо достъпа неща отговарящи на %(glob)s", - "%(senderName)s updated an invalid ban rule": "%(senderName)s обнови невалидно правило за блокиране", - "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s премахна правилото блокиращо достъпа на потребители отговарящи на %(glob)s поради %(reason)s", - "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s премахна правилото блокиращо достъпа до стаи отговарящи на %(glob)s поради %(reason)s", - "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s премахна правилото блокиращо достъпа до сървъри отговарящи на %(glob)s поради %(reason)s", - "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s премахна правилото блокиращо достъпа неща отговарящи на %(glob)s поради %(reason)s", + "%(senderName)s updated an invalid ban rule": "%(senderName)s промени невалидно правило за блокиране", + "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s промени правилото блокиращо достъпа на потребители отговарящи на %(glob)s поради %(reason)s", + "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s промени правилото блокиращо достъпа до стаи отговарящи на %(glob)s поради %(reason)s", + "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s промени правилото блокиращо достъпа до сървъри отговарящи на %(glob)s поради %(reason)s", + "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s промени правило блокиращо достъпа неща отговарящи на %(glob)s поради %(reason)s", "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s създаде правило блокиращо достъпа на потребители отговарящи на %(glob)s поради %(reason)s", "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s създаде правило блокиращо достъпа до стаи отговарящи на %(glob)s поради %(reason)s", "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s създаде правило блокиращо достъпа до сървъри отговарящи на %(glob)s поради %(reason)s", @@ -1949,7 +1949,7 @@ "Accepting…": "Приемане…", "Start Verification": "Започни верификация", "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Съобщенията ви са защитени и само вие и получателят имате уникалните ключове за да ги отключите.", - "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "В шифровани стаи, съобщенията ви са защитени и само вие и получателят имате уникалните ключове за да ги отключите.", + "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "В шифровани стаи, съобщенията ви са защитени и само вие и получателят имате уникалните ключове за да ги отключите.", "Verify User": "Потвърди потребителя", "For extra security, verify this user by checking a one-time code on both of your devices.": "За допълнителна сигурност, потвърдете този потребител като проверите еднократен код на устройствата ви.", "Your messages are not secure": "Съобщенията ви не са защитени", @@ -2530,5 +2530,306 @@ "%(brand)s Desktop": "%(brand)s Desktop", "%(brand)s Web": "Уеб версия на %(brand)s", "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Въведете адреса на вашия Element Matrix Services сървър. Той или използва ваш собствен домейн или е поддомейн на element.io.", - "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Може да използвате опцията за собствен сървър, за да влезете в друг Matrix сървър, чрез указване на адреса му. Това позволява да използвате %(brand)s с Matrix профил съществуващ на друг сървър." + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Може да използвате опцията за собствен сървър, за да влезете в друг Matrix сървър, чрез указване на адреса му. Това позволява да използвате %(brand)s с Matrix профил съществуващ на друг сървър.", + "Forgot password?": "Забравена парола?", + "Search (must be enabled)": "Търсене (трябва да е включено)", + "Go to Home View": "Отиване на начален изглед", + "%(creator)s created this DM.": "%(creator)s създаде този директен чат.", + "You have no visible notifications.": "Нямате видими уведомления.", + "Filter rooms and people": "Филтриране на стаи и хора", + "Got an account? Sign in": "Имате профил? Влезте от тук", + "New here? Create an account": "Вие сте нов тук? Създайте профил", + "There was a problem communicating with the homeserver, please try again later.": "Възникна проблем при комуникацията със Home сървъра, моля опитайте отново по-късно.", + "New? Create account": "Вие сте нов? Създайте профил", + "That username already exists, please try another.": "Това потребителско име е вече заето, моля опитайте с друго.", + "Continue with %(ssoButtons)s": "Продължаване с %(ssoButtons)s", + "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s Или %(usernamePassword)s", + "Already have an account? Sign in here": "Вече имате профил? Влезте от тук", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Ние ще запазим шифровано копие на вашите ключове на нашият сървър. Защитете вашето резервно копие с фраза за сигурност.", + "Your Security Key has been copied to your clipboard, paste it to:": "Ключа за сигурност беше копиран в клиборда, поставете го в:", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Тази сесия откри, че вашата фраза за сигурност и ключ за защитени съобщения бяха премахнати.", + "A new Security Phrase and key for Secure Messages have been detected.": "Новa фраза за сигурност и ключ за защитени съобщения бяха открити.", + "Use Security Key or Phrase": "Използване на ключ или фраза за сигурност", + "Use Security Key": "Използване на ключ за сигурност", + "Great! This Security Phrase looks strong enough.": "Чудесно! Тази фраза за сигурност изглежда достатъчно силна.", + "Set up with a Security Key": "Настройка със ключ за сигурност", + "Please enter your Security Phrase a second time to confirm.": "Моля въведете фразата си за сигурност повторно за да потвърдите.", + "Repeat your Security Phrase...": "Повторете фразата си за сигурност...", + "Your Security Key is in your Downloads folder.": "Ключа за сигурност е във вашата папка Изтегляния.", + "Your Security Key": "Вашият ключ за сигурност", + "Secure your backup with a Security Phrase": "Защитете вашето резервно копие с фраза за сигурност", + "Make a copy of your Security Key": "Направете копие на вашият ключ за сигурност", + "Confirm your Security Phrase": "Потвърдете вашата фраза за сигурност", + "Converts the DM to a room": "Превръща директния чат в стая", + "Converts the room to a DM": "Превръща стаята в директен чат", + "Takes the call in the current room off hold": "Възстановява повикването в текущата стая", + "Places the call in the current room on hold": "Задържа повикването в текущата стая", + "Permission is granted to use the webcam": "Разрешение за използване на уеб камерата е дадено", + "Call failed because webcam or microphone could not be accessed. Check that:": "Неуспешно повикване поради неуспешен достъп до уеб камера или микрофон. Проверете дали:", + "A microphone and webcam are plugged in and set up correctly": "Микрофон и уеб камера са включени и настроени правилно", + "We couldn't log you in": "Не можахме да ви впишем", + "You've reached the maximum number of simultaneous calls.": "Достигнахте максималният брой едновременни повиквания.", + "No other application is using the webcam": "Никое друго приложение не използва уеб камерата", + "Unable to access webcam / microphone": "Неуспешен достъп до уеб камера / микрофон", + "Unable to access microphone": "Неуспешен достъп до микрофон", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Неуспешно свързване към вашият Home сървър. Моля затворете този прозорец и опитайте отново.", + "Abort": "Прекрати", + "%(hostSignupBrand)s Setup": "Настройка на %(hostSignupBrand)s", + "Maximize dialog": "Максимизирай прозореца", + "Minimize dialog": "Минимизирай прозореца", + "Learn more in our , and .": "Научете повече в нашите , и .", + "Cookie Policy": "Политика за бисквитките", + "Privacy Policy": "Политика за поверителност", + "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "Добавя ┬──┬ ノ( ゜-゜ノ) в началото на съобщението", + "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Добавя (╯°□°)╯︵ ┻━┻ в началото на съобщението", + "Effects": "Ефекти", + "Anguilla": "Ангила", + "British Indian Ocean Territory": "Британска територия в Индийския океан", + "Pitcairn Islands": "острови Питкерн", + "Heard & McDonald Islands": "острови Хърд и Макдоналд", + "Cook Islands": "острови Кук", + "Christmas Island": "остров Рождество", + "Brunei": "Бруней Даруссалам", + "Bouvet Island": "остров Буве", + "Zimbabwe": "Зимбабве", + "Zambia": "Замбия", + "Yemen": "Йемен", + "Western Sahara": "Западна Сахара", + "Wallis & Futuna": "Уолис и Футуна", + "Vietnam": "Виетнам", + "Venezuela": "Венецуела", + "Vatican City": "Ватикан", + "Vanuatu": "Вануату", + "Uzbekistan": "Узбекистан", + "Uruguay": "Уругвай", + "United Arab Emirates": "Обединени арабски емирства", + "Ukraine": "Украйна", + "Uganda": "Уганда", + "U.S. Virgin Islands": "Американски Вирджински острови", + "Tuvalu": "Тувалу", + "Turks & Caicos Islands": "острови Търкс и Кайкос", + "Turkmenistan": "Туркменистан", + "Turkey": "Турция", + "Tunisia": "Тунис", + "Trinidad & Tobago": "Тринидад и Тобаго", + "Tonga": "Тонга", + "Timor-Leste": "Източен Тимор", + "Tokelau": "Токелау", + "Togo": "Того", + "Thailand": "Тайланд", + "Tanzania": "Танзания", + "Tajikistan": "Таджикистан", + "Taiwan": "Тайван", + "São Tomé & Príncipe": "Сао Томе и Принсипи", + "Syria": "Сирия", + "Switzerland": "Швейцария", + "Sweden": "Швеция", + "Swaziland": "Есватини", + "Svalbard & Jan Mayen": "Свалбард и Ян Майен", + "Suriname": "Суринам", + "Sudan": "Судан", + "St. Vincent & Grenadines": "Сейнт Винсънт и Гренадини", + "St. Pierre & Miquelon": "Сен Пиер и Микелон", + "St. Martin": "Сен Мартен", + "St. Lucia": "Сейнт Лусия", + "St. Kitts & Nevis": "Сейнт Китс и Невис", + "St. Helena": "Света Елена", + "St. Barthélemy": "Сен Бартелеми", + "Sri Lanka": "Шри Ланка", + "Spain": "Испания", + "South Sudan": "Южен Судан", + "South Korea": "Южна Корея", + "South Georgia & South Sandwich Islands": "Южна Джорджия и Южни Сандвичеви острови", + "South Africa": "Южна Африка", + "Somalia": "Сомалия", + "Solomon Islands": "Соломонови острови", + "Slovenia": "Словения", + "Slovakia": "Словакия", + "Sint Maarten": "Синт Мартен", + "Singapore": "Сингапур", + "Sierra Leone": "Сиера Леоне", + "Seychelles": "Сейшели", + "Serbia": "Сърбия", + "Senegal": "Сенегал", + "Saudi Arabia": "Саудитска Арабия", + "San Marino": "Сан Марино", + "Samoa": "Самоа", + "Réunion": "Реюнион", + "Rwanda": "Руанда", + "Russia": "Русия", + "Romania": "Румъния", + "Qatar": "Катар", + "Puerto Rico": "Пуерто Рико", + "Portugal": "Португалия", + "Poland": "Полша", + "Philippines": "Филипини", + "Peru": "Перу", + "Paraguay": "Парагвай", + "Papua New Guinea": "Папуа-Нова Гвинея", + "Panama": "Панама", + "Palestine": "Палестина", + "Palau": "Палау", + "Pakistan": "Пакистан", + "Oman": "Оман", + "Norway": "Норвегия", + "Northern Mariana Islands": "Северни Мариански острови", + "North Korea": "Северна Корея", + "Norfolk Island": "остров Норфолк", + "Niue": "Ниуе", + "Nigeria": "Нигерия", + "Niger": "Нигер", + "Nicaragua": "Никарагуа", + "New Zealand": "Нова Зеландия", + "New Caledonia": "Нова Каледония", + "Netherlands": "Нидерландия", + "Nepal": "Непал", + "Nauru": "Науру", + "Namibia": "Намибия", + "Myanmar": "Мианмар (Бирма)", + "Mozambique": "Мозамбик", + "Morocco": "Мароко", + "Montserrat": "Монтсерат", + "Montenegro": "Черна гора", + "Mongolia": "Монголия", + "Monaco": "Монако", + "Moldova": "Молдова", + "Micronesia": "Микронезия", + "Mexico": "Мексико", + "Mayotte": "Майот", + "Mauritius": "Мавриций", + "Mauritania": "Мавритания", + "Martinique": "Мартиника", + "Marshall Islands": "Маршалови острови", + "Malta": "Малта", + "Mali": "Мали", + "Maldives": "Малдиви", + "Malaysia": "Малайзия", + "Malawi": "Малави", + "Madagascar": "Мадагаскар", + "Macedonia": "Северна Македония", + "Macau": "Макао", + "Luxembourg": "Люксембург", + "Lithuania": "Литва", + "Liechtenstein": "Лихтенщайн", + "Libya": "Либия", + "Liberia": "Либерия", + "Lesotho": "Лесото", + "Lebanon": "Ливан", + "Latvia": "Латвия", + "Laos": "Лаос", + "Kyrgyzstan": "Киргизстан", + "Kuwait": "Кувейт", + "Kosovo": "Косово", + "Kiribati": "Кирибати", + "Kenya": "Кения", + "Kazakhstan": "Казахстан", + "Jordan": "Йордания", + "Jersey": "Джърси", + "Japan": "Япония", + "Jamaica": "Ямайка", + "Italy": "Италия", + "Israel": "Израел", + "Isle of Man": "остров Ман", + "Ireland": "Ирландия", + "Iraq": "Ирак", + "Iran": "Иран", + "Indonesia": "Индонезия", + "India": "Индия", + "Iceland": "Исландия", + "Hungary": "Унгария", + "Hong Kong": "Хонконг", + "Honduras": "Хондурас", + "Haiti": "Хаити", + "Guyana": "Гаяна", + "Guinea-Bissau": "Гвинея-Бисау", + "Guinea": "Гвинея", + "Guernsey": "Гърнзи", + "Guatemala": "Гватемала", + "Guam": "Гуам", + "Guadeloupe": "Гваделупа", + "Grenada": "Гренада", + "Greenland": "Гренландия", + "Greece": "Гърция", + "Gibraltar": "Гибралтар", + "Ghana": "Гана", + "Germany": "Германия", + "Georgia": "Грузия", + "Gambia": "Гамбия", + "Gabon": "Габон", + "French Southern Territories": "Френски южни територии", + "French Polynesia": "Френска Полинезия", + "French Guiana": "Френска Гвиана", + "France": "Франция", + "Finland": "Финландия", + "Fiji": "Фиджи", + "Faroe Islands": "Фарьорски острови", + "Falkland Islands": "Фолкландски острови", + "Ethiopia": "Етиопия", + "Estonia": "Естония", + "Eritrea": "Еритрея", + "Equatorial Guinea": "Екваториална Гвинея", + "El Salvador": "Салвадор", + "Egypt": "Египет", + "Ecuador": "Еквадор", + "Dominican Republic": "Доминиканска република", + "Dominica": "Доминика", + "Djibouti": "Джибути", + "Denmark": "Дания", + "Côte d’Ivoire": "Кот д’Ивоар", + "Czech Republic": "Чешка република", + "Cyprus": "Кипър", + "Curaçao": "Кюрасао", + "Cuba": "Куба", + "Croatia": "Хърватия", + "Costa Rica": "Коста Рика", + "Congo - Kinshasa": "Конго (Киншаса)", + "Congo - Brazzaville": "Конго (Бразавил)", + "Comoros": "Коморски острови", + "Colombia": "Колумбия", + "Cocos (Keeling) Islands": "Кокосови острови", + "China": "Китай", + "Chile": "Чили", + "Chad": "Чад", + "Central African Republic": "Централноафриканска република", + "Cayman Islands": "Кайманови острови", + "Caribbean Netherlands": "Карибска Нидерландия", + "Cape Verde": "Кабо Верде", + "Canada": "Канада", + "Cameroon": "Камерун", + "Cambodia": "Камбоджа", + "Burundi": "Бурунди", + "Burkina Faso": "Буркина Фасо", + "Bulgaria": "България", + "British Virgin Islands": "Британски Вирджински острови", + "Brazil": "Бразилия", + "Botswana": "Ботсвана", + "Bosnia": "Босна и Херцеговина", + "Bolivia": "Боливия", + "Bhutan": "Бутан", + "Bermuda": "Бермудски острови", + "Benin": "Бенин", + "Belize": "Белиз", + "Belgium": "Белгия", + "Belarus": "Беларус", + "Barbados": "Барбадос", + "Bangladesh": "Бангладеш", + "Bahrain": "Бахрейн", + "Bahamas": "Бахамски острови", + "Azerbaijan": "Азербайджан", + "Austria": "Австрия", + "Australia": "Австралия", + "Aruba": "Аруба", + "Armenia": "Армения", + "Argentina": "Аржентина", + "Antigua & Barbuda": "Антигуа и Барбуда", + "Antarctica": "Антарктика", + "Angola": "Ангола", + "Andorra": "Андора", + "American Samoa": "Американска Самоа", + "Algeria": "Алжир", + "Albania": "Албания", + "Åland Islands": "Оландски острови", + "Afghanistan": "Афганистан", + "United States": "Съединените щати", + "United Kingdom": "Обединеното кралство" } From e6fbcbce6e653a777086cf685ac58b6ea0c1f141 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 10 Feb 2021 16:33:51 +0000 Subject: [PATCH 0220/2651] Translated using Weblate (Albanian) Currently translated at 99.6% (2755 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sq/ --- src/i18n/strings/sq.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index cf9c316019..e8e47ac81b 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -3043,5 +3043,18 @@ "Show line numbers in code blocks": "Shfaq numra rreshtat në blloqe kodi", "Expand code blocks by default": "Zgjeroji blloqet e kodit, si parazgjedhje", "Show stickers button": "Shfaq buton ngjitësish", - "Recently visited rooms": "Dhoma të vizituara së fundi" + "Recently visited rooms": "Dhoma të vizituara së fundi", + "Upgrade to pro": "Përmirësojeni me pro", + "Minimize dialog": "Minimizoje dialogun", + "Maximize dialog": "Zmadhoje plotësisht dialogun", + "%(hostSignupBrand)s Setup": "Ujdisje %(hostSignupBrand)s", + "You should know": "Duhet të dini", + "Privacy Policy": "Rregulla Privatësie", + "Cookie Policy": "Rregulla Cookie-sh", + "Learn more in our , and .": "Mësoni më tepër te , dhe tonat.", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Vazhdimi lejon përkohësisht procesin e ujdisjes së %(hostSignupBrand)s të hyjë në llogarinë tuaj dhe të sjellë adresa email të verifikuara. Këto të dhëna nuk depozitohen.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "S’u arrit të lidhej me shërbyesin tuaj Home. Ju lutemi, mbylleni këtë dialog dhe riprovoni.", + "Abort": "Ndërprite", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Jeni i sigurt se doni të ndërpritet krijimi i strehës? Procesi s’mund të vazhdohet.", + "Confirm abort of host creation": "Ripohoni ndërprerjen e krijimit të strehës" } From a274ec95010971b5f81f25054f2921e6367c65b2 Mon Sep 17 00:00:00 2001 From: nilsjha Date: Thu, 18 Feb 2021 20:56:06 +0000 Subject: [PATCH 0221/2651] Translated using Weblate (Norwegian Nynorsk) Currently translated at 44.8% (1240 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/nn/ --- src/i18n/strings/nn.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/nn.json b/src/i18n/strings/nn.json index d7ad9e8320..478f05b5cb 100644 --- a/src/i18n/strings/nn.json +++ b/src/i18n/strings/nn.json @@ -1346,7 +1346,7 @@ "This session is backing up your keys. ": "Denne økta har aktivert sikkerheitskopiering av nøklane dine ", "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.": "Lag sikkerheitskopiar av krypteringsnøklane saman med kontoinnstillingane, slik at du kan gjenopprette data viss det skulle skje at du å mister tilgang til øktene dine. Sikkerheitskopiane er beskytta med ein unik gjenopprettingsnøkkel (Recovery Key).", "Encryption": "Kryptografi", - "Use Ctrl + Enter to send a message": "Bruk tastekombinasjonen Ctrl + Enter for å sende meldingar", + "Use Ctrl + Enter to send a message": "Bruk Ctrl + Enter for å sende meldingar", "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Skriv namnet på skrifttypen(fonten) og %(brand)s forsøka å henta den frå operativsystemet.", "Use a system font": "Bruk tilpassa skrifttype henta frå operativsystemet", "System font name": "Namn på skrifttype", @@ -1371,5 +1371,10 @@ "List options": "Sjå alternativ", "Explore Public Rooms": "Utforsk offentlege rom", "Explore all public rooms": "Utforsk alle offentlege rom", - "Explore public rooms": "Utforsk offentlege rom" + "Explore public rooms": "Utforsk offentlege rom", + "Use Ctrl + F to search": "Bruk Ctrl + F for søk", + "Identity Server": "Identitetstenar", + "Email Address": "E-postadresse", + "Go Back": "Gå attende", + "Notification settings": "Varslingsinnstillingar" } From 50c5a2d5fc43084b880e1d1a46189ac7db6d4b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 10 Feb 2021 18:12:10 +0000 Subject: [PATCH 0222/2651] Translated using Weblate (Estonian) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/et/ --- src/i18n/strings/et.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json index 4d129c2ca3..7769cf61c8 100644 --- a/src/i18n/strings/et.json +++ b/src/i18n/strings/et.json @@ -3053,5 +3053,18 @@ "Share your screen": "Jaga oma ekraani", "Show line numbers in code blocks": "Näita koodiblokkides reanumbreid", "Expand code blocks by default": "Vaikimisi kuva koodiblokid tervikuna", - "Recently visited rooms": "Hiljuti külastatud jututoad" + "Recently visited rooms": "Hiljuti külastatud jututoad", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Jätkates ajutistel alustel, on sul võimalik %(hostSignupBrand)s seadistamisega edasi minna ning kontole ligipääsuka laadida verifitseeritud e-posti aadress. Seda teavet ei salvestata.", + "Abort": "Katkesta", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Kas sa oled kindel, et soovid katkestada seoste loomise? Sel juhul me edasi ei jätka.", + "Confirm abort of host creation": "Kinnita seoste loomise katkestamine", + "Upgrade to pro": "Võta kasutusele tasuline teenus", + "Minimize dialog": "Tee aken väikeseks", + "Maximize dialog": "Tee aken suureks", + "%(hostSignupBrand)s Setup": "%(hostSignupBrand)s seadistus", + "You should know": "Sa peaksid teadma", + "Privacy Policy": "Privaatsuspoliitika", + "Cookie Policy": "Küpsiste kasutamine", + "Learn more in our , and .": "Lisateavet leiad , ja lehtedelt.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Ei õnnestunud ühendada koduserveriga. Palun sulge see aken ja proovi uuesti." } From fa9ae89b5bdf214d56b1d102cfa20b3c90f0f148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 18:24:44 +0100 Subject: [PATCH 0223/2651] Don't show info if no event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index cd104cce37..c00b62ecc8 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -245,6 +245,30 @@ export default class ImageView extends React.Component { const event = this.props.mxEvent; + let info; + if (event) { + info = ( +
+ +
+ { event.sender ? event.sender.name : event.getSender() } + { metadata } +
+
+ ); + } else { + // If there is no event - we're viewing an avatar, we set + // an empty div here, since the panel uses space-between + // and we want the same placement of elements + info = ( +
+ ); + } + return (
-
- -
- { event.sender ? event.sender.name : event.getSender() } - { metadata } -
-
+ {info}
Date: Wed, 24 Feb 2021 17:27:56 +0000 Subject: [PATCH 0224/2651] Upgrade matrix-js-sdk to 9.8.0-rc.1 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d4f931d811..7b4e577406 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "9.8.0-rc.1", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "pako": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index 01450908cc..bef26e27b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5572,9 +5572,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "9.7.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/c82bc35202f93efa2cb9b27b140f83df37c64ab2" +matrix-js-sdk@9.8.0-rc.1: + version "9.8.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-9.8.0-rc.1.tgz#229122583bec5971f22a423a4a40d749e07602d9" + integrity sha512-Tmo5cdyBBgYcMZMaAavEvtdCsEwr5sYE0RLd6etLOSTxmGRSYpqKvvKQqGsYrogmZYNbx9nNZYYYV2aJkCKcQg== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From c78d1c49abc6b278f16e289681ed61a7d3f5dd0e Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Feb 2021 17:32:00 +0000 Subject: [PATCH 0225/2651] Apply changes from review --- src/components/structures/LoggedInView.tsx | 4 ++-- src/toasts/ServerLimitToast.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index f3cce3ef34..c01214f3f4 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -305,7 +305,7 @@ class LoggedInView extends React.Component { } }; - _onHideToast = () => { + private onUsageLimitDismissed = () => { this.setState({ usageLimitDismissed: true, }); @@ -322,7 +322,7 @@ class LoggedInView extends React.Component { if (usageLimitEventContent && this.state.usageLimitDismissed) { showServerLimitToast( usageLimitEventContent.limit_type, - this._onHideToast, + this.onUsageLimitDismissed, usageLimitEventContent.admin_contact, error, ); diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index 068d62f9ea..28c0ec9598 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -40,7 +40,7 @@ export const showToast = (limitType: string, onHideToast: () => void, adminConta acceptLabel: _t("Ok"), onAccept: () => { hideToast() - onHideToast() + if (onHideToast) { onHideToast() } }, }, component: GenericToast, From 364f24851355fe0b1a716cd5973bbc19cf575d7a Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 24 Feb 2021 17:32:53 +0000 Subject: [PATCH 0226/2651] Prepare changelog for v3.15.0-rc.1 --- CHANGELOG.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c87f1c62e6..e727adabfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,65 @@ +Changes in [3.15.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.15.0-rc.1) (2021-02-24) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.14.0...v3.15.0-rc.1) + + * Upgrade to JS SDK 9.8.0-rc.1 + * Translations update from Weblate + [\#5683](https://github.com/matrix-org/matrix-react-sdk/pull/5683) + * Fix object diffing when objects have different keys + [\#5681](https://github.com/matrix-org/matrix-react-sdk/pull/5681) + * Add if it's missing + [\#5673](https://github.com/matrix-org/matrix-react-sdk/pull/5673) + * Add email only if the verification is complete + [\#5629](https://github.com/matrix-org/matrix-react-sdk/pull/5629) + * Fix portrait videocalls + [\#5676](https://github.com/matrix-org/matrix-react-sdk/pull/5676) + * Tweak code block icon positions + [\#5643](https://github.com/matrix-org/matrix-react-sdk/pull/5643) + * Revert "Improve URL preview formatting and image upload thumbnail size" + [\#5677](https://github.com/matrix-org/matrix-react-sdk/pull/5677) + * Fix context menu leaving visible area + [\#5644](https://github.com/matrix-org/matrix-react-sdk/pull/5644) + * Jitsi conferences names, take 3 + [\#5675](https://github.com/matrix-org/matrix-react-sdk/pull/5675) + * Update isUserOnDarkTheme to take use_system_theme in account + [\#5670](https://github.com/matrix-org/matrix-react-sdk/pull/5670) + * Discard some dead code + [\#5665](https://github.com/matrix-org/matrix-react-sdk/pull/5665) + * Add developer tool to explore and edit settings + [\#5664](https://github.com/matrix-org/matrix-react-sdk/pull/5664) + * Use and create new room helpers + [\#5663](https://github.com/matrix-org/matrix-react-sdk/pull/5663) + * Clear message previews when the maximum limit is reached for history + [\#5661](https://github.com/matrix-org/matrix-react-sdk/pull/5661) + * VoIP virtual rooms, mk II + [\#5639](https://github.com/matrix-org/matrix-react-sdk/pull/5639) + * Disable chat effects when reduced motion preferred + [\#5660](https://github.com/matrix-org/matrix-react-sdk/pull/5660) + * Improve URL preview formatting and image upload thumbnail size + [\#5637](https://github.com/matrix-org/matrix-react-sdk/pull/5637) + * Fix border radius when the panel is collapsed + [\#5641](https://github.com/matrix-org/matrix-react-sdk/pull/5641) + * Use a more generic layout setting - useIRCLayout → layout + [\#5571](https://github.com/matrix-org/matrix-react-sdk/pull/5571) + * Remove redundant lockOrigin parameter from usercontent + [\#5657](https://github.com/matrix-org/matrix-react-sdk/pull/5657) + * Set ICE candidate pool size option + [\#5655](https://github.com/matrix-org/matrix-react-sdk/pull/5655) + * Prepare to encrypt when a call arrives + [\#5654](https://github.com/matrix-org/matrix-react-sdk/pull/5654) + * Use config for host signup branding + [\#5650](https://github.com/matrix-org/matrix-react-sdk/pull/5650) + * Use randomly generated conference names for Jitsi + [\#5649](https://github.com/matrix-org/matrix-react-sdk/pull/5649) + * Modified regex to account for an immediate new line after slash commands + [\#5647](https://github.com/matrix-org/matrix-react-sdk/pull/5647) + * Fix codeblock scrollbar color for non-Firefox + [\#5642](https://github.com/matrix-org/matrix-react-sdk/pull/5642) + * Fix codeblock scrollbar colors + [\#5630](https://github.com/matrix-org/matrix-react-sdk/pull/5630) + * Added loading and disabled the button while searching for server + [\#5634](https://github.com/matrix-org/matrix-react-sdk/pull/5634) + Changes in [3.14.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.14.0) (2021-02-16) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.14.0-rc.1...v3.14.0) From 8860c8bfe7b48cbfb230f28e81d48ea7f474e3f4 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 24 Feb 2021 17:32:54 +0000 Subject: [PATCH 0227/2651] v3.15.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7b4e577406..f49b99831f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.14.0", + "version": "3.15.0-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -27,7 +27,7 @@ "matrix-gen-i18n": "scripts/gen-i18n.js", "matrix-prune-i18n": "scripts/prune-i18n.js" }, - "main": "./src/index.js", + "main": "./lib/index.js", "matrix_src_main": "./src/index.js", "matrix_lib_main": "./lib/index.js", "matrix_lib_typings": "./lib/index.d.ts", @@ -189,5 +189,6 @@ "transformIgnorePatterns": [ "/node_modules/(?!matrix-js-sdk).+$" ] - } + }, + "typings": "./lib/index.d.ts" } From bd5efc7ceb0d1d56ef4b87e8a77ec12b1cc2c11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 19:11:08 +0100 Subject: [PATCH 0228/2651] Pass permallinkCreator to ImageView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 1 + src/components/views/messages/MImageBody.js | 3 +++ src/components/views/messages/MessageEvent.js | 3 +++ src/components/views/rooms/EventTile.js | 1 + 4 files changed, 8 insertions(+) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index c00b62ecc8..ede4cc9623 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -42,6 +42,7 @@ export default class ImageView extends React.Component { // properties above, which let us use lightboxes to display images which aren't associated // with events. mxEvent: PropTypes.object, + permalinkCreator: PropTypes.object, }; constructor(props) { diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 8456a5bd09..616f2b1cc8 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -38,6 +38,8 @@ export default class MImageBody extends React.Component { /* the maximum image height to use */ maxImageHeight: PropTypes.number, + + permalinkCreator: PropTypes.object, }; static contextType = MatrixClientContext; @@ -103,6 +105,7 @@ export default class MImageBody extends React.Component { src: httpUrl, name: content.body && content.body.length > 0 ? content.body : _t('Attachment'), mxEvent: this.props.mxEvent, + permalinkCreator: this.props.permalinkCreator, }; if (content.info) { diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index f93813fe79..daee6558c9 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -44,6 +44,8 @@ export default class MessageEvent extends React.Component { /* the maximum image height to use, if the event is an image */ maxImageHeight: PropTypes.number, + + permalinkCreator: PropTypes.object, }; constructor(props) { @@ -120,6 +122,7 @@ export default class MessageEvent extends React.Component { editState={this.props.editState} onHeightChanged={this.props.onHeightChanged} onMessageAllowed={this.onTileUpdate} + permalinkCreator={this.props.permalinkCreator} />; } } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index c856919f5a..fb0fa7d6d2 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -968,6 +968,7 @@ export default class EventTile extends React.Component { highlights={this.props.highlights} highlightLink={this.props.highlightLink} showUrlPreview={this.props.showUrlPreview} + permalinkCreator={this.props.permalinkCreator} onHeightChanged={this.props.onHeightChanged} /> { keyRequestInfo } { reactionsRow } From 9312becee56ee0dd5b704e0913b9fc8fc2c1119a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 19:17:33 +0100 Subject: [PATCH 0229/2651] Add context menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 48 +++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index ede4cc9623..5f77b1ccfa 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from 'react'; +import React, { createRef } from 'react'; import PropTypes from 'prop-types'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {formatDate} from '../../../DateUtils'; @@ -26,6 +26,9 @@ import * as sdk from "../../../index"; import {Key} from "../../../Keyboard"; import FocusLock from "react-focus-lock"; import MemberAvatar from "../avatars/MemberAvatar"; +import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/ContextMenuTooltipButton"; +import MessageContextMenu from "../context_menus/MessageContextMenu"; +import {aboveLeftOf, ContextMenu} from '../../structures/ContextMenu'; export default class ImageView extends React.Component { static propTypes = { @@ -53,9 +56,11 @@ export default class ImageView extends React.Component { translationX: 0, translationY: 0, moving: false, + contextMenuDisplay: false, }; } + contextMenuButton = createRef(); initX = 0; initY = 0; lastX = 0; @@ -179,6 +184,20 @@ export default class ImageView extends React.Component { a.click(); } + onOpenContextMenu = (ev) => { + ev.preventDefault(); + ev.stopPropagation(); + this.setState({ + contextMenuDisplay: true, + }); + } + + onCloseContextMenu = () => { + this.setState({ + contextMenuDisplay: false, + }); + } + onPanelClick = (ev) => { this.props.onFinished(); } @@ -210,6 +229,30 @@ export default class ImageView extends React.Component { this.setState({moving: false}); } + renderContextMenu() { + let contextMenu = null; + if (this.state.contextMenuDisplay) { + contextMenu = ( + + + + ); + } + + return ( + + { contextMenu } + + ); + } + render() { const showEventMeta = !!this.props.mxEvent; @@ -313,12 +356,15 @@ export default class ImageView extends React.Component { + {this.renderContextMenu()}
From c11c8c2fafc23564e9cacbfc947e941e341b3cc3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 24 Feb 2021 11:20:58 -0700 Subject: [PATCH 0230/2651] Update src/toasts/ServerLimitToast.tsx --- src/toasts/ServerLimitToast.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index 28c0ec9598..81b5492402 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -40,7 +40,7 @@ export const showToast = (limitType: string, onHideToast: () => void, adminConta acceptLabel: _t("Ok"), onAccept: () => { hideToast() - if (onHideToast) { onHideToast() } + if (onHideToast) onHideToast(); }, }, component: GenericToast, From 81698a2714ff2637d522831c109f4e7a0750fbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 19:31:19 +0100 Subject: [PATCH 0231/2651] Fix pointer-events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index bb99454152..cd5f9a247b 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -58,9 +58,7 @@ limitations under the License. .mx_ImageView_panel { width: 100%; height: 68px; - z-index: 1000; align-self: flex-start; - pointer-events: all; display: flex; justify-content: space-between; align-items: center; @@ -76,6 +74,7 @@ limitations under the License. .mx_ImageView_toolbar_buttons { display: flex; align-items: center; + pointer-events: all; } .mx_ImageView_info_wrapper { @@ -91,6 +90,7 @@ limitations under the License. .mx_ImageView_info { padding-left: 12px; + pointer-events: all; } .mx_ImageView_button { From 2021e4e345c7cfc554421509e88253dcddedcf07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 19:33:17 +0100 Subject: [PATCH 0232/2651] Remove ugly workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 5f77b1ccfa..dc785aabb2 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -131,24 +131,18 @@ export default class ImageView extends React.Component { }; onRotateCounterClockwiseClick = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; this.setState({ rotation: rotationDegrees }); }; onRotateClockwiseClick = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); const cur = this.state.rotation; const rotationDegrees = (cur + 90) % 360; this.setState({ rotation: rotationDegrees }); }; onZoomInClick = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); if (this.state.zoom >= this.maxZoom) { this.setState({zoom: this.maxZoom}); return; @@ -160,8 +154,6 @@ export default class ImageView extends React.Component { }; onZoomOutClick = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); if (this.state.zoom <= this.minZoom) { this.setState({ zoom: this.minZoom, @@ -176,8 +168,6 @@ export default class ImageView extends React.Component { } onDownloadClick = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); const a = document.createElement("a"); a.href = this.props.src; a.download = this.props.name; @@ -185,8 +175,6 @@ export default class ImageView extends React.Component { } onOpenContextMenu = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); this.setState({ contextMenuDisplay: true, }); @@ -198,10 +186,6 @@ export default class ImageView extends React.Component { }); } - onPanelClick = (ev) => { - this.props.onFinished(); - } - onStartMoving = ev => { ev.stopPropagation(); ev.preventDefault(); @@ -324,7 +308,7 @@ export default class ImageView extends React.Component { ref={ref => this.focusLock = ref} >
-
+
{info}
From 7293181552b3bad2b24ec9f9dae80597be82ab04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 19:33:22 +0100 Subject: [PATCH 0233/2651] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 74617e17af..e94e1bbae6 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1861,14 +1861,10 @@ "collapse": "collapse", "expand": "expand", "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", - "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", - "Zoom": "Zoom", + "Rotate Right": "Rotate Right", + "Rotate Left": "Rotate Left", "Zoom out": "Zoom out", "Zoom in": "Zoom in", - "Rotate Left": "Rotate Left", - "Rotate counter-clockwise": "Rotate counter-clockwise", - "Rotate Right": "Rotate Right", - "Rotate clockwise": "Rotate clockwise", "Download": "Download", "Information": "Information", "Language Dropdown": "Language Dropdown", From 983895289c30a9626816ba0ef971cbc01d4eefbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 20:04:25 +0100 Subject: [PATCH 0234/2651] Update info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 7 +--- src/components/views/elements/ImageView.js | 47 +++++++++------------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index cd5f9a247b..11ef9ec692 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -91,6 +91,8 @@ limitations under the License. .mx_ImageView_info { padding-left: 12px; pointer-events: all; + display: flex; + flex-direction: column; } .mx_ImageView_button { @@ -142,8 +144,3 @@ limitations under the License. background-color: none; } } - -.mx_ImageView_metadata { - font-size: $font-15px; - opacity: 0.5; -} diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index dc785aabb2..1a93b5c3f7 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -18,7 +18,6 @@ limitations under the License. import React, { createRef } from 'react'; import PropTypes from 'prop-types'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; -import {formatDate} from '../../../DateUtils'; import { _t } from '../../../languageHandler'; import AccessibleTooltipButton from "./AccessibleTooltipButton"; import Modal from "../../../Modal"; @@ -29,6 +28,8 @@ import MemberAvatar from "../avatars/MemberAvatar"; import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/ContextMenuTooltipButton"; import MessageContextMenu from "../context_menus/MessageContextMenu"; import {aboveLeftOf, ContextMenu} from '../../structures/ContextMenu'; +import MessageTimestamp from "../messages/MessageTimestamp"; +import SenderProfile from '../messages/SenderProfile'; export default class ImageView extends React.Component { static propTypes = { @@ -240,22 +241,6 @@ export default class ImageView extends React.Component { render() { const showEventMeta = !!this.props.mxEvent; - let metadata; - if (showEventMeta) { - // Figure out the sender, defaulting to mxid - let sender = this.props.mxEvent.getSender(); - const cli = MatrixClientPeg.get(); - const room = cli.getRoom(this.props.mxEvent.getRoomId()); - if (room) { - const member = room.getMember(sender); - if (member) sender = member.name; - } - - metadata = (
- { formatDate(new Date(this.props.mxEvent.getTs())) } -
); - } - const rotationDegrees = this.state.rotation + "deg"; const zoomPercentage = this.state.zoom/100; const translatePixelsX = this.state.translationX + "px"; @@ -271,20 +256,28 @@ export default class ImageView extends React.Component { rotate(${rotationDegrees})`, }; - const event = this.props.mxEvent; - let info; - if (event) { + if (showEventMeta) { + const mxEvent = this.props.mxEvent; + + const senderName = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); + const messageTimestamp = ( + + ); + const avatar = ( + + ); + info = (
- + {avatar}
- { event.sender ? event.sender.name : event.getSender() } - { metadata } + {senderName} + {messageTimestamp}
); From 6008a6f9fa09060f2c6851e61a5d416d7a28469d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 24 Feb 2021 20:07:41 +0100 Subject: [PATCH 0235/2651] Use showTwelveHourTimestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 1a93b5c3f7..cbe5b0592f 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -29,7 +29,7 @@ import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/Cont import MessageContextMenu from "../context_menus/MessageContextMenu"; import {aboveLeftOf, ContextMenu} from '../../structures/ContextMenu'; import MessageTimestamp from "../messages/MessageTimestamp"; -import SenderProfile from '../messages/SenderProfile'; +import SettingsStore from "../../../settings/SettingsStore"; export default class ImageView extends React.Component { static propTypes = { @@ -259,10 +259,11 @@ export default class ImageView extends React.Component { let info; if (showEventMeta) { const mxEvent = this.props.mxEvent; + const showTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps"); const senderName = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); const messageTimestamp = ( - + ); const avatar = ( Date: Wed, 24 Feb 2021 20:14:12 +0100 Subject: [PATCH 0236/2651] Make permalink clickable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index cbe5b0592f..073b9dddbd 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -30,6 +30,8 @@ import MessageContextMenu from "../context_menus/MessageContextMenu"; import {aboveLeftOf, ContextMenu} from '../../structures/ContextMenu'; import MessageTimestamp from "../messages/MessageTimestamp"; import SettingsStore from "../../../settings/SettingsStore"; +import {formatTime} from "../../../DateUtils"; +import dis from '../../../dispatcher/dispatcher'; export default class ImageView extends React.Component { static propTypes = { @@ -187,6 +189,18 @@ export default class ImageView extends React.Component { }); } + onPermalinkClicked = e => { + // This allows the permalink to be opened in a new tab/window or copied as + // matrix.to, but also for it to enable routing within Element when clicked. + e.preventDefault(); + dis.dispatch({ + action: 'view_room', + event_id: this.props.mxEvent.getId(), + highlighted: true, + room_id: this.props.mxEvent.getRoomId(), + }); + }; + onStartMoving = ev => { ev.stopPropagation(); ev.preventDefault(); @@ -260,10 +274,21 @@ export default class ImageView extends React.Component { if (showEventMeta) { const mxEvent = this.props.mxEvent; const showTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps"); + let permalink = "#"; + if (this.props.permalinkCreator) { + permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId()); + } const senderName = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); const messageTimestamp = ( - + + + + ); const avatar = ( Date: Wed, 24 Feb 2021 20:41:20 +0100 Subject: [PATCH 0237/2651] Remove rounded border --- res/css/views/elements/_ImageView.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 11ef9ec692..f904d31330 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -48,8 +48,6 @@ limitations under the License. min-width: 100px; min-height: 100px; - border-radius: 8px; - &:hover { cursor: grab; } From 5f74fac2e84057ff9155474416e00793c671c89f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 24 Feb 2021 17:55:27 -0500 Subject: [PATCH 0238/2651] fall back to the old method if the default key isn't available --- src/SecurityManager.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SecurityManager.ts b/src/SecurityManager.ts index 11d228e7ab..03cbe88c22 100644 --- a/src/SecurityManager.ts +++ b/src/SecurityManager.ts @@ -105,9 +105,12 @@ async function getSecretStorageKey( // use the default SSSS key if set keyInfo = keyInfos[keyId]; if (!keyInfo) { - throw new Error("Unable to use default SSSS key"); + // if the default key is not available, pretend the default key + // isn't set + keyId = undefined; } - } else { + } + if (!keyId) { // if no default SSSS key is set, fall back to a heuristic of using the // only available key, if only one key is set const keyInfoEntries = Object.entries(keyInfos); From e2fb9b3ae878fcf68f1b4dd72b3badf16e0b2e13 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 24 Feb 2021 18:10:35 -0700 Subject: [PATCH 0239/2651] Clean up widgets when leaving the room --- .../views/elements/PersistentApp.js | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/PersistentApp.js b/src/components/views/elements/PersistentApp.js index a1e805c085..eb5f4eab7d 100644 --- a/src/components/views/elements/PersistentApp.js +++ b/src/components/views/elements/PersistentApp.js @@ -31,6 +31,7 @@ export default class PersistentApp extends React.Component { componentDidMount() { this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); ActiveWidgetStore.on('update', this._onActiveWidgetStoreUpdate); + MatrixClientPeg.get().on("Room.myMembership", this._onMyMembership); } componentWillUnmount() { @@ -38,6 +39,9 @@ export default class PersistentApp extends React.Component { this._roomStoreToken.remove(); } ActiveWidgetStore.removeListener('update', this._onActiveWidgetStoreUpdate); + if (MatrixClientPeg.get()) { + MatrixClientPeg.get().removeListener("Room.myMembership", this._onMyMembership); + } } _onRoomViewStoreUpdate = payload => { @@ -53,16 +57,28 @@ export default class PersistentApp extends React.Component { }); }; + _onMyMembership = async (room) => { + const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId); + if (room.getMyMembership() !== "join") { + // we're not in the room anymore - delete + if (room.roomId === persistentWidgetInRoomId) { + ActiveWidgetStore.destroyPersistentWidget(this.state.persistentWidgetId); + } + } + }; + render() { if (this.state.persistentWidgetId) { const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId); - if (this.state.roomId !== persistentWidgetInRoomId) { - const persistentWidgetInRoom = MatrixClientPeg.get().getRoom(persistentWidgetInRoomId); - // Sanity check the room - the widget may have been destroyed between render cycles, and - // thus no room is associated anymore. - if (!persistentWidgetInRoom) return null; + const persistentWidgetInRoom = MatrixClientPeg.get().getRoom(persistentWidgetInRoomId); + // Sanity check the room - the widget may have been destroyed between render cycles, and + // thus no room is associated anymore. + if (!persistentWidgetInRoom) return null; + + const myMembership = persistentWidgetInRoom.getMyMembership(); + if (this.state.roomId !== persistentWidgetInRoomId && myMembership === "join") { // get the widget data const appEvent = WidgetUtils.getRoomWidgets(persistentWidgetInRoom).find((ev) => { return ev.getStateKey() === ActiveWidgetStore.getPersistentWidgetId(); From fbe5d177851ce836ca33afb09ab981511e4c87b3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 24 Feb 2021 18:27:59 -0700 Subject: [PATCH 0240/2651] sanity --- src/components/views/elements/PersistentApp.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/PersistentApp.js b/src/components/views/elements/PersistentApp.js index eb5f4eab7d..7801076c66 100644 --- a/src/components/views/elements/PersistentApp.js +++ b/src/components/views/elements/PersistentApp.js @@ -57,9 +57,9 @@ export default class PersistentApp extends React.Component { }); }; - _onMyMembership = async (room) => { + _onMyMembership = async (room, membership) => { const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId); - if (room.getMyMembership() !== "join") { + if (membership !== "join") { // we're not in the room anymore - delete if (room.roomId === persistentWidgetInRoomId) { ActiveWidgetStore.destroyPersistentWidget(this.state.persistentWidgetId); From d58c17ff3bfb75c61329979b7ea8d3ccd69bfe70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 07:50:53 +0100 Subject: [PATCH 0241/2651] Show grabbing cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 4 ---- src/components/views/elements/ImageView.js | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index f904d31330..d864ad9adf 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -47,10 +47,6 @@ limitations under the License. max-height: 70vh; min-width: 100px; min-height: 100px; - - &:hover { - cursor: grab; - } } .mx_ImageView_panel { diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 073b9dddbd..51e700c481 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -264,6 +264,7 @@ export default class ImageView extends React.Component { * we would apply the translation to an already rotated * image causing it translate in the wrong direction. */ const style = { + cursor: this.state.moving ? "grabbing" : "grab", transform: `translateX(${translatePixelsX}) translateY(${translatePixelsY}) scale(${zoomPercentage}) From fe8e90f92063d8efd6f1b880e6f70e994cb84f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 07:51:38 +0100 Subject: [PATCH 0242/2651] Change comment styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 51e700c481..d91b7c8aba 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -72,8 +72,8 @@ export default class ImageView extends React.Component { maxZoom = 300; componentDidMount() { - /* We have to use addEventListener() because the listener - * needs to be passive in order to work with Chromium */ + // We have to use addEventListener() because the listener + // needs to be passive in order to work with Chromium this.focusLock.addEventListener('wheel', this.onWheel, { passive: false }); } @@ -259,10 +259,10 @@ export default class ImageView extends React.Component { const zoomPercentage = this.state.zoom/100; const translatePixelsX = this.state.translationX + "px"; const translatePixelsY = this.state.translationY + "px"; - /* The order of the values is important! - * First, we translate and only then we rotate, otherwise - * we would apply the translation to an already rotated - * image causing it translate in the wrong direction. */ + // The order of the values is important! + // First, we translate and only then we rotate, otherwise + // we would apply the translation to an already rotated + // image causing it translate in the wrong direction. const style = { cursor: this.state.moving ? "grabbing" : "grab", transform: `translateX(${translatePixelsX}) From 5a9e1a14822e5f6ecb5e0fed186e9f021921286c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 08:10:54 +0100 Subject: [PATCH 0243/2651] Fix close icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 7 ++++--- res/img/image-view/close.svg | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index d864ad9adf..9b77f70262 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -90,7 +90,7 @@ limitations under the License. } .mx_ImageView_button { - padding-left: 24px; + margin-left: 24px; display: block; &::before { @@ -130,11 +130,12 @@ limitations under the License. } .mx_ImageView_button_close { - padding-left: 32px; + border-radius: 100%; + background: #21262C; &::before { width: 32px; height: 32px; mask-image: url('$(res)/img/image-view/close.svg'); - background-color: none; + mask-size: 40%; } } diff --git a/res/img/image-view/close.svg b/res/img/image-view/close.svg index f849425264..d603b7f5cc 100644 --- a/res/img/image-view/close.svg +++ b/res/img/image-view/close.svg @@ -1,4 +1,3 @@ - - - + + From 83de84972ed143750f0f633f962398818643207b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 08:13:27 +0100 Subject: [PATCH 0244/2651] Close onPermalinkClicked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index d91b7c8aba..f7826d45fe 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -199,6 +199,7 @@ export default class ImageView extends React.Component { highlighted: true, room_id: this.props.mxEvent.getRoomId(), }); + this.props.onFinished(); }; onStartMoving = ev => { From b18622efe492860153bf60a92ea56ce49dbd4480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 08:20:34 +0100 Subject: [PATCH 0245/2651] Show full date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 6 +++--- src/components/views/messages/MessageTimestamp.js | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index f7826d45fe..5acd36bde0 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -30,7 +30,7 @@ import MessageContextMenu from "../context_menus/MessageContextMenu"; import {aboveLeftOf, ContextMenu} from '../../structures/ContextMenu'; import MessageTimestamp from "../messages/MessageTimestamp"; import SettingsStore from "../../../settings/SettingsStore"; -import {formatTime} from "../../../DateUtils"; +import {formatFullDate} from "../../../DateUtils"; import dis from '../../../dispatcher/dispatcher'; export default class ImageView extends React.Component { @@ -286,9 +286,9 @@ export default class ImageView extends React.Component { - + ); diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.js index 199a6f47ce..26b8096c4f 100644 --- a/src/components/views/messages/MessageTimestamp.js +++ b/src/components/views/messages/MessageTimestamp.js @@ -23,13 +23,18 @@ export default class MessageTimestamp extends React.Component { static propTypes = { ts: PropTypes.number.isRequired, showTwelveHour: PropTypes.bool, + showFullDate: PropTypes.bool, }; render() { const date = new Date(this.props.ts); return ( - { formatTime(date, this.props.showTwelveHour) } + { + this.props.showFullDate ? + formatFullDate(date, this.props.showTwelveHour) : + formatTime(date, this.props.showTwelveHour) + } ); } From 273753a42a9a122b1f6044c2840ef4830896781d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 08:25:34 +0100 Subject: [PATCH 0246/2651] Fix hex formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 9b77f70262..45968ddaa5 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -131,7 +131,7 @@ limitations under the License. .mx_ImageView_button_close { border-radius: 100%; - background: #21262C; + background: #21262c; &::before { width: 32px; height: 32px; From a4130cb7f35ae8325b2b68b457246e23db02158a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 10:23:27 +0100 Subject: [PATCH 0247/2651] Revert trash icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/feather-customised/trash.custom.svg | 89 ++------------------- 1 file changed, 7 insertions(+), 82 deletions(-) diff --git a/res/img/feather-customised/trash.custom.svg b/res/img/feather-customised/trash.custom.svg index 589bb0a4e5..70eeaf35cd 100644 --- a/res/img/feather-customised/trash.custom.svg +++ b/res/img/feather-customised/trash.custom.svg @@ -1,82 +1,7 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - + + + + + + + \ No newline at end of file From 7fc375805628a6b7a11777b70f8c06011e132b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 10:23:59 +0100 Subject: [PATCH 0248/2651] Add newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/feather-customised/trash.custom.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/img/feather-customised/trash.custom.svg b/res/img/feather-customised/trash.custom.svg index 70eeaf35cd..dc1985ddb2 100644 --- a/res/img/feather-customised/trash.custom.svg +++ b/res/img/feather-customised/trash.custom.svg @@ -4,4 +4,4 @@ - \ No newline at end of file + From 984b4372db4e6c56638dc0f6d419acb5b4e8a324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 10:25:24 +0100 Subject: [PATCH 0249/2651] Remove trash red icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/trash-red.svg | 89 ------------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 res/img/trash-red.svg diff --git a/res/img/trash-red.svg b/res/img/trash-red.svg deleted file mode 100644 index 0b1d201d2e..0000000000 --- a/res/img/trash-red.svg +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - From 4f3fe3d236640f744eec9f966b0a0260d698f469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:09:52 +0100 Subject: [PATCH 0250/2651] Add comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/messages/MImageBody.js | 1 + src/components/views/messages/MessageEvent.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 616f2b1cc8..b1d5995121 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -39,6 +39,7 @@ export default class MImageBody extends React.Component { /* the maximum image height to use */ maxImageHeight: PropTypes.number, + /* the permalinkCreator */ permalinkCreator: PropTypes.object, }; diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index daee6558c9..fe0bb19fda 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -45,6 +45,7 @@ export default class MessageEvent extends React.Component { /* the maximum image height to use, if the event is an image */ maxImageHeight: PropTypes.number, + /* the permalinkCreator */ permalinkCreator: PropTypes.object, }; From d0dea91e92986cbcb07d53888a4014cb69a0ba6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:16:40 +0100 Subject: [PATCH 0251/2651] contextMenuDisplay -> contextMenuDisplayed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 5acd36bde0..bbadad9778 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -59,7 +59,7 @@ export default class ImageView extends React.Component { translationX: 0, translationY: 0, moving: false, - contextMenuDisplay: false, + contextMenuDisplayed: false, }; } @@ -179,13 +179,13 @@ export default class ImageView extends React.Component { onOpenContextMenu = (ev) => { this.setState({ - contextMenuDisplay: true, + contextMenuDisplayed: true, }); } onCloseContextMenu = () => { this.setState({ - contextMenuDisplay: false, + contextMenuDisplayed: false, }); } @@ -231,7 +231,7 @@ export default class ImageView extends React.Component { renderContextMenu() { let contextMenu = null; - if (this.state.contextMenuDisplay) { + if (this.state.contextMenuDisplayed) { contextMenu = ( Date: Thu, 25 Feb 2021 11:19:50 +0100 Subject: [PATCH 0252/2651] ZOOM shouldn't be a part of the class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index bbadad9778..6e9066ccbf 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -33,6 +33,9 @@ import SettingsStore from "../../../settings/SettingsStore"; import {formatFullDate} from "../../../DateUtils"; import dis from '../../../dispatcher/dispatcher'; +const MIN_ZOOM = 100; +const MAX_ZOOM = 300; + export default class ImageView extends React.Component { static propTypes = { src: PropTypes.string.isRequired, // the source of the image being displayed @@ -68,8 +71,6 @@ export default class ImageView extends React.Component { initY = 0; lastX = 0; lastY = 0; - minZoom = 100; - maxZoom = 300; componentDidMount() { // We have to use addEventListener() because the listener @@ -94,16 +95,16 @@ export default class ImageView extends React.Component { ev.preventDefault(); const newZoom =this.state.zoom - ev.deltaY; - if (newZoom <= this.minZoom) { + if (newZoom <= MIN_ZOOM) { this.setState({ - zoom: this.minZoom, + zoom: MIN_ZOOM, translationX: 0, translationY: 0, }); return; } - if (newZoom >= this.maxZoom) { - this.setState({zoom: this.maxZoom}); + if (newZoom >= MAX_ZOOM) { + this.setState({zoom: MAX_ZOOM}); return; } @@ -146,8 +147,8 @@ export default class ImageView extends React.Component { }; onZoomInClick = (ev) => { - if (this.state.zoom >= this.maxZoom) { - this.setState({zoom: this.maxZoom}); + if (this.state.zoom >= MAX_ZOOM) { + this.setState({zoom: MAX_ZOOM}); return; } @@ -157,9 +158,9 @@ export default class ImageView extends React.Component { }; onZoomOutClick = (ev) => { - if (this.state.zoom <= this.minZoom) { + if (this.state.zoom <= MIN_ZOOM) { this.setState({ - zoom: this.minZoom, + zoom: MIN_ZOOM, translationX: 0, translationY: 0, }); From 80ce4da9b66a2d2cf0044bb4ef59f47410a72a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:21:04 +0100 Subject: [PATCH 0253/2651] Remove onRedactClick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 6e9066ccbf..dd5ad56a4a 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -113,27 +113,6 @@ export default class ImageView extends React.Component { }); } - onRedactClick = () => { - const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog"); - Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, { - onFinished: (proceed) => { - if (!proceed) return; - this.props.onFinished(); - MatrixClientPeg.get().redactEvent( - this.props.mxEvent.getRoomId(), this.props.mxEvent.getId(), - ).catch(function(e) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - // display error message stating you couldn't delete this. - const code = e.errcode || e.statusCode; - Modal.createTrackedDialog('You cannot delete this image.', '', ErrorDialog, { - title: _t('Error'), - description: _t('You cannot delete this image. (%(code)s)', {code: code}), - }); - }); - }, - }); - }; - onRotateCounterClockwiseClick = (ev) => { const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; From 4c377ae037fc8bbc1a8a320092550470de8a0b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:23:14 +0100 Subject: [PATCH 0254/2651] Consistent evs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index dd5ad56a4a..c14b8c60bb 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -113,19 +113,19 @@ export default class ImageView extends React.Component { }); } - onRotateCounterClockwiseClick = (ev) => { + onRotateCounterClockwiseClick = () => { const cur = this.state.rotation; const rotationDegrees = (cur - 90) % 360; this.setState({ rotation: rotationDegrees }); }; - onRotateClockwiseClick = (ev) => { + onRotateClockwiseClick = () => { const cur = this.state.rotation; const rotationDegrees = (cur + 90) % 360; this.setState({ rotation: rotationDegrees }); }; - onZoomInClick = (ev) => { + onZoomInClick = () => { if (this.state.zoom >= MAX_ZOOM) { this.setState({zoom: MAX_ZOOM}); return; @@ -136,7 +136,7 @@ export default class ImageView extends React.Component { }); }; - onZoomOutClick = (ev) => { + onZoomOutClick = () => { if (this.state.zoom <= MIN_ZOOM) { this.setState({ zoom: MIN_ZOOM, @@ -150,14 +150,14 @@ export default class ImageView extends React.Component { }); } - onDownloadClick = (ev) => { + onDownloadClick = () => { const a = document.createElement("a"); a.href = this.props.src; a.download = this.props.name; a.click(); } - onOpenContextMenu = (ev) => { + onOpenContextMenu = () => { this.setState({ contextMenuDisplayed: true, }); @@ -169,10 +169,10 @@ export default class ImageView extends React.Component { }); } - onPermalinkClicked = e => { + onPermalinkClicked = (ev) => { // This allows the permalink to be opened in a new tab/window or copied as // matrix.to, but also for it to enable routing within Element when clicked. - e.preventDefault(); + ev.preventDefault(); dis.dispatch({ action: 'view_room', event_id: this.props.mxEvent.getId(), @@ -182,7 +182,7 @@ export default class ImageView extends React.Component { this.props.onFinished(); }; - onStartMoving = ev => { + onStartMoving = (ev) => { ev.stopPropagation(); ev.preventDefault(); @@ -191,7 +191,7 @@ export default class ImageView extends React.Component { this.initY = ev.pageY - this.lastY; } - onMoving = ev => { + onMoving = (ev) => { ev.stopPropagation(); ev.preventDefault(); @@ -205,7 +205,7 @@ export default class ImageView extends React.Component { }); } - onEndMoving = ev => { + onEndMoving = () => { this.setState({moving: false}); } From 436a17bcc91feca49de9c454646a7efeda1404e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:26:34 +0100 Subject: [PATCH 0255/2651] Remove imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/elements/ImageView.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index c14b8c60bb..ea424d9925 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -17,11 +17,8 @@ limitations under the License. import React, { createRef } from 'react'; import PropTypes from 'prop-types'; -import {MatrixClientPeg} from "../../../MatrixClientPeg"; import { _t } from '../../../languageHandler'; import AccessibleTooltipButton from "./AccessibleTooltipButton"; -import Modal from "../../../Modal"; -import * as sdk from "../../../index"; import {Key} from "../../../Keyboard"; import FocusLock from "react-focus-lock"; import MemberAvatar from "../avatars/MemberAvatar"; From dc283241aa08d9cdc24bc35552c8703b38348b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:28:42 +0100 Subject: [PATCH 0256/2651] Remove wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 6 ------ src/components/views/elements/ImageView.js | 2 -- 2 files changed, 8 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 45968ddaa5..4b786a244b 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -22,12 +22,6 @@ limitations under the License. display: flex; width: 100%; height: 100%; -} - -.mx_ImageView_content { - width: 100%; - - display: flex; flex-direction: column; } diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index ea424d9925..21b16ed89d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -305,7 +305,6 @@ export default class ImageView extends React.Component { className="mx_ImageView" ref={ref => this.focusLock = ref} > -
{info}
@@ -363,7 +362,6 @@ export default class ImageView extends React.Component { onMouseLeave={this.onEndMoving} />
-
); } From 1955fff08cfb11761d9328718852270367269719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:50:50 +0100 Subject: [PATCH 0257/2651] CSS cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_ImageView.scss | 31 +++------ src/components/views/elements/ImageView.js | 76 +++++++++++----------- 2 files changed, 47 insertions(+), 60 deletions(-) diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 4b786a244b..626878b03e 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -34,10 +34,9 @@ limitations under the License. } .mx_ImageView_image { - object-fit: contain; pointer-events: all; - max-width: 100vw; + max-width: 70vw; max-height: 70vh; min-width: 100px; min-height: 100px; @@ -46,43 +45,33 @@ limitations under the License. .mx_ImageView_panel { width: 100%; height: 68px; - align-self: flex-start; display: flex; justify-content: space-between; align-items: center; } -.mx_ImageView_toolbar { - padding-right: 16px; - right: 0; - display: flex; - align-items: center; -} - -.mx_ImageView_toolbar_buttons { - display: flex; - align-items: center; - pointer-events: all; -} - .mx_ImageView_info_wrapper { + pointer-events: all; padding-left: 32px; - left: 0; - text-align: left; display: flex; - justify-content: center; flex-direction: row; - color: $lightbox-fg-color; align-items: center; + color: $lightbox-fg-color; } .mx_ImageView_info { padding-left: 12px; - pointer-events: all; display: flex; flex-direction: column; } +.mx_ImageView_toolbar { + padding-right: 16px; + pointer-events: all; + display: flex; + align-items: center; +} + .mx_ImageView_button { margin-left: 24px; display: block; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 21b16ed89d..15bb25d473 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -308,45 +308,43 @@ export default class ImageView extends React.Component {
{info}
-
- - - - - - - - - - - - - - {this.renderContextMenu()} -
+ + + + + + + + + + + + + + {this.renderContextMenu()}
From fc32ceade74c072585c58905e153027f9ab766f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 11:57:39 +0100 Subject: [PATCH 0258/2651] i18n --- src/i18n/strings/en_EN.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e94e1bbae6..982ee44452 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1860,7 +1860,6 @@ "Please create a new issue on GitHub so that we can investigate this bug.": "Please create a new issue on GitHub so that we can investigate this bug.", "collapse": "collapse", "expand": "expand", - "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", "Rotate Right": "Rotate Right", "Rotate Left": "Rotate Left", "Zoom out": "Zoom out", From 864a9974b1fe6015d56c6bf1987e19a354b3378d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 25 Feb 2021 12:20:10 +0000 Subject: [PATCH 0259/2651] Tweak spaces labs flag copy --- src/i18n/strings/en_EN.json | 2 +- src/settings/Settings.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 77451c1da8..973c426420 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -777,7 +777,7 @@ "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s", "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s", "Change notification settings": "Change notification settings", - "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags", + "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.", "Render LaTeX maths in messages": "Render LaTeX maths in messages", "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.", "New spinner design": "New spinner design", diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index a8fa88179b..b452f10e73 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -122,7 +122,8 @@ export interface ISetting { export const SETTINGS: {[setting: string]: ISetting} = { "feature_spaces": { isFeature: true, - displayName: _td("Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags"), + displayName: _td("Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. " + + "Requires compatible homeserver for some features."), supportedLevels: LEVELS_FEATURE, default: false, controller: new ReloadOnChangeController(), From 7030c636f07c32c3616eeddba64e0a0c8dfc6587 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 25 Feb 2021 15:18:54 +0000 Subject: [PATCH 0260/2651] Initial Space Store for keeping track of space hierarchies from sync --- src/@types/global.d.ts | 2 + src/stores/SpaceStore.tsx | 462 ++++++++++++++++++ .../notifications/SpaceNotificationState.ts | 82 ++++ 3 files changed, 546 insertions(+) create mode 100644 src/stores/SpaceStore.tsx create mode 100644 src/stores/notifications/SpaceNotificationState.ts diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 28f22780a2..4aa6df5488 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -38,6 +38,7 @@ import UserActivity from "../UserActivity"; import {ModalWidgetStore} from "../stores/ModalWidgetStore"; import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; import VoipUserMapper from "../VoipUserMapper"; +import {SpaceStoreClass} from "../stores/SpaceStore"; declare global { interface Window { @@ -68,6 +69,7 @@ declare global { mxUserActivity: UserActivity; mxModalWidgetStore: ModalWidgetStore; mxVoipUserMapper: VoipUserMapper; + mxSpaceStore: SpaceStoreClass; } interface Document { diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx new file mode 100644 index 0000000000..d675879138 --- /dev/null +++ b/src/stores/SpaceStore.tsx @@ -0,0 +1,462 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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 {throttle, sortBy} from "lodash"; +import {EventType} from "matrix-js-sdk/src/@types/event"; +import {Room} from "matrix-js-sdk/src/models/room"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; + +import {AsyncStoreWithClient} from "./AsyncStoreWithClient"; +import defaultDispatcher from "../dispatcher/dispatcher"; +import {ActionPayload} from "../dispatcher/payloads"; +import RoomListStore from "./room-list/RoomListStore"; +import SettingsStore from "../settings/SettingsStore"; +import DMRoomMap from "../utils/DMRoomMap"; +import {FetchRoomFn} from "./notifications/ListNotificationState"; +import {SpaceNotificationState} from "./notifications/SpaceNotificationState"; +import {RoomNotificationStateStore} from "./notifications/RoomNotificationStateStore"; +import {DefaultTagID} from "./room-list/models"; +import {EnhancedMap, mapDiff} from "../utils/maps"; +import {setHasDiff} from "../utils/sets"; +import {objectDiff} from "../utils/objects"; +import {arrayHasDiff} from "../utils/arrays"; + +type SpaceKey = string | symbol; + +interface IState {} + +const ACTIVE_SPACE_LS_KEY = "mx_active_space"; + +export const HOME_SPACE = Symbol("home-space"); + +export const UPDATE_TOP_LEVEL_SPACES = Symbol("top-level-spaces"); +export const UPDATE_SELECTED_SPACE = Symbol("selected-space"); +// Space Room ID/HOME_SPACE will be emitted when a Space's children change + +const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms] + return arr.reduce((result, room: Room) => { + result[room.isSpaceRoom() ? 0 : 1].push(room); + return result; + }, [[], []]); +}; + +const getOrder = (ev: MatrixEvent): string | null => { + const content = ev.getContent(); + if (typeof content.order === "string" && Array.from(content.order).every((c: string) => { + const charCode = c.charCodeAt(0); + return charCode >= 0x20 && charCode <= 0x7F; + })) { + return content.order; + } + return null; +} + +const getRoomFn: FetchRoomFn = (room: Room) => { + return RoomNotificationStateStore.instance.getRoomState(room); +}; + +export class SpaceStoreClass extends AsyncStoreWithClient { + constructor() { + super(defaultDispatcher, {}); + } + + // The spaces representing the roots of the various tree-like hierarchies + private rootSpaces: Room[] = []; + // The list of rooms not present in any currently joined spaces + private orphanedRooms = new Set(); + // Map from room ID to set of spaces which list it as a child + private parentMap = new EnhancedMap>(); + // Map from space key to SpaceNotificationState instance representing that space + private notificationStateMap = new Map(); + // Map from space key to Set of room IDs that should be shown as part of that space's filter + private spaceFilteredRooms = new Map>(); + // The space currently selected in the Space Panel - if null then `Home` is selected + private _activeSpace?: Room = null; + + public get spacePanelSpaces(): Room[] { + return this.rootSpaces; + } + + public get activeSpace(): Room | null { + return this._activeSpace || null; + } + + public setActiveSpace(space: Room | null) { + if (space === this.activeSpace) return; + + this._activeSpace = space; + this.emit(UPDATE_SELECTED_SPACE, this.activeSpace); + + // persist space selected + if (space) { + window.localStorage.setItem(ACTIVE_SPACE_LS_KEY, space.roomId); + } else { + window.localStorage.removeItem(ACTIVE_SPACE_LS_KEY); + } + } + + public addRoomToSpace(space: Room, roomId: string, via: string[], autoJoin = false) { + return this.matrixClient.sendStateEvent(space.roomId, EventType.SpaceChild, { + via, + auto_join: autoJoin, + }, roomId); + } + + private getChildren(spaceId: string): Room[] { + const room = this.matrixClient?.getRoom(spaceId); + const childEvents = room?.currentState.getStateEvents(EventType.SpaceChild).filter(ev => ev.getContent()?.via); + return sortBy(childEvents, getOrder) + .map(ev => this.matrixClient.getRoom(ev.getStateKey())) + .filter(room => room?.getMyMembership() === "join") || []; + } + + public getChildRooms(spaceId: string): Room[] { + return this.getChildren(spaceId).filter(r => !r.isSpaceRoom()); + } + + public getChildSpaces(spaceId: string): Room[] { + return this.getChildren(spaceId).filter(r => r.isSpaceRoom()); + } + + public getParents(roomId: string, canonicalOnly = false): Room[] { + const room = this.matrixClient?.getRoom(roomId); + return room?.currentState.getStateEvents(EventType.SpaceParent) + .filter(ev => { + const content = ev.getContent(); + if (!content?.via) return false; + // TODO apply permissions check to verify that the parent mapping is valid + if (canonicalOnly && !content?.canonical) return false; + return true; + }) + .map(ev => this.matrixClient.getRoom(ev.getStateKey())) + .filter(Boolean) || []; + } + + public getCanonicalParent(roomId: string): Room | null { + const parents = this.getParents(roomId, true); + return sortBy(parents, r => r.roomId)?.[0] || null; + } + + public getSpaces = () => { + return this.matrixClient.getRooms().filter(r => r.isSpaceRoom() && r.getMyMembership() === "join"); + }; + + public getSpaceFilteredRoomIds = (space: Room | null): Set => { + return this.spaceFilteredRooms.get(space?.roomId || HOME_SPACE) || new Set(); + }; + + public rebuild = throttle(() => { // exported for tests + const visibleRooms = this.matrixClient.getVisibleRooms(); + + // Sort spaces by room ID to force the loop breaking to be deterministic + const spaces = sortBy(this.getSpaces(), space => space.roomId); + const unseenChildren = new Set([...visibleRooms, ...spaces]); + + const backrefs = new EnhancedMap>(); + + // TODO handle cleaning up links when a Space is removed + spaces.forEach(space => { + const children = this.getChildren(space.roomId); + children.forEach(child => { + unseenChildren.delete(child); + + backrefs.getOrCreate(child.roomId, new Set()).add(space.roomId); + }); + }); + + const [rootSpaces, orphanedRooms] = partitionSpacesAndRooms(Array.from(unseenChildren)); + + // untested algorithm to handle full-cycles + const detachedNodes = new Set(spaces); + + const markTreeChildren = (rootSpace: Room, unseen: Set) => { + const stack = [rootSpace]; + while (stack.length) { + const op = stack.pop(); + unseen.delete(op); + this.getChildSpaces(op.roomId).forEach(space => { + if (unseen.has(space)) { + stack.push(space); + } + }); + } + }; + + rootSpaces.forEach(rootSpace => { + markTreeChildren(rootSpace, detachedNodes); + }); + + // Handle spaces forming fully cyclical relationships. + // In order, assume each detachedNode is a root unless it has already + // been claimed as the child of prior detached node. + // Work from a copy of the detachedNodes set as it will be mutated as part of this operation. + Array.from(detachedNodes).forEach(detachedNode => { + if (!detachedNodes.has(detachedNode)) return; + // declare this detached node a new root, find its children, without ever looping back to it + detachedNodes.delete(detachedNode); + rootSpaces.push(detachedNode); + markTreeChildren(detachedNode, detachedNodes); + + // TODO only consider a detached node a root space if it has no *parents other than the ones forming cycles + }); + + // TODO neither of these handle an A->B->C->A with an additional C->D + // detachedNodes.forEach(space => { + // rootSpaces.push(space); + // }); + + this.orphanedRooms = new Set(orphanedRooms); + this.rootSpaces = rootSpaces; + this.parentMap = backrefs; + + // if the currently selected space no longer exists, remove its selection + if (this._activeSpace && detachedNodes.has(this._activeSpace)) { + this.setActiveSpace(null); + } + + this.onRoomsUpdate(); // TODO only do this if a change has happened + this.emit(UPDATE_TOP_LEVEL_SPACES, this.spacePanelSpaces); + }, 100, {trailing: true, leading: true}); + + onSpaceUpdate = () => { + this.rebuild(); + } + + private showInHomeSpace = (room: Room) => { + return !this.parentMap.get(room.roomId)?.size // put all orphaned rooms in the Home Space + || DMRoomMap.shared().getUserIdForRoomId(room.roomId) // put all DMs in the Home Space + || RoomListStore.instance.getTagsForRoom(room).includes(DefaultTagID.Favourite) // show all favourites + }; + + // Update a given room due to its tag changing (e.g DM-ness or Fav-ness) + // This can only change whether it shows up in the HOME_SPACE or not + private onRoomUpdate = (room: Room) => { + if (this.showInHomeSpace(room)) { + this.spaceFilteredRooms.get(HOME_SPACE)?.add(room.roomId); + this.emit(HOME_SPACE); + } else if (!this.orphanedRooms.has(room.roomId)) { + this.spaceFilteredRooms.get(HOME_SPACE)?.delete(room.roomId); + this.emit(HOME_SPACE); + } + }; + + private onRoomsUpdate = throttle(() => { + // TODO resolve some updates as deltas + const visibleRooms = this.matrixClient.getVisibleRooms(); + + const oldFilteredRooms = this.spaceFilteredRooms; + this.spaceFilteredRooms = new Map(); + + // put all invites (rooms & spaces) in the Home Space + const invites = this.matrixClient.getRooms().filter(r => r.getMyMembership() === "invite"); + this.spaceFilteredRooms.set(HOME_SPACE, new Set(invites.map(room => room.roomId))); + + visibleRooms.forEach(room => { + if (this.showInHomeSpace(room)) { + this.spaceFilteredRooms.get(HOME_SPACE).add(room.roomId); + } + }); + + this.rootSpaces.forEach(s => { + // traverse each space tree in DFS to build up the supersets as you go up, + // reusing results from like subtrees. + const fn = (spaceId: string, parentPath: Set): Set => { + if (parentPath.has(spaceId)) return; // prevent cycles + + // reuse existing results if multiple similar branches exist + if (this.spaceFilteredRooms.has(spaceId)) { + return this.spaceFilteredRooms.get(spaceId); + } + + const [childSpaces, childRooms] = partitionSpacesAndRooms(this.getChildren(spaceId)); + const roomIds = new Set(childRooms.map(r => r.roomId)); + const space = this.matrixClient?.getRoom(spaceId); + + // Add relevant DMs + space?.getJoinedMembers().forEach(member => { + DMRoomMap.shared().getDMRoomsForUserId(member.userId).forEach(roomId => { + roomIds.add(roomId); + }); + }); + + const newPath = new Set(parentPath).add(spaceId); + childSpaces.forEach(childSpace => { + fn(childSpace.roomId, newPath)?.forEach(roomId => { + roomIds.add(roomId); + }); + }); + this.spaceFilteredRooms.set(spaceId, roomIds); + return roomIds; + }; + + fn(s.roomId, new Set()); + }); + + const diff = mapDiff(oldFilteredRooms, this.spaceFilteredRooms); + // filter out keys which changed by reference only by checking whether the sets differ + const changed = diff.changed.filter(k => setHasDiff(oldFilteredRooms.get(k), this.spaceFilteredRooms.get(k))); + [...diff.added, ...diff.removed, ...changed].forEach(k => { + this.emit(k); + }); + + this.spaceFilteredRooms.forEach((roomIds, s) => { + // Update NotificationStates + const rooms = this.matrixClient.getRooms().filter(room => roomIds.has(room.roomId)); + this.getNotificationState(s)?.setRooms(rooms); + }); + }, 100, {trailing: true, leading: true}); + + private onRoom = (room: Room) => { + if (room?.isSpaceRoom()) { + this.onSpaceUpdate(); + this.emit(room.roomId); + } else { + // this.onRoomUpdate(room); + this.onRoomsUpdate(); + } + }; + + private onRoomState = (ev: MatrixEvent) => { + const room = this.matrixClient.getRoom(ev.getRoomId()); + if (!room) return; + + if (ev.getType() === EventType.SpaceChild && room.isSpaceRoom()) { + this.onSpaceUpdate(); + this.emit(room.roomId); + } else if (ev.getType() === EventType.SpaceParent) { + // TODO rebuild the space parent and not the room - check permissions? + // TODO confirm this after implementing parenting behaviour + if (room.isSpaceRoom()) { + this.onSpaceUpdate(); + } else { + this.onRoomUpdate(room); + } + this.emit(room.roomId); + } + }; + + private onRoomAccountData = (ev: MatrixEvent, room: Room, lastEvent: MatrixEvent) => { + if (ev.getType() === EventType.Tag && !room.isSpaceRoom()) { + // If the room was in favourites and now isn't or the opposite then update its position in the trees + if (!!ev.getContent()[DefaultTagID.Favourite] !== !!lastEvent.getContent()[DefaultTagID.Favourite]) { + this.onRoomUpdate(room); + } + } + } + + private onAccountData = (ev: MatrixEvent, lastEvent: MatrixEvent) => { + if (ev.getType() === EventType.Direct) { + const lastContent = lastEvent.getContent(); + const content = ev.getContent(); + + const diff = objectDiff>(lastContent, content); + // filter out keys which changed by reference only by checking whether the sets differ + const changed = diff.changed.filter(k => arrayHasDiff(lastContent[k], content[k])); + // DM tag changes, refresh relevant rooms + new Set([...diff.added, ...diff.removed, ...changed]).forEach(roomId => { + const room = this.matrixClient?.getRoom(roomId); + if (room) { + this.onRoomUpdate(room); + } + }); + } + }; + + protected async onNotReady() { + if (!SettingsStore.getValue("feature_spaces")) return; + if (this.matrixClient) { + this.matrixClient.removeListener("Room", this.onRoom); + this.matrixClient.removeListener("Room.myMembership", this.onRoom); + this.matrixClient.removeListener("RoomState.events", this.onRoomState); + this.matrixClient.removeListener("Room.accountData", this.onRoomAccountData); + this.matrixClient.removeListener("accountData", this.onAccountData); + } + await this.reset({}); + } + + protected async onReady() { + if (!SettingsStore.getValue("feature_spaces")) return; + this.matrixClient.on("Room", this.onRoom); + this.matrixClient.on("Room.myMembership", this.onRoom); + this.matrixClient.on("RoomState.events", this.onRoomState); + this.matrixClient.on("Room.accountData", this.onRoomAccountData); + this.matrixClient.on("accountData", this.onAccountData); + + await this.onSpaceUpdate(); // trigger an initial update + + // restore selected state from last session if any and still valid + const lastSpaceId = window.localStorage.getItem(ACTIVE_SPACE_LS_KEY); + if (lastSpaceId) { + const space = this.rootSpaces.find(s => s.roomId === lastSpaceId); + if (space) { + this.setActiveSpace(space); + } + } + } + + protected async onAction(payload: ActionPayload) { + switch (payload.action) { + case "view_room": { + const room = this.matrixClient?.getRoom(payload.room_id); + + if (room?.getMyMembership() === "join") { + if (room.isSpaceRoom()) { + this.setActiveSpace(room); + } else if (!this.spaceFilteredRooms.get(this._activeSpace?.roomId || HOME_SPACE).has(room.roomId)) { + // TODO maybe reverse these first 2 clauses once space panel active is fixed + let parent = this.rootSpaces.find(s => this.spaceFilteredRooms.get(s.roomId)?.has(room.roomId)); + if (!parent) { + parent = this.getCanonicalParent(room.roomId); + } + if (!parent) { + const parents = Array.from(this.parentMap.get(room.roomId) || []); + parent = parents.find(p => this.matrixClient.getRoom(p)); + } + if (parent) { + this.setActiveSpace(parent); + } + } + } + break; + } + case "after_leave_room": + if (this._activeSpace && payload.room_id === this._activeSpace.roomId) { + this.setActiveSpace(null); + } + break; + } + } + + public getNotificationState(key: SpaceKey): SpaceNotificationState { + if (this.notificationStateMap.has(key)) { + return this.notificationStateMap.get(key); + } + + const state = new SpaceNotificationState(key, getRoomFn); + this.notificationStateMap.set(key, state); + return state; + } +} + +export default class SpaceStore { + private static internalInstance = new SpaceStoreClass(); + + public static get instance(): SpaceStoreClass { + return SpaceStore.internalInstance; + } +} + +window.mxSpaceStore = SpaceStore.instance; diff --git a/src/stores/notifications/SpaceNotificationState.ts b/src/stores/notifications/SpaceNotificationState.ts new file mode 100644 index 0000000000..61a9701a07 --- /dev/null +++ b/src/stores/notifications/SpaceNotificationState.ts @@ -0,0 +1,82 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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 { Room } from "matrix-js-sdk/src/models/room"; + +import { NotificationColor } from "./NotificationColor"; +import { arrayDiff } from "../../utils/arrays"; +import { RoomNotificationState } from "./RoomNotificationState"; +import { NOTIFICATION_STATE_UPDATE, NotificationState } from "./NotificationState"; +import { FetchRoomFn } from "./ListNotificationState"; + +export class SpaceNotificationState extends NotificationState { + private rooms: Room[] = []; + private states: { [spaceId: string]: RoomNotificationState } = {}; + + constructor(private spaceId: string | symbol, private getRoomFn: FetchRoomFn) { + super(); + } + + public get symbol(): string { + return null; // This notification state doesn't support symbols + } + + public setRooms(rooms: Room[]) { + const oldRooms = this.rooms; + const diff = arrayDiff(oldRooms, rooms); + this.rooms = rooms; + for (const oldRoom of diff.removed) { + const state = this.states[oldRoom.roomId]; + if (!state) continue; // We likely just didn't have a badge (race condition) + delete this.states[oldRoom.roomId]; + state.off(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate); + } + for (const newRoom of diff.added) { + const state = this.getRoomFn(newRoom); + state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate); + this.states[newRoom.roomId] = state; + } + + this.calculateTotalState(); + } + + public destroy() { + super.destroy(); + for (const state of Object.values(this.states)) { + state.off(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate); + } + this.states = {}; + } + + private onRoomNotificationStateUpdate = () => { + this.calculateTotalState(); + }; + + private calculateTotalState() { + const snapshot = this.snapshot(); + + this._count = 0; + this._color = NotificationColor.None; + for (const state of Object.values(this.states)) { + this._count += state.count; + this._color = Math.max(this.color, state.color); + } + + // finally, publish an update if needed + this.emitIfUpdated(snapshot); + } +} + From ad85764a8e3d1025c76db29e9f53ba690ac2eb4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:23:32 +0100 Subject: [PATCH 0261/2651] Fix timeline expansion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 1 + res/css/structures/_RoomView.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index f05f24d0d7..9597083e9c 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -19,6 +19,7 @@ limitations under the License. flex-direction: row; min-width: 0; height: 100%; + justify-content: space-between; } .mx_MainSplit > .mx_RightPanel_ResizeWrapper { diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index cd8c640132..5240a0650f 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -121,6 +121,7 @@ limitations under the License. position: relative; //for .mx_RoomView_auxPanel_fullHeight display: flex; flex-direction: column; + width: 100%; } .mx_RoomView_body { From aa4ec9fca1a65202306ee77d705b15f1782de188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:27:52 +0100 Subject: [PATCH 0262/2651] Make $droptarget-bg-color more opaque MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/themes/light/css/_light.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 1c89d83c01..ea7b0472e0 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -68,7 +68,7 @@ $groupFilterPanel-bg-color: rgba(232, 232, 232, 0.77); $plinth-bg-color: $secondary-accent-color; // used by RoomDropTarget -$droptarget-bg-color: rgba(255,255,255,0.5); +$droptarget-bg-color: rgba(255,255,255,0.95); // used by AddressSelector $selected-color: $secondary-accent-color; From 8551855a5626d06e6feda6f849f50b26af85a194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:30:14 +0100 Subject: [PATCH 0263/2651] Add $droptarget-bg-color to the dark theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/themes/dark/css/_dark.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index a878aa3cdd..f6f415ce70 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -42,6 +42,9 @@ $preview-bar-bg-color: $header-panel-bg-color; $groupFilterPanel-bg-color: rgba(38, 39, 43, 0.82); $inverted-bg-color: $base-color; +// used by RoomDropTarget +$droptarget-bg-color: rgba(21,25,30,0.95); + // used by AddressSelector $selected-color: $room-highlight-color; From a3001f77e46e7c3ac3479a70eb56db312c6f1361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:30:39 +0100 Subject: [PATCH 0264/2651] Remove rounded corners of the drop area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 5240a0650f..e80ac062b6 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -30,9 +30,6 @@ limitations under the License. pointer-events: none; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - background-color: $droptarget-bg-color; position: absolute; From 26b70b62280b7f4fa21c6287faf20a309a399abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:32:04 +0100 Subject: [PATCH 0265/2651] Remove label background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index e80ac062b6..8ba31fac20 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -42,11 +42,6 @@ limitations under the License. .mx_RoomView_fileDropTargetLabel { position: absolute; - - border-radius: 10px; - padding: 10px; - - background-color: $menu-bg-color; } .mx_RoomView_auxPanel { From 6a7340e8be3844881b1c114d74687983b9c0ba20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 18:46:48 +0100 Subject: [PATCH 0266/2651] Use new upload icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/upload-big.svg | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/res/img/upload-big.svg b/res/img/upload-big.svg index 6099c2e976..9a6a265fdb 100644 --- a/res/img/upload-big.svg +++ b/res/img/upload-big.svg @@ -1,19 +1,3 @@ - - - - icons_upload_drop - Created with bin/sketchtool. - - - - - - - - - - - - - + + From 1c48804d96c3cdda150e38e2d520a2268dd5728e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 19:28:08 +0100 Subject: [PATCH 0267/2651] Remove unnecessary class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 4 ---- src/components/views/rooms/AuxPanel.tsx | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 8ba31fac20..28d8d1e196 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -40,10 +40,6 @@ limitations under the License. align-items: center; } -.mx_RoomView_fileDropTargetLabel { - position: absolute; -} - .mx_RoomView_auxPanel { min-width: 0px; width: 100%; diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index 7966643084..543a50d59f 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -156,7 +156,7 @@ export default class AuxPanel extends React.Component { if (this.props.draggingFile) { fileDropTarget = (
-
+

{ _t("Drop file here to upload") } From 43e1144ae7ca7eff08c1666b4a179ba828d41432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 19:36:55 +0100 Subject: [PATCH 0268/2651] Don't use TintableSVG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seemed to have caused a little lag and it was unnecessary Signed-off-by: Šimon Brandner --- src/components/views/rooms/AuxPanel.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index 543a50d59f..c9150d588f 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -150,14 +150,12 @@ export default class AuxPanel extends React.Component { } render() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - let fileDropTarget = null; if (this.props.draggingFile) { fileDropTarget = (
- +
{ _t("Drop file here to upload") }
From 7277c285a9326928555e05766ee3ce33603de18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 20:10:38 +0100 Subject: [PATCH 0269/2651] Fix weird crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/AuxPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index c9150d588f..cc3408476c 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -155,7 +155,7 @@ export default class AuxPanel extends React.Component { fileDropTarget = (
- +
{ _t("Drop file here to upload") }
From 49ea9a4788243346b20fcf5b4b79f46a7c3a80ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 25 Feb 2021 20:10:58 +0100 Subject: [PATCH 0270/2651] Remove sdk import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/AuxPanel.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index cc3408476c..59ea8e237a 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import { Room } from 'matrix-js-sdk/src/models/room' -import * as sdk from '../../../index'; import dis from "../../../dispatcher/dispatcher"; import * as ObjectUtils from '../../../ObjectUtils'; import AppsDrawer from './AppsDrawer'; From 563620484df6fa79f666ef72f414838cf0e342f1 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Thu, 25 Feb 2021 14:39:20 -0500 Subject: [PATCH 0271/2651] Support replying with a message command Signed-off-by: Robin Townsend --- src/SlashCommands.tsx | 28 +++++++----- .../views/rooms/SendMessageComposer.js | 44 +++++++++++++------ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 6b5f261374..06468c135e 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -20,6 +20,7 @@ limitations under the License. import * as React from 'react'; +import { ContentHelpers } from 'matrix-js-sdk'; import {MatrixClientPeg} from './MatrixClientPeg'; import dis from './dispatcher/dispatcher'; import * as sdk from './index'; @@ -126,10 +127,10 @@ export class Command { return this.getCommand() + " " + this.args; } - run(roomId: string, args: string, cmd: string) { + run(roomId: string, args: string) { // if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me` if (!this.runFn) return reject(_t("Command error")); - return this.runFn.bind(this)(roomId, args, cmd); + return this.runFn.bind(this)(roomId, args); } getUsage() { @@ -163,7 +164,7 @@ export const Commands = [ if (args) { message = message + ' ' + args; } - return success(MatrixClientPeg.get().sendTextMessage(roomId, message)); + return success(ContentHelpers.makeTextMessage(message)); }, category: CommandCategories.messages, }), @@ -176,7 +177,7 @@ export const Commands = [ if (args) { message = message + ' ' + args; } - return success(MatrixClientPeg.get().sendTextMessage(roomId, message)); + return success(ContentHelpers.makeTextMessage(message)); }, category: CommandCategories.messages, }), @@ -189,7 +190,7 @@ export const Commands = [ if (args) { message = message + ' ' + args; } - return success(MatrixClientPeg.get().sendTextMessage(roomId, message)); + return success(ContentHelpers.makeTextMessage(message)); }, category: CommandCategories.messages, }), @@ -202,7 +203,7 @@ export const Commands = [ if (args) { message = message + ' ' + args; } - return success(MatrixClientPeg.get().sendTextMessage(roomId, message)); + return success(ContentHelpers.makeTextMessage(message)); }, category: CommandCategories.messages, }), @@ -211,7 +212,7 @@ export const Commands = [ args: '', description: _td('Sends a message as plain text, without interpreting it as markdown'), runFn: function(roomId, messages) { - return success(MatrixClientPeg.get().sendTextMessage(roomId, messages)); + return success(ContentHelpers.makeTextMessage(messages)); }, category: CommandCategories.messages, }), @@ -220,7 +221,7 @@ export const Commands = [ args: '', description: _td('Sends a message as html, without interpreting it as markdown'), runFn: function(roomId, messages) { - return success(MatrixClientPeg.get().sendHtmlMessage(roomId, messages, messages)); + return success(ContentHelpers.makeHtmlMessage(messages, messages)); }, category: CommandCategories.messages, }), @@ -966,7 +967,7 @@ export const Commands = [ args: '', runFn: function(roomId, args) { if (!args) return reject(this.getUserId()); - return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, textToHtmlRainbow(args))); + return success(ContentHelpers.makeHtmlMessage(args, textToHtmlRainbow(args))); }, category: CommandCategories.messages, }), @@ -976,7 +977,7 @@ export const Commands = [ args: '', runFn: function(roomId, args) { if (!args) return reject(this.getUserId()); - return success(MatrixClientPeg.get().sendHtmlEmote(roomId, args, textToHtmlRainbow(args))); + return success(ContentHelpers.makeHtmlEmote(args, textToHtmlRainbow(args))); }, category: CommandCategories.messages, }), @@ -1201,10 +1202,13 @@ export function parseCommandString(input: string) { * processing the command, or 'promise' if a request was sent out. * Returns null if the input didn't match a command. */ -export function getCommand(roomId: string, input: string) { +export function getCommand(input: string) { const {cmd, args} = parseCommandString(input); if (CommandMap.has(cmd) && CommandMap.get(cmd).isEnabled()) { - return () => CommandMap.get(cmd).run(roomId, args, cmd); + return { + cmd: CommandMap.get(cmd), + args, + }; } } diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 62c474e417..d1482c0df6 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -33,7 +33,7 @@ import ReplyThread from "../elements/ReplyThread"; import {parseEvent} from '../../../editor/deserialize'; import {findEditableEvent} from '../../../utils/EventUtils'; import SendHistoryManager from "../../../SendHistoryManager"; -import {getCommand} from '../../../SlashCommands'; +import {CommandCategories, getCommand} from '../../../SlashCommands'; import * as sdk from '../../../index'; import Modal from '../../../Modal'; import {_t, _td} from '../../../languageHandler'; @@ -287,15 +287,22 @@ export default class SendMessageComposer extends React.Component { } return text + part.text; }, ""); - return [getCommand(this.props.room.roomId, commandText), commandText]; + const {cmd, args} = getCommand(commandText); + return [cmd, args, commandText]; } - async _runSlashCommand(fn) { - const cmd = fn(); - let error = cmd.error; - if (cmd.promise) { + async _runSlashCommand(cmd, args) { + const result = cmd.run(this.props.room.roomId, args); + let messageContent; + let error = result.error; + if (result.promise) { try { - await cmd.promise; + if (cmd.category === CommandCategories.messages) { + // The command returns a modified message that we need to pass on + messageContent = await result.promise; + } else { + await result.promise; + } } catch (err) { error = err; } @@ -304,7 +311,7 @@ export default class SendMessageComposer extends React.Component { console.error("Command failure: %s", error); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); // assume the error is a server error when the command is async - const isServerError = !!cmd.promise; + const isServerError = !!result.promise; const title = isServerError ? _td("Server error") : _td("Command error"); let errText; @@ -322,6 +329,7 @@ export default class SendMessageComposer extends React.Component { }); } else { console.log("Command success."); + if (messageContent) return messageContent; } } @@ -330,13 +338,22 @@ export default class SendMessageComposer extends React.Component { return; } + const replyToEvent = this.props.replyToEvent; let shouldSend = true; + let content; if (!containsEmote(this.model) && this._isSlashCommand()) { - const [cmd, commandText] = this._getSlashCommand(); + const [cmd, args, commandText] = this._getSlashCommand(); if (cmd) { - shouldSend = false; - this._runSlashCommand(cmd); + if (cmd.category === CommandCategories.messages) { + content = await this._runSlashCommand(cmd, args); + if (replyToEvent) { + addReplyToMessageContent(content, replyToEvent, this.props.permalinkCreator); + } + } else { + this._runSlashCommand(cmd, args); + shouldSend = false; + } } else { // ask the user if their unknown command should be sent as a message const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); @@ -371,11 +388,12 @@ export default class SendMessageComposer extends React.Component { this._sendQuickReaction(); } - const replyToEvent = this.props.replyToEvent; if (shouldSend) { const startTime = CountlyAnalytics.getTimestamp(); const {roomId} = this.props.room; - const content = createMessageContent(this.model, this.props.permalinkCreator, replyToEvent); + if (!content) { + content = createMessageContent(this.model, this.props.permalinkCreator, replyToEvent); + } // don't bother sending an empty message if (!content.body.trim()) return; From dba52fb5b1411fcc03e2df5db85f1f94601a0337 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Thu, 25 Feb 2021 16:01:46 -0500 Subject: [PATCH 0272/2651] Autocomplete invited users Signed-off-by: Robin Townsend --- src/autocomplete/UserProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx index 32eea55b0b..7fc01daef9 100644 --- a/src/autocomplete/UserProvider.tsx +++ b/src/autocomplete/UserProvider.tsx @@ -155,6 +155,7 @@ export default class UserProvider extends AutocompleteProvider { const currentUserId = MatrixClientPeg.get().credentials.userId; this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId); + this.users = this.users.concat(this.room.getMembersWithMembership("invite")); this.users = sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20); From 1a7f9091b4fc41eac6d5cc1b71d1dbe61f5d7f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 07:51:03 +0100 Subject: [PATCH 0273/2651] Animate icon size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 12 ++++++++++++ src/components/views/rooms/AuxPanel.tsx | 10 +++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 28d8d1e196..d5caee5e8b 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -36,10 +36,22 @@ limitations under the License. z-index: 3000; display: flex; + flex-direction: column; justify-content: center; align-items: center; } +@keyframes mx_RoomView_fileDropTarget_image_animation { + from {width: 0px;} + to {width: 32px;} +} + +.mx_RoomView_fileDropTarget_image { + animation: mx_RoomView_fileDropTarget_image_animation; + animation-duration: 0.5s; + margin-bottom: 16px; +} + .mx_RoomView_auxPanel { min-width: 0px; width: 100%; diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index 59ea8e237a..b3ef8c3cc8 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -153,11 +153,11 @@ export default class AuxPanel extends React.Component { if (this.props.draggingFile) { fileDropTarget = (
-
- -
- { _t("Drop file here to upload") } -
+ + { _t("Drop file here to upload") }
); } From f0c26846c75559e5be013eb25ebe5f54b4f6e264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 08:11:58 +0100 Subject: [PATCH 0274/2651] Fix formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index d5caee5e8b..2c3fb2b32b 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -42,8 +42,8 @@ limitations under the License. } @keyframes mx_RoomView_fileDropTarget_image_animation { - from {width: 0px;} - to {width: 32px;} + from {width: 0px;} + to {width: 32px;} } .mx_RoomView_fileDropTarget_image { From 172cc01f7d3dcba08235a621cff118efe3e76d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 08:12:10 +0100 Subject: [PATCH 0275/2651] Add background animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 2c3fb2b32b..5870e107c6 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -20,6 +20,12 @@ limitations under the License. flex-direction: column; } + +@keyframes mx_RoomView_fileDropTarget_animation { + from {opacity: 0;} + to {opacity: 0.95;} +} + .mx_RoomView_fileDropTarget { min-width: 0px; width: 100%; @@ -30,7 +36,8 @@ limitations under the License. pointer-events: none; - background-color: $droptarget-bg-color; + background-color: $primary-bg-color; + opacity: 0.95; position: absolute; z-index: 3000; @@ -39,6 +46,9 @@ limitations under the License. flex-direction: column; justify-content: center; align-items: center; + + animation: mx_RoomView_fileDropTarget_animation; + animation-duration: 0.5s; } @keyframes mx_RoomView_fileDropTarget_image_animation { From 3e0558f4d97bc618cc8e6d71f411370e894d642f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 08:12:38 +0100 Subject: [PATCH 0276/2651] Remove droptarget colors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/themes/dark/css/_dark.scss | 3 --- res/themes/light/css/_light.scss | 3 --- 2 files changed, 6 deletions(-) diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index f6f415ce70..a878aa3cdd 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -42,9 +42,6 @@ $preview-bar-bg-color: $header-panel-bg-color; $groupFilterPanel-bg-color: rgba(38, 39, 43, 0.82); $inverted-bg-color: $base-color; -// used by RoomDropTarget -$droptarget-bg-color: rgba(21,25,30,0.95); - // used by AddressSelector $selected-color: $room-highlight-color; diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index ea7b0472e0..c92e491ca2 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -67,9 +67,6 @@ $groupFilterPanel-bg-color: rgba(232, 232, 232, 0.77); // used by RoomDirectory permissions $plinth-bg-color: $secondary-accent-color; -// used by RoomDropTarget -$droptarget-bg-color: rgba(255,255,255,0.95); - // used by AddressSelector $selected-color: $secondary-accent-color; From 49ea83edb93dfa0e6f572aeac002adaaa0370fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 08:14:27 +0100 Subject: [PATCH 0277/2651] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5bbbdf60b5..9af8ccc172 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1381,7 +1381,6 @@ "Remove %(phone)s?": "Remove %(phone)s?", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.", "Phone Number": "Phone Number", - "Drop File Here": "Drop File Here", "Drop file here to upload": "Drop file here to upload", "This user has not verified all of their sessions.": "This user has not verified all of their sessions.", "You have not verified this user.": "You have not verified this user.", From e90ae2ea7596bff850cf4014c1109f93234132b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 08:18:05 +0100 Subject: [PATCH 0278/2651] Delint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 5870e107c6..5e8d84ff32 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -22,8 +22,12 @@ limitations under the License. @keyframes mx_RoomView_fileDropTarget_animation { - from {opacity: 0;} - to {opacity: 0.95;} + from { + opacity: 0; + } + to { + opacity: 0.95; + } } .mx_RoomView_fileDropTarget { @@ -52,8 +56,12 @@ limitations under the License. } @keyframes mx_RoomView_fileDropTarget_image_animation { - from {width: 0px;} - to {width: 32px;} + from { + width: 0px; + } + to { + width: 32px; + } } .mx_RoomView_fileDropTarget_image { From 819a0b013fda927bea3197e458741f4f4f85a271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 11:08:31 +0100 Subject: [PATCH 0279/2651] min-width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to allow the container to be smaller Signed-off-by: Šimon Brandner --- res/css/structures/_RoomView.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 5e8d84ff32..28591ad7a4 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -140,6 +140,7 @@ limitations under the License. display: flex; flex-direction: column; width: 100%; + min-width: 0; } .mx_RoomView_body { From 0d6a9fce67d24f441a62e140a2a73f669b959cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 11:12:14 +0100 Subject: [PATCH 0280/2651] Remove weird styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index ff09af454e..42eafe5bdc 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2058,7 +2058,7 @@ export default class RoomView extends React.Component { appsShown={this.state.showApps} /> -
+
{auxPanel}
From 11c5aa02d290739fff31bfa8365fe76562032594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 11:19:45 +0100 Subject: [PATCH 0281/2651] Remove mx_RoomView_container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 1 + res/css/structures/_RoomView.scss | 8 ------- src/components/structures/RoomView.tsx | 30 ++++++++++++-------------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 9597083e9c..5fa62e921d 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -20,6 +20,7 @@ limitations under the License. min-width: 0; height: 100%; justify-content: space-between; + min-height: 0; } .mx_MainSplit > .mx_RightPanel_ResizeWrapper { diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 28591ad7a4..b3dab5f992 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -135,14 +135,6 @@ limitations under the License. height: 50px; } -.mx_RoomView_container { - position: relative; //for .mx_RoomView_auxPanel_fullHeight - display: flex; - flex-direction: column; - width: 100%; - min-width: 0; -} - .mx_RoomView_body { display: flex; flex-direction: column; diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 42eafe5bdc..be2f81a176 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2058,24 +2058,22 @@ export default class RoomView extends React.Component { appsShown={this.state.showApps} /> -
+
{auxPanel} -
-
- {topUnreadMessagesBar} - {jumpToBottom} - {messagePanel} - {searchResultsPanel} -
-
-
-
- {statusBar} -
-
- {previewBar} - {messageComposer} +
+ {topUnreadMessagesBar} + {jumpToBottom} + {messagePanel} + {searchResultsPanel}
+
+
+
+ {statusBar} +
+
+ {previewBar} + {messageComposer}
From 9a5ba072ba0f551dc618cdf8bfb7afba004d01fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 11:23:58 +0100 Subject: [PATCH 0282/2651] Fix auxPanel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index be2f81a176..5b79f23e0b 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2059,8 +2059,8 @@ export default class RoomView extends React.Component { />
- {auxPanel}
+ {auxPanel} {topUnreadMessagesBar} {jumpToBottom} {messagePanel} From 3bed37463fea1ff1a7c86ef5fe9a0a123e06008f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 26 Feb 2021 11:38:05 +0100 Subject: [PATCH 0283/2651] Remove unnecessary code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/structures/_MainSplit.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 5fa62e921d..2d9ea2729c 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -19,7 +19,6 @@ limitations under the License. flex-direction: row; min-width: 0; height: 100%; - justify-content: space-between; min-height: 0; } From f21aedc6cf38d741de183fa1d158d7f7de673699 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 26 Feb 2021 10:23:09 +0000 Subject: [PATCH 0284/2651] Add Space Panel with Room List filtering --- res/css/_components.scss | 1 + res/css/structures/_LeftPanel.scss | 22 +- res/css/structures/_SpacePanel.scss | 237 ++++++++++++++++++ res/img/element-icons/expand-space-panel.svg | 4 + res/themes/light/css/_mods.scss | 4 + src/components/structures/LeftPanel.tsx | 23 +- src/components/views/avatars/RoomAvatar.tsx | 2 +- src/components/views/spaces/SpacePanel.tsx | 212 ++++++++++++++++ .../views/spaces/SpaceTreeLevel.tsx | 184 ++++++++++++++ src/i18n/strings/en_EN.json | 4 +- src/stores/room-list/RoomListStore.ts | 23 +- src/stores/room-list/SpaceWatcher.ts | 39 +++ src/stores/room-list/algorithms/Algorithm.ts | 3 + .../room-list/filters/SpaceFilterCondition.ts | 69 +++++ 14 files changed, 796 insertions(+), 31 deletions(-) create mode 100644 res/css/structures/_SpacePanel.scss create mode 100644 res/img/element-icons/expand-space-panel.svg create mode 100644 src/components/views/spaces/SpacePanel.tsx create mode 100644 src/components/views/spaces/SpaceTreeLevel.tsx create mode 100644 src/stores/room-list/SpaceWatcher.ts create mode 100644 src/stores/room-list/filters/SpaceFilterCondition.ts diff --git a/res/css/_components.scss b/res/css/_components.scss index 006bac09c9..29b5262826 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -27,6 +27,7 @@ @import "./structures/_RoomView.scss"; @import "./structures/_ScrollPanel.scss"; @import "./structures/_SearchBox.scss"; +@import "./structures/_SpacePanel.scss"; @import "./structures/_TabbedView.scss"; @import "./structures/_ToastContainer.scss"; @import "./structures/_UploadBar.scss"; diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss index 168590502d..f1f27014ee 100644 --- a/res/css/structures/_LeftPanel.scss +++ b/res/css/structures/_LeftPanel.scss @@ -15,6 +15,7 @@ limitations under the License. */ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculations +$roomListCollapsedWidth: 68px; .mx_LeftPanel { background-color: $roomlist-bg-color; @@ -37,18 +38,12 @@ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculation // GroupFilterPanel handles its own CSS } - &:not(.mx_LeftPanel_hasGroupFilterPanel) { - .mx_LeftPanel_roomListContainer { - width: 100%; - } - } - // Note: The 'room list' in this context is actually everything that isn't the tag // panel, such as the menu options, breadcrumbs, filtering, etc .mx_LeftPanel_roomListContainer { - width: calc(100% - $groupFilterPanelWidth); background-color: $roomlist-bg-color; - + flex: 1 0 0; + min-width: 0; // Create another flexbox (this time a column) for the room list components display: flex; flex-direction: column; @@ -168,17 +163,10 @@ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculation // These styles override the defaults for the minimized (66px) layout &.mx_LeftPanel_minimized { min-width: unset; - - // We have to forcefully set the width to override the resizer's style attribute. - &.mx_LeftPanel_hasGroupFilterPanel { - width: calc(68px + $groupFilterPanelWidth) !important; - } - &:not(.mx_LeftPanel_hasGroupFilterPanel) { - width: 68px !important; - } + width: unset !important; .mx_LeftPanel_roomListContainer { - width: 68px; + width: $roomListCollapsedWidth; .mx_LeftPanel_userHeader { flex-direction: row; diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss new file mode 100644 index 0000000000..8de85f95ef --- /dev/null +++ b/res/css/structures/_SpacePanel.scss @@ -0,0 +1,237 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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. +*/ + +$topLevelHeight: 32px; +$nestedHeight: 24px; +$gutterSize: 21px; +$activeStripeSize: 4px; + +.mx_SpacePanel { + flex: 0 0 auto; + background-color: $groupFilterPanel-bg-color; + padding: 0; + margin: 0; + + // Create another flexbox so the Panel fills the container + display: flex; + flex-direction: column; + overflow-y: auto; + + .mx_SpacePanel_spaceTreeWrapper { + flex: 1; + } + + .mx_SpacePanel_toggleCollapse { + flex: 0 0 auto; + width: 40px; + height: 40px; + mask-position: center; + mask-size: 32px; + mask-repeat: no-repeat; + margin-left: $gutterSize; + margin-bottom: 12px; + background-color: $roomlist-header-color; + mask-image: url('$(res)/img/element-icons/expand-space-panel.svg'); + + &.expanded { + transform: scaleX(-1); + } + } + + ul { + margin: 0; + list-style: none; + padding: 0; + padding-left: 16px; + } + + .mx_AutoHideScrollbar { + padding: 16px 12px 16px 0; + } + + .mx_SpaceButton_toggleCollapse { + cursor: pointer; + } + + .mx_SpaceItem { + position: relative; + } + + .mx_SpaceItem.collapsed { + & > .mx_SpaceButton > .mx_SpaceButton_toggleCollapse { + transform: rotate(-90deg); + } + + & > .mx_SpaceTreeLevel { + display: none; + } + } + + .mx_SpaceItem:not(.hasSubSpaces) > .mx_SpaceButton { + margin-left: $gutterSize; + + &.mx_SpaceButton_active { + &::before { + left: -$gutterSize; + } + } + } + + .mx_SpaceButton { + border-radius: 8px; + position: relative; + margin-bottom: 16px; + display: flex; + align-items: center; + + .mx_SpaceButton_name { + flex: 1; + margin-left: 8px; + white-space: nowrap; + display: block; + max-width: 150px; + text-overflow: ellipsis; + overflow: hidden; + + font-size: $font-14px; + line-height: $font-18px; + } + + .mx_SpaceButton_toggleCollapse { + width: calc($gutterSize - $activeStripeSize); + margin-left: 1px; + height: 20px; + mask-position: center; + mask-size: 20px; + mask-repeat: no-repeat; + background-color: $roomlist-header-color; + mask-image: url('$(res)/img/feather-customised/chevron-down.svg'); + } + + &.mx_SpaceButton_active { + &::before { + position: absolute; + content: ''; + width: $activeStripeSize; + top: 0; + left: 0; + bottom: 0; + background-color: $accent-color; + border-radius: 0 4px 4px 0; + } + } + + .mx_SpaceButton_avatarPlaceholder { + width: $topLevelHeight; + min-width: $topLevelHeight; + height: $topLevelHeight; + border-radius: 8px; + + &::before { + position: absolute; + content: ''; + width: $topLevelHeight; + height: $topLevelHeight; + top: 0; + left: 0; + mask-position: center; + mask-repeat: no-repeat; + mask-size: 18px; + } + } + + &.mx_SpaceButton_home .mx_SpaceButton_avatarPlaceholder { + background-color: #ffffff; + + &::before { + background-color: #3f3d3d; + mask-image: url('$(res)/img/element-icons/home.svg'); + } + } + + &.mx_SpaceButton_newCancel .mx_SpaceButton_avatarPlaceholder { + background-color: $icon-button-color; + + &::before { + transform: rotate(45deg); + } + } + + .mx_BaseAvatar_image { + border-radius: 8px; + } + } + + .mx_SpacePanel_badgeContainer { + height: 16px; + // don't set width so that it takes no space when there is no badge to show + margin: auto 0; // vertically align + + // Create a flexbox to make aligning dot badges easier + display: flex; + align-items: center; + + .mx_NotificationBadge { + margin: 0 2px; // centering + } + + .mx_NotificationBadge_dot { + // make the smaller dot occupy the same width for centering + margin-left: 7px; + margin-right: 7px; + } + } + + &.collapsed { + .mx_SpaceButton { + .mx_SpacePanel_badgeContainer { + position: absolute; + right: -8px; + top: -4px; + } + } + } + + &:not(.collapsed) { + .mx_SpaceButton:hover, + .mx_SpaceButton:focus-within, + .mx_SpaceButton_hasMenuOpen { + // Hide the badge container on hover because it'll be a menu button + .mx_SpacePanel_badgeContainer { + width: 0; + height: 0; + display: none; + } + } + } + + /* root space buttons are bigger and not indented */ + & > .mx_AutoHideScrollbar { + & > .mx_SpaceButton { + height: $topLevelHeight; + + &.mx_SpaceButton_active::before { + height: $topLevelHeight; + } + } + + & > ul { + padding-left: 0; + } + } +} diff --git a/res/img/element-icons/expand-space-panel.svg b/res/img/element-icons/expand-space-panel.svg new file mode 100644 index 0000000000..11232acd58 --- /dev/null +++ b/res/img/element-icons/expand-space-panel.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/themes/light/css/_mods.scss b/res/themes/light/css/_mods.scss index 30aaeedf8f..fbca58dfb1 100644 --- a/res/themes/light/css/_mods.scss +++ b/res/themes/light/css/_mods.scss @@ -16,6 +16,10 @@ backdrop-filter: blur($groupFilterPanel-background-blur-amount); } + .mx_SpacePanel { + backdrop-filter: blur($groupFilterPanel-background-blur-amount); + } + .mx_LeftPanel .mx_LeftPanel_roomListContainer { backdrop-filter: blur($roomlist-background-blur-amount); } diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index 4445ff3ff8..82dd9443cc 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -39,6 +39,7 @@ import { OwnProfileStore } from "../../stores/OwnProfileStore"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import RoomListNumResults from "../views/rooms/RoomListNumResults"; import LeftPanelWidget from "./LeftPanelWidget"; +import SpacePanel from "../views/spaces/SpacePanel"; interface IProps { isMinimized: boolean; @@ -388,12 +389,19 @@ export default class LeftPanel extends React.Component { } public render(): React.ReactNode { - const groupFilterPanel = !this.state.showGroupFilterPanel ? null : ( -
- - {SettingsStore.getValue("feature_custom_tags") ? : null} -
- ); + let leftLeftPanel; + // Currently TagPanel.enableTagPanel is disabled when Legacy Communities are disabled so for now + // ignore it and force the rendering of SpacePanel if that Labs flag is enabled. + if (SettingsStore.getValue("feature_spaces")) { + leftLeftPanel = ; + } else if (this.state.showGroupFilterPanel) { + leftLeftPanel = ( +
+ + {SettingsStore.getValue("feature_custom_tags") ? : null} +
+ ); + } const roomList = { const containerClasses = classNames({ "mx_LeftPanel": true, - "mx_LeftPanel_hasGroupFilterPanel": !!groupFilterPanel, "mx_LeftPanel_minimized": this.props.isMinimized, }); @@ -417,7 +424,7 @@ export default class LeftPanel extends React.Component { return (
- {groupFilterPanel} + {leftLeftPanel}