From 833dcbac644911a845a91e3bef18ffc534461be2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 19 Dec 2019 09:25:51 +0000 Subject: [PATCH 001/332] Rewire the Sticker button to be an Emoji Picker --- src/components/views/rooms/MessageComposer.js | 37 ++++++++++++++++++- .../views/rooms/SendMessageComposer.js | 14 +++++++ src/components/views/rooms/Stickerpicker.js | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 580e3b0d81..00cb276923 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -22,10 +22,10 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import RoomViewStore from '../../../stores/RoomViewStore'; -import Stickerpicker from './Stickerpicker'; import { makeRoomPermalink } from '../../../utils/permalinks/Permalinks'; import ContentMessages from '../../../ContentMessages'; import E2EIcon from './E2EIcon'; +import {aboveLeftOf, ContextMenu, ContextMenuButton, useContextMenu} from "../../structures/ContextMenu"; function ComposerAvatar(props) { const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar'); @@ -102,6 +102,32 @@ HangupButton.propTypes = { roomId: PropTypes.string.isRequired, }; +const EmojiButton = ({addEmoji}) => { + const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); + + let contextMenu; + if (menuDisplayed) { + const buttonRect = button.current.getBoundingClientRect(); + const EmojiPicker = sdk.getComponent('emojipicker.EmojiPicker'); + contextMenu = + + ; + } + + return + + + + + { contextMenu } + ; +}; + class UploadButton extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, @@ -298,6 +324,13 @@ export default class MessageComposer extends React.Component { } } + addEmoji(emoji) { + dis.dispatch({ + action: "insert_emoji", + emoji, + }); + } + render() { const controls = [ this.state.me ? : null, @@ -321,7 +354,7 @@ export default class MessageComposer extends React.Component { room={this.props.room} placeholder={this.renderPlaceholderText()} permalinkCreator={this.props.permalinkCreator} />, - , + , , callInProgress ? : null, callInProgress ? null : , diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index af25155588..c2f79c72d7 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -317,6 +317,9 @@ export default class SendMessageComposer extends React.Component { case 'quote': this._insertQuotedMessage(payload.event); break; + case 'insert_emoji': + this._insertEmoji(payload.emoji); + break; } }; @@ -353,6 +356,17 @@ export default class SendMessageComposer extends React.Component { this._editorRef && this._editorRef.focus(); } + _insertEmoji = (emoji) => { + const {model} = this; + const {partCreator} = model; + const caret = this._editorRef.getCaret(); + const position = model.positionForOffset(caret.offset, caret.atNodeEnd); + model.transform(() => { + const addedLen = model.insert([partCreator.plain(emoji)], position); + return model.positionForOffset(caret.offset + addedLen, true); + }); + }; + _onPaste = (event) => { const {clipboardData} = event; if (clipboardData.files.length) { diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 24f256e706..095a0dca31 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -36,6 +36,7 @@ const STICKERPICKER_Z_INDEX = 3500; // Key to store the widget's AppTile under in PersistedElement const PERSISTED_ELEMENT_KEY = "stickerPicker"; +// TODO figure out where to expose it now that the EmojiPicker has taken its place export default class Stickerpicker extends React.Component { static currentWidget; From e3d1cf8d84d57e438755fc264dd742b00e77f979 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 5 Apr 2020 20:55:26 +0200 Subject: [PATCH 002/332] Replace {} with null to be compliant with newer specs. While older also accepted null for the auth part of the registration request object Took 18 minutes --- src/components/structures/auth/Registration.js | 2 +- src/components/views/auth/InteractiveAuthEntryComponents.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index c74f6ed6e3..dc22516cd8 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -243,7 +243,7 @@ export default createReactClass({ }); }; try { - await this._makeRegisterRequest({}); + await this._makeRegisterRequest(null); // This should never succeed since we specified an empty // auth object. console.log("Expecting 401 from register request but got success!"); diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index 327451be17..bee99306a3 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -650,7 +650,7 @@ export class SSOAuthEntry extends React.Component { }; onConfirmClick = () => { - this.props.submitAuthDict({}); + this.props.submitAuthDict(null); }; render() { @@ -740,7 +740,7 @@ export const FallbackAuthEntry = createReactClass({ event.data === "authDone" && event.origin === this.props.matrixClient.getHomeserverUrl() ) { - this.props.submitAuthDict({}); + this.props.submitAuthDict(null); } }, From 9820400680003564b8538502b98227836c0ea723 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 8 Apr 2020 20:53:05 +0200 Subject: [PATCH 003/332] Update src/components/structures/auth/Registration.js Co-Authored-By: Travis Ralston --- src/components/structures/auth/Registration.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index dc22516cd8..a84d779371 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -244,8 +244,7 @@ export default createReactClass({ }; try { await this._makeRegisterRequest(null); - // This should never succeed since we specified an empty - // auth object. + // This should never succeed since we're doing UIA console.log("Expecting 401 from register request but got success!"); } catch (e) { if (e.httpStatus === 401) { From 69c1e117a3310e66d88023b16a7dcc7249f01b2d Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 8 Apr 2020 20:55:02 +0200 Subject: [PATCH 004/332] Fix submitAuthDict(null) being null in places where it actually should be auth: {} Took 16 minutes --- src/components/views/auth/InteractiveAuthEntryComponents.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index bee99306a3..327451be17 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -650,7 +650,7 @@ export class SSOAuthEntry extends React.Component { }; onConfirmClick = () => { - this.props.submitAuthDict(null); + this.props.submitAuthDict({}); }; render() { @@ -740,7 +740,7 @@ export const FallbackAuthEntry = createReactClass({ event.data === "authDone" && event.origin === this.props.matrixClient.getHomeserverUrl() ) { - this.props.submitAuthDict(null); + this.props.submitAuthDict({}); } }, From 0e42a6ff851ae2fadbfe1ecc0d24991516d3aa74 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 10 Apr 2020 19:16:15 +0200 Subject: [PATCH 005/332] Send empty auth key value pair if doing FallbackStage Took 3 minutes --- src/components/views/auth/InteractiveAuthEntryComponents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index 327451be17..4222aa9255 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -740,7 +740,7 @@ export const FallbackAuthEntry = createReactClass({ event.data === "authDone" && event.origin === this.props.matrixClient.getHomeserverUrl() ) { - this.props.submitAuthDict({}); + this.props.submitAuthDict(null); } }, From 384336e8f149612b22f77ae6a5967407864e736b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Apr 2020 10:06:57 +0100 Subject: [PATCH 006/332] s/alias/address/ in copy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/GroupAddressPicker.js | 2 +- src/SlashCommands.tsx | 8 ++-- src/components/structures/GroupView.js | 2 +- src/components/structures/RoomDirectory.js | 4 +- src/components/views/create_room/RoomAlias.js | 2 +- .../views/dialogs/CreateRoomDialog.js | 2 +- .../views/elements/RoomAliasField.js | 8 ++-- .../views/room_settings/AliasSettings.js | 14 +++---- .../tabs/room/SecurityRoomSettingsTab.js | 2 +- .../tabs/user/MjolnirUserSettingsTab.js | 4 +- src/i18n/strings/en_EN.json | 38 +++++++++---------- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index 9131a89e5d..2928137f9d 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -73,7 +73,7 @@ export function showGroupAddRoomDialog(groupId) { title: _t("Add rooms to the community"), description: description, extraNode: checkboxContainer, - placeholder: _t("Room name or alias"), + placeholder: _t("Room name or address"), button: _t("Add to community"), pickerType: 'room', validAddressTypes: ['mx-room-id'], diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index aac42b6740..b205af477d 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -441,8 +441,8 @@ export const Commands = [ new Command({ command: 'join', aliases: ['j', 'goto'], - args: '', - description: _td('Joins room with given alias'), + args: '', + description: _td('Joins room with given address'), runFn: function(_, args) { if (args) { // Note: we support 2 versions of this command. The first is @@ -553,7 +553,7 @@ export const Commands = [ }), new Command({ command: 'part', - args: '[]', + args: '[]', description: _td('Leave room'), runFn: function(roomId, args) { const cli = MatrixClientPeg.get(); @@ -585,7 +585,7 @@ export const Commands = [ } if (targetRoomId) break; } - if (!targetRoomId) return reject(_t('Unrecognised room alias:') + ' ' + roomAlias); + if (!targetRoomId) return reject(_t('Unrecognised room address:') + ' ' + roomAlias); } } diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 3b32e5c907..cae9e096a6 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -92,7 +92,7 @@ const CategoryRoomList = createReactClass({ Modal.createTrackedDialog('Add Rooms to Group Summary', '', AddressPickerDialog, { title: _t('Add rooms to the community summary'), description: _t("Which rooms would you like to add to this summary?"), - placeholder: _t("Room name or alias"), + placeholder: _t("Room name or address"), button: _t("Add to summary"), pickerType: 'room', validAddressTypes: ['mx-room-id'], diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 0b07c10c8a..03cf06ec3f 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -199,7 +199,7 @@ export default createReactClass({ let desc; if (alias) { - desc = _t('Delete the room alias %(alias)s and remove %(name)s from the directory?', {alias: alias, name: name}); + desc = _t('Delete the room address %(alias)s and remove %(name)s from the directory?', {alias, name}); } else { desc = _t('Remove %(name)s from the directory?', {name: name}); } @@ -216,7 +216,7 @@ export default createReactClass({ MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => { if (!alias) return; - step = _t('delete the alias.'); + step = _t('delete the address.'); return MatrixClientPeg.get().deleteAlias(alias); }).then(() => { modal.close(); diff --git a/src/components/views/create_room/RoomAlias.js b/src/components/views/create_room/RoomAlias.js index bc5dec1468..5bdfdde08d 100644 --- a/src/components/views/create_room/RoomAlias.js +++ b/src/components/views/create_room/RoomAlias.js @@ -98,7 +98,7 @@ export default createReactClass({ render: function() { return ( - ); diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index 88e90627e8..ec53f99b78 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -180,7 +180,7 @@ export default createReactClass({ let publicPrivateLabel; let aliasField; if (this.state.isPublic) { - publicPrivateLabel = (

{_t("Set a room alias to easily share your room with other people.")}

); + publicPrivateLabel = (

{_t("Set a room address to easily share your room with other people.")}

); const domain = MatrixClientPeg.get().getDomain(); aliasField = (
diff --git a/src/components/views/elements/RoomAliasField.js b/src/components/views/elements/RoomAliasField.js index d3de6a5d34..ee18913971 100644 --- a/src/components/views/elements/RoomAliasField.js +++ b/src/components/views/elements/RoomAliasField.js @@ -45,7 +45,7 @@ export default class RoomAliasField extends React.PureComponent { const maxlength = 255 - this.props.domain.length - 2; // 2 for # and : return ( allowEmpty || !!value, - invalid: () => _t("Please provide a room alias"), + invalid: () => _t("Please provide a room address"), }, { key: "taken", final: true, @@ -107,8 +107,8 @@ export default class RoomAliasField extends React.PureComponent { return !!err.errcode; } }, - valid: () => _t("This alias is available to use"), - invalid: () => _t("This alias is already in use"), + valid: () => _t("This address is available to use"), + invalid: () => _t("This address is already in use"), }, ], }); diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index 3994d78390..37d1e66e98 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -220,10 +220,10 @@ export default class AliasSettings extends React.Component { } }).catch((err) => { console.error(err); - Modal.createTrackedDialog('Error creating alias', '', ErrorDialog, { - title: _t("Error creating alias"), + Modal.createTrackedDialog('Error creating address', '', ErrorDialog, { + title: _t("Error creating address"), description: _t( - "There was an error creating that alias. It may not be allowed by the server " + + "There was an error creating that address. It may not be allowed by the server " + "or a temporary failure occurred.", ), }); @@ -245,15 +245,15 @@ export default class AliasSettings extends React.Component { console.error(err); let description; if (err.errcode === "M_FORBIDDEN") { - description = _t("You don't have permission to delete the alias."); + description = _t("You don't have permission to delete the address."); } else { description = _t( - "There was an error removing that alias. It may no longer exist or a temporary " + + "There was an error removing that address. It may no longer exist or a temporary " + "error occurred.", ); } - Modal.createTrackedDialog('Error removing alias', '', ErrorDialog, { - title: _t("Error removing alias"), + Modal.createTrackedDialog('Error removing address', '', ErrorDialog, { + title: _t("Error removing address"), description, }); }); diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js index eb2b885a22..c67596a3a5 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js @@ -247,7 +247,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
- {_t("To link to this room, please add an alias.")} + {_t("To link to this room, please add an address.")}
); diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js index d22b7ec183..f1fe5f2556 100644 --- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js @@ -84,7 +84,7 @@ export default class MjolnirUserSettingsTab extends React.Component { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, { title: _t('Error subscribing to list'), - description: _t('Please verify the room ID or alias and try again.'), + description: _t('Please verify the room ID or address and try again.'), }); } finally { this.setState({busy: false}); @@ -305,7 +305,7 @@ export default class MjolnirUserSettingsTab extends React.Component {
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ae8ed90402..3bbad1d585 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -114,7 +114,7 @@ "Which rooms would you like to add to this community?": "Which rooms would you like to add to this community?", "Show these rooms to non-members on the community page and room list?": "Show these rooms to non-members on the community page and room list?", "Add rooms to the community": "Add rooms to the community", - "Room name or alias": "Room name or alias", + "Room name or address": "Room name or address", "Add to community": "Add to community", "Failed to invite the following users to %(groupId)s:": "Failed to invite the following users to %(groupId)s:", "Failed to invite users to community": "Failed to invite users to community", @@ -183,9 +183,9 @@ "Use an identity server": "Use an identity server", "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.", "Use an identity server to invite by email. Manage in Settings.": "Use an identity server to invite by email. Manage in Settings.", - "Joins room with given alias": "Joins room with given alias", + "Joins room with given address": "Joins room with given address", "Leave room": "Leave room", - "Unrecognised room alias:": "Unrecognised room alias:", + "Unrecognised room address:": "Unrecognised room address:", "Kicks user with given id": "Kicks user with given id", "Bans user with given id": "Bans user with given id", "Unbans user with given ID": "Unbans user with given ID", @@ -788,7 +788,7 @@ "Error adding ignored user/server": "Error adding ignored user/server", "Something went wrong. Please try again or view your console for hints.": "Something went wrong. Please try again or view your console for hints.", "Error subscribing to list": "Error subscribing to list", - "Please verify the room ID or alias and try again.": "Please verify the room ID or alias and try again.", + "Please verify the room ID or address and try again.": "Please verify the room ID or address and try again.", "Error removing ignored user/server": "Error removing ignored user/server", "Error unsubscribing from list": "Error unsubscribing from list", "Please try again or view your console for hints.": "Please try again or view your console for hints.", @@ -815,7 +815,7 @@ "Subscribed lists": "Subscribed lists", "Subscribing to a ban list will cause you to join it!": "Subscribing to a ban list will cause you to join it!", "If this isn't what you want, please use a different tool to ignore users.": "If this isn't what you want, please use a different tool to ignore users.", - "Room ID or alias of ban list": "Room ID or alias of ban list", + "Room ID or address of ban list": "Room ID or address of ban list", "Subscribe": "Subscribe", "Notifications": "Notifications", "Start automatically after system login": "Start automatically after system login", @@ -916,7 +916,7 @@ "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.": "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.", "Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.", "Click here to fix": "Click here to fix", - "To link to this room, please add an alias.": "To link to this room, please add an alias.", + "To link to this room, please add an address.": "To link to this room, please add an address.", "Only people who have been invited": "Only people who have been invited", "Anyone who knows the room's link, apart from guests": "Anyone who knows the room's link, apart from guests", "Anyone who knows the room's link, including guests": "Anyone who knows the room's link, including guests", @@ -1187,11 +1187,11 @@ "Error updating main address": "Error updating main address", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.", "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.", - "Error creating alias": "Error creating alias", - "There was an error creating that alias. It may not be allowed by the server or a temporary failure occurred.": "There was an error creating that alias. It may not be allowed by the server or a temporary failure occurred.", - "You don't have permission to delete the alias.": "You don't have permission to delete the alias.", - "There was an error removing that alias. It may no longer exist or a temporary error occurred.": "There was an error removing that alias. It may no longer exist or a temporary error occurred.", - "Error removing alias": "Error removing alias", + "Error creating address": "Error creating address", + "There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.": "There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.", + "You don't have permission to delete the address.": "You don't have permission to delete the address.", + "There was an error removing that address. It may no longer exist or a temporary error occurred.": "There was an error removing that address. It may no longer exist or a temporary error occurred.", + "Error removing address": "Error removing address", "Main address": "Main address", "not specified": "not specified", "This room has no local addresses": "This room has no local addresses", @@ -1484,12 +1484,12 @@ "Custom level": "Custom level", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.", "In reply to ": "In reply to ", - "Room alias": "Room alias", + "Room address": "Room address", "e.g. my-room": "e.g. my-room", "Some characters not allowed": "Some characters not allowed", - "Please provide a room alias": "Please provide a room alias", - "This alias is available to use": "This alias is available to use", - "This alias is already in use": "This alias is already in use", + "Please provide a room address": "Please provide a room address", + "This address is available to use": "This address is available to use", + "This address is already in use": "This address is already in use", "Room directory": "Room directory", "Sign in with single sign-on": "Sign in with single sign-on", "And %(count)s more...|other": "And %(count)s more...", @@ -1556,7 +1556,7 @@ "example": "example", "Create": "Create", "Please enter a name for the room": "Please enter a name for the room", - "Set a room alias to easily share your room with other people.": "Set a room alias to easily share your room with other people.", + "Set a room address to easily share your room with other people.": "Set a room address to easily share your room with other people.", "This room is private, and can only be joined by invitation.": "This room is private, and can only be joined by invitation.", "Enable end-to-end encryption": "Enable end-to-end encryption", "You can’t disable this later. Bridges & most bots won’t work yet.": "You can’t disable this later. Bridges & most bots won’t work yet.", @@ -1807,7 +1807,7 @@ "Private Chat": "Private Chat", "Public Chat": "Public Chat", "Custom": "Custom", - "Alias (optional)": "Alias (optional)", + "Address (optional)": "Address (optional)", "Reject invitation": "Reject invitation", "Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?", "Unable to reject invite": "Unable to reject invite", @@ -2001,11 +2001,11 @@ "Riot failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.": "Riot failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.", "Riot failed to get the public room list.": "Riot failed to get the public room list.", "The homeserver may be unavailable or overloaded.": "The homeserver may be unavailable or overloaded.", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", + "Delete the room address %(alias)s and remove %(name)s from the directory?": "Delete the room address %(alias)s and remove %(name)s from the directory?", "Remove %(name)s from the directory?": "Remove %(name)s from the directory?", "Remove from Directory": "Remove from Directory", "remove %(name)s from the directory.": "remove %(name)s from the directory.", - "delete the alias.": "delete the alias.", + "delete the address.": "delete the address.", "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", "Unable to join network": "Unable to join network", "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", From a8e92589ad9c88db00a69a7debfd8d601378c3cf Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Mon, 18 May 2020 09:17:10 +0000 Subject: [PATCH 007/332] Translated using Weblate (Slovak) Currently translated at 62.7% (1450 of 2312 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index e85732ed82..168f2b4f39 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -1018,7 +1018,7 @@ "Failed to decrypt %(failedCount)s sessions!": "Nepodarilo sa dešifrovať %(failedCount)s relácií!", "Restored %(sessionCount)s session keys": "Obnovených %(sessionCount)s kľúčov relácií", "Enter Recovery Passphrase": "Zadajte heslo bezpečného obnovenia", - "Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Zabezpečte svoju komunikáciu a prístup k šifrovanej histórii konverzácií zadaním hesla obnovenia.", + "Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Zabezpečte svoju komunikáciu a prístup k šifrovanej histórii konverzácií zadaním (dlhého) hesla obnovenia.", "Waiting for %(userId)s to confirm...": "Čakanie na potvrdenie od používateľa %(userId)s…", "Prompt before sending invites to potentially invalid matrix IDs": "Upozorniť pred odoslaním pozvaní na potenciálne neexistujúce Matrix ID", "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "Nie je možné nájsť používateľský profil pre Matrix ID zobrazené nižšie. Chcete ich napriek tomu pozvať?", @@ -1531,5 +1531,26 @@ "Keep recovery passphrase in memory for this session": "Ponechať (dlhé) heslo pre obnovu zálohy v pamäti pre túto reláciu", "Enter recovery passphrase": "Zadajte (dlhé) heslo pre obnovu zálohy", "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Nemožno sa dostať do tajného úložiska. Prosím, overte, že ste zadali správne (dlhé) heslo pre obnovu zálohy.", - "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Získajte prístup k vašej zabezpečenej histórií správ a vašemu krížom-podpísanej identite na potvrdenie iných relácií zadaním vášho (dlhého) hesla na obnovu zálohy." + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Získajte prístup k vašej šifrovanej histórií správ a vašemu krížom-podpísanej identite na potvrdenie iných relácií zadaním vášho (dlhého) hesla na obnovu zálohy.", + "Encryption upgrade available": "Je dostupná aktualizácia šifrovania", + "Set up encryption": "Nastaviť šifrovanie", + "Review where you’re logged in": "Zobraziť, kde ste prihlásený", + "New login. Was this you?": "Nové pihlásenie. Ste to vy?", + "%(name)s is requesting verification": "%(name) žiada o overenie", + "Sign In or Create Account": "Prihlásiť sa alebo vytvoriť nový účet", + "Use your account or create a new one to continue.": "Použite váš existujúci účet alebo vytvorte si nový, aby ste mohli pokračovať.", + "Create Account": "Vytvoriť účet", + "Sign In": "Prihlásiť sa", + "Sends a message as html, without interpreting it as markdown": "Pošlite správu ako HTML, bez interpretácie v Markdowne", + "Failed to set topic": "Nastavenie témy zlyhalo", + "Command failed": "Príkaz zlyhal", + "Could not find user in room": "Nepodarilo sa nájsť používateľa v miestnosti", + "Please supply a widget URL or embed code": "Prosím, zadajte URL widgetu alebo vložte kód", + "Verifies a user, session, and pubkey tuple": "Overí používateľa, reláciu a verejné kľúče", + "Unknown (user, session) pair:": "Neznámy pár (používateľ, relácia):", + "Session already verified!": "Relácia je už overená!", + "WARNING: Session already verified, but keys do NOT MATCH!": "VAROVANIE: Relácia je už overená, ale kľúče sa NEZHODUJÚ!", + "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Pokiaľ ste zabudli na vaše (dlhé) heslo na obnovu zálohy, môžete použiť váš kľúč na obnovu zálohy alebo nastaviť nové spôsoby obnovy zálohy.", + "Incorrect recovery passphrase": "Nesprávne (dlhé) heslo pre obnovu zálohy", + "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Záloha nemohla byť rozšifrovaná pomocou tohto (dlhého) helsa na obnovu zálohy: prosím, overte, či ste zadali správne (dlhé) helso na obnovu zálohy." } From b9c31b27a2526c5670b43e3506008a0366e4a639 Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Mon, 18 May 2020 10:14:36 +0000 Subject: [PATCH 008/332] Translated using Weblate (Slovak) Currently translated at 64.9% (1500 of 2311 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 93 +++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 168f2b4f39..d117843ccf 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -814,7 +814,7 @@ "Invite to this room": "Pozvať do tejto miestnosti", "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", "Thursday": "Štvrtok", - "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", + "I understand the risks and wish to continue": "Rozumiem riziku a chcem pokračovať", "Logs sent": "Záznamy boli odoslané", "Back": "Naspäť", "Reply": "Odpovedať", @@ -1018,7 +1018,7 @@ "Failed to decrypt %(failedCount)s sessions!": "Nepodarilo sa dešifrovať %(failedCount)s relácií!", "Restored %(sessionCount)s session keys": "Obnovených %(sessionCount)s kľúčov relácií", "Enter Recovery Passphrase": "Zadajte heslo bezpečného obnovenia", - "Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Zabezpečte svoju komunikáciu a prístup k šifrovanej histórii konverzácií zadaním (dlhého) hesla obnovenia.", + "Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Získajte prístup k šifrovanej histórií správ a nastavte šiforvanú komunikáciu zadaním vášho (dlhého) hesla obnovenia.", "Waiting for %(userId)s to confirm...": "Čakanie na potvrdenie od používateľa %(userId)s…", "Prompt before sending invites to potentially invalid matrix IDs": "Upozorniť pred odoslaním pozvaní na potenciálne neexistujúce Matrix ID", "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "Nie je možné nájsť používateľský profil pre Matrix ID zobrazené nižšie. Chcete ich napriek tomu pozvať?", @@ -1029,7 +1029,7 @@ "Enter Recovery Key": "Zadajte kľúč obnovenia", "This looks like a valid recovery key!": "Zdá sa, že toto je platný kľúč obnovenia!", "Not a valid recovery key": "Neplatný kľúč obnovenia", - "Access your secure message history and set up secure messaging by entering your recovery key.": "Zabezpečte svoju komunikáciu a prístup k šifrovanej histórii konverzácií zadaním kľúča obnovenia.", + "Access your secure message history and set up secure messaging by entering your recovery key.": "Získajte prístup k šifrovanej histórií správ a nastavte šiforvanú komunikáciu zadaním vášho kľúča obnovenia.", "Set a new status...": "Nastaviť nový stav…", "Clear status": "Zrušiť stav", "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Ste správcom tejto komunity. Nebudete môcť znovu vstúpiť bez pozvania od iného správcu.", @@ -1041,8 +1041,8 @@ "Great! This passphrase looks strong enough.": "Výborne! Toto je dostatočne silné heslo.", "Enter a passphrase...": "Zadajte heslo…", "That matches!": "Zhoda!", - "That doesn't match.": "Nezhodujú sa.", - "Go back to set it again.": "Vráťte sa späť a nastavte znovu.", + "That doesn't match.": "To sa nezhoduje.", + "Go back to set it again.": "Vráťte sa späť a nastavte to znovu.", "Repeat your passphrase...": "Zopakujte heslo…", "As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.": "Ak zabudnete svoje heslo obnovenia, tento kľúč môžete použiť ako ďalší bezpečnostný prvok na obnovenie histórii šifrovaných konverzácií.", "As a safety net, you can use it to restore your encrypted message history.": "Tento kľúč môžete použiť ako ďalší bezpečnostný prvok na obnovenie histórii šifrovaných konverzácií.", @@ -1059,8 +1059,8 @@ "Retry": "Skúsiť znovu", "Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "Ak si nenastavíte Bezpečné obnovenie správ, po odhlásení stratíte prístup k histórii šifrovaných konverzácií.", "If you don't want to set this up now, you can later in Settings.": "Ak nechcete pokračovať v nastavení teraz, môžete sa k tomu vrátiť neskôr v časti nastavenia.", - "New Recovery Method": "Nový spôsob obnovi", - "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 útočníci sa môžu pokúsiť dostať k vášmu účtu. Ihneď si v nastaveniach zmeňte heslo a znovu si nastavte možnosti obnovenia.", + "New Recovery Method": "Nový spôsob obnovy", + "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)", @@ -1321,7 +1321,7 @@ "Premium hosting for organisations Learn more": "Platený hosting pre organizácie Zistiť viac", "Other": "Ďalšie", "Find other public servers or use a custom server": "Nájdite ďalšie verejné domovské servery alebo nastavte pripojenie k serveru ručne", - "Please install Chrome, Firefox, or Safari for the best experience.": "Pre najlepší zážitok si prosím nainštalujte Chrome, Firefox alebo Safari.", + "Please install Chrome, Firefox, or Safari for the best experience.": "Prosím, nainštalujte si Chrome, Firefox alebo Safari pre najlepší zážitok.", "Couldn't load page": "Nie je možné načítať stránku", "Want more than a community? Get your own server": "Chceli by ste viac než komunitu? Získajte vlastný server", "This homeserver does not support communities": "Tento domovský server nepodporuje komunity", @@ -1339,7 +1339,7 @@ "Create your account": "Vytvoriť váš účet", "Keep going...": "Pokračujte…", "We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.": "Zašifrovanú kópiu vašich šifrovacích kľúčov uchováme na domovskom servery. Zabezpečte si zálohovanie zadaním hesla obnovenia, čo posilní ochranu vašich údajov.", - "For maximum security, this should be different from your account password.": "Aby ste zachovali maximálnu mieru zabezpečenia, heslo obnovenia by malo byť odlišné ako heslo, ktorým sa prihlasujete do Matrix účtu.", + "For maximum security, this should be different from your account password.": "Aby ste zachovali maximálnu mieru zabezpečenia, (dlhé) heslo by malo byť odlišné od hesla, ktorým sa prihlasujete do vášho účtu.", "Set up with a Recovery Key": "Nastaviť použitím kľúča obnovenia", "Please enter your passphrase a second time to confirm.": "Prosím zadajte heslo obnovenia ešte raz pre potvrdenie.", "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Kľúč obnovenia je bezpečnostný mechanizmus - môžete ho použiť na prístup k šifrovacím kľúčom v prípade, ak zabudnete vaše heslo obnovenia.", @@ -1348,10 +1348,10 @@ "Confirm your passphrase": "Potvrdiť heslo obnovenia", "Recovery key": "Kľúč obnovenia", "Starting backup...": "Začína sa zálohovanie…", - "Success!": "Hotovo!", - "A new recovery passphrase and key for Secure Messages have been detected.": "Boli zistené nový kľúč a nové heslo obnovenia zálohovania šifrovacích kľúčov.", + "Success!": "Úspech!", + "A new recovery passphrase and key for Secure Messages have been detected.": "Nové (dlhé) heslo na obnovu zálohy a kľúč pre bezpečné správy boli spozorované.", "Recovery Method Removed": "Odstránený spôsob obnovenia", - "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.": "Ak ste spôsob obnovenia neodstránili vy, útočník sa pravdepodobne usiluje dostať k vašemu účtu. Zmente si prosím heslo na prihlásenie do Matrix účtu a znovu si ihneď nastavte možnosti obnovenia.", + "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.": "Ak ste neodstránili spôsob obnovenia vy, 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.", "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Či používate alebo nie funkcionalitu známu ako „omrvinky“ (obrázky nad zoznamom miestností)", "Call failed due to misconfigured server": "Hovor zlyhal kvôli nesprávne nakonfigurovanému serveru", "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Prosím, požiadajte správcu vášho domovského servera (%(homeserverDomain)s) aby nakonfiguroval Turn server, čo zlepší spoľahlivosť audio / video hovorov.", @@ -1410,7 +1410,7 @@ "Send cross-signing keys to homeserver": "Poslať kľúče pre podpisovanie naprieč zariadeniami na domovský server", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Táto akcia si vyžaduje mať overenú emailovú adresu alebo telefónne číslo cez predvolený server totožností , ale server nezverejnil podmienky používania.", "Trust": "Dôverovať", - "Custom (%(level)s)": "Vlastná (%(level)s)", + "Custom (%(level)s)": "Vlastný (%(level)s)", "Sends a message as plain text, without interpreting it as markdown": "Odošle správu vo formáte obyčajný text, bez prekladu markdown", "You do not have the required permissions to use this command.": "Na použitie tohoto príkazu nemáte dostatočné povolenia.", "Error upgrading room": "Chyba pri aktualizácii miestnosti", @@ -1441,7 +1441,7 @@ "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s zmenil pravidlo zakázať vstúpiť z domovských serverov pôvodne sa zhodujúcich s %(oldGlob)s na servery zhodujúce sa s %(newGlob)s, dôvod: %(reason)s", "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s aktualizoval pravidlo zakázať vstúpiť pôvodne sa zhodujúce s %(oldGlob)s na %(newGlob)s, dôvod: %(reason)s", "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", - "Multiple integration managers": "Viacej integračných serverov", + "Multiple integration managers": "Viac integračných serverov", "Try out new ways to ignore people (experimental)": "Vyskúšajte si nový spôsob ignorovania používateľov (experiment)", "Enable local event indexing and E2EE search (requires restart)": "Povoliť lokálne indexovanie udalostí a vyhľadávanie v šifrovaných miestnostiach", "Match system theme": "Prispôsobiť sa vzhľadu systému", @@ -1452,12 +1452,12 @@ "The message you are trying to send is too large.": "Správa, ktorú sa usilujete odoslať, je príliš veľká.", "This is your list of users/servers you have blocked - don't leave the room!": "Toto je zoznam používateľov / serverov, ktorých ste zablokovali - neopúšťajte miestnosť!", "Upload": "Nahrať", - "Cross-signing and secret storage are enabled.": "Podpisovanie naprieč zariadeniami a bezpečné úložisko sú aktívne.", - "Cross-signing and secret storage are not yet set up.": "Podpisovanie naprieč zariadeniami a bezpečné úložisko zatiaľ nie sú nastavené.", + "Cross-signing and secret storage are enabled.": "Krížové podpisovanie a bezpečné úložisko sú zapnuté.", + "Cross-signing and secret storage are not yet set up.": "Krížové podpisovanie a bezpečné úložisko zatiaľ nie sú nastavené.", "Bootstrap cross-signing and secret storage": "Zaviesť podpisovanie naprieč zariadeniami a bezpečné úložisko", - "Cross-signing public keys:": "Verejné kľúče podpisovania naprieč zariadeniami:", + "Cross-signing public keys:": "Verejné kľúče krížového podpisovania:", "not found": "nenájdené", - "Cross-signing private keys:": "Súkromné kľúče podpisovania naprieč zariadeniami:", + "Cross-signing private keys:": "Súkromné kľúče krížového podpisovania:", "in secret storage": "na bezpečnom úložisku", "Secret storage public key:": "Verejný kľúč bezpečného úložiska:", "in account data": "v údajoch účtu", @@ -1475,13 +1475,13 @@ "Disconnect identity server": "Odpojiť server totožností", "Disconnect from the identity server ?": "Naozaj sa chcete odpojiť od servera totožností ?", "Disconnect": "Odpojiť", - "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Pred odpojením zo servera totožností by ste mali z neho odstrániť vaše osobné údaje. Žiaľ, server momentálne nie je dostupný a nie je možné sa k nemu pripojiť.", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Pred odpojením by ste mali odstrániť vaše osobné údaje zo servera totožností . Žiaľ, server totožnosti momentálne nie je dostupný a nie je možné sa k nemu pripojiť.", "You should:": "Mali by ste:", "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "Skontrolovať rozšírenia inštalované vo webovom prehliadači, ktoré by mohli blokovať prístup k serveru totožností (napr. rozšírenie Privacy Badger)", "contact the administrators of identity server ": "Kontaktovať správcu servera totožností ", "wait and try again later": "Počkať a skúsiť znovu neskôr", "Disconnect anyway": "Napriek tomu sa odpojiť", - "You are still sharing your personal data on the identity server .": "na servery máte stále uložené vaše osobné údaje.", + "You are still sharing your personal data on the identity server .": "Stále zdielate vaše osobné údaje so serverom totožnosti .", "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Odporúčame, aby ste ešte pred odpojením sa zo servera totožností odstránili vašu emailovú adresu a telefónne číslo.", "Identity Server (%(server)s)": "Server totožností (%(server)s)", "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Momentálne na vyhľadávanie kontaktov a na možnosť byť nájdení kontaktmi ktorých poznáte používate . Zmeniť server totožností môžete nižšie.", @@ -1496,7 +1496,7 @@ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Použiť integračný server na správu botov, widgetov a balíčkov s nálepkami.", "Manage integrations": "Spravovať integrácie", "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integračné servery zhromažďujú údaje nastavení, môžu spravovať widgety, odosielať vo vašom mene pozvánky alebo meniť úroveň moci.", - "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Súhlas s podmienkami používania servera totožností (%(serverName)s), aby ste mohli byť nájdení zadaním emailovej adresy alebo telefónneho čísla.", + "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Súhlaste s podmienkami používania servera totožností (%(serverName)s), aby ste mohli byť nájdení zadaním emailovej adresy alebo telefónneho čísla.", "Discovery": "Objaviť", "Deactivate account": "Deaktivovať účet", "Clear cache and reload": "Vymazať vyrovnávaciu pamäť a načítať znovu", @@ -1531,7 +1531,7 @@ "Keep recovery passphrase in memory for this session": "Ponechať (dlhé) heslo pre obnovu zálohy v pamäti pre túto reláciu", "Enter recovery passphrase": "Zadajte (dlhé) heslo pre obnovu zálohy", "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Nemožno sa dostať do tajného úložiska. Prosím, overte, že ste zadali správne (dlhé) heslo pre obnovu zálohy.", - "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Získajte prístup k vašej šifrovanej histórií správ a vašemu krížom-podpísanej identite na potvrdenie iných relácií zadaním vášho (dlhého) hesla na obnovu zálohy.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Získajte prístup k vašej šifrovanej histórií správ a vašej krížom podpísanej identite na potvrdenie iných relácií zadaním vášho (dlhého) hesla na obnovu zálohy.", "Encryption upgrade available": "Je dostupná aktualizácia šifrovania", "Set up encryption": "Nastaviť šifrovanie", "Review where you’re logged in": "Zobraziť, kde ste prihlásený", @@ -1550,7 +1550,52 @@ "Unknown (user, session) pair:": "Neznámy pár (používateľ, relácia):", "Session already verified!": "Relácia je už overená!", "WARNING: Session already verified, but keys do NOT MATCH!": "VAROVANIE: Relácia je už overená, ale kľúče sa NEZHODUJÚ!", - "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Pokiaľ ste zabudli na vaše (dlhé) heslo na obnovu zálohy, môžete použiť váš kľúč na obnovu zálohy alebo nastaviť nové spôsoby obnovy zálohy.", + "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Pokiaľ ste zabudli vaše (dlhé) heslo na obnovu zálohy, môžete použiť váš kľúč na obnovu zálohy alebo nastaviť nové spôsoby obnovy zálohy.", "Incorrect recovery passphrase": "Nesprávne (dlhé) heslo pre obnovu zálohy", - "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Záloha nemohla byť rozšifrovaná pomocou tohto (dlhého) helsa na obnovu zálohy: prosím, overte, či ste zadali správne (dlhé) helso na obnovu zálohy." + "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Záloha nemohla byť rozšifrovaná pomocou tohto (dlhého) helsa na obnovu zálohy: prosím, overte, či ste zadali správne (dlhé) helso na obnovu zálohy.", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROVANIE: OVERENIE KĽÚČOV ZLYHALO! Podpisovaný kľúč používateľa %(userId)s a relácia %(deviceId)s je \"%(fprint)s\" čo nezodpovedá zadanému kľúču \"%(fingerprint)s\". Môže to znamenať, že vaša komunikácia je infiltrovaná!", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Zadaný podpísaný kľúč sa zhoduje s podpísaným kľúčom od relácie %(deviceId)s používateľa %(userId)s. Relácia je označená ako overená.", + "Displays information about a user": "Zobrazuje informácie o používateľovi", + "Send a bug report with logs": "Zaslať chybové hlásenie so záznamami", + "Opens chat with the given user": "Otvorí konverzáciu s daným používateľom", + "Sends a message to the given user": "Pošle správu danému používateľovi", + "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s zmenil/a meno miestnosti z %(oldRoomName)s na %(newRoomName)s.", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s pridal/a alternatívne adresy %(addresses)s pre túto miestnosť.", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s pridal/a alternatívnu adresu %(addresses)s pre túto miestnosť.", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s odstránil/a alternatívne adresy %(addresses)s pre túto miestnosť.", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s odstránil/a alternatívnu adresu %(addresses)s pre túto miestnosť.", + "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s zmenil/a alternatívne adresy pre túto miestnosť.", + "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s zmenil hlavnú a alternatívne adresy pre túto miestnosť.", + "%(senderName)s changed the addresses for this room.": "%(senderName)s zmenil/a adresy pre túto miestnosť.", + "You signed in to a new session without verifying it:": "Prihlásili ste sa do novej relácie bez jej overenia:", + "Verify your other session using one of the options below.": "Overte svoje ostatné relácie pomocou jednej z nižšie uvedených možností.", + "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) sa prihlásil do novej relácie bez jej overenia:", + "Ask this user to verify their session, or manually verify it below.": "Poproste tohto používateľa, aby si overil svoju reláciu alebo ju nižšie manuálne overte.", + "Not Trusted": "Nedôveryhodné", + "Manually Verify by Text": "Manuálne overte pomocou textu", + "Interactively verify by Emoji": "Interaktívne overte pomocou emotikonov", + "Done": "Hotovo", + "a few seconds ago": "pred pár sekundami", + "about a minute ago": "približne pred minutou", + "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", + "about a minute from now": "približne o minutu", + "about an hour from now": "približne o hodinu", + "about a day from now": "približne o deň", + "Support adding custom themes": "Umožniť pridávať vlastný vzhľad", + "Enable cross-signing to verify per-user instead of per-session": "Povoliť krížové podpisovanie na overovanie používateľa namiesto overovania jednotlivých relácií", + "Your homeserver does not support cross-signing.": "Váš domovský server nepodporuje krížové podpisovanie.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Váš účet má krížovo podpísanú identitu v bezpečnom úložisku, ale zatiaľ nie je nedôveryhodná pre túto reláciu.", + "Reset cross-signing and secret storage": "Obnoviť krížové podpisovanie a bezpečné úložisko", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individuálne overte každú používateľskú reláciu a označte ju za dôveryhodnú, bez dôvery krížovo podpísaných zariadení.", + "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Zálohovací kľúč je uložený v bezpečnom úložisku, ale jeho načítanie nie je povolené v tejto relácií. Prosím, zapnite krížové podpisovanie v Experimentoch, aby ste mohli modifikovať stav zálohy.", + "Cross-signing": "Krížové podpisovanie", + "Destroy cross-signing keys?": "Zmazať kľúče pre krížové podpisovanie?", + "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.": "Zmazanie kľúčov pre krížové podpisovanie je nenávratné. Každý, s kým ste sa overili, bude vidieť bezpečnostné upozornenia. Toto určite nechcete robiť dokiaľ ste nestratili všetky zariadenia, s ktorými by ste mohli krížovo podpisovať.", + "Clear cross-signing keys": "Zmazať kľúče pre krížové podpisovanie", + "a new cross-signing key signature": "nový podpis kľúča pre krížové podpisovanie", + "a device cross-signing signature": "podpis krížovo podpísaného zariadenia", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Získajte prístup k vašej šifrovanej histórií správ a vašej krížom podpísanej identite pre overenie iných relácií zadaním vášho kľúču obnovy.", + "or another cross-signing capable Matrix client": "alebo iný Matrixový klient podporujúci krížové podpisovanie" } From 82ca614fa78958172e8d855e8fd37ca220f34d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 19 May 2020 06:50:47 +0000 Subject: [PATCH 009/332] Translated using Weblate (Estonian) Currently translated at 53.6% (1239 of 2311 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/et/ --- src/i18n/strings/et.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json index 3fb069055c..3d4b7ec888 100644 --- a/src/i18n/strings/et.json +++ b/src/i18n/strings/et.json @@ -1236,5 +1236,11 @@ "Nothing appearing? Not all clients support interactive verification yet. .": "Mitte midagi ei kuvata? Kõik Matrix'i kliendid ei toeta veel interaktiivset verifitseerimist. .", "Waiting for %(userId)s to confirm...": "Ootan kinnitust kasutajalt %(userId)s…", "Skip": "Jäta vahele", - "Token incorrect": "Vigane tunnusluba" + "Token incorrect": "Vigane tunnusluba", + "%(oneUser)schanged their name %(count)s times|one": "Kasutaja %(oneUser)s muutis oma nime", + "Are you sure you want to deactivate your account? This is irreversible.": "Kas sa oled kindel, et soovid oma konto sulgeda? Seda tegevust ei saa hiljem tagasi pöörata.", + "Confirm account deactivation": "Kinnita konto sulgemine", + "There was a problem communicating with the server. Please try again.": "Serveriühenduses tekkis viga. Palun proovi uuesti.", + "Server did not return valid authentication information.": "Serveri saadetud vastuses ei olnud kehtivat autentimisteavet.", + "Please fill why you're reporting.": "Palun kirjelda veateate põhjust." } From 0016d8e744a1c345af8494745f805b2d38d2405e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 May 2020 11:36:44 +0100 Subject: [PATCH 010/332] Add e2ee_default_for_private_rooms to control default e2ee behaviour Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateRoomDialog.js | 3 ++- src/components/views/dialogs/InviteDialog.js | 5 ++--- src/components/views/right_panel/UserInfo.js | 4 ++-- src/createRoom.js | 7 ++++++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index fb08afa5f7..df5f559e3b 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -25,6 +25,7 @@ import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {Key} from "../../../Keyboard"; import SettingsStore from "../../../settings/SettingsStore"; +import {privateShouldBeEncrypted} from "../../../createRoom"; export default createReactClass({ displayName: 'CreateRoomDialog', @@ -37,7 +38,7 @@ export default createReactClass({ const config = SdkConfig.get(); return { isPublic: this.props.defaultPublic || false, - isEncrypted: true, + isEncrypted: privateShouldBeEncrypted(), name: "", topic: "", alias: "", diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index 7cbbf8ba64..6b7d2ff69d 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -31,9 +31,8 @@ import dis from "../../../dispatcher"; import IdentityAuthClient from "../../../IdentityAuthClient"; import Modal from "../../../Modal"; import {humanizeTime} from "../../../utils/humanize"; -import createRoom, {canEncryptToAllUsers} from "../../../createRoom"; +import createRoom, {canEncryptToAllUsers, privateShouldBeEncrypted} from "../../../createRoom"; import {inviteMultipleToRoom} from "../../../RoomInvite"; -import SettingsStore from '../../../settings/SettingsStore'; import RoomListStore, {TAG_DM} from "../../../stores/RoomListStore"; import {Key} from "../../../Keyboard"; @@ -574,7 +573,7 @@ export default class InviteDialog extends React.PureComponent { const createRoomOptions = {inlineErrors: true}; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { // Check whether all users have uploaded device keys before. // If so, enable encryption in the new room. const has3PidMembers = targets.some(t => t instanceof ThreepidMember); diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index 478dc90418..68139e5726 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -25,7 +25,7 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import createRoom from '../../../createRoom'; +import createRoom, {privateShouldBeEncrypted} from '../../../createRoom'; import DMRoomMap from '../../../utils/DMRoomMap'; import AccessibleButton from '../elements/AccessibleButton'; import SdkConfig from '../../../SdkConfig'; @@ -111,7 +111,7 @@ async function openDMForUser(matrixClient, userId) { dmUserId: userId, }; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { // Check whether all users have uploaded device keys before. // If so, enable encryption in the new room. const usersToDevicesMap = await matrixClient.downloadKeys([userId]); diff --git a/src/createRoom.js b/src/createRoom.js index a39d2c2216..2573c438c2 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -24,6 +24,7 @@ import * as Rooms from "./Rooms"; import DMRoomMap from "./utils/DMRoomMap"; import {getAddressType} from "./UserAddress"; import SettingsStore from "./settings/SettingsStore"; +import SdkConfig from "./SdkConfig"; /** * Create a new room, and switch to it. @@ -227,7 +228,7 @@ export async function ensureDMExists(client, userId) { roomId = existingDMRoom.roomId; } else { let encryption; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { encryption = canEncryptToAllUsers(client, [userId]); } roomId = await createRoom({encryption, dmUserId: userId, spinner: false, andView: false}); @@ -235,3 +236,7 @@ export async function ensureDMExists(client, userId) { } return roomId; } + +export function privateShouldBeEncrypted() { + return SettingsStore.getValue("feature_cross_signing") && SdkConfig.get().e2ee_default_for_private_rooms !== false; +} From 3cd03812022ee7d9b7b7fbc9eca2b09ba22517e4 Mon Sep 17 00:00:00 2001 From: rkfg Date: Tue, 19 May 2020 10:34:45 +0000 Subject: [PATCH 011/332] Translated using Weblate (Russian) Currently translated at 89.8% (2075 of 2311 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 3591d96120..be9c6bfdd4 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -97,13 +97,13 @@ "Who can read history?": "Кто может читать историю?", "You do not have permission to post to this room": "Вы не можете писать в эту комнату", "You have no visible notifications": "Нет видимых уведомлений", - "%(targetName)s accepted an invitation.": "%(targetName)s принял приглашение.", - "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", + "%(targetName)s accepted an invitation.": "%(targetName)s принимает приглашение.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принимает приглашение от %(displayName)s.", "Active call": "Активный вызов", "%(senderName)s answered the call.": "%(senderName)s ответил(а) на звонок.", - "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s забанил(а) %(targetName)s.", "Call Timeout": "Нет ответа", - "%(senderName)s changed their profile picture.": "%(senderName)s изменил(а) свой аватар.", + "%(senderName)s changed their profile picture.": "%(senderName)s изменяет свой аватар.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровни прав %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s изменил(а) название комнаты на %(roomName)s.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил(а) тему комнаты на \"%(topic)s\".", @@ -223,8 +223,8 @@ "Reason": "Причина", "%(targetName)s rejected the invitation.": "%(targetName)s отклонил(а) приглашение.", "Reject invitation": "Отклонить приглашение", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил(а) свое отображаемое имя (%(oldDisplayName)s).", - "%(senderName)s removed their profile picture.": "%(senderName)s удалил(а) свой аватар.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удаляет своё отображаемое имя (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s удаляет свой аватар.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать конференц-звонок.", "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешения на отправку уведомлений — проверьте настройки браузера", "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -302,8 +302,8 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.", "Server unavailable, overloaded, or something else went wrong.": "Возможно, сервер недоступен, перегружен или что-то еще пошло не так.", "Session ID": "ID сессии", - "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил(а) отображаемое имя на %(displayName)s.", + "%(senderName)s set a profile picture.": "%(senderName)s устанавливает себе аватар.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s меняет отображаемое имя на %(displayName)s.", "Signed Out": "Выполнен выход", "This room is not accessible by remote Matrix servers": "Это комната недоступна из других серверов Matrix", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", @@ -696,7 +696,7 @@ "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Community IDs cannot be empty.": "ID сообществ не могут быть пустыми.", "In reply to ": "В ответ на ", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил(а) отображаемое имя на %(displayName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s меняет отображаемое имя на %(displayName)s.", "Failed to set direct chat tag": "Не удалось установить тег прямого чата", "Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты", "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату", @@ -977,7 +977,7 @@ "Render simple counters in room header": "Отображать простые счетчики в заголовке комнаты", "Enable Emoji suggestions while typing": "Включить предложения смайликов при наборе", "Show a placeholder for removed messages": "Показывать плашки вместо удалённых сообщений", - "Show join/leave messages (invites/kicks/bans unaffected)": "Показывать сообщения о вступлении | выходе (не влияет на приглашения, исключения и запреты)", + "Show join/leave messages (invites/kicks/bans unaffected)": "Показывать сообщения о входе/выходе (не влияет на приглашения, кики и баны)", "Show avatar changes": "Показывать изменения аватара", "Show display name changes": "Показывать изменения отображаемого имени", "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Напоминать включить Безопасное Восстановление Сообщений в зашифрованных комнатах", @@ -1639,7 +1639,7 @@ "This alias is already in use": "Этот псевдоним уже используется", "Close dialog": "Закрыть диалог", "Please enter a name for the room": "Пожалуйста, введите название комнаты", - "This room is private, and can only be joined by invitation.": "Эта комната приватная и может быть присоединена только по приглашению.", + "This room is private, and can only be joined by invitation.": "Эта комната приватная, в неё можно войти только по приглашению.", "Hide advanced": "Скрыть расширения", "Show advanced": "Показать расширения", "Please fill why you're reporting.": "Пожалуйста, заполните, почему вы сообщаете.", From af2eed2228dbf7552c94fe10e970d8a4af88640d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 May 2020 13:17:34 +0100 Subject: [PATCH 012/332] Fix room alias lookup vs peeking race condition Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 24 ++++++++++++++++++++---- src/stores/RoomViewStore.js | 12 ++---------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 635597db74..8e343fe08f 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -164,6 +164,8 @@ export default createReactClass({ canReact: false, canReply: false, + + matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), }; }, @@ -232,7 +234,8 @@ export default createReactClass({ initialEventId: RoomViewStore.getInitialEventId(), isInitialEventHighlighted: RoomViewStore.isInitialEventHighlighted(), forwardingEvent: RoomViewStore.getForwardingEvent(), - shouldPeek: RoomViewStore.shouldPeek(), + // we should only peek once we have a ready client + shouldPeek: this.state.matrixClientIsReady && RoomViewStore.shouldPeek(), showingPinned: SettingsStore.getValue("PinnedEvents.isOpen", roomId), showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId), }; @@ -681,6 +684,16 @@ export default createReactClass({ }); } break; + case 'sync_state': + if (!this.state.matrixClientIsReady) { + this.setState({ + matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), + }, () => { + // send another "initial" RVS update to trigger peeking if needed + this._onRoomViewStoreUpdate(true); + }); + } + break; } }, @@ -1663,14 +1676,16 @@ export default createReactClass({ const ErrorBoundary = sdk.getComponent("elements.ErrorBoundary"); if (!this.state.room) { - const loading = this.state.roomLoading || this.state.peekLoading; + const loading = this.state.matrixClientIsReady || this.state.roomLoading || this.state.peekLoading; if (loading) { + // Assume preview loading if we don't have a ready client or a room ID (still resolving the alias) + const previewLoading = !this.state.matrixClientIsReady || !this.state.roomId || this.state.peekLoading; return (
- Date: Tue, 19 May 2020 13:00:53 +0000 Subject: [PATCH 013/332] Translated using Weblate (Esperanto) Currently translated at 100.0% (2312 of 2312 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 3f749ebe0f..2729248bb0 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -2409,5 +2409,6 @@ "QR Code": "Rapidresponda kodo", "Dismiss read marker and jump to bottom": "Forigi legomarkon kaj iri al fundo", "Jump to oldest unread message": "Iri al plej malnova nelegita mesaĝo", - "Upload a file": "Alŝuti dosieron" + "Upload a file": "Alŝuti dosieron", + "Create room": "Krei ĉambron" } From 894412ca4c32299630f2633e557e9ef4496a00cd Mon Sep 17 00:00:00 2001 From: Kim Brose Date: Tue, 19 May 2020 14:51:57 +0000 Subject: [PATCH 014/332] Translated using Weblate (German) Currently translated at 99.8% (2308 of 2312 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 1166e7710a..eaefbdaa71 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1103,7 +1103,7 @@ "Room information": "Rauminformationen", "Internal room ID:": "Interne Raum ID:", "Room version": "Raum Version", - "Room version:": "Raum Version:", + "Room version:": "Raum-Version:", "Developer options": "Entwickleroptionen", "General": "Allgemein", "Set a new account password...": "Neues Benutzerkonto-Passwort festlegen...", From b0e0073970a904cdbf7b1cd8120c5b616b4f9029 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 20 May 2020 08:13:27 +0000 Subject: [PATCH 015/332] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2314 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 4995eeccb0..f222d7d09f 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2434,5 +2434,8 @@ "QR Code": "QR Code", "Dismiss read marker and jump to bottom": "取消讀取標記並跳至底部", "Jump to oldest unread message": "跳至最舊的未讀訊息", - "Upload a file": "上傳檔案" + "Upload a file": "上傳檔案", + "Use IRC layout": "使用 IRC 佈局", + "IRC display name width": "IRC 顯示名稱寬度", + "Create room": "建立聊天室" } From 48a66a817fe6f6324bd5dc863baf8ae7bbaf5067 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Wed, 20 May 2020 10:20:52 +0000 Subject: [PATCH 016/332] Translated using Weblate (Esperanto) Currently translated at 100.0% (2314 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 2729248bb0..56b5d53008 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -2410,5 +2410,7 @@ "Dismiss read marker and jump to bottom": "Forigi legomarkon kaj iri al fundo", "Jump to oldest unread message": "Iri al plej malnova nelegita mesaĝo", "Upload a file": "Alŝuti dosieron", - "Create room": "Krei ĉambron" + "Create room": "Krei ĉambron", + "Use IRC layout": "Uzi aranĝon de IRC", + "IRC display name width": "Larĝo de vidiga nomo de IRC" } From 402c1b0d65d097915bca5faf4b43715606c94b8c Mon Sep 17 00:00:00 2001 From: Samu Voutilainen Date: Wed, 20 May 2020 04:37:45 +0000 Subject: [PATCH 017/332] Translated using Weblate (Finnish) Currently translated at 94.3% (2183 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 77 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index ae08572eb2..bf2566990c 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -2189,5 +2189,80 @@ "Successfully restored %(sessionCount)s keys": "%(sessionCount)s avaimen palautus onnistui", "This requires the latest Riot on your other devices:": "Tämä vaatii uusimman Riotin muilla laitteillasi:", "Currently indexing: %(currentRoom)s": "Indeksoidaan huonetta: %(currentRoom)s", - "Jump to oldest unread message": "Siirry vanhimpaan lukemattomaan viestiin" + "Jump to oldest unread message": "Siirry vanhimpaan lukemattomaan viestiin", + "Opens chat with the given user": "Avaa keskustelun annetun käyttäjän kanssa", + "Sends a message to the given user": "Lähettää viestin annetulle käyttäjälle", + "Manually Verify by Text": "Varmenna käsin tekstillä", + "Interactively verify by Emoji": "Varmenna interaktiivisesti emojilla", + "Use IRC layout": "Käytä IRC-asettelua", + "Enable cross-signing to verify per-user instead of per-session": "Ota ristivarmennus käyttöön varmentaaksesi käyttäjät istuntojen sijaan", + "Keep recovery passphrase in memory for this session": "Pidä palautuksen salalause muistissa tämän istunnon ajan", + "Manually verify all remote sessions": "Varmenna kaikki etäistunnot käsin", + "IRC display name width": "IRC-näyttönimen leveys", + "Verify this session by confirming the following number appears on its screen.": "Varmenna tämä istunto varmistamalla, että seuraava numero ilmestyy sen näytölle.", + "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Odotetaan toista istuntoasi, %(deviceName)s (%(deviceId)s), varmennukseen…", + "Waiting for your other session to verify…": "odotetaan toista istuntoasi varmennukseen…", + "Verify all your sessions to ensure your account & messages are safe": "Varmenna kaikki istuntosi varmistaaksesi, että tunnuksesi ja viestisi ovat turvassa", + "Verify the new login accessing your account: %(name)s": "Varmenna uusi tunnuksellesi sisäänkirjautunut taho: %(name)s", + "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.": "Tällä hetkellä salasanan vaihtaminen nollaa kaikki osapuolten välisen salauksen avaimet kaikissa istunnoissa, tehden salatusta keskusteluhistoriasta lukukelvotonta, ellet ensin vie kaikkia huoneavaimiasi ja tuo niitä salasanan vaihtamisen jäkeen takaisin. Tulevaisuudessa tämä tulee toimimaan paremmin.", + "Your homeserver does not support cross-signing.": "Kotipalvelimesi ei tue ristivarmennusta.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Tunnuksellasi on ristivarmennuksen identiteetti salavarastossa, mutta tämä istunto ei luota siihen.", + "Reset cross-signing and secret storage": "Nollaa ristivarmennus ja salavarasto", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Varmenna jokainen käyttäjän istunto erikseen, äläkä luota ristivarmennettuihin laitteisiin.", + "Securely cache encrypted messages locally for them to appear in search results.": "Pidä salatut viestit turvallisessa välimuistissa, jotta ne näkyvät hakutuloksissa.", + "Riot is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom Riot Desktop with search components added.": "Riotissa ei ole joitain komponentteja, joita tarvitaan viestien turvalliseen välimuistitallennukseen. Jos haluat kokeilla tätä ominaisuutta, käännä mukautettu Riot Desktop, jossa on mukana hakukomponentit.", + "Riot can't securely cache encrypted messages locally while running in a web browser. Use Riot Desktop for encrypted messages to appear in search results.": "Riot ei voi tallentaa viestejä turvalliseen välimuistiin pyöriessään selaimessa. Käytä Electron-pohjaista Riot Desktop-sovellusta nähdäksesi salatut viestit hakutuloksissa.", + "This session is backing up your keys. ": "Tämä istunto varmuuskopioi avaimesi. ", + "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Tämä istunto ei varmuuskopioi avaimiasi, mutta sillä on olemassaoleva varmuuskopio, jonka voit palauttaa ja lisätä jatkaaksesi.", + "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Yhdistä tämä istunto avainten varmuuskopiointiin ennen uloskirjautumista, jotta et menetä avaimia, jotka ovat vain tässä istunnossa.", + "Connect this session to Key Backup": "Yhdistä tämä istunto avainten varmuuskopiointiin", + "Backup has a valid signature from verified session ": "Varmuuskopiossa on kelvollinen allekirjoitus varmennetusta istunnosta ", + "Backup has a valid signature from unverified session ": "Varmuuskopiossa on kelvollinen allekirjoitus varmentamattomasta istunnosta ", + "Backup has an invalid signature from verified session ": "Varmuuskopiossa on epäkelpo allekirjoitus varmennetusta istunnosta ", + "Backup has an invalid signature from unverified session ": "Varmuuskopiossa on epäkelpo allekirjoitus varmentamattomasta istunnosta ", + "This backup is trusted because it has been restored on this session": "Tähän varmuuskopioon luotetaan, koska se on palautettu tässä istunnossa", + "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Vara-avain on salavarastossa, mutta salavarasto ei ole käytössä tässä istunnossa. Ota ristivarmennus käyttöön Laboratoriosta muokkaaksesi avainten varmuuskopioinnin tilaa.", + "Your keys are not being backed up from this session.": "Avaimiasi ei varmuuskopioida tästä istunnosta.", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Salasanasi on onnistuneesti vaihdettu. Et saa ilmoituksia muilla laitteillasi ennen kuin kirjaudut niillä takaisin sisään", + "Invalid theme schema.": "Epäkelpo teeman skeema.", + "Custom theme URL": "Mukautettu teeman osoite", + "Keyboard Shortcuts": "Pikanäppäimet", + "Session ID:": "Istunnon tunnus:", + "Session key:": "Istunnon avain:", + "Where you’re logged in": "Missä olet sisäänkirjautuneena", + "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Muokkaa istuntojesi nimiä ja kirjaudu niistä ulos alapuolella tai varmenna ne käyttäjäprofiilissasi.", + "This user has not verified all of their sessions.": "Tämä käyttäjä ei ole varmentanut kaikkia istuntojaan.", + "You have not verified this user.": "Et ole varmentanut tätä käyttäjää.", + "You have verified this user. This user has verified all of their sessions.": "Olet varmentanut tämän käyttäjän. Tämä käyttäjä on varmentanut kaikki istuntonsa.", + "This room is end-to-end encrypted": "Tämä huone käyttää osapuolten välistä salausta", + "Everyone in this room is verified": "Kaikki tämän huoneen käyttäjät on varmennettu", + "Some sessions for this user are not trusted": "Osaan tämän käyttäjän istunnoista ei luoteta", + "All sessions for this user are trusted": "Kaikkiin tämän käyttäjän istunnoista luotetaan", + "Some sessions in this encrypted room are not trusted": "Osaan tämän salausta käyttävän huoneen istunnoista ei luoteta", + "All sessions in this encrypted room are trusted": "Kaikkiin tämän salausta käyttävän huoneen istuntoihin luotetaan", + "Your key share request has been sent - please check your other sessions for key share requests.": "Avainten jakopyyntösi on lähetetty. Tarkista muut istuntosi avainten jakopyyntöjen varalta.", + "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.": "Avainten jakopyynnöt lähetetään muille istunnoillesi automaattisesti. Jos hylkäsit tai jätit huomiotta avainten jakopyynnön toisessa istunnossasi, klikkaa tästä pyytääksesi avaimia uudelleen.", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Jos muissa laitteissasi ei ole avainta tämän viestin purkamiseen, niillä istunnoilla ei voi lukea tätä viestiä.", + "Encrypted by an unverified session": "Salattu varmentamattoman istunnon toimesta", + "Encrypted by a deleted session": "Salattu poistetun istunnon toimesta", + "No sessions with registered encryption keys": "Yhdelläkään istunnolla ei ole rekisteröityjä salausavaimia", + "Create room": "Luo huone", + "Reject & Ignore user": "Hylkää ja jätä käyttäjä huomiotta", + "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.", + "Verify User": "Varmenna käyttäjä", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Lisäturvaksi, varmenna tämä käyttäjä tarkistamalla koodin kummankin laitteella.", + "The homeserver the user you’re verifying is connected to": "Käyttäjä, jota varmennat, on kotipalvelimella", + "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what Riot supports. Try with a different client.": "Istunto, jota yrität varmentaa, ei tue QR-koodin skannausta tai emoji-varmennusta, joita Riot tukee. Kokeile eri asiakasohjelmalla.", + "Verify by scanning": "Varmenna skannaamalla", + "If you can't scan the code above, verify by comparing unique emoji.": "Jos et pysty skannaamaan yläpuolella olevaa koodia, varmenna vertaamalla emojia.", + "Verify by comparing unique emoji.": "Varmenna vertaamalla uniikkia emojia.", + "Verify by emoji": "Varmenna emojilla", + "Verify all users in a room to ensure it's secure.": "Varmenna kaikki huoneen käyttäjät varmistaaksesi, että se on turvallinen.", + "In encrypted rooms, verify all users to ensure it’s secure.": "Varmenna kaikki käyttäjät salausta käyttävissä huoneissa, jotta huone on varmasti turvallinen.", + "You've successfully verified your device!": "Olet onnistuneesti varmentanut laitteesi!", + "You've successfully verified %(deviceName)s (%(deviceId)s)!": "Olet onnistuneesti varmentanut laitteen %(deviceName)s (%(deviceId)s)!", + "You've successfully verified %(displayName)s!": "Olet varmentanut käyttäjän %(displayName)s!", + "Verified": "Varmennettu" } From a462a374cb716c35489db12441279147803cfce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 20 May 2020 06:30:49 +0000 Subject: [PATCH 018/332] Translated using Weblate (French) Currently translated at 100.0% (2314 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index c231769f27..7a89f71b73 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2435,5 +2435,8 @@ "QR Code": "Code QR", "Dismiss read marker and jump to bottom": "Ignorer le signet de lecture et aller en bas", "Jump to oldest unread message": "Aller au plus vieux message non lu", - "Upload a file": "Envoyer un fichier" + "Upload a file": "Envoyer un fichier", + "Use IRC layout": "Utiliser la mise en page d’IRC", + "IRC display name width": "Largeur du nom affiché IRC", + "Create room": "Créer un salon" } From 1f75caf6d276c0e6f8c626a14a75c60dfd890389 Mon Sep 17 00:00:00 2001 From: Xose M Date: Wed, 20 May 2020 06:19:20 +0000 Subject: [PATCH 019/332] Translated using Weblate (Galician) Currently translated at 41.1% (950 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 3328292be0..f3b9e38273 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -545,7 +545,7 @@ "Are you sure you want to leave the room '%(roomName)s'?": "Seguro que desexa saír da sala '%(roomName)s'?", "Failed to leave room": "Algo fallou ao saír da sala", "Signed Out": "Desconectada", - "For security, this session has been signed out. Please sign in again.": "Por seguridade, pechouse a sesión. Por favor, conéctese de novo.", + "For security, this session has been signed out. Please sign in again.": "Por seguridade, pechouse a sesión. Por favor, conéctate outra vez.", "Old cryptography data detected": "Detectouse o uso de criptografía sobre datos antigos", "Logout": "Desconectar", "Your Communities": "As súas Comunidades", @@ -621,10 +621,10 @@ "A new password must be entered.": "Debe introducir un novo contrasinal.", "New passwords must match each other.": "Os novos contrasinais deben ser coincidentes.", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Detectáronse datos de una versión anterior de Riot. Isto causará un mal funcionamento da criptografía extremo-a-extremo na versión antiga. As mensaxes cifradas extremo-a-extremo intercambiadas mentres utilizaba a versión anterior poderían non ser descifrables en esta versión. Isto tamén podería causar que mensaxes intercambiadas con esta versión tampouco funcionasen. Se ten problemas, desconéctese e conéctese de novo. Para manter o historial de mensaxes, exporte e reimporte as súas chaves.", - "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Enviouse un correo a %(emailAddress)s. Unha vez siga a ligazón que contén, pulse abaixo.", - "I have verified my email address": "Validei o meu enderezo de correo electrónico", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Enviouse un correo a %(emailAddress)s. Unha vez sigas a ligazón que contén, preme embaixo.", + "I have verified my email address": "Validei o meu enderezo de email", "Return to login screen": "Volver a pantalla de conexión", - "Send Reset Email": "Enviar correo electrónico de restablecemento", + "Send Reset Email": "Enviar email de restablecemento", "Incorrect username and/or password.": "Nome de usuaria ou contrasinal non válidos.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Teña en conta que se está a conectar ao servidor %(hs)s, non a matrix.org.", "The phone number entered looks invalid": "O número de teléfono introducido non semella ser válido", @@ -834,7 +834,7 @@ "Off": "Off", "Riot does not know how to join a room on this network": "Riot non sabe como conectar cunha sala nesta rede", "Mentions only": "Só mencións", - "You can now return to your account after signing out, and sign in on other devices.": "Pode volver a súa contra tras desconectarse, e conectarse en outros dispositivos.", + "You can now return to your account after signing out, and sign in on other devices.": "Podes voltar a túa conta tras desconectarte, e conectarte noutros dispositivos.", "Enable email notifications": "Activar notificacións de correo", "Event Type": "Tipo de evento", "Download this file": "Descargue este ficheiro", @@ -860,7 +860,7 @@ "Clear Storage and Sign Out": "Limpar o almacenamento e Desconectar", "Refresh": "Actualizar", "We encountered an error trying to restore your previous session.": "Atopamos un fallo intentando restablecer a súa sesión anterior.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpando o almacenamento do navegador podería resolver o problema, pero desconectarao e non poderá ler o historial cifrado da conversa.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpando o almacenamento do navegador podería resolver o problema, pero desconectarate e non poderás ler o historial cifrado da conversa.", "Collapse Reply Thread": "Comprimir o fío de respostas", "e.g. %(exampleValue)s": "p.ex. %(exampleValue)s", "Send analytics data": "Enviar datos de análises", @@ -937,5 +937,30 @@ "Whether you're using Riot as an installed Progressive Web App": "Se estás a usar Riot como unha Progressive Web App instalada", "Your user agent": "User Agent do navegador", "The information being sent to us to help make Riot better includes:": "Información que nos envías para mellorar Riot inclúe:", - "Please install Chrome, Firefox, or Safari for the best experience.": "Instala Chrome, Firefox, ou Safari para ter unha mellor experiencia." + "Please install Chrome, Firefox, or Safari for the best experience.": "Instala Chrome, Firefox, ou Safari para ter unha mellor experiencia.", + "Sign In or Create Account": "Conéctate ou Crea unha Conta", + "Sign In": "Conectar", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Confirma o borrado destas sesións ao usar Single Sign On como proba da túa identidade.", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Confirma o borrado desta sesión ao utilizar Single Sign On como proba da túa identidade.", + "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Xestiona os nomes e pecha as sesións embaixo ou verificaas no teu Perfil de Usuaria.", + "Sign Up": "Rexistro", + "Sign in with single sign-on": "Conectar usando Single Sign On", + "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.": "O eliminación das chaves de sinatura cruzada é permanente. Calquera a quen verificases con elas verá alertas de seguridade. Seguramente non queres facer esto, a menos que perdeses todos os dispositivos nos que podías asinar.", + "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "Usaches anteriormente unha versión máis recente de Riot en %(host)s. Para usar esta versión de novo con cifrado E2E, tes que desconectar e conectar outra vez. ", + "Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirma a desactivación da túa conta usando Single Sign On para probar a túa identidade.", + "To continue, use Single Sign On to prove your identity.": "Para continuar, usa Single Sign On para probar a túa identidade.", + "Are you sure you want to sign out?": "Tes a certeza de querer desconectar?", + "If you didn’t sign in to this session, your account may be compromised.": "Se ti non iniciaches esta sesión a túa conta podería estar comprometida.", + "Sign out and remove encryption keys?": "Desconectar e eliminar as chaves de cifrado?", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Esto permitirache voltar a túa conta tras desconectar, e conectarte noutras sesións.", + "Sign in to your Matrix account on %(serverName)s": "Conecta a túa conta Matrix en %(serverName)s", + "Sign in to your Matrix account on ": "Conecta a túa conta Matrix en ", + "Sign in with SSO": "Conecta utilizando SSO", + "Sign in instead": "Conectar", + "A verification email will be sent to your inbox to confirm setting your new password.": "Ímosche enviar un email para confirmar o teu novo contrasinal.", + "Your password has been reset.": "Restableceuse o contrasinal.", + "Enter your password to sign in and regain access to your account.": "Escribe o contrasinal para conectarte e retomar o acceso a túa conta.", + "Sign in and regain access to your account.": "Conéctate e recupera o acceso a túa conta.", + "You cannot sign in to your account. Please contact your homeserver admin for more information.": "Non podes conectar a conta. Contacta coa administración do teu servidor para máis información.", + "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.": "Aviso: os teus datos personais (incluíndo chaves de cifrado) aínda están gardadas nesta sesión. Pechaa se remataches de usar esta sesión, ou se quere conectar con outra conta." } From 31ac5aaa77600f01492cf499cabce7a66c683bec Mon Sep 17 00:00:00 2001 From: random Date: Wed, 20 May 2020 09:27:36 +0000 Subject: [PATCH 020/332] Translated using Weblate (Italian) Currently translated at 100.0% (2314 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 014d6015b3..359938ff3b 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2430,5 +2430,8 @@ "QR Code": "Codice QR", "Dismiss read marker and jump to bottom": "Scarta il segno di lettura e salta alla fine", "Jump to oldest unread message": "Salta al messaggio non letto più vecchio", - "Upload a file": "Invia un file" + "Upload a file": "Invia un file", + "Use IRC layout": "Usa il layout IRC", + "IRC display name width": "Larghezza nome di IRC", + "Create room": "Crea stanza" } From a40d795153a73095cc3ed81bd9f891ce28c48d59 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Wed, 20 May 2020 13:52:59 +0000 Subject: [PATCH 021/332] Translated using Weblate (Lithuanian) Currently translated at 45.8% (1059 of 2314 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 2652433075..c893034644 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -13,9 +13,9 @@ "The information being sent to us to help make Riot.im better includes:": "Informacija, siunčiama mums, kad padėtų tobulinti Riot.im, apima:", "Fetching third party location failed": "Nepavyko gauti trečios šalies vietos", "A new version of Riot is available.": "Yra prieinama nauja Riot versija.", - "I understand the risks and wish to continue": "Aš suprantu riziką ir noriu tęsti", + "I understand the risks and wish to continue": "Suprantu šią riziką ir noriu tęsti", "Send Account Data": "Siųsti paskyros duomenis", - "Advanced notification settings": "Sudėtingesni pranešimų nustatymai", + "Advanced notification settings": "Išplėstiniai pranešimų nustatymai", "Uploading report": "Išsiunčiama ataskaita", "Sunday": "Sekmadienis", "Guests can join": "Svečiai gali prisijungti", @@ -324,7 +324,7 @@ "Anyone who knows the room's link, including guests": "Bet kas, žinantis kambario nuorodą, įskaitant svečius", "Anyone": "Bet kas", "Permissions": "Leidimai", - "Advanced": "Sudėtingesni nustatymai", + "Advanced": "Išplėstiniai", "Add a topic": "Pridėti temą", "Local addresses for this room:": "Vietiniai šio kambario adresai:", "This room has no local addresses": "Šis kambarys neturi jokių vietinių adresų", @@ -1058,7 +1058,7 @@ "You'll lose access to your encrypted messages": "Jūs prarasite prieigą prie savo užšifruotų žinučių", "New session": "Naujas seansas", "Enter secret storage passphrase": "Įveskite slaptos saugyklos slaptafrazę", - "Enter recovery passphrase": "Įveskite atstatymo slaptafrazę", + "Enter recovery passphrase": "Įveskite atgavimo slaptafrazę", "Warning: you should only set up key backup from a trusted computer.": "Įspėjimas: atsarginę raktų kopiją sukurkite tik iš patikimo kompiuterio.", "Warning: You should only set up key backup from a trusted computer.": "Įspėjimas: Atsarginę raktų kopiją sukurkite tik iš patikimo kompiuterio.", "Server Name": "Serverio Pavadinimas", @@ -1073,5 +1073,25 @@ "For maximum security, this should be different from your account password.": "Maksimaliam saugumui užtikrinti ji turi skirtis nuo jūsų paskyros slaptažodžio.", "Enter a passphrase...": "Įveskite slaptafrazę...", "Please enter your passphrase a second time to confirm.": "Įveskite slaptafrazę antrą kartą, kad ją patvirtintumėte.", - "Secure your backup with a passphrase": "Apsaugokite savo atsarginę kopiją slaptafraze" + "Secure your backup with a passphrase": "Apsaugokite savo atsarginę kopiją slaptafraze", + "Set up encryption": "Nustatyti šifravimą", + "COPY": "Kopijuoti", + "Enter recovery key": "Įveskite atgavimo raktą", + "Keep going...": "Tęskite...", + "Please install Chrome, Firefox, or Safari for the best experience.": "Riot geriausiai veikia su Chrome, Firefox, arba Safari naršyklėmis.", + "Syncing...": "Sinchronizuojama...", + "Signing In...": "Prijungiama...", + "If you've joined lots of rooms, this might take a while": "Jei esate prisijungę prie daug kambarių, tai gali užtrukti", + "Without completing security on this session, it won’t have access to encrypted messages.": "Neužbaigus saugumo šioje sesijoje, ji neturės priėjimo prie šifruotų žinučių.", + "Set a recovery passphrase to secure encrypted information and recover it if you log out. This should be different to your account password:": "Nustatykite atgavimo slaptafrazę, kad apsaugotumėte šifruotą informaciją ir atgautumėte ją jei atsijungsite. Ji turi skirtis nuo jūsų paskyros slaptažodžio:", + "Enter a recovery passphrase": "Įveskite atgavimo slaptafrazę", + "Back up encrypted message keys": "Padaryti atsargines šifruotų žinučių raktų kopijas", + "Set up with a recovery key": "Nustatyti su atgavimo raktu", + "Enter your recovery passphrase a second time to confirm it.": "Įveskite atgavimo slaptafrazę antrą kartą, kad ją patvirtintumėte.", + "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Jūsų atgavimo raktas yra atsarginė saugumo priemonė - jūs galite jį naudoti priėjimo prie jūsų šifruotų žinučių atgavimui, jei pamiršite savo atgavimo slaptafrazę.", + "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Laikykite šio rakto kopiją saugioje vietoje, pavyzdžiui slaptažodžių tvarkyklėje arba seife.", + "Your recovery key": "Jūsų atgavimo raktas", + "Copy": "Kopijuoti", + "Make a copy of your recovery key": "Padaryti jūsų atgavimo rakto kopiją", + "Please enter your recovery passphrase a second time to confirm.": "Įveskite atgavimo slaptafrazę antrą kartą, kad patvirtintumėte." } From 2828cc1d258a70f48908969e044e735a9655645f Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 20 May 2020 15:13:31 +0000 Subject: [PATCH 022/332] Translated using Weblate (Albanian) Currently translated at 99.9% (2318 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sq/ --- src/i18n/strings/sq.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index 7058ad67b0..6519c54065 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -2424,5 +2424,15 @@ "Click the button below to confirm setting up encryption.": "Klikoni mbi butonin më poshtë që të ripohoni ujdisjen e fshehtëzimit.", "Dismiss read marker and jump to bottom": "Mos merr parasysh piketë leximi dhe hidhu te fundi", "Jump to oldest unread message": "Hidhu te mesazhi më i vjetër i palexuar", - "Upload a file": "Ngarkoni një kartelë" + "Upload a file": "Ngarkoni një kartelë", + "Font scaling": "Përshkallëzim shkronjash", + "Use IRC layout": "Përdor skemë IRC-je", + "Font size": "Madhësi shkronjash", + "Custom font size": "Madhësi vetjake shkronjash", + "IRC display name width": "Gjerësi shfaqjeje emrash IRC", + "Size must be a number": "Madhësia duhet të jetë një numër", + "Custom font size can only be between %(min)s pt and %(max)s pt": "Madhësia vetjake për shkronjat mund të jetë vetëm mes vlerave %(min)s pt dhe %(max)s pt", + "Use between %(min)s pt and %(max)s pt": "Përdor me %(min)s pt dhe %(max)s pt", + "Appearance": "Dukje", + "Create room": "Krijo dhomë" } From b1c80df0b4b7cf9d2fd4332435f5b3809cc81b48 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 21 May 2020 05:05:17 +0000 Subject: [PATCH 023/332] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2321 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index f222d7d09f..7c55826005 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2437,5 +2437,12 @@ "Upload a file": "上傳檔案", "Use IRC layout": "使用 IRC 佈局", "IRC display name width": "IRC 顯示名稱寬度", - "Create room": "建立聊天室" + "Create room": "建立聊天室", + "Font scaling": "字型縮放", + "Font size": "字型大小", + "Custom font size": "自訂字型大小", + "Size must be a number": "大小必須為數字", + "Custom font size can only be between %(min)s pt and %(max)s pt": "自訂字型大小僅能為 %(min)s 點至 %(max)s 點間", + "Use between %(min)s pt and %(max)s pt": "使用 %(min)s 點至 %(max)s 點間", + "Appearance": "外觀" } From 19b9776e897d5de817aea1bb9d9374f846890af0 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Wed, 20 May 2020 15:09:40 +0000 Subject: [PATCH 024/332] Translated using Weblate (Esperanto) Currently translated at 100.0% (2321 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 56b5d53008..89c75532df 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -2412,5 +2412,12 @@ "Upload a file": "Alŝuti dosieron", "Create room": "Krei ĉambron", "Use IRC layout": "Uzi aranĝon de IRC", - "IRC display name width": "Larĝo de vidiga nomo de IRC" + "IRC display name width": "Larĝo de vidiga nomo de IRC", + "Font scaling": "Skalado de tiparoj", + "Font size": "Grando de tiparo", + "Custom font size": "Propra grando de tiparo", + "Size must be a number": "Grando devas esti nombro", + "Custom font size can only be between %(min)s pt and %(max)s pt": "Propra grando de tiparo povas interi nur %(min)s punktojn kaj %(max)s punktojn", + "Use between %(min)s pt and %(max)s pt": "Uzi inter %(min)s punktoj kaj %(max)s punktoj", + "Appearance": "Aspekto" } From 4c39b6a9889f0a88ba0de44ee0065ec22da6d464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 21 May 2020 06:23:40 +0000 Subject: [PATCH 025/332] Translated using Weblate (French) Currently translated at 100.0% (2321 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 7a89f71b73..ee3c398e86 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2438,5 +2438,12 @@ "Upload a file": "Envoyer un fichier", "Use IRC layout": "Utiliser la mise en page d’IRC", "IRC display name width": "Largeur du nom affiché IRC", - "Create room": "Créer un salon" + "Create room": "Créer un salon", + "Font scaling": "Mise à l’échelle de la police", + "Font size": "Taille de la police", + "Custom font size": "Taille personnalisée de la police", + "Size must be a number": "La taille doit être un nombre", + "Custom font size can only be between %(min)s pt and %(max)s pt": "La taille de police personnalisée doit être comprise entre %(min)s pt et %(max)s pt", + "Use between %(min)s pt and %(max)s pt": "Utiliser entre %(min)s pt et %(max)s pt", + "Appearance": "Apparence" } From 23bfa6f11ea192b8253d7f45bc00ae82a7124926 Mon Sep 17 00:00:00 2001 From: random Date: Thu, 21 May 2020 08:05:57 +0000 Subject: [PATCH 026/332] Translated using Weblate (Italian) Currently translated at 100.0% (2321 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 359938ff3b..1fd6d7dc0c 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2433,5 +2433,12 @@ "Upload a file": "Invia un file", "Use IRC layout": "Usa il layout IRC", "IRC display name width": "Larghezza nome di IRC", - "Create room": "Crea stanza" + "Create room": "Crea stanza", + "Font scaling": "Ridimensionamento carattere", + "Font size": "Dimensione carattere", + "Custom font size": "Dimensione carattere personalizzata", + "Size must be a number": "La dimensione deve essere un numero", + "Custom font size can only be between %(min)s pt and %(max)s pt": "La dimensione del carattere personalizzata può solo essere tra %(min)s pt e %(max)s pt", + "Use between %(min)s pt and %(max)s pt": "Usa tra %(min)s pt e %(max)s pt", + "Appearance": "Aspetto" } From 0409932b4dee8293761f8aabb2d7d80d5e028e59 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Wed, 20 May 2020 14:30:14 +0000 Subject: [PATCH 027/332] Translated using Weblate (Lithuanian) Currently translated at 46.4% (1076 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index c893034644..fbdd41c16f 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -72,7 +72,7 @@ "Keywords": "Raktažodžiai", "Unpin Message": "Atsegti žinutę", "Enable notifications for this account": "Įjungti pranešimus šiai paskyrai", - "Remove": "Šalinti", + "Remove": "Pašalinti", "Invite to this community": "Pakviesti į šią bendruomenę", "Messages containing keywords": "Žinutės, kuriose yra raktažodžiai", "When I'm invited to a room": "Kai aš esu pakviestas į pokalbių kambarį", @@ -86,7 +86,7 @@ "Unnamed room": "Kambarys be pavadinimo", "Dismiss": "Atmesti", "Explore Account Data": "Peržiūrėti paskyros duomenis", - "Remove from Directory": "Šalinti iš katalogo", + "Remove from Directory": "Pašalinti iš katalogo", "Download this file": "Atsisiųsti šį failą", "Saturday": "Šeštadienis", "Remember, you can always set an email address in user settings if you change your mind.": "Nepamirškite, kad jei persigalvosite, tai bet kada galite nustatyti el. pašto adresą vartotojo nustatymuose.", @@ -146,7 +146,7 @@ "Off": "Išjungta", "Edit": "Koreguoti", "Mentions only": "Tik paminėjimai", - "remove %(name)s from the directory.": "šalinti %(name)s iš katalogo.", + "remove %(name)s from the directory.": "pašalinti %(name)s iš katalogo.", "You can now return to your account after signing out, and sign in on other devices.": "Po atsijungimo galite grįžti prie savo paskyros ir prisijungti kituose įrenginiuose.", "Continue": "Tęsti", "Enable email notifications": "Įjungti pranešimus el. paštu", @@ -353,8 +353,8 @@ "The phone number field must not be blank.": "Telefono numerio laukas negali būti tuščias.", "The password field must not be blank.": "Slaptažodžio laukas negali būti tuščias.", "Email address": "El. pašto adresas", - "Remove from community": "Šalinti iš bendruomenės", - "Remove this user from community?": "Šalinti šį naudotoją iš bendruomenės?", + "Remove from community": "Pašalinti iš bendruomenės", + "Remove this user from community?": "Pašalinti šį vartotoją iš bendruomenės?", "Failed to remove user from community": "Nepavyko pašalinti naudotoją iš bendruomenės", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Ar tikrai norite pašalinti \"%(roomName)s\" iš %(groupId)s?", "Failed to remove room from community": "Nepavyko pašalinti kambarį iš bendruomenės", @@ -1018,8 +1018,8 @@ "Order rooms by name": "Rūšiuoti kambarius pagal pavadinimą", "The other party cancelled the verification.": "Kita šalis atšaukė patvirtinimą.", "Public Name": "Viešas Vardas", - "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Užšifruotos žinutės yra apsaugotos su \"end-to-end\" šifravimu. Tik jūs ir gavėjas(-ai) turi raktus šioms žinutėms perskaityti.", - "Back up your keys before signing out to avoid losing them.": "Prieš atsijungdami sukurkite atsarginę savo raktų kopiją, kad jų neprarastumėte.", + "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Užšifruotos žinutės yra apsaugotos visapusiu šifravimu. Tik jūs ir gavėjas(-ai) turi raktus šioms žinutėms perskaityti.", + "Back up your keys before signing out to avoid losing them.": "Prieš atsijungdami sukurkite atsarginę savo raktų kopiją, kad išvengtumėte jų praradimo.", "Start using Key Backup": "Pradėti naudoti Atsarginę Raktų Kopiją", "Display Name": "Rodomas Vardas", "Please verify the room ID or alias and try again.": "Prašome patikrinti kambario ID arba slapyvardį ir bandyti dar kartą.", @@ -1093,5 +1093,24 @@ "Your recovery key": "Jūsų atgavimo raktas", "Copy": "Kopijuoti", "Make a copy of your recovery key": "Padaryti jūsų atgavimo rakto kopiją", - "Please enter your recovery passphrase a second time to confirm.": "Įveskite atgavimo slaptafrazę antrą kartą, kad patvirtintumėte." + "Please enter your recovery passphrase a second time to confirm.": "Įveskite atgavimo slaptafrazę antrą kartą, kad patvirtintumėte.", + "Later": "Vėliau", + "Verify yourself & others to keep your chats safe": "Patvirtinkite save ir kitus, kad jūsų pokalbiai būtų saugūs", + "Go back": "", + "This room is end-to-end encrypted": "Šis kambarys užšifruotas visapusiu šifravimu", + "Send a message…": "Siųsti žinutę…", + "Never lose encrypted messages": "Niekada nepraraskite šifruotų žinučių", + "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Žinutės šiame kambaryje yra apsaugotos visapusiu šifravimu. Tik jūs ir gavėjas(-ai) turite raktus šioms žinutėms perskaityti.", + "Securely back up your keys to avoid losing them. Learn more.": "Saugiai sukurkite jūsų raktų atsargines kopijas, kad išvengtumėte jų praradimo. Sužinoti daugiau.", + "Not now": "Ne dabar", + "Don't ask me again": "Daugiau neklausti", + "Send as message": "Siųsti kaip žinutę", + "Messages in this room are end-to-end encrypted.": "Žinutės šiame kambaryje yra užšifruotos visapusiu šifravimu.", + "Messages in this room are not end-to-end encrypted.": "Žinutės šiame kambaryje nėra užšifruotos visapusiu šifravimu.", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Žinutės šiame kambaryje yra užšifruotos visapusiu šifravimu. Sužinokite daugiau ir patvirtinkite šį vartotoją jų profilyje.", + "Confirm Removal": "Patvirtinkite pašalinimą", + "Manually export keys": "Eksportuoti raktus rankiniu būdu", + "Send a Direct Message": "Siųsti tiesioginę žinutę", + "Go Back": "", + "Go back to set it again.": "Grįžti atgal, kad nustatyti iš naujo." } From 3b353f1e7ab3cd7467e34cb55c1abf7c9a0d0721 Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Thu, 21 May 2020 09:21:10 +0000 Subject: [PATCH 028/332] Translated using Weblate (Slovak) Currently translated at 65.3% (1515 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index d117843ccf..4cd954c891 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -627,7 +627,7 @@ "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.", - "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, k to 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.", + "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", "Export": "Exportovať", @@ -1336,7 +1336,7 @@ "Create account": "Vytvoriť účet", "Registration has been disabled on this homeserver.": "Na tomto domovskom servery nie je povolená registrácia.", "Unable to query for supported registration methods.": "Nie je možné požiadať o podporované metódy registrácie.", - "Create your account": "Vytvoriť váš účet", + "Create your account": "Vytvorte si váš účet", "Keep going...": "Pokračujte…", "We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.": "Zašifrovanú kópiu vašich šifrovacích kľúčov uchováme na domovskom servery. Zabezpečte si zálohovanie zadaním hesla obnovenia, čo posilní ochranu vašich údajov.", "For maximum security, this should be different from your account password.": "Aby ste zachovali maximálnu mieru zabezpečenia, (dlhé) heslo by malo byť odlišné od hesla, ktorým sa prihlasujete do vášho účtu.", @@ -1408,7 +1408,7 @@ "Add Email Address": "Pridať emailovú adresu", "Add Phone Number": "Pridať telefónne číslo", "Send cross-signing keys to homeserver": "Poslať kľúče pre podpisovanie naprieč zariadeniami na domovský server", - "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Táto akcia si vyžaduje mať overenú emailovú adresu alebo telefónne číslo cez predvolený server totožností , ale server nezverejnil podmienky používania.", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Táto akcia vyžaduje prístup k predvolenému serveru totožností na overenie emailovej adresy alebo telefónneho čísla, ale server nemá žiadne podmienky používania.", "Trust": "Dôverovať", "Custom (%(level)s)": "Vlastný (%(level)s)", "Sends a message as plain text, without interpreting it as markdown": "Odošle správu vo formáte obyčajný text, bez prekladu markdown", @@ -1538,7 +1538,7 @@ "New login. Was this you?": "Nové pihlásenie. Ste to vy?", "%(name)s is requesting verification": "%(name) žiada o overenie", "Sign In or Create Account": "Prihlásiť sa alebo vytvoriť nový účet", - "Use your account or create a new one to continue.": "Použite váš existujúci účet alebo vytvorte si nový, aby ste mohli pokračovať.", + "Use your account or create a new one to continue.": "Použite váš existujúci účet alebo si vytvorte nový, aby ste mohli pokračovať.", "Create Account": "Vytvoriť účet", "Sign In": "Prihlásiť sa", "Sends a message as html, without interpreting it as markdown": "Pošlite správu ako HTML, bez interpretácie v Markdowne", @@ -1592,10 +1592,26 @@ "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Zálohovací kľúč je uložený v bezpečnom úložisku, ale jeho načítanie nie je povolené v tejto relácií. Prosím, zapnite krížové podpisovanie v Experimentoch, aby ste mohli modifikovať stav zálohy.", "Cross-signing": "Krížové podpisovanie", "Destroy cross-signing keys?": "Zmazať kľúče pre krížové podpisovanie?", - "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.": "Zmazanie kľúčov pre krížové podpisovanie je nenávratné. Každý, s kým ste sa overili, bude vidieť bezpečnostné upozornenia. Toto určite nechcete robiť dokiaľ ste nestratili všetky zariadenia, s ktorými by ste mohli krížovo podpisovať.", + "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.": "Zmazanie kľúčov pre krížové podpisovanie je nenávratné. Každý, s kým ste sa overili, bude vidieť bezpečnostné upozornenia. Toto určite nechcete robiť, dokiaľ ste nestratili všetky zariadenia, s ktorými by ste mohli krížovo podpisovať.", "Clear cross-signing keys": "Zmazať kľúče pre krížové podpisovanie", "a new cross-signing key signature": "nový podpis kľúča pre krížové podpisovanie", "a device cross-signing signature": "podpis krížovo podpísaného zariadenia", "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Získajte prístup k vašej šifrovanej histórií správ a vašej krížom podpísanej identite pre overenie iných relácií zadaním vášho kľúču obnovy.", - "or another cross-signing capable Matrix client": "alebo iný Matrixový klient podporujúci krížové podpisovanie" + "or another cross-signing capable Matrix client": "alebo iný Matrixový klient podporujúci krížové podpisovanie", + "Removing…": "Odstraňovanie…", + "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Váš nový účet (%(newAccountId)s) je registrovaný, ale už ste prihlásený pod iným účtom (%(loggedInUserId)s).", + "Continue with previous account": "Pokračovať s predošlým účtom", + "Log in to your new account.": "Prihláste sa do vášho nového účtu.", + "You can now close this window or log in to your new account.": "Teraz môžete toto okno zavrieť alebo sa prihlásiť do vášho nového účtu.", + "Registration Successful": "Úspešná registrácia", + "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Potvrďte svoju identitu overením tohto účtu z jednej z vašich iných relácií, čím mu povolíte prístup k šifrovaným správam.", + "This requires the latest Riot on your other devices:": "Toto vyžaduje najnovší Riot na vašich ostatných zariadeniach:", + "Use Recovery Passphrase or Key": "Použite (dlhé) heslo pre obnovu zálohy alebo kľúč", + "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Vaša nová relácia je teraz overená. Má prístup k vašim šifrovaným správam a ostatný používatelia ju uvidia ako dôveryhodnú.", + "Your new session is now verified. Other users will see it as trusted.": "Vaša nová relácia je teraz overená. Ostatný používatelia ju uvidia ako dôveryhodnú.", + "Without completing security on this session, it won’t have access to encrypted messages.": "Bez dokončenia overenia nebude mať táto relácia prístup k šifrovaným správam.", + "Go Back": "Späť", + "Failed to re-authenticate due to a homeserver problem": "Opätovná autentifikácia zlyhala kvôli problému domovského servera", + "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." } From 53d90234c35cf232cd527011abeee5f1ff8a9cd8 Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Thu, 21 May 2020 10:53:55 +0000 Subject: [PATCH 029/332] Translated using Weblate (Czech) Currently translated at 94.7% (2198 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index ddd5e5521b..e5568d7bfb 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -2150,7 +2150,7 @@ "Sign In or Create Account": "Přihlásit nebo vytvořit nový účet", "Use your account or create a new one to continue.": "Pro pokračování se přihlaste existujícím účtem, nebo si vytvořte nový.", "Create Account": "Vytvořit účet", - "Order rooms by name": "Seřadit místnosti podle názvz", + "Order rooms by name": "Seřadit místnosti podle názvu", "Show rooms with unread notifications first": "Zobrazovat místnosti s nepřečtenými oznámeními navrchu", "Show shortcuts to recently viewed rooms above the room list": "Zobrazovat zkratky do nedávno zobrazených místností navrchu", "Cancelling…": "Rušení…", From a3e790d72ca58f4220715821c73be35cf1b20bb5 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Thu, 21 May 2020 11:19:30 +0000 Subject: [PATCH 030/332] Translated using Weblate (Lithuanian) Currently translated at 47.0% (1090 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index fbdd41c16f..54ebd93051 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -65,7 +65,7 @@ "Cancel": "Atšaukti", "Filter results": "Išfiltruoti rezultatus", "Members": "Nariai", - "No update available.": "Nėra prieinamų atnaujinimų.", + "No update available.": "Nėra galimų atnaujinimų.", "Noisy": "Triukšmingas", "Collecting app version information": "Renkama programėlės versijos informacija", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ar ištrinti kambarį %(alias)s ir %(name)s kambario pavadinimą iš katalogo?", @@ -705,7 +705,7 @@ "That doesn't look like a valid email address": "Tai nepanašu į teisingą el. pašto adresą", "Preparing to send logs": "Ruošiamasi išsiųsti žurnalus", "Incompatible Database": "Nesuderinama duomenų bazė", - "Deactivate Account": "Pasyvinti paskyrą", + "Deactivate Account": "Deaktyvuoti paskyrą", "I verify that the keys match": "Aš patvirtinu, kad raktai sutampa", "Incompatible local cache": "Nesuderinamas vietinis podėlis", "Updating Riot": "Atnaujinama Riot", @@ -1112,5 +1112,19 @@ "Manually export keys": "Eksportuoti raktus rankiniu būdu", "Send a Direct Message": "Siųsti tiesioginę žinutę", "Go Back": "", - "Go back to set it again.": "Grįžti atgal, kad nustatyti iš naujo." + "Go back to set it again.": "Grįžti atgal, kad nustatyti iš naujo.", + "Click the button below to confirm adding this email address.": "Paspauskite mygtuką žemiau, kad patvirtintumėte šio el. pašto pridėjimą.", + "Add an email address to configure email notifications": "Pridėkite el. pašto adresą, kad nustatytumėte el. pašto pranešimus", + "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Prieš atsijungiant rekomenduojame iš identiteto serverio pašalinti savo el. pašto adresus ir telefono numerius.", + "Email addresses": "El. pašto adresai", + "Account management": "Paskyros valdymas", + "Deactivating your account is a permanent action - be careful!": "Paskyros deaktyvavimas yra neatšaukiamas veiksmas - būkite atsargūs!", + "Your email address hasn't been verified yet": "Jūsų el. pašto adresas dar nebuvo patvirtintas", + "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Išsiuntėme jums el. laišką, kad patvirtintumėme jūsų adresą. Sekite ten esančiais nurodymais ir tada paspauskite žemiau esantį mygtuką.", + "Email Address": "El. pašto adresas", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.": "Jūs galite naudoti pasirinktinius serverio nustatymus, kad prisijungtumėte prie kitų Matrix serverių, nurodydami kito serverio URL. Tai leidžia jums naudotis šia programa su kitame serveryje esančia Matrix paskyra.", + "Enter your custom homeserver URL What does this mean?": "Įveskite pasirinktinio serverio URL Ką tai reiškia?", + "Homeserver URL": "Serverio URL", + "Homeserver URL does not appear to be a valid Matrix homeserver": "Serverio adresas neatrodo esantis tinkamas Matrix serveris", + "This homeserver does not support login using email address.": "Šis serveris nepalaiko prisijungimo naudojant el. pašto adresą." } From 6d92f54934e8b7a4947bf71a3e14a754bac91bf6 Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Thu, 21 May 2020 10:07:36 +0000 Subject: [PATCH 031/332] Translated using Weblate (Slovak) Currently translated at 66.7% (1547 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 51 ++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 4cd954c891..a9111a91a6 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -540,7 +540,7 @@ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Pri zobrazovaní časových značiek používať 12 hodinový formát (napr. 2:30pm)", "Use compact timeline layout": "Použiť kompaktné rozloženie časovej osy", "Enable automatic language detection for syntax highlighting": "Povoliť automatickú detegciu jazyka pre zvýrazňovanie syntaxe", - "Automatically replace plain text Emoji": "Automaticky nahrádzať textové Emoji", + "Automatically replace plain text Emoji": "Automaticky nahrádzať textové emotikony modernými emoji", "Mirror local video feed": "Zrkadliť lokálne video", "Light theme": "Svetlý vzhľad", "Dark theme": "Tmavý vzhľad", @@ -604,7 +604,7 @@ "Stops ignoring a user, showing their messages going forward": "Prestane ignorovať používateľa a začne zobrazovať jeho správy", "Commands": "Príkazy", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", - "Emoji": "Emoji", + "Emoji": "Emotikon", "Notify the whole room": "Oznamovať celú miestnosť", "Room Notification": "Oznámenie miestnosti", "Users": "Používatelia", @@ -1089,14 +1089,14 @@ "The user must be unbanned before they can be invited.": "Tomuto používateľovi musíte pred odoslaním pozvania povoliť vstup.", "Group & filter rooms by custom tags (refresh to apply changes)": "Zoskupiť a filtrovať miestnosti podľa vlastných značiek (zmeny sa prejavia po obnovení stránky)", "Render simple counters in room header": "Zobraziť jednoduchú štatistiku v záhlaví miestnosti", - "Enable Emoji suggestions while typing": "Umožniť automatické návrhy Emoji počas písania", + "Enable Emoji suggestions while typing": "Umožniť automatické návrhy emoji počas písania", "Show a placeholder for removed messages": "Zobrazovať náhrady za odstránené správy", "Show join/leave messages (invites/kicks/bans unaffected)": "Zobrazovať správy o vstupe a opustení miestnosti (Nemá vplyv na pozvania/vykázania/zákazy vstupu)", "Show avatar changes": "Zobrazovať zmeny obrázka v profile", "Show display name changes": "Zobrazovať zmeny zobrazovaného mena", "Show read receipts sent by other users": "Zobrazovať potvrdenia o prečítaní od ostatných používateľov", "Show avatars in user and room mentions": "Pri zmienkach používateľov a miestností zobrazovať aj obrázok", - "Enable big emoji in chat": "Povoliť veľké Emoji v konverzáciách", + "Enable big emoji in chat": "Povoliť veľké emoji v konverzáciách", "Send typing notifications": "Posielať oznámenia, keď píšete", "Enable Community Filter Panel": "Povoliť panel filter komunít", "Allow Peer-to-Peer for 1:1 calls": "Povoliť P2P počas priamych audio/video hovorov", @@ -1107,7 +1107,7 @@ "You've successfully verified this user.": "Úspešne ste overili tohoto používateľa.", "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Zabezpečené správi s týmto používateľom sú E2E šifrované, čo znamená, že čítanie tretími stranami nie je možné.", "Got It": "Rozumiem", - "Verify this user by confirming the following emoji appear on their screen.": "Overte tohoto používateľa tým, že zistíte, či sa na jeho obrazovke objaví nasledujúci emoji.", + "Verify this user by confirming the following emoji appear on their screen.": "Overte tohto používateľa tak, že zistíte, či sa na jeho obrazovke objaví nasledujúci emoji.", "Verify this user by confirming the following number appears on their screen.": "Overte tohoto používateľa tým, že zistíte, či sa na jeho obrazovke objaví nasledujúce číslo.", "Unable to find a supported verification method.": "Nie je možné nájsť podporovanú metódu overenia.", "Dog": "Hlava psa", @@ -1573,7 +1573,7 @@ "Ask this user to verify their session, or manually verify it below.": "Poproste tohto používateľa, aby si overil svoju reláciu alebo ju nižšie manuálne overte.", "Not Trusted": "Nedôveryhodné", "Manually Verify by Text": "Manuálne overte pomocou textu", - "Interactively verify by Emoji": "Interaktívne overte pomocou emotikonov", + "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", @@ -1613,5 +1613,42 @@ "Go Back": "Späť", "Failed to re-authenticate due to a homeserver problem": "Opätovná autentifikácia zlyhala kvôli problému domovského servera", "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." + "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", + "Use IRC layout": "Použiť IRC rozloženie", + "Show info about bridges in room settings": "Zobraziť informácie o mostoch v Nastaveniach miestnosti", + "Font size": "Veľkosť písma", + "Custom font size": "Vlastná 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", + "Never send encrypted messages to unverified sessions in this room from this session": "Nikdy neposielať šifrované správy neovereným reláciam v tejto miestnosti z tejto relácie", + "Order rooms by name": "Zoradiť miestnosti podľa názvu", + "Show rooms with unread notifications first": "Zobraziť miestnosti s neprečítanými oznámeniami navrchu", + "Show shortcuts to recently viewed rooms above the room list": "Zobraziť skratky nedávno zobrazených miestnosti nad zoznamom miestností", + "Enable message search in encrypted rooms": "Povoliť vyhľadávanie správ v šifrovaných miestnostiach", + "How fast should messages be downloaded.": "Ako rýchlo sa majú správy sťahovať.", + "Manually verify all remote sessions": "Manuálne overiť všetky relácie", + "IRC display name width": "Šírka zobrazovaného mena IRC", + "Verify this session by completing one of the following:": "Overte túto reláciu dokončením jedného z nasledujúcich:", + "Scan this unique code": "Naskenujte tento jedinečný kód", + "or": "alebo", + "Compare unique emoji": "Porovnajte jedinečnú kombináciu emoji", + "Compare a unique set of emoji if you don't have a camera on either device": "Pokiaľ nemáte na svojich zariadeniach kameru, porovnajte jedinečnú kombináciu emoji", + "Confirm the emoji below are displayed on both sessions, in the same order:": "Potvrďte, že nasledujúce emoji sú zobrazené na oboch reláciach v rovnakom poradí:", + "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what Riot supports. Try with a different client.": "Relácia, ktorú sa snažíte overiť, nepodporuje overovanie QR kódom a ani pomocou emoji, čo sú funkcie, ktoré Riot podporuje. Skúste použiť iného klienta.", + "QR Code": "QR kód", + "Enter your password to sign in and regain access to your account.": "Prihláste sa zadaním hesla a znovuzískajte prístup k vášmu účtu.", + "Forgotten your password?": "Zabudli ste heslo?", + "Sign in and regain access to your account.": "Prihláste sa a znovuzískajte prístup k vášmu účtu.", + "You cannot sign in to your account. Please contact your homeserver admin for more information.": "Nemôžete sa prihlásiť do vášho účtu. Kontaktujte prosím vášho správcu domovského servera pre viac informácií.", + "You're signed out": "Ste odhlásený", + "Clear personal data": "Zmazať osobné dáta", + "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.": "Varovanie: Vaše osobné údaje (vrátane šifrovacích kľúčov) sú stále uložené v tejto relácií. Zmažte ich, ak chcete túto reláciu zahodiť alebo sa chcete prihlásiť cez iný účet.", + "Command Autocomplete": "Automatické dopĺňanie príkazov", + "Community Autocomplete": "Automatické dopĺňanie skupín", + "DuckDuckGo Results": "Výsledky hľadania DuckDuckGo", + "Emoji Autocomplete": "Automatické dopĺňanie emotikonov", + "Notification Autocomplete": "Automatické dopĺňanie oznámení", + "Room Autocomplete": "Automatické dopĺňanie miestností", + "User Autocomplete": "Automatické dopĺňanie používateľov" } From 7e7c48e0460ae163b2d3a66a1b54f767f8777e71 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 May 2020 16:32:19 +0100 Subject: [PATCH 032/332] Improve style of toasts to match Figma Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/structures/_ToastContainer.scss | 46 ++++++++++++++++----- src/components/structures/ToastContainer.js | 5 ++- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index 6ec4a0d152..d39d6cdfe8 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -28,8 +28,8 @@ limitations under the License. margin: 0 4px; grid-row: 2 / 4; grid-column: 1; - background-color: white; - box-shadow: 0px 4px 12px $menu-box-shadow-color; + background-color: $dark-panel-bg-color; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.5); border-radius: 8px; } @@ -37,8 +37,8 @@ limitations under the License. grid-row: 1 / 3; grid-column: 1; color: $primary-fg-color; - background-color: $primary-bg-color; - box-shadow: 0px 4px 12px $menu-box-shadow-color; + background-color: $dark-panel-bg-color; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.5); border-radius: 8px; overflow: hidden; display: grid; @@ -73,12 +73,23 @@ limitations under the License. } } - h2 { - grid-column: 1 / 3; - grid-row: 1; - margin: 0; - font-size: $font-15px; - font-weight: 600; + .mx_Toast_title { + h2 { + grid-column: 1 / 3; + grid-row: 1; + margin: 0; + font-size: $font-15px; + font-weight: 600; + display: inline; + width: auto; + } + + span { + float: right; + font-size: $font-12px; + line-height: $font-21px; + color: $muted-fg-color; + } } .mx_Toast_body { @@ -87,7 +98,13 @@ limitations under the License. } .mx_Toast_buttons { + float: right; display: flex; + + .mx_FormButton { + min-width: 96px; + box-sizing: border-box; + } } .mx_Toast_description { @@ -96,6 +113,15 @@ limitations under the License. text-overflow: ellipsis; margin: 4px 0 11px 0; font-size: $font-12px; + + .mx_AccessibleButton_kind_link { + font-size: inherit; + padding: 0; + } + + a { + text-decoration: none; + } } .mx_Toast_deviceID { diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index 283fbdd96a..ddbef42421 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -57,7 +57,10 @@ export default class ToastContainer extends React.Component { toastKey: key, }); toast = (
-

{title}{countIndicator}

+
+

{title}

+ {countIndicator} +
{React.createElement(component, toastProps)}
); } From 5995a27ced87200c60b208a5549e6b4a6c608831 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 May 2020 16:52:36 +0100 Subject: [PATCH 033/332] Iterate paddings Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/structures/_ToastContainer.scss | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index d39d6cdfe8..464eaf488d 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -46,7 +46,6 @@ limitations under the License. column-gap: 10px; row-gap: 4px; padding: 8px; - padding-right: 16px; &.mx_Toast_hasIcon { &::after { @@ -68,12 +67,27 @@ limitations under the License. background-image: url("$(res)/img/e2e/warning.svg"); } - h2, .mx_Toast_body { + .mx_Toast_title, .mx_Toast_body { grid-column: 2; } } + &:not(.mx_Toast_hasIcon) { + padding-left: 12px; + + .mx_Toast_title { + grid-column: 1 / -1; + } + } + + .mx_Toast_title, + .mx_Toast_description { + padding-right: 8px; + } .mx_Toast_title { + width: 100%; + box-sizing: border-box; + h2 { grid-column: 1 / 3; grid-row: 1; From 6a0ffe905f14ec916ab32ed10601fcb63f912ecb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 May 2020 17:12:16 +0100 Subject: [PATCH 034/332] Iterate text alignment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/structures/_ToastContainer.scss | 3 ++- src/components/structures/ToastContainer.js | 6 +++++- src/i18n/strings/en_EN.json | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index 464eaf488d..f64e688498 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -99,9 +99,10 @@ limitations under the License. } span { + padding-left: 8px; float: right; font-size: $font-12px; - line-height: $font-21px; + line-height: $font-22px; color: $muted-fg-color; } } diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index ddbef42421..729171bd6a 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -50,7 +50,11 @@ export default class ToastContainer extends React.Component { "mx_Toast_hasIcon": icon, [`mx_Toast_icon_${icon}`]: icon, }); - const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null; + + let countIndicator; + if (isStacked) { + countIndicator = `1/${totalCount}`; + } const toastProps = Object.assign({}, props, { key, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index cd09170285..99b1d2ad6f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2073,7 +2073,6 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", - " (1/%(totalCount)s)": " (1/%(totalCount)s)", "Guest": "Guest", "Your profile": "Your profile", "Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others", From 1dfd62c1425c9f6462ccc424d475e70461e1b4f1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 May 2020 17:47:35 +0100 Subject: [PATCH 035/332] iterate alignment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/structures/_ToastContainer.scss | 5 +++-- src/components/structures/ToastContainer.js | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index f64e688498..2916c4ffdc 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -42,8 +42,8 @@ limitations under the License. border-radius: 8px; overflow: hidden; display: grid; - grid-template-columns: 20px 1fr; - column-gap: 10px; + grid-template-columns: 22px 1fr; + column-gap: 8px; row-gap: 4px; padding: 8px; @@ -96,6 +96,7 @@ limitations under the License. font-weight: 600; display: inline; width: auto; + vertical-align: middle; } span { diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index 729171bd6a..8f20dcd61d 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -15,7 +15,6 @@ limitations under the License. */ import * as React from "react"; -import { _t } from '../../languageHandler'; import ToastStore from "../../stores/ToastStore"; import classNames from "classnames"; From f539a960e1af71b1fec4e2bedd7fe3a2d240f951 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 May 2020 17:50:32 +0100 Subject: [PATCH 036/332] re-add brackets Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/ToastContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index 8f20dcd61d..c7789d861f 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -52,7 +52,7 @@ export default class ToastContainer extends React.Component { let countIndicator; if (isStacked) { - countIndicator = `1/${totalCount}`; + countIndicator = `(1/${totalCount})`; } const toastProps = Object.assign({}, props, { From 3741c296aa3147bb3d9ed4f1b348118d4b98b3b6 Mon Sep 17 00:00:00 2001 From: XoseM Date: Thu, 21 May 2020 14:40:28 +0000 Subject: [PATCH 037/332] Translated using Weblate (Galician) Currently translated at 42.0% (974 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index f3b9e38273..d433d58146 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -962,5 +962,29 @@ "Enter your password to sign in and regain access to your account.": "Escribe o contrasinal para conectarte e retomar o acceso a túa conta.", "Sign in and regain access to your account.": "Conéctate e recupera o acceso a túa conta.", "You cannot sign in to your account. Please contact your homeserver admin for more information.": "Non podes conectar a conta. Contacta coa administración do teu servidor para máis información.", - "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.": "Aviso: os teus datos personais (incluíndo chaves de cifrado) aínda están gardadas nesta sesión. Pechaa se remataches de usar esta sesión, ou se quere conectar con outra conta." + "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.": "Aviso: os teus datos personais (incluíndo chaves de cifrado) aínda están gardadas nesta sesión. Pechaa se remataches de usar esta sesión, ou se quere conectar con outra conta.", + "Unable to load! Check your network connectivity and try again.": "Non cargou! Comproba a conexión a rede e volta a intentalo.", + "There are unknown sessions in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Hai sesións descoñecidas nesta sala: se continúas sen verificalas será posible para alguén fisgar na túa chamada.", + "Review Sessions": "Revisar Sesións", + "Call failed due to misconfigured server": "Fallou a chamada porque o servidor está mal configurado", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Contacta coa administración do teu servidor (%(homeserverDomain)s) para configurar un servidor TURN para que as chamadas funcionen de xeito fiable.", + "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.": "De xeito alternativo, podes intentar usar o servidor público turn.matrix.org, pero non é tan fiable, e compartirá o teu enderezo IP con ese servidor. Podes xestionar esto en Axustes.", + "Try using turn.matrix.org": "Inténtao usando turn.matrix.org", + "Replying With Files": "Respondendo con Ficheiros", + "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Neste intre non é posible responder cun ficheiro. Queres subir este ficheiro sen responder?", + "The file '%(fileName)s' failed to upload.": "Fallou a subida do ficheiro '%(fileName)s'.", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "O ficheiro '%(fileName)s' supera o tamaño máximo permitido polo servidor", + "The server does not support the room version specified.": "O servidor non soporta a versión da sala indicada.", + "If you cancel now, you won't complete verifying the other user.": "Se cancelas agora non completarás a verificación da outra usuaria.", + "If you cancel now, you won't complete verifying your other session.": "Se cancelas agora non completarás o proceso de verificación da outra sesión.", + "If you cancel now, you won't complete your operation.": "Se cancelas agora, non completarás a operación.", + "Cancel entering passphrase?": "Cancelar a escrita da frase de paso?", + "Setting up keys": "Configurando as chaves", + "Verify this session": "Verificar esta sesión", + "Encryption upgrade available": "Mellora do cifrado dispoñible", + "Set up encryption": "Configurar cifrado", + "Review where you’re logged in": "Revisar onde estás conectada", + "New login. Was this you?": "Nova conexión. Foches ti?", + "Name or Matrix ID": "Nome ou ID Matrix", + "Identity server has no terms of service": "O servidor de identidade non ten termos dos servizo" } From e849d288741765950e63fb532e1117e2aa9facd8 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Thu, 21 May 2020 13:42:07 +0000 Subject: [PATCH 038/332] Translated using Weblate (Lithuanian) Currently translated at 48.2% (1119 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 54ebd93051..e96e0e9199 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -1092,11 +1092,11 @@ "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Laikykite šio rakto kopiją saugioje vietoje, pavyzdžiui slaptažodžių tvarkyklėje arba seife.", "Your recovery key": "Jūsų atgavimo raktas", "Copy": "Kopijuoti", - "Make a copy of your recovery key": "Padaryti jūsų atgavimo rakto kopiją", + "Make a copy of your recovery key": "Padaryti atgavimo rakto kopiją", "Please enter your recovery passphrase a second time to confirm.": "Įveskite atgavimo slaptafrazę antrą kartą, kad patvirtintumėte.", "Later": "Vėliau", "Verify yourself & others to keep your chats safe": "Patvirtinkite save ir kitus, kad jūsų pokalbiai būtų saugūs", - "Go back": "", + "Go back": "Grįžti", "This room is end-to-end encrypted": "Šis kambarys užšifruotas visapusiu šifravimu", "Send a message…": "Siųsti žinutę…", "Never lose encrypted messages": "Niekada nepraraskite šifruotų žinučių", @@ -1111,7 +1111,7 @@ "Confirm Removal": "Patvirtinkite pašalinimą", "Manually export keys": "Eksportuoti raktus rankiniu būdu", "Send a Direct Message": "Siųsti tiesioginę žinutę", - "Go Back": "", + "Go Back": "Grįžti", "Go back to set it again.": "Grįžti atgal, kad nustatyti iš naujo.", "Click the button below to confirm adding this email address.": "Paspauskite mygtuką žemiau, kad patvirtintumėte šio el. pašto pridėjimą.", "Add an email address to configure email notifications": "Pridėkite el. pašto adresą, kad nustatytumėte el. pašto pranešimus", @@ -1126,5 +1126,32 @@ "Enter your custom homeserver URL What does this mean?": "Įveskite pasirinktinio serverio URL Ką tai reiškia?", "Homeserver URL": "Serverio URL", "Homeserver URL does not appear to be a valid Matrix homeserver": "Serverio adresas neatrodo esantis tinkamas Matrix serveris", - "This homeserver does not support login using email address.": "Šis serveris nepalaiko prisijungimo naudojant el. pašto adresą." + "This homeserver does not support login using email address.": "Šis serveris nepalaiko prisijungimo naudojant el. pašto adresą.", + "Review Sessions": "Peržiūrėti sesijas", + "Setting up keys": "Raktų nustatymas", + "Review where you’re logged in": "Peržiūrėkite kur esate prisijungę", + "Verify all your sessions to ensure your account & messages are safe": "Patvirtinkite visas savo sesijas, kad užtikrintumėte savo paskyros ir žinučių saugumą", + "Review": "Peržiūrėti", + "Message deleted": "Žinutė ištrinta", + "Message deleted by %(name)s": "Žinutė, ištrinta %(name)s", + "Warning: You should only do this on a trusted computer.": "Įspėjimas: Tai atlikite tik saugiame kompiuteryje.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Prieikite prie savo saugių žinučių istorijos ir kryžminio parašo kitų sesijų patvirtinimui tapatybės įvesdami savo atgavimo slaptafrazę.", + "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus.", + "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus", + "Confirm your identity by entering your account password below.": "Patvirtinkite savo tapatybę žemiau įvesdami savo paskyros slaptažodį.", + "Use an email address to recover your account": "Naudokite el. pašto adresą, kad prireikus galėtumėte atgauti paskyrą", + "Passwords don't match": "Slaptažodžiai nesutampa", + "Use lowercase letters, numbers, dashes and underscores only": "Naudokite tik mažąsias raides, brūkšnelius ir pabraukimus", + "Great! This recovery passphrase looks strong enough.": "Puiku! Ši slaptafrazė atrodo pakankamai stipri.", + "That matches!": "Tai sutampa!", + "That doesn't match.": "Tai nesutampa.", + "Confirm your recovery passphrase": "Patvirtinti atgavimo slaptafrazę", + "Your recovery key has been copied to your clipboard, paste it to:": "Jūsų atgavimo raktas buvo nukopijuotas į jūsų iškarpinę, jūs galite:", + "Your recovery key is in your Downloads folder.": "Jūsų atgavimo raktas yra Parsisiuntimų kataloge.", + "Print it and store it somewhere safe": "Atsispausdinti jį ir laikyti saugioje vietoje", + "Save it on a USB key or backup drive": "Išsaugoti jį USB rakte arba atsarginių kopijų diske", + "Copy it to your personal cloud storage": "Nukopijuoti jį į savo asmeninę debesų saugyklą", + "You can now verify your other devices, and other users to keep your chats safe.": "Jūs dabar galite patvirtinti kitus savo įrenginius ir kitus vartotojus, kad jūsų pokalbiai būtų saugūs.", + "Confirm recovery passphrase": "Patvirtinkite atgavimo slaptafrazę", + "You're done!": "Atlikta!" } From 565562ab5c8701c2f63a888de46a58a53c75864a Mon Sep 17 00:00:00 2001 From: yuuki-san Date: Thu, 21 May 2020 11:57:59 +0000 Subject: [PATCH 039/332] Translated using Weblate (Slovak) Currently translated at 67.1% (1558 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index a9111a91a6..6473dad0cf 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -604,7 +604,7 @@ "Stops ignoring a user, showing their messages going forward": "Prestane ignorovať používateľa a začne zobrazovať jeho správy", "Commands": "Príkazy", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", - "Emoji": "Emotikon", + "Emoji": "Emoji", "Notify the whole room": "Oznamovať celú miestnosť", "Room Notification": "Oznámenie miestnosti", "Users": "Používatelia", @@ -1647,8 +1647,22 @@ "Command Autocomplete": "Automatické dopĺňanie príkazov", "Community Autocomplete": "Automatické dopĺňanie skupín", "DuckDuckGo Results": "Výsledky hľadania DuckDuckGo", - "Emoji Autocomplete": "Automatické dopĺňanie emotikonov", + "Emoji Autocomplete": "Automatické dopĺňanie emoji", "Notification Autocomplete": "Automatické dopĺňanie oznámení", "Room Autocomplete": "Automatické dopĺňanie miestností", - "User Autocomplete": "Automatické dopĺňanie používateľov" + "User Autocomplete": "Automatické dopĺňanie používateľov", + "Start": "Začať", + "Verify this session by confirming the following number appears on its screen.": "Overte túto reláciu tým, že zistíte, či sa na jeho obrazovke objaví nasledujúce číslo.", + "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Čakám na overenie od relácie %(deviceName)s (%(deviceId)s)…", + "Waiting for your other session to verify…": "Čakám na overenie od vašej druhej relácie…", + "Waiting for %(displayName)s to verify…": "Čakám na %(displayName)s, kým nás overí…", + "Cancelling…": "Rušenie…", + "They match": "Zhodujú sa", + "They don't match": "Nezhodujú sa", + "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 emoji": "Overte pomocou emoji", + "Compare emoji": "Porovnajte emoji" } From 41a11bbdb2c0dfe1ac962a78525d8f98a264a9db Mon Sep 17 00:00:00 2001 From: MamasLT Date: Thu, 21 May 2020 18:29:58 +0000 Subject: [PATCH 040/332] Translated using Weblate (Lithuanian) Currently translated at 48.4% (1124 of 2321 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index e96e0e9199..b02cb5c485 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -418,7 +418,7 @@ "A new password must be entered.": "Privalo būti įvestas naujas slaptažodis.", "New passwords must match each other.": "Nauji slaptažodžiai privalo sutapti.", "I have verified my email address": "Aš patvirtinau savo el. pašto adresą", - "Return to login screen": "Grįžti į prisijungimo ekraną", + "Return to login screen": "Grįžti į prisijungimą", "Send Reset Email": "Siųsti atstatymo el. laišką", "Incorrect username and/or password.": "Neteisingas vartotojo vardas ir/arba slaptažodis.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Turėkite omenyje, kad jūs prisijungiate prie %(hs)s serverio, o ne matrix.org.", @@ -1153,5 +1153,10 @@ "Copy it to your personal cloud storage": "Nukopijuoti jį į savo asmeninę debesų saugyklą", "You can now verify your other devices, and other users to keep your chats safe.": "Jūs dabar galite patvirtinti kitus savo įrenginius ir kitus vartotojus, kad jūsų pokalbiai būtų saugūs.", "Confirm recovery passphrase": "Patvirtinkite atgavimo slaptafrazę", - "You're done!": "Atlikta!" + "You're done!": "Atlikta!", + "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.": "Slaptažodžio keitimas šiuo metu anuliuos visapusio šifravimo ranktus visose sesijose, tad šifruotų pokalbių istorija taps neperskaitoma, nebent jūs eksportuosite savo kambarių raktus ir po to importuosite juos atgal. Ateityje ši funkcija bus pataisyta.", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Jūsų slaptažodis buvo sėkmingai pakeistas. Jūs nematysite pranešimų kitose sesijose kol iš naujo prie jų neprisijungsite", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "El. laiškas buvo išsiųstas į %(emailAddress)s. Kai paspausite jame esančią nuorodą, tada spauskite žemiau.", + "Your password has been reset.": "Jūsų slaptažodis buvo iš naujo nustatytas.", + "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.": "Jūs buvote atjungtas iš visų sesijų ir nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, prisijunkite iš naujo kiekviename įrenginyje." } From cb270ba0d5a0c6478a38e0dd92577393e20e9082 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Thu, 21 May 2020 21:59:22 +0000 Subject: [PATCH 041/332] Translated using Weblate (Esperanto) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 89c75532df..f201d5a117 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -2419,5 +2419,6 @@ "Size must be a number": "Grando devas esti nombro", "Custom font size can only be between %(min)s pt and %(max)s pt": "Propra grando de tiparo povas interi nur %(min)s punktojn kaj %(max)s punktojn", "Use between %(min)s pt and %(max)s pt": "Uzi inter %(min)s punktoj kaj %(max)s punktoj", - "Appearance": "Aspekto" + "Appearance": "Aspekto", + "Use the improved room list (in development - refresh to apply changes)": "Uzi la plibonigitan liston de ĉambroj (ankoraŭ evoluigate – aktualigu la paĝon por efektivigi ŝanĝojn)" } From f0c8f20cf6a4ea06e421adc50152337f9453d8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 21 May 2020 20:03:09 +0000 Subject: [PATCH 042/332] Translated using Weblate (Estonian) Currently translated at 54.8% (1273 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/et/ --- src/i18n/strings/et.json | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json index 3d4b7ec888..d00525b420 100644 --- a/src/i18n/strings/et.json +++ b/src/i18n/strings/et.json @@ -1242,5 +1242,39 @@ "Confirm account deactivation": "Kinnita konto sulgemine", "There was a problem communicating with the server. Please try again.": "Serveriühenduses tekkis viga. Palun proovi uuesti.", "Server did not return valid authentication information.": "Serveri saadetud vastuses ei olnud kehtivat autentimisteavet.", - "Please fill why you're reporting.": "Palun kirjelda veateate põhjust." + "Please fill why you're reporting.": "Palun kirjelda veateate põhjust.", + "Something went wrong trying to invite the users.": "Kasutajatele kutse saatmisel läks midagi viltu.", + "We couldn't invite those users. Please check the users you want to invite and try again.": "Meil ei õnnestunud neile kasutajatele kutset saata. Palun kontrolli, keda soovid kutsuda ning proovi uuesti.", + "Failed to find the following users": "Järgnevaid kasutajaid ei õnnestunud leida", + "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Järgmisi kasutajanimesid pole olemas või on vigaselt kirjas ning seega ei saa neile kutset saata: %(csvNames)s", + "Recently Direct Messaged": "Viimased otsesõnumite saajad", + "Invite someone using their name, username (like ), email address or share this room.": "Kutsu kedagi tema nime, kasutajanime (nagu ), e-posti aadressi alusel või jaga seda jututuba.", + "You added a new session '%(displayName)s', which is requesting encryption keys.": "Sa oled lisanud uue sessiooni '%(displayName)s', mis küsib krüptimisvõtmeid.", + "Start verification": "Alusta verifitseerimist", + "Share without verifying": "Jaga ilma verifitseerimata", + "Loading session info...": "Laen sessiooniteavet…", + "Encryption key request": "Krüptimisvõtmete päring", + "Upload completed": "Üleslaadimine valmis", + "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "Riot kasutab varasemaga võrreldes 3-5 korda vähem mälu, sest laeb teavet kasutajate kohta vaid siis, kui vaja. Palun oota hetke, kuni sünkroniseerime andmeid serveriga!", + "Updating Riot": "Uuenda Riot'it", + "I don't want my encrypted messages": "Ma ei soovi oma krüptitud sõnumeid", + "Manually export keys": "Ekspordi võtmed käsitsi", + "You'll lose access to your encrypted messages": "Sa kaotad ligipääsu oma krüptitud sõnumitele", + "Are you sure you want to sign out?": "Kas sa oled kindel, et soovid välja logida?", + "Upload %(count)s other files|one": "Lae üles %(count)s muu fail", + "Cancel All": "Tühista kõik", + "Upload Error": "Üleslaadimise viga", + "Verify other session": "Verifitseeri teine sessioon", + "Verification Request": "Verifitseerimispäring", + "A widget would like to verify your identity": "Vidin soovib verifitseerida sinu isikut", + "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.": "Vidin %(widgetUrl)s saidist soovib verifitseerida sinu isikut. Kui sa seda lubad, siis vidin verifitseerib vaid sinu kasutajatunnuse, kuid ei saa teha toiminguid sinuna.", + "Remember my selection for this widget": "Jäta meelde minu valik selle vidina kohta", + "Allow": "Luba", + "Deny": "Keela", + "Unable to restore backup": "Varukoopiast taastamine ei õnenstu", + "No backup found!": "Varukoopiat ei leidunud!", + "Keys restored": "Krüptimise võtmed on taastatud", + "Failed to decrypt %(failedCount)s sessions!": "%(failedCount)s sessiooni dekrüptimine ei õnnestunud!", + "Successfully restored %(sessionCount)s keys": "%(sessionCount)s sessiooni võtme taastamine õnnestus", + "Warning: you should only set up key backup from a trusted computer.": "Hoiatus: sa peaksid võtmete varunduse seadistama vaid usaldusväärsest arvutist." } From 19667964a7e1a826e086722ded126bf9d476e665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 22 May 2020 06:36:51 +0000 Subject: [PATCH 043/332] Translated using Weblate (French) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index ee3c398e86..66bb97118f 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2445,5 +2445,6 @@ "Size must be a number": "La taille doit être un nombre", "Custom font size can only be between %(min)s pt and %(max)s pt": "La taille de police personnalisée doit être comprise entre %(min)s pt et %(max)s pt", "Use between %(min)s pt and %(max)s pt": "Utiliser entre %(min)s pt et %(max)s pt", - "Appearance": "Apparence" + "Appearance": "Apparence", + "Use the improved room list (in development - refresh to apply changes)": "Utiliser la liste de salons améliorée (en développement − actualisez pour appliquer les changements)" } From f00ce9aace4a780e6a393eaef7128c932f9377e4 Mon Sep 17 00:00:00 2001 From: XoseM Date: Fri, 22 May 2020 09:18:06 +0000 Subject: [PATCH 044/332] Translated using Weblate (Galician) Currently translated at 43.7% (1014 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index d433d58146..48eb1338b4 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -986,5 +986,45 @@ "Review where you’re logged in": "Revisar onde estás conectada", "New login. Was this you?": "Nova conexión. Foches ti?", "Name or Matrix ID": "Nome ou ID Matrix", - "Identity server has no terms of service": "O servidor de identidade non ten termos dos servizo" + "Identity server has no terms of service": "O servidor de identidade non ten termos dos servizo", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Esta acción precisa acceder ao servidor de indentidade para validar o enderezo de email ou o número de teléfono, pero o servidor non publica os seus termos do servizo.", + "Only continue if you trust the owner of the server.": "Continúa se realmente confías no dono do servidor.", + "Trust": "Confiar", + "%(name)s is requesting verification": "%(name)s está pedindo a verificación", + "Use your account or create a new one to continue.": "Usa a túa conta ou crea unha nova para continuar.", + "Create Account": "Crear conta", + "Custom (%(level)s)": "Personalizado (%(level)s)", + "Failed to invite users to the room:": "Fallo a convidar a persoas a sala:", + "Messages": "Mensaxes", + "Actions": "Accións", + "Other": "Outro", + "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Anteponse ¯\\_(ツ)_/¯ a mensaxe en texto plano", + "Sends a message as plain text, without interpreting it as markdown": "Envía unha mensaxe como texto plano, sen interpretalo como markdown", + "Sends a message as html, without interpreting it as markdown": "Envía unha mensaxe como html, sen interpretalo como markdown", + "Upgrades a room to a new version": "Subir a sala de versión", + "You do not have the required permissions to use this command.": "Non tes os permisos suficientes para usar este comando.", + "Error upgrading room": "Fallo ao actualizar a sala", + "Double check that your server supports the room version chosen and try again.": "Comproba ben que o servidor soporta a versión da sala escollida e inténtao outra vez.", + "Changes your display nickname in the current room only": "Cambia o teu nome mostrado só para esta esta sala", + "Changes the avatar of the current room": "Cambia o avatar da sala actual", + "Changes your avatar in this current room only": "Cambia o teu avatar só nesta sala", + "Changes your avatar in all rooms": "Cambia o teu avatar en todas as salas", + "Gets or sets the room topic": "Obtén ou establece o asunto da sala", + "Failed to set topic": "Fallo ao establecer asunto", + "This room has no topic.": "Esta sala non ten asunto.", + "Sets the room name": "Establecer nome da sala", + "Use an identity server": "Usar un servidor de identidade", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Usar un servidor de identidade para convidar por email. Preme continuar para usar o servidor de identidade por omisión (%(defaultIdentityServerName)s) ou cambiao en Axustes.", + "Use an identity server to invite by email. Manage in Settings.": "Usar un servidor de indentidade para convidar por email. Xestionao en Axustes.", + "Command failed": "O comando fallou", + "Could not find user in room": "Non se atopa a usuaria na sala", + "Adds a custom widget by URL to the room": "Engade un widget por URL personalizado a sala", + "Please supply a widget URL or embed code": "Proporciona o URL do widget ou incrusta o código", + "Please supply a https:// or http:// widget URL": "Escribe un https:// ou http:// como URL do widget", + "You cannot modify widgets in this room.": "Non podes modificar os widgets desta sala.", + "Unknown (user, session) pair:": "Par descoñecido (usuaria, sesión):", + "Session already verified!": "A sesión xa está verificada!", + "WARNING: Session already verified, but keys do NOT MATCH!": "AVISO: xa está verificada a sesión, pero as chaves NON CONCORDAN!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "AVISO: FALLOU A VERIFICACIÓN DAS CHAVES! A chave de firma para %(userId)s na sesión %(deviceId)s é \"%(fprint)s\" que non concordan coa chave proporcionada \"%(fingerprint)s\". Esto podería significar que as túas comunicacións foron interceptadas!", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A chave de firma proporcionada concorda coa chave de firma recibida desde a sesión %(deviceId)s de %(userId)s. Sesión marcada como verificada." } From ead1fc59fabb1a86a7e1763661ef48cb53493da2 Mon Sep 17 00:00:00 2001 From: random Date: Fri, 22 May 2020 08:08:45 +0000 Subject: [PATCH 045/332] Translated using Weblate (Italian) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 1fd6d7dc0c..7f6d3bf1e2 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2440,5 +2440,6 @@ "Size must be a number": "La dimensione deve essere un numero", "Custom font size can only be between %(min)s pt and %(max)s pt": "La dimensione del carattere personalizzata può solo essere tra %(min)s pt e %(max)s pt", "Use between %(min)s pt and %(max)s pt": "Usa tra %(min)s pt e %(max)s pt", - "Appearance": "Aspetto" + "Appearance": "Aspetto", + "Use the improved room list (in development - refresh to apply changes)": "Usa l'elenco stanze migliorato (in sviluppo - ricarica per applicare le modifiche)" } From fe357e530dc482b5338a59a9e74a36727797252c Mon Sep 17 00:00:00 2001 From: MamasLT Date: Thu, 21 May 2020 21:54:40 +0000 Subject: [PATCH 046/332] Translated using Weblate (Lithuanian) Currently translated at 48.5% (1127 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index b02cb5c485..c6f3abef0f 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -1158,5 +1158,8 @@ "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Jūsų slaptažodis buvo sėkmingai pakeistas. Jūs nematysite pranešimų kitose sesijose kol iš naujo prie jų neprisijungsite", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "El. laiškas buvo išsiųstas į %(emailAddress)s. Kai paspausite jame esančią nuorodą, tada spauskite žemiau.", "Your password has been reset.": "Jūsų slaptažodis buvo iš naujo nustatytas.", - "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.": "Jūs buvote atjungtas iš visų sesijų ir nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, prisijunkite iš naujo kiekviename įrenginyje." + "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.": "Jūs buvote atjungtas iš visų sesijų ir nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, prisijunkite iš naujo kiekviename įrenginyje.", + "Show more": "Rodyti daugiau", + "Log in to your new account.": "Prisijunkite į savo naują paskyrą.", + "Registration Successful": "Registracija sėkminga" } From 67ffe94df4c0774a97748e886b9c88b696cf843a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 11:18:14 +0100 Subject: [PATCH 047/332] Fix typo and improve error context Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 2 +- src/stores/RoomViewStore.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 8e343fe08f..39cd497098 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1676,7 +1676,7 @@ export default createReactClass({ const ErrorBoundary = sdk.getComponent("elements.ErrorBoundary"); if (!this.state.room) { - const loading = this.state.matrixClientIsReady || this.state.roomLoading || this.state.peekLoading; + const loading = !this.state.matrixClientIsReady || this.state.roomLoading || this.state.peekLoading; if (loading) { // Assume preview loading if we don't have a ready client or a room ID (still resolving the alias) const previewLoading = !this.state.matrixClientIsReady || !this.state.roomId || this.state.peekLoading; diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 1958b9539f..a38445c89b 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -215,7 +215,7 @@ class RoomViewStore extends Store { storeRoomAliasInCache(payload.room_alias, result.room_id); roomId = result.room_id; } catch (err) { - console.error(err); + console.error("RVS failed to get room id for alias: ", err); dis.dispatch({ action: 'view_room_error', room_id: null, From dc37469808d23000f3a7c9b6f184b07a31677379 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 12:47:40 +0100 Subject: [PATCH 048/332] Convert ToastContainer and ToastStore to Typescript Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- package.json | 1 + src/@types/global.d.ts | 3 + src/components/structures/MatrixChat.tsx | 2 +- .../{ToastContainer.js => ToastContainer.tsx} | 16 ++-- src/stores/ToastStore.js | 73 ------------------ src/stores/ToastStore.ts | 77 +++++++++++++++++++ yarn.lock | 5 ++ 7 files changed, 98 insertions(+), 79 deletions(-) rename src/components/structures/{ToastContainer.js => ToastContainer.tsx} (87%) delete mode 100644 src/stores/ToastStore.js create mode 100644 src/stores/ToastStore.ts diff --git a/package.json b/package.json index 193fb86218..440fe3beac 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "@types/classnames": "^2.2.10", "@types/flux": "^3.1.9", "@types/modernizr": "^3.5.3", + "@types/node": "^12.12.41", "@types/qrcode": "^1.3.4", "@types/react": "16.9", "@types/zxcvbn": "^4.4.0", diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index e6e339d067..6c62000143 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,6 +15,7 @@ limitations under the License. */ import * as ModernizrStatic from "modernizr"; +import ToastStore from "../stores/ToastStore"; declare global { interface Window { @@ -22,6 +23,8 @@ declare global { Olm: { init: () => Promise; }; + + mx_ToastStore: ToastStore; } // workaround for https://github.com/microsoft/TypeScript/issues/30933 diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 48dc72f4fa..89db30c7b4 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1559,7 +1559,7 @@ export default class MatrixChat extends React.PureComponent { icon: "verification", props: {request}, component: sdk.getComponent("toasts.VerificationRequestToast"), - priority: ToastStore.PRIORITY_REALTIME, + priority: 95, }); } }); diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.tsx similarity index 87% rename from src/components/structures/ToastContainer.js rename to src/components/structures/ToastContainer.tsx index 283fbdd96a..9440aa3463 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.tsx @@ -16,13 +16,19 @@ limitations under the License. import * as React from "react"; import { _t } from '../../languageHandler'; -import ToastStore from "../../stores/ToastStore"; +import ToastStore, {IToast} from "../../stores/ToastStore"; import classNames from "classnames"; -export default class ToastContainer extends React.Component { - constructor() { - super(); - this.state = {toasts: ToastStore.sharedInstance().getToasts()}; +interface IState { + toasts: IToast[]; +} + +export default class ToastContainer extends React.Component<{}, IState> { + constructor(props, context) { + super(props, context); + this.state = { + toasts: ToastStore.sharedInstance().getToasts(), + }; // Start listening here rather than in componentDidMount because // toasts may dismiss themselves in their didMount if they find diff --git a/src/stores/ToastStore.js b/src/stores/ToastStore.js deleted file mode 100644 index 8901736739..0000000000 --- a/src/stores/ToastStore.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -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 EventEmitter from 'events'; - -/** - * Holds the active toasts - */ -export default class ToastStore extends EventEmitter { - static PRIORITY_REALTIME = 0; - static PRIORITY_DEFAULT = 1; - static PRIORITY_LOW = 2; - - static sharedInstance() { - if (!global.mx_ToastStore) global.mx_ToastStore = new ToastStore(); - return global.mx_ToastStore; - } - - constructor() { - super(); - this._dispatcherRef = null; - this._toasts = []; - } - - reset() { - this._toasts = []; - } - - /** - * Add or replace a toast - * If a toast with the same toastKey already exists, the given toast will replace it - * Toasts are always added underneath any toasts of the same priority, so existing - * toasts stay at the top unless a higher priority one arrives (better to not change the - * toast unless necessary). - * - * @param {boject} newToast The new toast - */ - addOrReplaceToast(newToast) { - if (newToast.priority === undefined) newToast.priority = ToastStore.PRIORITY_DEFAULT; - - const oldIndex = this._toasts.findIndex(t => t.key === newToast.key); - if (oldIndex === -1) { - let newIndex = this._toasts.length; - while (newIndex > 0 && this._toasts[newIndex - 1].priority > newToast.priority) --newIndex; - this._toasts.splice(newIndex, 0, newToast); - } else { - this._toasts[oldIndex] = newToast; - } - this.emit('update'); - } - - dismissToast(key) { - this._toasts = this._toasts.filter(t => t.key !== key); - this.emit('update'); - } - - getToasts() { - return this._toasts; - } -} diff --git a/src/stores/ToastStore.ts b/src/stores/ToastStore.ts new file mode 100644 index 0000000000..4f6d2963c5 --- /dev/null +++ b/src/stores/ToastStore.ts @@ -0,0 +1,77 @@ +/* +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 EventEmitter from "events"; +import React, {JSXElementConstructor} from "react"; + +export interface IToast> { + key: string; + // higher priority number will be shown on top of lower priority + priority: number; + title: string; + icon?: string; + component: C; + props?: React.ComponentProps; +} + +/** + * Holds the active toasts + */ +export default class ToastStore extends EventEmitter { + private toasts: IToast[] = []; + + static sharedInstance() { + if (!window.mx_ToastStore) window.mx_ToastStore = new ToastStore(); + return window.mx_ToastStore; + } + + reset() { + this.toasts = []; + } + + /** + * Add or replace a toast + * If a toast with the same toastKey already exists, the given toast will replace it + * Toasts are always added underneath any toasts of the same priority, so existing + * toasts stay at the top unless a higher priority one arrives (better to not change the + * toast unless necessary). + * + * @param {object} newToast The new toast + */ + addOrReplaceToast>(newToast: IToast) { + const oldIndex = this.toasts.findIndex(t => t.key === newToast.key); + if (oldIndex === -1) { + let newIndex = this.toasts.length; + while (newIndex > 0 && this.toasts[newIndex - 1].priority > newToast.priority) --newIndex; + this.toasts.splice(newIndex, 0, newToast); + } else { + this.toasts[oldIndex] = newToast; + } + this.emit('update'); + } + + dismissToast(key) { + const length = this.toasts.length; + this.toasts = this.toasts.filter(t => t.key !== key); + if (length !== this.toasts.length) { + this.emit('update'); + } + } + + getToasts() { + return this.toasts; + } +} diff --git a/yarn.lock b/yarn.lock index 6cdc771c5b..340d0b4454 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1280,6 +1280,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== +"@types/node@^12.12.41": + version "12.12.42" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.42.tgz#d0d1149336bd07540dd1ea576692829d575dec34" + integrity sha512-R/9QdYFLL9dE9l5cWWzWIZByVGFd7lk7JVOJ7KD+E1SJ4gni7XJRLz9QTjyYQiHIqEAgku9VgxdLjMlhhUaAFg== + "@types/prop-types@*": version "15.7.3" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" From 3bf5e003a154ff54704f5873ff81d51688d60052 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 12:54:03 +0100 Subject: [PATCH 049/332] Convert DeviceListener to Typescript Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/@types/global.d.ts | 2 + src/{DeviceListener.js => DeviceListener.ts} | 91 +++++++++----------- 2 files changed, 45 insertions(+), 48 deletions(-) rename src/{DeviceListener.js => DeviceListener.ts} (81%) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 6c62000143..bcf08b26bb 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -16,6 +16,7 @@ limitations under the License. import * as ModernizrStatic from "modernizr"; import ToastStore from "../stores/ToastStore"; +import DeviceListener from "../DeviceListener"; declare global { interface Window { @@ -25,6 +26,7 @@ declare global { }; mx_ToastStore: ToastStore; + mx_DeviceListener: DeviceListener; } // workaround for https://github.com/microsoft/TypeScript/issues/30933 diff --git a/src/DeviceListener.js b/src/DeviceListener.ts similarity index 81% rename from src/DeviceListener.js rename to src/DeviceListener.ts index 27caba971e..ce1f781dad 100644 --- a/src/DeviceListener.js +++ b/src/DeviceListener.ts @@ -29,28 +29,23 @@ function toastKey(deviceId) { } export default class DeviceListener { + // device IDs for which the user has dismissed the verify toast ('Later') + private dismissed = new Set(); + // has the user dismissed any of the various nag toasts to setup encryption on this device? + private dismissedThisDeviceToast = false; + // cache of the key backup info + private keyBackupInfo: object = null; + private keyBackupFetchedAt: number = null; + // We keep a list of our own device IDs so we can batch ones that were already + // there the last time the app launched into a single toast, but display new + // ones in their own toasts. + private ourDeviceIdsAtStart: Set = null; + // The set of device IDs we're currently displaying toasts for + private displayingToastsForDeviceIds = new Set(); + static sharedInstance() { - if (!global.mx_DeviceListener) global.mx_DeviceListener = new DeviceListener(); - return global.mx_DeviceListener; - } - - constructor() { - // device IDs for which the user has dismissed the verify toast ('Later') - this._dismissed = new Set(); - // has the user dismissed any of the various nag toasts to setup encryption on this device? - this._dismissedThisDeviceToast = false; - - // cache of the key backup info - this._keyBackupInfo = null; - this._keyBackupFetchedAt = null; - - // We keep a list of our own device IDs so we can batch ones that were already - // there the last time the app launched into a single toast, but display new - // ones in their own toasts. - this._ourDeviceIdsAtStart = null; - - // The set of device IDs we're currently displaying toasts for - this._displayingToastsForDeviceIds = new Set(); + if (!window.mx_DeviceListener) window.mx_DeviceListener = new DeviceListener(); + return window.mx_DeviceListener; } start() { @@ -74,12 +69,12 @@ export default class DeviceListener { MatrixClientPeg.get().removeListener('accountData', this._onAccountData); MatrixClientPeg.get().removeListener('sync', this._onSync); } - this._dismissed.clear(); - this._dismissedThisDeviceToast = false; - this._keyBackupInfo = null; - this._keyBackupFetchedAt = null; - this._ourDeviceIdsAtStart = null; - this._displayingToastsForDeviceIds = new Set(); + this.dismissed.clear(); + this.dismissedThisDeviceToast = false; + this.keyBackupInfo = null; + this.keyBackupFetchedAt = null; + this.ourDeviceIdsAtStart = null; + this.displayingToastsForDeviceIds = new Set(); } /** @@ -87,29 +82,29 @@ export default class DeviceListener { * * @param {String[]} deviceIds List of device IDs to dismiss notifications for */ - async dismissUnverifiedSessions(deviceIds) { + async dismissUnverifiedSessions(deviceIds: string[]) { for (const d of deviceIds) { - this._dismissed.add(d); + this.dismissed.add(d); } this._recheck(); } dismissEncryptionSetup() { - this._dismissedThisDeviceToast = true; + this.dismissedThisDeviceToast = true; this._recheck(); } _ensureDeviceIdsAtStartPopulated() { - if (this._ourDeviceIdsAtStart === null) { + if (this.ourDeviceIdsAtStart === null) { const cli = MatrixClientPeg.get(); - this._ourDeviceIdsAtStart = new Set( + this.ourDeviceIdsAtStart = new Set( cli.getStoredDevicesForUser(cli.getUserId()).map(d => d.deviceId), ); } } - _onWillUpdateDevices = async (users, initialFetch) => { + _onWillUpdateDevices = async (users: string[], initialFetch?: boolean) => { // If we didn't know about *any* devices before (ie. it's fresh login), // then they are all pre-existing devices, so ignore this and set the // devicesAtStart list to the devices that we see after the fetch. @@ -122,17 +117,17 @@ export default class DeviceListener { // before we download any new ones. } - _onDevicesUpdated = (users) => { + _onDevicesUpdated = (users: string[]) => { if (!users.includes(MatrixClientPeg.get().getUserId())) return; this._recheck(); } - _onDeviceVerificationChanged = (userId) => { + _onDeviceVerificationChanged = (userId: string) => { if (userId !== MatrixClientPeg.get().getUserId()) return; this._recheck(); } - _onUserTrustStatusChanged = (userId, trustLevel) => { + _onUserTrustStatusChanged = (userId: string) => { if (userId !== MatrixClientPeg.get().getUserId()) return; this._recheck(); } @@ -163,11 +158,11 @@ export default class DeviceListener { // & cache the result async _getKeyBackupInfo() { const now = (new Date()).getTime(); - if (!this._keyBackupInfo || this._keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL) { - this._keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); - this._keyBackupFetchedAt = now; + if (!this.keyBackupInfo || this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL) { + this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); + this.keyBackupFetchedAt = now; } - return this._keyBackupInfo; + return this.keyBackupInfo; } async _recheck() { @@ -186,7 +181,7 @@ export default class DeviceListener { const crossSigningReady = await cli.isCrossSigningReady(); - if (this._dismissedThisDeviceToast) { + if (this.dismissedThisDeviceToast) { ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); } else { if (!crossSigningReady) { @@ -239,20 +234,20 @@ export default class DeviceListener { // (technically could just be a boolean: we don't actually // need to remember the device IDs, but for the sake of // symmetry...). - const oldUnverifiedDeviceIds = new Set(); + const oldUnverifiedDeviceIds = new Set(); // Unverified devices that have appeared since then - const newUnverifiedDeviceIds = new Set(); + const newUnverifiedDeviceIds = new Set(); // as long as cross-signing isn't ready, // you can't see or dismiss any device toasts if (crossSigningReady) { const devices = cli.getStoredDevicesForUser(cli.getUserId()); for (const device of devices) { - if (device.deviceId == cli.deviceId) continue; + if (device.deviceId === cli.deviceId) continue; const deviceTrust = await cli.checkDeviceTrust(cli.getUserId(), device.deviceId); - if (!deviceTrust.isCrossSigningVerified() && !this._dismissed.has(device.deviceId)) { - if (this._ourDeviceIdsAtStart.has(device.deviceId)) { + if (!deviceTrust.isCrossSigningVerified() && !this.dismissed.has(device.deviceId)) { + if (this.ourDeviceIdsAtStart.has(device.deviceId)) { oldUnverifiedDeviceIds.add(device.deviceId); } else { newUnverifiedDeviceIds.add(device.deviceId); @@ -289,12 +284,12 @@ export default class DeviceListener { } // ...and hide any we don't need any more - for (const deviceId of this._displayingToastsForDeviceIds) { + for (const deviceId of this.displayingToastsForDeviceIds) { if (!newUnverifiedDeviceIds.has(deviceId)) { ToastStore.sharedInstance().dismissToast(toastKey(deviceId)); } } - this._displayingToastsForDeviceIds = newUnverifiedDeviceIds; + this.displayingToastsForDeviceIds = newUnverifiedDeviceIds; } } From b21e5ba10b313ebc492b2241d808f917814a5706 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 12:57:48 +0100 Subject: [PATCH 050/332] Set new granular priorities Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/DeviceListener.ts | 6 +++++- src/components/structures/MatrixChat.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts index ce1f781dad..1ecaca9b40 100644 --- a/src/DeviceListener.ts +++ b/src/DeviceListener.ts @@ -197,6 +197,7 @@ export default class DeviceListener { icon: "verification_warning", props: {kind: 'verify_this_session'}, component: sdk.getComponent("toasts.SetupEncryptionToast"), + priority: 95, }); } else { const backupInfo = await this._getKeyBackupInfo(); @@ -208,6 +209,7 @@ export default class DeviceListener { icon: "verification_warning", props: {kind: 'upgrade_encryption'}, component: sdk.getComponent("toasts.SetupEncryptionToast"), + priority: 40, }); } else { // No cross-signing or key backup on account (set up encryption) @@ -217,6 +219,7 @@ export default class DeviceListener { icon: "verification_warning", props: {kind: 'set_up_encryption'}, component: sdk.getComponent("toasts.SetupEncryptionToast"), + priority: 40, }); } } @@ -262,11 +265,11 @@ export default class DeviceListener { key: OTHER_DEVICES_TOAST_KEY, title: _t("Review where you’re logged in"), icon: "verification_warning", - priority: ToastStore.PRIORITY_LOW, props: { deviceIds: oldUnverifiedDeviceIds, }, component: sdk.getComponent("toasts.BulkUnverifiedSessionsToast"), + priority: 50, }); } else { ToastStore.sharedInstance().dismissToast(OTHER_DEVICES_TOAST_KEY); @@ -280,6 +283,7 @@ export default class DeviceListener { icon: "verification_warning", props: { deviceId }, component: sdk.getComponent("toasts.UnverifiedSessionToast"), + priority: 80, }); } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 89db30c7b4..e6a56c683f 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1559,7 +1559,7 @@ export default class MatrixChat extends React.PureComponent { icon: "verification", props: {request}, component: sdk.getComponent("toasts.VerificationRequestToast"), - priority: 95, + priority: 90, }); } }); From 14cee413603ce4fc36bdf1ac2f2b0551fe6b4516 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 13:29:53 +0100 Subject: [PATCH 051/332] Convert things to Typescript and re-use a generic component Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/DeviceListener.ts | 111 ++++++------------ .../toasts/BulkUnverifiedSessionsToast.js | 56 --------- src/components/views/toasts/GenericToast.tsx | 42 +++++++ .../views/toasts/SetupEncryptionToast.js | 88 -------------- .../views/toasts/UnverifiedSessionToast.js | 66 ----------- ...tToast.js => VerificationRequestToast.tsx} | 48 +++++--- src/toasts/BulkUnverifiedSessionsToast.ts | 58 +++++++++ src/toasts/SetupEncryptionToast.ts | 106 +++++++++++++++++ src/toasts/UnverifiedSessionToast.ts | 70 +++++++++++ 9 files changed, 342 insertions(+), 303 deletions(-) delete mode 100644 src/components/views/toasts/BulkUnverifiedSessionsToast.js create mode 100644 src/components/views/toasts/GenericToast.tsx delete mode 100644 src/components/views/toasts/SetupEncryptionToast.js delete mode 100644 src/components/views/toasts/UnverifiedSessionToast.js rename src/components/views/toasts/{VerificationRequestToast.js => VerificationRequestToast.tsx} (86%) create mode 100644 src/toasts/BulkUnverifiedSessionsToast.ts create mode 100644 src/toasts/SetupEncryptionToast.ts create mode 100644 src/toasts/UnverifiedSessionToast.ts diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts index 1ecaca9b40..ca51b5ac1c 100644 --- a/src/DeviceListener.ts +++ b/src/DeviceListener.ts @@ -14,19 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixClientPeg } from './MatrixClientPeg'; +import {MatrixClientPeg} from './MatrixClientPeg'; import SettingsStore from './settings/SettingsStore'; -import * as sdk from './index'; -import { _t } from './languageHandler'; -import ToastStore from './stores/ToastStore'; +import { + hideToast as hideBulkUnverifiedSessionsToast, + showToast as showBulkUnverifiedSessionsToast +} from "./toasts/BulkUnverifiedSessionsToast"; +import { + hideToast as hideSetupEncryptionToast, + Kind as SetupKind, + Kind, + showToast as showSetupEncryptionToast +} from "./toasts/SetupEncryptionToast"; +import { + hideToast as hideUnverifiedSessionsToast, + showToast as showUnverifiedSessionsToast +} from "./toasts/UnverifiedSessionToast"; const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000; -const THIS_DEVICE_TOAST_KEY = 'setupencryption'; -const OTHER_DEVICES_TOAST_KEY = 'reviewsessions'; - -function toastKey(deviceId) { - return "unverified_session_" + deviceId; -} export default class DeviceListener { // device IDs for which the user has dismissed the verify toast ('Later') @@ -82,7 +87,7 @@ export default class DeviceListener { * * @param {String[]} deviceIds List of device IDs to dismiss notifications for */ - async dismissUnverifiedSessions(deviceIds: string[]) { + async dismissUnverifiedSessions(deviceIds: Iterable) { for (const d of deviceIds) { this.dismissed.add(d); } @@ -181,51 +186,25 @@ export default class DeviceListener { const crossSigningReady = await cli.isCrossSigningReady(); - if (this.dismissedThisDeviceToast) { - ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); + if (this.dismissedThisDeviceToast || crossSigningReady) { + hideSetupEncryptionToast(); } else { - if (!crossSigningReady) { - // make sure our keys are finished downlaoding - await cli.downloadKeys([cli.getUserId()]); - // cross signing isn't enabled - nag to enable it - // There are 3 different toasts for: - if (cli.getStoredCrossSigningForUser(cli.getUserId())) { - // Cross-signing on account but this device doesn't trust the master key (verify this session) - ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Verify this session"), - icon: "verification_warning", - props: {kind: 'verify_this_session'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), - priority: 95, - }); - } else { - const backupInfo = await this._getKeyBackupInfo(); - if (backupInfo) { - // No cross-signing on account but key backup available (upgrade encryption) - ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Encryption upgrade available"), - icon: "verification_warning", - props: {kind: 'upgrade_encryption'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), - priority: 40, - }); - } else { - // No cross-signing or key backup on account (set up encryption) - ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Set up encryption"), - icon: "verification_warning", - props: {kind: 'set_up_encryption'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), - priority: 40, - }); - } - } + // make sure our keys are finished downloading + await cli.downloadKeys([cli.getUserId()]); + // cross signing isn't enabled - nag to enable it + // There are 3 different toasts for: + if (cli.getStoredCrossSigningForUser(cli.getUserId())) { + // Cross-signing on account but this device doesn't trust the master key (verify this session) + showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION); } else { - // cross-signing is ready, and we don't need to upgrade encryption - ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); + const backupInfo = await this._getKeyBackupInfo(); + if (backupInfo) { + // No cross-signing on account but key backup available (upgrade encryption) + showSetupEncryptionToast(Kind.UPGRADE_ENCRYPTION); + } else { + // No cross-signing or key backup on account (set up encryption) + showSetupEncryptionToast(Kind.SET_UP_ENCRYPTION); + } } } @@ -261,36 +240,20 @@ export default class DeviceListener { // Display or hide the batch toast for old unverified sessions if (oldUnverifiedDeviceIds.size > 0) { - ToastStore.sharedInstance().addOrReplaceToast({ - key: OTHER_DEVICES_TOAST_KEY, - title: _t("Review where you’re logged in"), - icon: "verification_warning", - props: { - deviceIds: oldUnverifiedDeviceIds, - }, - component: sdk.getComponent("toasts.BulkUnverifiedSessionsToast"), - priority: 50, - }); + showBulkUnverifiedSessionsToast(oldUnverifiedDeviceIds); } else { - ToastStore.sharedInstance().dismissToast(OTHER_DEVICES_TOAST_KEY); + hideBulkUnverifiedSessionsToast(); } // Show toasts for new unverified devices if they aren't already there for (const deviceId of newUnverifiedDeviceIds) { - ToastStore.sharedInstance().addOrReplaceToast({ - key: toastKey(deviceId), - title: _t("New login. Was this you?"), - icon: "verification_warning", - props: { deviceId }, - component: sdk.getComponent("toasts.UnverifiedSessionToast"), - priority: 80, - }); + showUnverifiedSessionsToast(deviceId); } // ...and hide any we don't need any more for (const deviceId of this.displayingToastsForDeviceIds) { if (!newUnverifiedDeviceIds.has(deviceId)) { - ToastStore.sharedInstance().dismissToast(toastKey(deviceId)); + hideUnverifiedSessionsToast(deviceId); } } diff --git a/src/components/views/toasts/BulkUnverifiedSessionsToast.js b/src/components/views/toasts/BulkUnverifiedSessionsToast.js deleted file mode 100644 index 99ff529c35..0000000000 --- a/src/components/views/toasts/BulkUnverifiedSessionsToast.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -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 PropTypes from 'prop-types'; -import { _t } from '../../../languageHandler'; -import dis from "../../../dispatcher/dispatcher"; -import { MatrixClientPeg } from '../../../MatrixClientPeg'; -import DeviceListener from '../../../DeviceListener'; -import FormButton from '../elements/FormButton'; -import { replaceableComponent } from '../../../utils/replaceableComponent'; - -@replaceableComponent("views.toasts.BulkUnverifiedSessionsToast") -export default class BulkUnverifiedSessionsToast extends React.PureComponent { - static propTypes = { - deviceIds: PropTypes.array, - } - - _onLaterClick = () => { - DeviceListener.sharedInstance().dismissUnverifiedSessions(this.props.deviceIds); - }; - - _onReviewClick = async () => { - DeviceListener.sharedInstance().dismissUnverifiedSessions(this.props.deviceIds); - - dis.dispatch({ - action: 'view_user_info', - userId: MatrixClientPeg.get().getUserId(), - }); - }; - - render() { - return (
-
- {_t("Verify all your sessions to ensure your account & messages are safe")} -
-
- - -
-
); - } -} diff --git a/src/components/views/toasts/GenericToast.tsx b/src/components/views/toasts/GenericToast.tsx new file mode 100644 index 0000000000..9d69330857 --- /dev/null +++ b/src/components/views/toasts/GenericToast.tsx @@ -0,0 +1,42 @@ +/* +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, {ReactChild} from "react"; + +import FormButton from "../elements/FormButton"; + +interface IProps { + description: ReactChild; + acceptLabel: string; + rejectLabel?: string; + + onAccept(); + onReject?(); +} + +const GenericToast: React.FC = ({description, acceptLabel, rejectLabel, onAccept, onReject}) => { + return
+
+ { description } +
+
+ {onReject && rejectLabel && } + +
+
; +}; + +export default GenericToast; diff --git a/src/components/views/toasts/SetupEncryptionToast.js b/src/components/views/toasts/SetupEncryptionToast.js deleted file mode 100644 index b5510e85b6..0000000000 --- a/src/components/views/toasts/SetupEncryptionToast.js +++ /dev/null @@ -1,88 +0,0 @@ -/* -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 PropTypes from 'prop-types'; -import Modal from '../../../Modal'; -import * as sdk from "../../../index"; -import { _t } from '../../../languageHandler'; -import DeviceListener from '../../../DeviceListener'; -import SetupEncryptionDialog from "../dialogs/SetupEncryptionDialog"; -import { accessSecretStorage } from '../../../CrossSigningManager'; - -export default class SetupEncryptionToast extends React.PureComponent { - static propTypes = { - toastKey: PropTypes.string.isRequired, - kind: PropTypes.oneOf([ - 'set_up_encryption', - 'verify_this_session', - 'upgrade_encryption', - ]).isRequired, - }; - - _onLaterClick = () => { - DeviceListener.sharedInstance().dismissEncryptionSetup(); - }; - - _onSetupClick = async () => { - if (this.props.kind === "verify_this_session") { - Modal.createTrackedDialog('Verify session', 'Verify session', SetupEncryptionDialog, - {}, null, /* priority = */ false, /* static = */ true); - } else { - const Spinner = sdk.getComponent("elements.Spinner"); - const modal = Modal.createDialog( - Spinner, null, 'mx_Dialog_spinner', /* priority */ false, /* static */ true, - ); - try { - await accessSecretStorage(); - } finally { - modal.close(); - } - } - }; - - getDescription() { - switch (this.props.kind) { - case 'set_up_encryption': - case 'upgrade_encryption': - return _t('Verify yourself & others to keep your chats safe'); - case 'verify_this_session': - return _t('Other users may not trust it'); - } - } - - getSetupCaption() { - switch (this.props.kind) { - case 'set_up_encryption': - return _t('Set up'); - case 'upgrade_encryption': - return _t('Upgrade'); - case 'verify_this_session': - return _t('Verify'); - } - } - - render() { - const FormButton = sdk.getComponent("elements.FormButton"); - return (
-
{this.getDescription()}
-
- - -
-
); - } -} diff --git a/src/components/views/toasts/UnverifiedSessionToast.js b/src/components/views/toasts/UnverifiedSessionToast.js deleted file mode 100644 index 38cd9f20df..0000000000 --- a/src/components/views/toasts/UnverifiedSessionToast.js +++ /dev/null @@ -1,66 +0,0 @@ -/* -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 PropTypes from 'prop-types'; -import { _t } from '../../../languageHandler'; -import { MatrixClientPeg } from '../../../MatrixClientPeg'; -import Modal from '../../../Modal'; -import DeviceListener from '../../../DeviceListener'; -import NewSessionReviewDialog from '../dialogs/NewSessionReviewDialog'; -import FormButton from '../elements/FormButton'; -import { replaceableComponent } from '../../../utils/replaceableComponent'; - -@replaceableComponent("views.toasts.UnverifiedSessionToast") -export default class UnverifiedSessionToast extends React.PureComponent { - static propTypes = { - deviceId: PropTypes.string, - } - - _onLaterClick = () => { - DeviceListener.sharedInstance().dismissUnverifiedSessions([this.props.deviceId]); - }; - - _onReviewClick = async () => { - const cli = MatrixClientPeg.get(); - Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, { - userId: cli.getUserId(), - device: cli.getStoredDevice(cli.getUserId(), this.props.deviceId), - onFinished: (r) => { - if (!r) { - /* This'll come back false if the user clicks "this wasn't me" and saw a warning dialog */ - DeviceListener.sharedInstance().dismissUnverifiedSessions([this.props.deviceId]); - } - }, - }, null, /* priority = */ false, /* static = */ true); - }; - - render() { - const cli = MatrixClientPeg.get(); - const device = cli.getStoredDevice(cli.getUserId(), this.props.deviceId); - - return (
-
- {_t( - "Verify the new login accessing your account: %(name)s", { name: device.getDisplayName()})} -
-
- - -
-
); - } -} diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.tsx similarity index 86% rename from src/components/views/toasts/VerificationRequestToast.js rename to src/components/views/toasts/VerificationRequestToast.tsx index 421dd7bea1..38e7e31989 100644 --- a/src/components/views/toasts/VerificationRequestToast.js +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from 'react'; -import PropTypes from 'prop-types'; +import React from "react"; + import * as sdk from "../../../index"; import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; @@ -24,8 +24,23 @@ import {userLabelForEventRoom} from "../../../utils/KeyVerificationStateObserver import dis from "../../../dispatcher/dispatcher"; import ToastStore from "../../../stores/ToastStore"; import Modal from "../../../Modal"; +import GenericToast from "./GenericToast"; +import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; +import {DeviceInfo} from "matrix-js-sdk/src/crypto/deviceinfo"; + +interface IProps { + toastKey: string; + request: VerificationRequest; +} + +interface IState { + counter: number; + device?: DeviceInfo; +} + +export default class VerificationRequestToast extends React.PureComponent { + private intervalHandle: NodeJS.Timeout; -export default class VerificationRequestToast extends React.PureComponent { constructor(props) { super(props); this.state = {counter: Math.ceil(props.request.timeout / 1000)}; @@ -34,7 +49,7 @@ export default class VerificationRequestToast extends React.PureComponent { async componentDidMount() { const {request} = this.props; if (request.timeout && request.timeout > 0) { - this._intervalHandle = setInterval(() => { + this.intervalHandle = setInterval(() => { let {counter} = this.state; counter = Math.max(0, counter - 1); this.setState({counter}); @@ -56,7 +71,7 @@ export default class VerificationRequestToast extends React.PureComponent { } componentWillUnmount() { - clearInterval(this._intervalHandle); + clearInterval(this.intervalHandle); const {request} = this.props; request.off("change", this._checkRequestIsPending); } @@ -110,7 +125,6 @@ export default class VerificationRequestToast extends React.PureComponent { }; render() { - const FormButton = sdk.getComponent("elements.FormButton"); const {request} = this.props; let nameLabel; if (request.isSelfVerification) { @@ -133,20 +147,16 @@ export default class VerificationRequestToast extends React.PureComponent { } } } - const declineLabel = this.state.counter == 0 ? + const declineLabel = this.state.counter === 0 ? _t("Decline") : _t("Decline (%(counter)s)", {counter: this.state.counter}); - return (
-
{nameLabel}
-
- - -
-
); + + return ; } } - -VerificationRequestToast.propTypes = { - request: PropTypes.object.isRequired, - toastKey: PropTypes.string.isRequired, -}; diff --git a/src/toasts/BulkUnverifiedSessionsToast.ts b/src/toasts/BulkUnverifiedSessionsToast.ts new file mode 100644 index 0000000000..41717e0804 --- /dev/null +++ b/src/toasts/BulkUnverifiedSessionsToast.ts @@ -0,0 +1,58 @@ +/* +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 { _t } from '../languageHandler'; +import dis from "../dispatcher/dispatcher"; +import { MatrixClientPeg } from '../MatrixClientPeg'; +import DeviceListener from '../DeviceListener'; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; + +const TOAST_KEY = "reviewsessions"; + +export const showToast = (deviceIds: Set) => { + const onAccept = () => { + DeviceListener.sharedInstance().dismissUnverifiedSessions(deviceIds); + + dis.dispatch({ + action: 'view_user_info', + userId: MatrixClientPeg.get().getUserId(), + }); + }; + + const onReject = () => { + DeviceListener.sharedInstance().dismissUnverifiedSessions(deviceIds); + }; + + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Review where you’re logged in"), + icon: "verification_warning", + props: { + description: _t("Verify all your sessions to ensure your account & messages are safe"), + acceptLabel: _t("Review"), + onAccept, + rejectLabel: _t("Later"), + onReject, + }, + component: GenericToast, + priority: 50, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; diff --git a/src/toasts/SetupEncryptionToast.ts b/src/toasts/SetupEncryptionToast.ts new file mode 100644 index 0000000000..d35bbf1c88 --- /dev/null +++ b/src/toasts/SetupEncryptionToast.ts @@ -0,0 +1,106 @@ +/* +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 Modal from "../Modal"; +import * as sdk from "../index"; +import { _t } from "../languageHandler"; +import DeviceListener from "../DeviceListener"; +import SetupEncryptionDialog from "../components/views/dialogs/SetupEncryptionDialog"; +import { accessSecretStorage } from "../CrossSigningManager"; +import ToastStore from "../stores/ToastStore"; +import GenericToast from "../components/views/toasts/GenericToast"; + +const TOAST_KEY = "setupencryption"; + +const getTitle = (kind: Kind) => { + switch (kind) { + case Kind.SET_UP_ENCRYPTION: + return _t("Set up encryption"); + case Kind.UPGRADE_ENCRYPTION: + return _t("Encryption upgrade available"); + case Kind.VERIFY_THIS_SESSION: + return _t("Verify this session"); + } +}; + +const getSetupCaption = (kind: Kind) => { + switch (kind) { + case Kind.SET_UP_ENCRYPTION: + return _t("Set up"); + case Kind.UPGRADE_ENCRYPTION: + return _t("Upgrade"); + case Kind.VERIFY_THIS_SESSION: + return _t("Verify"); + } +}; + +const getDescription = (kind: Kind) => { + switch (kind) { + case Kind.SET_UP_ENCRYPTION: + case Kind.UPGRADE_ENCRYPTION: + return _t("Verify yourself & others to keep your chats safe"); + case Kind.VERIFY_THIS_SESSION: + return _t("Other users may not trust it"); + } +}; + +export enum Kind { + SET_UP_ENCRYPTION = "set_up_encryption", + UPGRADE_ENCRYPTION = "upgrade_encryption", + VERIFY_THIS_SESSION = "verify_this_session", +} + +const onReject = () => { + DeviceListener.sharedInstance().dismissEncryptionSetup(); +}; + +export const showToast = (kind: Kind) => { + const onAccept = async () => { + if (kind === Kind.VERIFY_THIS_SESSION) { + Modal.createTrackedDialog("Verify session", "Verify session", SetupEncryptionDialog, + {}, null, /* priority = */ false, /* static = */ true); + } else { + const Spinner = sdk.getComponent("elements.Spinner"); + const modal = Modal.createDialog( + Spinner, null, "mx_Dialog_spinner", /* priority */ false, /* static */ true, + ); + try { + await accessSecretStorage(); + } finally { + modal.close(); + } + } + }; + + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: getTitle(kind), + icon: "verification_warning", + props: { + description: getDescription(kind), + acceptLabel: getSetupCaption(kind), + onAccept, + rejectLabel: _t("Later"), + onReject, + }, + component: GenericToast, + priority: kind === Kind.VERIFY_THIS_SESSION ? 95 : 40, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts new file mode 100644 index 0000000000..635356b9db --- /dev/null +++ b/src/toasts/UnverifiedSessionToast.ts @@ -0,0 +1,70 @@ +/* +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 { _t } from '../languageHandler'; +import { MatrixClientPeg } from '../MatrixClientPeg'; +import Modal from '../Modal'; +import DeviceListener from '../DeviceListener'; +import NewSessionReviewDialog from '../components/views/dialogs/NewSessionReviewDialog'; +import ToastStore from "../stores/ToastStore"; +import GenericToast from "../components/views/toasts/GenericToast"; + +function toastKey(deviceId: string) { + return "unverified_session_" + deviceId; +} + +export const showToast = (deviceId: string) => { + const cli = MatrixClientPeg.get(); + + const onAccept = () => { + Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, { + userId: cli.getUserId(), + device: cli.getStoredDevice(cli.getUserId(), deviceId), + onFinished: (r) => { + if (!r) { + /* This'll come back false if the user clicks "this wasn't me" and saw a warning dialog */ + DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); + } + }, + }, null, /* priority = */ false, /* static = */ true); + }; + + const onReject = () => { + DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); + }; + + const device = cli.getStoredDevice(cli.getUserId(), deviceId); + + ToastStore.sharedInstance().addOrReplaceToast({ + key: toastKey(deviceId), + title: _t("New login. Was this you?"), + icon: "verification_warning", + props: { + description: _t( + "Verify the new login accessing your account: %(name)s", { name: device.getDisplayName()}), + acceptLabel: _t("Verify"), + onAccept, + rejectLabel: _t("Later"), + onReject, + }, + component: GenericToast, + priority: 80, + }); +}; + +export const hideToast = (deviceId: string) => { + ToastStore.sharedInstance().dismissToast(deviceId); +}; From a822ab49d5e9dbc2ead9d3a828b211bce3d4e053 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 13:40:30 +0100 Subject: [PATCH 052/332] i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/en_EN.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 96ccf1589d..8ac05bf429 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -102,11 +102,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", - "Verify this session": "Verify this session", - "Encryption upgrade available": "Encryption upgrade available", - "Set up encryption": "Set up encryption", - "Review where you’re logged in": "Review where you’re logged in", - "New login. Was this you?": "New login. Was this you?", "Who would you like to add to this community?": "Who would you like to add to this community?", "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID", "Invite new community members": "Invite new community members", @@ -396,6 +391,20 @@ "Common names and surnames are easy to guess": "Common names and surnames are easy to guess", "Straight rows of keys are easy to guess": "Straight rows of keys are easy to guess", "Short keyboard patterns are easy to guess": "Short keyboard patterns are easy to guess", + "Review where you’re logged in": "Review where you’re logged in", + "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", + "Review": "Review", + "Later": "Later", + "Set up encryption": "Set up encryption", + "Encryption upgrade available": "Encryption upgrade available", + "Verify this session": "Verify this session", + "Set up": "Set up", + "Upgrade": "Upgrade", + "Verify": "Verify", + "Verify yourself & others to keep your chats safe": "Verify yourself & others to keep your chats safe", + "Other users may not trust it": "Other users may not trust it", + "New login. Was this you?": "New login. Was this you?", + "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", "There was an error joining the room": "There was an error joining the room", "Sorry, your homeserver is too old to participate in this room.": "Sorry, your homeserver is too old to participate in this room.", "Please contact your homeserver administrator.": "Please contact your homeserver administrator.", @@ -570,15 +579,6 @@ "Headphones": "Headphones", "Folder": "Folder", "Pin": "Pin", - "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", - "Later": "Later", - "Review": "Review", - "Verify yourself & others to keep your chats safe": "Verify yourself & others to keep your chats safe", - "Other users may not trust it": "Other users may not trust it", - "Set up": "Set up", - "Upgrade": "Upgrade", - "Verify": "Verify", - "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", "From %(deviceName)s (%(deviceId)s)": "From %(deviceName)s (%(deviceId)s)", "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", From c464abaa498df44ea6d0366c64eec6be7afa4556 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 14:28:01 +0100 Subject: [PATCH 053/332] Iterate toast count indicator more logically Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/ToastContainer.tsx | 14 +++++++++++--- src/stores/ToastStore.ts | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/structures/ToastContainer.tsx b/src/components/structures/ToastContainer.tsx index 9440aa3463..c7b8e911d3 100644 --- a/src/components/structures/ToastContainer.tsx +++ b/src/components/structures/ToastContainer.tsx @@ -15,12 +15,12 @@ limitations under the License. */ import * as React from "react"; -import { _t } from '../../languageHandler'; import ToastStore, {IToast} from "../../stores/ToastStore"; import classNames from "classnames"; interface IState { toasts: IToast[]; + countSeen: number; } export default class ToastContainer extends React.Component<{}, IState> { @@ -28,6 +28,7 @@ export default class ToastContainer extends React.Component<{}, IState> { super(props, context); this.state = { toasts: ToastStore.sharedInstance().getToasts(), + countSeen: 0, }; // Start listening here rather than in componentDidMount because @@ -42,7 +43,10 @@ export default class ToastContainer extends React.Component<{}, IState> { } _onToastStoreUpdate = () => { - this.setState({toasts: ToastStore.sharedInstance().getToasts()}); + this.setState({ + toasts: ToastStore.sharedInstance().getToasts(), + countSeen: ToastStore.sharedInstance().getCountSeen(), + }); }; render() { @@ -56,7 +60,11 @@ export default class ToastContainer extends React.Component<{}, IState> { "mx_Toast_hasIcon": icon, [`mx_Toast_icon_${icon}`]: icon, }); - const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null; + + let countIndicator; + if (isStacked || this.state.countSeen > 0) { + countIndicator = ` (${this.state.countSeen + 1}/${this.state.countSeen + totalCount})`; + } const toastProps = Object.assign({}, props, { key, diff --git a/src/stores/ToastStore.ts b/src/stores/ToastStore.ts index 4f6d2963c5..b6b6f19872 100644 --- a/src/stores/ToastStore.ts +++ b/src/stores/ToastStore.ts @@ -32,6 +32,9 @@ export interface IToast[] = []; + // The count of toasts which have been seen & dealt with in this stack + // where the count resets when the stack of toasts clears. + private countSeen: number = 0; static sharedInstance() { if (!window.mx_ToastStore) window.mx_ToastStore = new ToastStore(); @@ -40,6 +43,7 @@ export default class ToastStore extends EventEmitter { reset() { this.toasts = []; + this.countSeen = 0; } /** @@ -67,6 +71,12 @@ export default class ToastStore extends EventEmitter { const length = this.toasts.length; this.toasts = this.toasts.filter(t => t.key !== key); if (length !== this.toasts.length) { + if (this.toasts.length === 0) { + this.countSeen = 0; + } else { + this.countSeen++; + } + this.emit('update'); } } @@ -74,4 +84,8 @@ export default class ToastStore extends EventEmitter { getToasts() { return this.toasts; } + + getCountSeen() { + return this.countSeen; + } } From 4e67e46863877a50e040dced1447970daa967cc5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 14:29:30 +0100 Subject: [PATCH 054/332] fix countSeen Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/ToastContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ToastContainer.tsx b/src/components/structures/ToastContainer.tsx index c7b8e911d3..c88c830d59 100644 --- a/src/components/structures/ToastContainer.tsx +++ b/src/components/structures/ToastContainer.tsx @@ -28,7 +28,7 @@ export default class ToastContainer extends React.Component<{}, IState> { super(props, context); this.state = { toasts: ToastStore.sharedInstance().getToasts(), - countSeen: 0, + countSeen: ToastStore.sharedInstance().getCountSeen(), }; // Start listening here rather than in componentDidMount because From 49c0748990b00be04520bfb85b2a79589b32cb34 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 14:32:41 +0100 Subject: [PATCH 055/332] delint and i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/en_EN.json | 1 - src/stores/ToastStore.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8ac05bf429..812ce826fc 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2083,7 +2083,6 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", - " (1/%(totalCount)s)": " (1/%(totalCount)s)", "Guest": "Guest", "Your profile": "Your profile", "Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others", diff --git a/src/stores/ToastStore.ts b/src/stores/ToastStore.ts index b6b6f19872..89b4dc2dc1 100644 --- a/src/stores/ToastStore.ts +++ b/src/stores/ToastStore.ts @@ -34,7 +34,7 @@ export default class ToastStore extends EventEmitter { private toasts: IToast[] = []; // The count of toasts which have been seen & dealt with in this stack // where the count resets when the stack of toasts clears. - private countSeen: number = 0; + private countSeen = 0; static sharedInstance() { if (!window.mx_ToastStore) window.mx_ToastStore = new ToastStore(); From 8a1ace43dac126f146b7fd468a746dca00135457 Mon Sep 17 00:00:00 2001 From: XoseM Date: Fri, 22 May 2020 13:52:01 +0000 Subject: [PATCH 056/332] Translated using Weblate (Galician) Currently translated at 44.4% (1030 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 48eb1338b4..b297f23fd6 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -1026,5 +1026,20 @@ "Session already verified!": "A sesión xa está verificada!", "WARNING: Session already verified, but keys do NOT MATCH!": "AVISO: xa está verificada a sesión, pero as chaves NON CONCORDAN!", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "AVISO: FALLOU A VERIFICACIÓN DAS CHAVES! A chave de firma para %(userId)s na sesión %(deviceId)s é \"%(fprint)s\" que non concordan coa chave proporcionada \"%(fingerprint)s\". Esto podería significar que as túas comunicacións foron interceptadas!", - "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A chave de firma proporcionada concorda coa chave de firma recibida desde a sesión %(deviceId)s de %(userId)s. Sesión marcada como verificada." + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A chave de firma proporcionada concorda coa chave de firma recibida desde a sesión %(deviceId)s de %(userId)s. Sesión marcada como verificada.", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Se usas ou non a función 'breadcrumbs ' (avatares enriba da listaxe de salas)", + "Unbans user with given ID": "Desbloquea usuaria co ID dado", + "Verifies a user, session, and pubkey tuple": "Verifica unha usuaria, sesión e chave pública", + "Forces the current outbound group session in an encrypted room to be discarded": "Forza que se descarte a sesión de saída actual nunha sala cifrada", + "Sends the given message coloured as a rainbow": "Envía a mensaxe dada colorida como o arco da vella", + "Sends the given emote coloured as a rainbow": "Envía o emoji colorido como un arco da vella", + "Displays list of commands with usages and descriptions": "Mostra unha listaxe de comandos con usos e descricións", + "Displays information about a user": "Mostra información acerca da usuaria", + "Send a bug report with logs": "Envía un informe de fallos con rexistros", + "Opens chat with the given user": "Abre unha conversa coa usuaria", + "Sends a message to the given user": "Envía unha mensaxe a usuaria", + "%(senderName)s made no change.": "%(senderName)s non fixo cambios.", + "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s cambiou o nome da sala de %(oldRoomName)s a %(newRoomName)s.", + "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s actualizou esta sala.", + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s converteu en pública a sala para calquera que teña a ligazón." } From 24c379119644ece7dce72e1618cb4bdc45da7b31 Mon Sep 17 00:00:00 2001 From: XoseM Date: Fri, 22 May 2020 13:57:33 +0000 Subject: [PATCH 057/332] Translated using Weblate (Galician) Currently translated at 44.4% (1030 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index b297f23fd6..5b7dd05251 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -1041,5 +1041,6 @@ "%(senderName)s made no change.": "%(senderName)s non fixo cambios.", "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s cambiou o nome da sala de %(oldRoomName)s a %(newRoomName)s.", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s actualizou esta sala.", - "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s converteu en pública a sala para calquera que teña a ligazón." + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s converteu en pública a sala para calquera que teña a ligazón.", + "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s fixo que a sala sexa só por convite." } From efb3dd2e25a390dfaba3825bb440b6daa18a85bd Mon Sep 17 00:00:00 2001 From: MamasLT Date: Fri, 22 May 2020 13:42:27 +0000 Subject: [PATCH 058/332] Translated using Weblate (Lithuanian) Currently translated at 48.7% (1131 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index c6f3abef0f..de8109913c 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -1161,5 +1161,9 @@ "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.": "Jūs buvote atjungtas iš visų sesijų ir nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, prisijunkite iš naujo kiekviename įrenginyje.", "Show more": "Rodyti daugiau", "Log in to your new account.": "Prisijunkite į savo naują paskyrą.", - "Registration Successful": "Registracija sėkminga" + "Registration Successful": "Registracija sėkminga", + "Welcome to %(appName)s": "Sveiki prisijungę į %(appName)s", + "Liberate your communication": "Išlaisvinkite savo bendravimą", + "Explore Public Rooms": "Žvalgyti viešus kambarius", + "Create a Group Chat": "Sukurti grupės pokalbį" } From 08fadb092c930cc25323bba29ec8f5979f4dd9e2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 21:43:15 +0100 Subject: [PATCH 059/332] Remove redundant component Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../settings/EnableNotificationsButton.js | 75 ------------------- 1 file changed, 75 deletions(-) delete mode 100644 src/components/views/settings/EnableNotificationsButton.js diff --git a/src/components/views/settings/EnableNotificationsButton.js b/src/components/views/settings/EnableNotificationsButton.js deleted file mode 100644 index e4b348dfbd..0000000000 --- a/src/components/views/settings/EnableNotificationsButton.js +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from "react"; -import createReactClass from 'create-react-class'; -import Notifier from "../../../Notifier"; -import dis from "../../../dispatcher/dispatcher"; -import { _t } from '../../../languageHandler'; - -export default createReactClass({ - displayName: 'EnableNotificationsButton', - - componentDidMount: function() { - this.dispatcherRef = dis.register(this.onAction); - }, - - componentWillUnmount: function() { - dis.unregister(this.dispatcherRef); - }, - - onAction: function(payload) { - if (payload.action !== "notifier_enabled") { - return; - } - this.forceUpdate(); - }, - - enabled: function() { - return Notifier.isEnabled(); - }, - - onClick: function() { - const self = this; - if (!Notifier.supportsDesktopNotifications()) { - return; - } - if (!Notifier.isEnabled()) { - Notifier.setEnabled(true, function() { - self.forceUpdate(); - }); - } else { - Notifier.setEnabled(false); - } - this.forceUpdate(); - }, - - render: function() { - if (this.enabled()) { - return ( - - ); - } else { - return ( - - ); - } - }, -}); From a977b8c4ca12570919a1cf5deceaf71652648510 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 21:55:43 +0100 Subject: [PATCH 060/332] Fix lifecycle to reset things before it starts them Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Lifecycle.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 22c5d48317..5fb54ede7f 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -575,10 +575,12 @@ async function startMatrixClient(startSyncing=true) { // to work). dis.dispatch({action: 'will_start_client'}, true); + // reset things first just in case + TypingStore.sharedInstance().reset(); + ToastStore.sharedInstance().reset(); + Notifier.start(); UserActivity.sharedInstance().start(); - TypingStore.sharedInstance().reset(); // just in case - ToastStore.sharedInstance().reset(); DMRoomMap.makeShared().start(); IntegrationManagers.sharedInstance().startWatching(); ActiveWidgetStore.start(); From 3732d1f5a5d0ad2fe22c73db924d612651967c79 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 21:56:25 +0100 Subject: [PATCH 061/332] Migrate Desktop Notifications MatrixToolbar to a Toast Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 15 +++--- src/components/structures/LoggedInView.tsx | 7 +-- src/components/structures/MatrixChat.tsx | 6 --- src/components/views/globals/MatrixToolbar.js | 45 ----------------- src/toasts/DesktopNotificationsToast.ts | 50 +++++++++++++++++++ 5 files changed, 60 insertions(+), 63 deletions(-) delete mode 100644 src/components/views/globals/MatrixToolbar.js create mode 100644 src/toasts/DesktopNotificationsToast.ts diff --git a/src/Notifier.js b/src/Notifier.js index 2ffa92452b..cc804904e2 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -26,6 +26,10 @@ import * as sdk from './index'; import { _t } from './languageHandler'; import Modal from './Modal'; import SettingsStore, {SettingLevel} from "./settings/SettingsStore"; +import { + showToast as showNotificationsToast, + hideToast as hideNotificationsToast, +} from "./toasts/DesktopNotificationsToast"; /* * Dispatches: @@ -184,6 +188,10 @@ const Notifier = { MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange); this.toolbarHidden = false; this.isSyncing = false; + + if (this.shouldShowToolbar()) { + showNotificationsToast(); + } }, stop: function() { @@ -278,12 +286,7 @@ const Notifier = { Analytics.trackEvent('Notifier', 'Set Toolbar Hidden', hidden); - // XXX: why are we dispatching this here? - // this is nothing to do with notifier_enabled - dis.dispatch({ - action: "notifier_enabled", - value: this.isEnabled(), - }); + hideNotificationsToast(); // update the info to localStorage for persistent settings if (persistent && global.localStorage) { diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 148d10fe8d..0d3eda759e 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -68,7 +68,6 @@ interface IProps { showCookieBar: boolean; hasNewVersion: boolean; userHasGeneratedPassword: boolean; - showNotifierToolbar: boolean; page_type: string; autoJoin: boolean; thirdPartyInvite?: object; @@ -184,8 +183,7 @@ class LoggedInView extends React.PureComponent { if ( (prevProps.showCookieBar !== this.props.showCookieBar) || (prevProps.hasNewVersion !== this.props.hasNewVersion) || - (prevState.userHasGeneratedPassword !== this.state.userHasGeneratedPassword) || - (prevProps.showNotifierToolbar !== this.props.showNotifierToolbar) + (prevState.userHasGeneratedPassword !== this.state.userHasGeneratedPassword) ) { this.props.resizeNotifier.notifyBannersChanged(); } @@ -599,7 +597,6 @@ class LoggedInView extends React.PureComponent { const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const ToastContainer = sdk.getComponent('structures.ToastContainer'); - const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); const CookieBar = sdk.getComponent('globals.CookieBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); @@ -680,8 +677,6 @@ class LoggedInView extends React.PureComponent { topBar = ; } else if (this.state.userHasGeneratedPassword) { topBar = ; - } else if (this.props.showNotifierToolbar) { - topBar = ; } let bodyClasses = 'mx_MatrixChat'; diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index e6a56c683f..120497e5ef 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -184,7 +184,6 @@ interface IState { hideToSRUsers: boolean; syncError?: Error; resizeNotifier: ResizeNotifier; - showNotifierToolbar: boolean; serverConfig?: ValidatedServerConfig; ready: boolean; thirdPartyInvite?: object; @@ -238,7 +237,6 @@ export default class MatrixChat extends React.PureComponent { syncError: null, // If the current syncing status is ERROR, the error object, otherwise null. resizeNotifier: new ResizeNotifier(), - showNotifierToolbar: false, ready: false, }; @@ -686,9 +684,6 @@ export default class MatrixChat extends React.PureComponent { dis.dispatch({action: 'view_my_groups'}); } break; - case 'notifier_enabled': - this.setState({showNotifierToolbar: Notifier.shouldShowToolbar()}); - break; case 'hide_left_panel': this.setState({ collapseLhs: true, @@ -1381,7 +1376,6 @@ export default class MatrixChat extends React.PureComponent { dis.dispatch({action: 'focus_composer'}); this.setState({ ready: true, - showNotifierToolbar: Notifier.shouldShowToolbar(), }); }); cli.on('Call.incoming', function(call) { diff --git a/src/components/views/globals/MatrixToolbar.js b/src/components/views/globals/MatrixToolbar.js deleted file mode 100644 index 758e4d62aa..0000000000 --- a/src/components/views/globals/MatrixToolbar.js +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import createReactClass from 'create-react-class'; -import { _t } from '../../../languageHandler'; -import Notifier from '../../../Notifier'; -import AccessibleButton from '../../../components/views/elements/AccessibleButton'; - -export default createReactClass({ - displayName: 'MatrixToolbar', - - hideToolbar: function() { - Notifier.setToolbarHidden(true); - }, - - onClick: function() { - Notifier.setEnabled(true); - }, - - render: function() { - return ( -
- -
- { _t('You are not receiving desktop notifications') } { _t('Enable them now') } -
- {_t('Close')} -
- ); - }, -}); diff --git a/src/toasts/DesktopNotificationsToast.ts b/src/toasts/DesktopNotificationsToast.ts new file mode 100644 index 0000000000..02f0730759 --- /dev/null +++ b/src/toasts/DesktopNotificationsToast.ts @@ -0,0 +1,50 @@ +/* +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 { _t } from "../languageHandler"; +import Notifier from "../Notifier"; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; + +const onAccept = () => { + Notifier.setEnabled(true); +}; + +const onReject = () => { + Notifier.setToolbarHidden(true); +}; + +const TOAST_KEY = "desktopnotifications"; + +export const showToast = () => { + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Notifications"), + props: { + description: _t("You are not receiving desktop notifications"), + acceptLabel: _t("Enable them now"), + onAccept, + rejectLabel: _t("Close"), + onReject, + }, + component: GenericToast, + priority: 20, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; From 89292ca47be3fc0a714024a708452452e9938ee6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:03:16 +0100 Subject: [PATCH 062/332] Fix toast priority sorting to put the highest priority into slot[0] Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/stores/ToastStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/ToastStore.ts b/src/stores/ToastStore.ts index 4f6d2963c5..23317a0ad3 100644 --- a/src/stores/ToastStore.ts +++ b/src/stores/ToastStore.ts @@ -55,7 +55,7 @@ export default class ToastStore extends EventEmitter { const oldIndex = this.toasts.findIndex(t => t.key === newToast.key); if (oldIndex === -1) { let newIndex = this.toasts.length; - while (newIndex > 0 && this.toasts[newIndex - 1].priority > newToast.priority) --newIndex; + while (newIndex > 0 && this.toasts[newIndex - 1].priority < newToast.priority) --newIndex; this.toasts.splice(newIndex, 0, newToast); } else { this.toasts[oldIndex] = newToast; From c91f8c2631799d92cc582dbe6eebcdec3e0a2cb4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:04:21 +0100 Subject: [PATCH 063/332] Migrate Analytics Banner to a Toast Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/LoggedInView.tsx | 9 -- src/components/structures/MatrixChat.tsx | 28 ++---- src/components/views/globals/CookieBar.js | 103 --------------------- src/i18n/strings/en_EN.json | 14 +-- src/toasts/AnalyticsToast.tsx | 75 +++++++++++++++ 5 files changed, 92 insertions(+), 137 deletions(-) delete mode 100644 src/components/views/globals/CookieBar.js create mode 100644 src/toasts/AnalyticsToast.tsx diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 0d3eda759e..88b64f0cbc 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -65,7 +65,6 @@ interface IProps { initialEventPixelOffset: number; leftDisabled: boolean; rightDisabled: boolean; - showCookieBar: boolean; hasNewVersion: boolean; userHasGeneratedPassword: boolean; page_type: string; @@ -181,7 +180,6 @@ class LoggedInView extends React.PureComponent { componentDidUpdate(prevProps, prevState) { // attempt to guess when a banner was opened or closed if ( - (prevProps.showCookieBar !== this.props.showCookieBar) || (prevProps.hasNewVersion !== this.props.hasNewVersion) || (prevState.userHasGeneratedPassword !== this.state.userHasGeneratedPassword) ) { @@ -597,7 +595,6 @@ class LoggedInView extends React.PureComponent { const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const ToastContainer = sdk.getComponent('structures.ToastContainer'); - const CookieBar = sdk.getComponent('globals.CookieBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar'); @@ -663,12 +660,6 @@ class LoggedInView extends React.PureComponent { adminContact={usageLimitEvent.getContent().admin_contact} limitType={usageLimitEvent.getContent().limit_type} />; - } else if (this.props.showCookieBar && - this.props.config.piwik && - navigator.doNotTrack !== "1" - ) { - const policyUrl = this.props.config.piwik.policyUrl || null; - topBar = ; } else if (this.props.hasNewVersion) { topBar = { newVersionReleaseNotes: null, checkingForUpdate: null, - showCookieBar: false, - hideToSRUsers: false, syncError: null, // If the current syncing status is ERROR, the error object, otherwise null. @@ -337,12 +338,6 @@ export default class MatrixChat extends React.PureComponent { }); } - if (SettingsStore.getValue("showCookieBar")) { - this.setState({ - showCookieBar: true, - }); - } - if (SettingsStore.getValue("analyticsOptIn")) { Analytics.enable(); } @@ -756,19 +751,13 @@ export default class MatrixChat extends React.PureComponent { case 'accept_cookies': SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, true); SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); - - this.setState({ - showCookieBar: false, - }); + hideAnalyticsToast(); Analytics.enable(); break; case 'reject_cookies': SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, false); SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); - - this.setState({ - showCookieBar: false, - }); + hideAnalyticsToast(); break; } }; @@ -1246,6 +1235,10 @@ export default class MatrixChat extends React.PureComponent { } StorageManager.tryPersistStorage(); + + if (SettingsStore.getValue("showCookieBar") && this.props.config.piwik && navigator.doNotTrack !== "1") { + showAnalyticsToast(this.props.config.piwik && this.props.config.piwik.policyUrl); + } } private showScreenAfterLogin() { @@ -2031,7 +2024,6 @@ export default class MatrixChat extends React.PureComponent { onCloseAllSettings={this.onCloseAllSettings} onRegistered={this.onRegistered} currentRoomId={this.state.currentRoomId} - showCookieBar={this.state.showCookieBar} /> ); } else { diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js deleted file mode 100644 index bf264686d0..0000000000 --- a/src/components/views/globals/CookieBar.js +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2018 New Vector Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import PropTypes from 'prop-types'; -import dis from '../../../dispatcher/dispatcher'; -import { _t } from '../../../languageHandler'; -import * as sdk from '../../../index'; -import Analytics from '../../../Analytics'; - -export default class CookieBar extends React.Component { - static propTypes = { - policyUrl: PropTypes.string, - } - - constructor() { - super(); - } - - onUsageDataClicked(e) { - e.stopPropagation(); - e.preventDefault(); - Analytics.showDetailsModal(); - } - - onAccept() { - dis.dispatch({ - action: 'accept_cookies', - }); - } - - onReject() { - dis.dispatch({ - action: 'reject_cookies', - }); - } - - render() { - const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); - const toolbarClasses = "mx_MatrixToolbar"; - return ( -
- -
- { this.props.policyUrl ? _t( - "Please help improve Riot.im by sending anonymous usage data. " + - "This will use a cookie " + - "(please see our Cookie Policy).", - {}, - { - 'UsageDataLink': (sub) => - { sub } - , - // XXX: We need to link to the page that explains our cookies - 'PolicyLink': (sub) => - { sub } - - , - }, - ) : _t( - "Please help improve Riot.im by sending anonymous usage data. " + - "This will use a cookie.", - {}, - { - 'UsageDataLink': (sub) => - { sub } - , - }, - ) } -
- - { _t("Yes, I want to help!") } - - - {_t('Close')} - -
- ); - } -} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8ac05bf429..a79ee97109 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -391,10 +391,17 @@ "Common names and surnames are easy to guess": "Common names and surnames are easy to guess", "Straight rows of keys are easy to guess": "Straight rows of keys are easy to guess", "Short keyboard patterns are easy to guess": "Short keyboard patterns are easy to guess", + "Notifications": "Notifications", + "Send anonymous usage data which helps us improve Riot. This will use a cookie.": "Send anonymous usage data which helps us improve Riot. This will use a cookie.", + "I want to help": "I want to help", + "No": "No", "Review where you’re logged in": "Review where you’re logged in", "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", "Review": "Review", "Later": "Later", + "You are not receiving desktop notifications": "You are not receiving desktop notifications", + "Enable them now": "Enable them now", + "Close": "Close", "Set up encryption": "Set up encryption", "Encryption upgrade available": "Encryption upgrade available", "Verify this session": "Verify this session", @@ -643,8 +650,6 @@ "Last seen": "Last seen", "Failed to set display name": "Failed to set display name", "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.", - "Disable Notifications": "Disable Notifications", - "Enable Notifications": "Enable Notifications", "Securely cache encrypted messages locally for them to appear in search results, using ": "Securely cache encrypted messages locally for them to appear in search results, using ", " to store messages from ": " to store messages from ", "rooms.": "rooms.", @@ -815,7 +820,6 @@ "Ban list rules - %(roomName)s": "Ban list rules - %(roomName)s", "Server rules": "Server rules", "User rules": "User rules", - "Close": "Close", "You have not ignored anyone.": "You have not ignored anyone.", "You are currently ignoring:": "You are currently ignoring:", "You are not subscribed to any lists": "You are not subscribed to any lists", @@ -836,7 +840,6 @@ "If this isn't what you want, please use a different tool to ignore users.": "If this isn't what you want, please use a different tool to ignore users.", "Room ID or alias of ban list": "Room ID or alias of ban list", "Subscribe": "Subscribe", - "Notifications": "Notifications", "Start automatically after system login": "Start automatically after system login", "Always show the window menu bar": "Always show the window menu bar", "Show tray icon and minimize window to it on close": "Show tray icon and minimize window to it on close", @@ -1287,7 +1290,6 @@ "Verify by emoji": "Verify by emoji", "Almost there! Is your other session showing the same shield?": "Almost there! Is your other session showing the same shield?", "Almost there! Is %(displayName)s showing the same shield?": "Almost there! Is %(displayName)s showing the same shield?", - "No": "No", "Yes": "Yes", "Verify all users in a room to ensure it's secure.": "Verify all users in a room to ensure it's secure.", "In encrypted rooms, verify all users to ensure it’s secure.": "In encrypted rooms, verify all users to ensure it’s secure.", @@ -1384,8 +1386,6 @@ "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).": "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).", "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.": "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.", "Yes, I want to help!": "Yes, I want to help!", - "You are not receiving desktop notifications": "You are not receiving desktop notifications", - "Enable them now": "Enable them now", "What's New": "What's New", "Update": "Update", "What's new?": "What's new?", diff --git a/src/toasts/AnalyticsToast.tsx b/src/toasts/AnalyticsToast.tsx new file mode 100644 index 0000000000..5b53a903fe --- /dev/null +++ b/src/toasts/AnalyticsToast.tsx @@ -0,0 +1,75 @@ +/* +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 { _t } from "../languageHandler"; +import dis from "../dispatcher/dispatcher"; +import Analytics from "../Analytics"; +import AccessibleButton from "../components/views/elements/AccessibleButton"; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; + +const onAccept = () => { + dis.dispatch({ + action: 'accept_cookies', + }); +}; + +const onReject = () => { + dis.dispatch({ + action: "reject_cookies", + }); +}; + +const onUsageDataClicked = () => { + Analytics.showDetailsModal(); +}; + +const TOAST_KEY = "analytics"; + +export const showToast = (policyUrl?: string) => { + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Notifications"), + props: { + description: _t( + "Send anonymous usage data which helps us improve Riot. " + + "This will use a cookie.", + {}, + { + "UsageDataLink": (sub) => ( + { sub } + ), + // XXX: We need to link to the page that explains our cookies + "PolicyLink": (sub) => policyUrl ? ( + { sub } + ) : sub, + }, + ), + acceptLabel: _t("I want to help"), + onAccept, + rejectLabel: _t("No"), + onReject, + }, + component: GenericToast, + priority: 10, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; From 5d0040b8b36d1474db807748d1191844b424a569 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:15:22 +0100 Subject: [PATCH 064/332] Migrate Password Nag Bar Banner to a Toast Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/LoggedInView.tsx | 22 ++++---- .../views/globals/PasswordNagBar.js | 53 ------------------- src/toasts/SetPasswordToast.ts | 47 ++++++++++++++++ 3 files changed, 58 insertions(+), 64 deletions(-) delete mode 100644 src/components/views/globals/PasswordNagBar.js create mode 100644 src/toasts/SetPasswordToast.ts diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 88b64f0cbc..131e6a3867 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -43,6 +43,11 @@ import ResizeNotifier from "../../utils/ResizeNotifier"; import PlatformPeg from "../../PlatformPeg"; import { RoomListStoreTempProxy } from "../../stores/room-list/RoomListStoreTempProxy"; import { DefaultTagID } from "../../stores/room-list/models"; +import { + showToast as showSetPasswordToast, + hideToast as hideSetPasswordToast +} from "../../toasts/SetPasswordToast"; + // We need to fetch each pinned message individually (if we don't already have it) // so each pinned message may trigger a request. Limit the number per room for sanity. // NB. this is just for server notices rather than pinned messages in general. @@ -66,7 +71,6 @@ interface IProps { leftDisabled: boolean; rightDisabled: boolean; hasNewVersion: boolean; - userHasGeneratedPassword: boolean; page_type: string; autoJoin: boolean; thirdPartyInvite?: object; @@ -96,7 +100,6 @@ interface IState { syncErrorData: any; useCompactLayout: boolean; serverNoticeEvents: MatrixEvent[]; - userHasGeneratedPassword: boolean; } /** @@ -139,7 +142,6 @@ class LoggedInView extends React.PureComponent { this.state = { mouseDown: undefined, syncErrorData: undefined, - userHasGeneratedPassword: false, // use compact timeline view useCompactLayout: SettingsStore.getValue('useCompactLayout'), // any currently active server notice events @@ -180,8 +182,7 @@ class LoggedInView extends React.PureComponent { componentDidUpdate(prevProps, prevState) { // attempt to guess when a banner was opened or closed if ( - (prevProps.hasNewVersion !== this.props.hasNewVersion) || - (prevState.userHasGeneratedPassword !== this.state.userHasGeneratedPassword) + (prevProps.hasNewVersion !== this.props.hasNewVersion) ) { this.props.resizeNotifier.notifyBannersChanged(); } @@ -216,9 +217,11 @@ class LoggedInView extends React.PureComponent { }; _setStateFromSessionStore = () => { - this.setState({ - userHasGeneratedPassword: Boolean(this._sessionStore.getCachedPassword()), - }); + if (this._sessionStore.getCachedPassword()) { + showSetPasswordToast(); + } else { + hideSetPasswordToast(); + } }; _createResizer() { @@ -597,7 +600,6 @@ class LoggedInView extends React.PureComponent { const ToastContainer = sdk.getComponent('structures.ToastContainer'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); - const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar'); const ServerLimitBar = sdk.getComponent('globals.ServerLimitBar'); let pageElement; @@ -666,8 +668,6 @@ class LoggedInView extends React.PureComponent { />; } else if (this.props.checkingForUpdate) { topBar = ; - } else if (this.state.userHasGeneratedPassword) { - topBar = ; } let bodyClasses = 'mx_MatrixChat'; diff --git a/src/components/views/globals/PasswordNagBar.js b/src/components/views/globals/PasswordNagBar.js deleted file mode 100644 index 74735ca5ea..0000000000 --- a/src/components/views/globals/PasswordNagBar.js +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -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 createReactClass from 'create-react-class'; -import * as sdk from '../../../index'; -import Modal from '../../../Modal'; -import { _t } from '../../../languageHandler'; - -export default createReactClass({ - onUpdateClicked: function() { - const SetPasswordDialog = sdk.getComponent('dialogs.SetPasswordDialog'); - Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog); - }, - - render: function() { - const toolbarClasses = "mx_MatrixToolbar mx_MatrixToolbar_clickable"; - return ( -
- -
- { _t( - "To return to your account in future you need to set a password", - {}, - { 'u': (sub) => { sub } }, - ) } -
- -
- ); - }, -}); diff --git a/src/toasts/SetPasswordToast.ts b/src/toasts/SetPasswordToast.ts new file mode 100644 index 0000000000..88cc317978 --- /dev/null +++ b/src/toasts/SetPasswordToast.ts @@ -0,0 +1,47 @@ +/* +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 { _t } from "../languageHandler"; +import Modal from "../Modal"; +import SetPasswordDialog from "../components/views/dialogs/SetPasswordDialog"; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; + +const onAccept = () => { + Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog); +}; + +const TOAST_KEY = "setpassword"; + +export const showToast = () => { + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Set password"), + props: { + description: _t("To return to your account in future you need to set a password"), + acceptLabel: _t("Set Password"), + onAccept, + rejectLabel: _t("Later"), + onReject: hideToast, // it'll return on reload + }, + component: GenericToast, + priority: 60, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; From ccf9e6512341bb7395b1eba3841b0ce475379da5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:27:19 +0100 Subject: [PATCH 065/332] Migrate Server Limit Bar Banner to a Toast Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/LoggedInView.tsx | 56 ++++++----- .../views/globals/ServerLimitBar.js | 99 ------------------- src/toasts/ServerLimitToast.tsx | 50 ++++++++++ 3 files changed, 80 insertions(+), 125 deletions(-) delete mode 100644 src/components/views/globals/ServerLimitBar.js create mode 100644 src/toasts/ServerLimitToast.tsx diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 131e6a3867..edb2482aa3 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -47,6 +47,10 @@ import { showToast as showSetPasswordToast, hideToast as hideSetPasswordToast } from "../../toasts/SetPasswordToast"; +import { + showToast as showServerLimitToast, + hideToast as hideServerLimitToast +} from "../../toasts/ServerLimitToast"; // We need to fetch each pinned message individually (if we don't already have it) // so each pinned message may trigger a request. Limit the number per room for sanity. @@ -99,7 +103,6 @@ interface IState { }; syncErrorData: any; useCompactLayout: boolean; - serverNoticeEvents: MatrixEvent[]; } /** @@ -144,8 +147,6 @@ class LoggedInView extends React.PureComponent { syncErrorData: undefined, // use compact timeline view useCompactLayout: SettingsStore.getValue('useCompactLayout'), - // any currently active server notice events - serverNoticeEvents: [], }; // stash the MatrixClient in case we log out before we are unmounted @@ -293,6 +294,8 @@ class LoggedInView extends React.PureComponent { if (oldSyncState === 'PREPARED' && syncState === 'SYNCING') { this._updateServerNoticeEvents(); + } else { + this._calculateServerLimitToast(data); } }; @@ -303,11 +306,24 @@ class LoggedInView extends React.PureComponent { } }; + _calculateServerLimitToast(syncErrorData, usageLimitEventContent?) { + const error = syncErrorData && syncErrorData.error && syncErrorData.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED"; + if (error) { + usageLimitEventContent = syncErrorData.error.data; + } + + if (usageLimitEventContent) { + showServerLimitToast(usageLimitEventContent.limit_type, usageLimitEventContent.admin_contact, error); + } else { + hideServerLimitToast(); + } + } + _updateServerNoticeEvents = async () => { const roomLists = RoomListStoreTempProxy.getRoomLists(); if (!roomLists[DefaultTagID.ServerNotice]) return []; - const pinnedEvents = []; + const events = []; for (const room of roomLists[DefaultTagID.ServerNotice]) { const pinStateEvent = room.currentState.getStateEvents("m.room.pinned_events", ""); @@ -317,12 +333,18 @@ class LoggedInView extends React.PureComponent { for (const eventId of pinnedEventIds) { const timeline = await this._matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId, 0); const event = timeline.getEvents().find(ev => ev.getId() === eventId); - if (event) pinnedEvents.push(event); + if (event) events.push(event); } } - this.setState({ - serverNoticeEvents: pinnedEvents, + + const usageLimitEvent = events.find((e) => { + return ( + e && e.getType() === 'm.room.message' && + e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' + ); }); + + this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEvent && usageLimitEvent.getContent()); }; _onPaste = (ev) => { @@ -600,7 +622,6 @@ class LoggedInView extends React.PureComponent { const ToastContainer = sdk.getComponent('structures.ToastContainer'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); - const ServerLimitBar = sdk.getComponent('globals.ServerLimitBar'); let pageElement; @@ -644,25 +665,8 @@ class LoggedInView extends React.PureComponent { break; } - const usageLimitEvent = this.state.serverNoticeEvents.find((e) => { - return ( - e && e.getType() === 'm.room.message' && - e.getContent()['server_notice_type'] === 'm.server_notice.usage_limit_reached' - ); - }); - let topBar; - if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') { - topBar = ; - } else if (usageLimitEvent) { - topBar = ; - } else if (this.props.hasNewVersion) { + if (this.props.hasNewVersion) { topBar = ; diff --git a/src/components/views/globals/ServerLimitBar.js b/src/components/views/globals/ServerLimitBar.js deleted file mode 100644 index 7d414a2826..0000000000 --- a/src/components/views/globals/ServerLimitBar.js +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2018 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import PropTypes from 'prop-types'; -import createReactClass from 'create-react-class'; -import classNames from 'classnames'; -import { _td } from '../../../languageHandler'; -import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; - -export default createReactClass({ - propTypes: { - // 'hard' if the logged in user has been locked out, 'soft' if they haven't - kind: PropTypes.string, - adminContact: PropTypes.string, - // The type of limit that has been hit. - limitType: PropTypes.string.isRequired, - }, - - getDefaultProps: function() { - return { - kind: 'hard', - }; - }, - - render: function() { - const toolbarClasses = { - 'mx_MatrixToolbar': true, - }; - - let adminContact; - let limitError; - if (this.props.kind === 'hard') { - toolbarClasses['mx_MatrixToolbar_error'] = true; - - adminContact = messageForResourceLimitError( - this.props.limitType, - this.props.adminContact, - { - '': _td("Please contact your service administrator to continue using the service."), - }, - ); - limitError = messageForResourceLimitError( - this.props.limitType, - this.props.adminContact, - { - 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."), - '': _td("This homeserver has exceeded one of its resource limits."), - }, - ); - } else { - toolbarClasses['mx_MatrixToolbar_info'] = true; - adminContact = messageForResourceLimitError( - this.props.limitType, - this.props.adminContact, - { - '': _td("Please contact your service administrator to get this limit increased."), - }, - ); - limitError = messageForResourceLimitError( - this.props.limitType, - this.props.adminContact, - { - 'monthly_active_user': _td( - "This homeserver has hit its Monthly Active User limit so " + - "some users will not be able to log in.", - ), - '': _td( - "This homeserver has exceeded one of its resource limits so " + - "some users will not be able to log in.", - ), - }, - {'b': sub => {sub}}, - ); - } - return ( -
-
- {limitError} - {' '} - {adminContact} -
-
- ); - }, -}); diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx new file mode 100644 index 0000000000..f2de9e3499 --- /dev/null +++ b/src/toasts/ServerLimitToast.tsx @@ -0,0 +1,50 @@ +/* +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 { _t, _td } from "../languageHandler"; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; +import {messageForResourceLimitError} from "../utils/ErrorUtils"; + +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."), + '': _td("Your homeserver has exceeded one of its resource limits."), + }); + const contactText = messageForResourceLimitError(limitType, adminContact, { + '': _td("Contact your server admin."), + }); + + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Notifications"), + props: { + description: {errorText} {contactText}, + acceptLabel: _t("Ok"), + onAccept: hideToast, + }, + component: GenericToast, + priority: 20, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; From 29cfb47a83f5fc016f941a8387efb8f5a3e7463f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:29:09 +0100 Subject: [PATCH 066/332] fix copy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/toasts/AnalyticsToast.tsx | 2 +- src/toasts/ServerLimitToast.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/toasts/AnalyticsToast.tsx b/src/toasts/AnalyticsToast.tsx index 5b53a903fe..b186a65d9d 100644 --- a/src/toasts/AnalyticsToast.tsx +++ b/src/toasts/AnalyticsToast.tsx @@ -44,7 +44,7 @@ const TOAST_KEY = "analytics"; export const showToast = (policyUrl?: string) => { ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Notifications"), + title: _t("Help us improve Riot"), props: { description: _t( "Send anonymous usage data which helps us improve Riot. " + diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx index f2de9e3499..d35140be3d 100644 --- a/src/toasts/ServerLimitToast.tsx +++ b/src/toasts/ServerLimitToast.tsx @@ -34,14 +34,14 @@ export const showToast = (limitType: string, adminContact?: string, syncError?: ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Notifications"), + title: _t("Warning"), props: { description: {errorText} {contactText}, acceptLabel: _t("Ok"), onAccept: hideToast, }, component: GenericToast, - priority: 20, + priority: 70, }); }; From 9f060d113259d3cf22d5e9ee4f6a98eb91c0d5d7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 22:34:32 +0100 Subject: [PATCH 067/332] i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/en_EN.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a79ee97109..72c19587c8 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -391,7 +391,7 @@ "Common names and surnames are easy to guess": "Common names and surnames are easy to guess", "Straight rows of keys are easy to guess": "Straight rows of keys are easy to guess", "Short keyboard patterns are easy to guess": "Short keyboard patterns are easy to guess", - "Notifications": "Notifications", + "Help us improve Riot": "Help us improve Riot", "Send anonymous usage data which helps us improve Riot. This will use a cookie.": "Send anonymous usage data which helps us improve Riot. This will use a cookie.", "I want to help": "I want to help", "No": "No", @@ -399,9 +399,18 @@ "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", "Review": "Review", "Later": "Later", + "Notifications": "Notifications", "You are not receiving desktop notifications": "You are not receiving desktop notifications", "Enable them now": "Enable them now", "Close": "Close", + "Your homeserver has exceeded its user limit.": "Your homeserver has exceeded its user limit.", + "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", + "Ok": "Ok", + "Set password": "Set password", + "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", + "Set Password": "Set Password", "Set up encryption": "Set up encryption", "Encryption upgrade available": "Encryption upgrade available", "Verify this session": "Verify this session", @@ -781,7 +790,6 @@ "Account management": "Account management", "Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!", "Deactivate Account": "Deactivate Account", - "Warning": "Warning", "General": "General", "Discovery": "Discovery", "Deactivate account": "Deactivate account", @@ -1383,18 +1391,10 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", - "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).": "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).", - "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.": "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.", - "Yes, I want to help!": "Yes, I want to help!", "What's New": "What's New", "Update": "Update", "What's new?": "What's new?", "A new version of Riot is available.": "A new version of Riot is available.", - "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", - "Set Password": "Set Password", - "Please contact your service administrator to get this limit increased.": "Please contact your service administrator to get this limit increased.", - "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.": "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.", - "This homeserver has exceeded one of its resource limits so some users will not be able to log in.": "This homeserver has exceeded one of its resource limits so some users will not be able to log in.", "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", "Checking for an update...": "Checking for an update...", "No update available.": "No update available.", From 891ba1bbe3c34bf5651846d425c07d969fec7cb7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 23:08:45 +0100 Subject: [PATCH 068/332] Replace New Version Bar with a Toast discards the `new_version` dispatch Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/globals/_MatrixToolbar.scss | 4 - src/components/structures/LoggedInView.tsx | 11 +- src/components/structures/MatrixChat.tsx | 21 ---- src/components/views/globals/NewVersionBar.js | 108 ------------------ src/i18n/strings/en_EN.json | 10 +- src/toasts/UpdateToast.tsx | 90 +++++++++++++++ 6 files changed, 99 insertions(+), 145 deletions(-) delete mode 100644 src/components/views/globals/NewVersionBar.js create mode 100644 src/toasts/UpdateToast.tsx diff --git a/res/css/views/globals/_MatrixToolbar.scss b/res/css/views/globals/_MatrixToolbar.scss index 5fdf572f99..07b92a7235 100644 --- a/res/css/views/globals/_MatrixToolbar.scss +++ b/res/css/views/globals/_MatrixToolbar.scss @@ -67,7 +67,3 @@ limitations under the License. .mx_MatrixToolbar_action { margin-right: 16px; } - -.mx_MatrixToolbar_changelog { - white-space: pre; -} diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index edb2482aa3..2a17233ec6 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -74,7 +74,6 @@ interface IProps { initialEventPixelOffset: number; leftDisabled: boolean; rightDisabled: boolean; - hasNewVersion: boolean; page_type: string; autoJoin: boolean; thirdPartyInvite?: object; @@ -96,6 +95,7 @@ interface IProps { newVersion?: string; newVersionReleaseNotes?: string; } + interface IState { mouseDown?: { x: number; @@ -183,7 +183,7 @@ class LoggedInView extends React.PureComponent { componentDidUpdate(prevProps, prevState) { // attempt to guess when a banner was opened or closed if ( - (prevProps.hasNewVersion !== this.props.hasNewVersion) + (prevProps.checkingForUpdate !== this.props.checkingForUpdate) ) { this.props.resizeNotifier.notifyBannersChanged(); } @@ -620,7 +620,6 @@ class LoggedInView extends React.PureComponent { const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const ToastContainer = sdk.getComponent('structures.ToastContainer'); - const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); let pageElement; @@ -666,11 +665,7 @@ class LoggedInView extends React.PureComponent { } let topBar; - if (this.props.hasNewVersion) { - topBar = ; - } else if (this.props.checkingForUpdate) { + if (this.props.checkingForUpdate) { topBar = ; } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index c69911fe04..f4d31708fe 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -173,10 +173,6 @@ interface IState { leftDisabled: boolean; middleDisabled: boolean; // the right panel's disabled state is tracked in its store. - version?: string; - newVersion?: string; - hasNewVersion: boolean; - newVersionReleaseNotes?: string; checkingForUpdate?: string; // updateCheckStatusEnum // Parameters used in the registration dance with the IS register_client_secret?: string; @@ -230,7 +226,6 @@ export default class MatrixChat extends React.PureComponent { leftDisabled: false, middleDisabled: false, - hasNewVersion: false, newVersionReleaseNotes: null, checkingForUpdate: null, @@ -726,12 +721,6 @@ export default class MatrixChat extends React.PureComponent { case 'client_started': this.onClientStarted(); break; - case 'new_version': - this.onVersion( - payload.currentVersion, payload.newVersion, - payload.releaseNotes, - ); - break; case 'check_updates': this.setState({ checkingForUpdate: payload.value }); break; @@ -1820,16 +1809,6 @@ export default class MatrixChat extends React.PureComponent { this.showScreen("settings"); }; - onVersion(current: string, latest: string, releaseNotes?: string) { - this.setState({ - version: current, - newVersion: latest, - hasNewVersion: current !== latest, - newVersionReleaseNotes: releaseNotes, - checkingForUpdate: null, - }); - } - onSendEvent(roomId: string, event: MatrixEvent) { const cli = MatrixClientPeg.get(); if (!cli) { diff --git a/src/components/views/globals/NewVersionBar.js b/src/components/views/globals/NewVersionBar.js deleted file mode 100644 index dedccdc6b6..0000000000 --- a/src/components/views/globals/NewVersionBar.js +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import PropTypes from 'prop-types'; -import createReactClass from 'create-react-class'; -import * as sdk from '../../../index'; -import Modal from '../../../Modal'; -import PlatformPeg from '../../../PlatformPeg'; -import { _t } from '../../../languageHandler'; - -/** - * Check a version string is compatible with the Changelog - * dialog ([vectorversion]-react-[react-sdk-version]-js-[js-sdk-version]) - */ -function checkVersion(ver) { - const parts = ver.split('-'); - return parts.length == 5 && parts[1] == 'react' && parts[3] == 'js'; -} - -export default createReactClass({ - propTypes: { - version: PropTypes.string.isRequired, - newVersion: PropTypes.string.isRequired, - releaseNotes: PropTypes.string, - }, - - displayReleaseNotes: function(releaseNotes) { - const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog'); - Modal.createTrackedDialog('Display release notes', '', QuestionDialog, { - title: _t("What's New"), - description:
{releaseNotes}
, - button: _t("Update"), - onFinished: (update) => { - if (update && PlatformPeg.get()) { - PlatformPeg.get().installUpdate(); - } - }, - }); - }, - - displayChangelog: function() { - const ChangelogDialog = sdk.getComponent('dialogs.ChangelogDialog'); - Modal.createTrackedDialog('Display Changelog', '', ChangelogDialog, { - version: this.props.version, - newVersion: this.props.newVersion, - onFinished: (update) => { - if (update && PlatformPeg.get()) { - PlatformPeg.get().installUpdate(); - } - }, - }); - }, - - onUpdateClicked: function() { - PlatformPeg.get().installUpdate(); - }, - - render: function() { - let action_button; - // If we have release notes to display, we display them. Otherwise, - // we display the Changelog Dialog which takes two versions and - // automatically tells you what's changed (provided the versions - // are in the right format) - if (this.props.releaseNotes) { - action_button = ( - - ); - } else if (checkVersion(this.props.version) && checkVersion(this.props.newVersion)) { - action_button = ( - - ); - } else if (PlatformPeg.get()) { - action_button = ( - - ); - } - return ( -
- -
- {_t("A new version of Riot is available.")} -
- {action_button} -
- ); - }, -}); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 72c19587c8..0170aee17a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -421,6 +421,12 @@ "Other users may not trust it": "Other users may not trust it", "New login. Was this you?": "New login. Was this you?", "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", + "What's New": "What's New", + "Update": "Update", + "What's new?": "What's new?", + "Restart": "Restart", + "Upgrade your Riot": "Upgrade your Riot", + "A new version of Riot is available!": "A new version of Riot is available!", "There was an error joining the room": "There was an error joining the room", "Sorry, your homeserver is too old to participate in this room.": "Sorry, your homeserver is too old to participate in this room.", "Please contact your homeserver administrator.": "Please contact your homeserver administrator.", @@ -1391,10 +1397,6 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", - "What's New": "What's New", - "Update": "Update", - "What's new?": "What's new?", - "A new version of Riot is available.": "A new version of Riot is available.", "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", "Checking for an update...": "Checking for an update...", "No update available.": "No update available.", diff --git a/src/toasts/UpdateToast.tsx b/src/toasts/UpdateToast.tsx new file mode 100644 index 0000000000..3d4b55a4ff --- /dev/null +++ b/src/toasts/UpdateToast.tsx @@ -0,0 +1,90 @@ +/* +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 { _t } from "../languageHandler"; +import GenericToast from "../components/views/toasts/GenericToast"; +import ToastStore from "../stores/ToastStore"; +import QuestionDialog from "../components/views/dialogs/QuestionDialog"; +import ChangelogDialog from "../components/views/dialogs/ChangelogDialog"; +import PlatformPeg from "../PlatformPeg"; +import Modal from "../Modal"; + +const TOAST_KEY = "update"; + +/* + * Check a version string is compatible with the Changelog + * dialog ([riot-version]-react-[react-sdk-version]-js-[js-sdk-version]) + */ +function checkVersion(ver) { + const parts = ver.split('-'); + return parts.length === 5 && parts[1] === 'react' && parts[3] === 'js'; +} + +function installUpdate() { + PlatformPeg.get().installUpdate(); +} + +export const showToast = (version: string, newVersion: string, releaseNotes?: string) => { + let onAccept; + let acceptLabel = _t("What's new?"); + if (releaseNotes) { + onAccept = () => { + Modal.createTrackedDialog('Display release notes', '', QuestionDialog, { + title: _t("What's New"), + description:
{releaseNotes}
, + button: _t("Update"), + onFinished: (update) => { + if (update && PlatformPeg.get()) { + PlatformPeg.get().installUpdate(); + } + }, + }); + }; + } else if (checkVersion(version) && checkVersion(newVersion)) { + onAccept = () => { + Modal.createTrackedDialog('Display Changelog', '', ChangelogDialog, { + version, + newVersion, + onFinished: (update) => { + if (update && PlatformPeg.get()) { + PlatformPeg.get().installUpdate(); + } + }, + }); + }; + } else { + onAccept = installUpdate; + acceptLabel = _t("Restart"); + } + + ToastStore.sharedInstance().addOrReplaceToast({ + key: TOAST_KEY, + title: _t("Upgrade your Riot"), + props: { + description: _t("A new version of Riot is available!"), + acceptLabel, + onAccept, + }, + component: GenericToast, + priority: 20, + }); +}; + +export const hideToast = () => { + ToastStore.sharedInstance().dismissToast(TOAST_KEY); +}; From 41934268087fa0b9be828f1714eb4a5e3ab6f28a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 23:14:33 +0100 Subject: [PATCH 069/332] delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/LoggedInView.tsx | 3 --- src/components/structures/MatrixChat.tsx | 1 - 2 files changed, 4 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 2a17233ec6..df21768da5 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -91,9 +91,6 @@ interface IProps { currentUserId?: string; currentGroupId?: string; currentGroupIsNew?: boolean; - version?: string; - newVersion?: string; - newVersionReleaseNotes?: string; } interface IState { diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index f4d31708fe..e6db42af1d 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -226,7 +226,6 @@ export default class MatrixChat extends React.PureComponent { leftDisabled: false, middleDisabled: false, - newVersionReleaseNotes: null, checkingForUpdate: null, hideToSRUsers: false, From 3d2b56aecd38ea399f2666b688c4007438384411 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 May 2020 23:23:23 +0100 Subject: [PATCH 070/332] i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- 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 0170aee17a..97ada284b0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -421,9 +421,9 @@ "Other users may not trust it": "Other users may not trust it", "New login. Was this you?": "New login. Was this you?", "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", + "What's new?": "What's new?", "What's New": "What's New", "Update": "Update", - "What's new?": "What's new?", "Restart": "Restart", "Upgrade your Riot": "Upgrade your Riot", "A new version of Riot is available!": "A new version of Riot is available!", From fe03d02cf62b4656a47635dce28af58ef01f091d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 23 May 2020 08:43:15 +0100 Subject: [PATCH 071/332] Fix reacting to redactions Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/utils/EventUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/EventUtils.js b/src/utils/EventUtils.js index ac7ac8c9ec..6558a11ed4 100644 --- a/src/utils/EventUtils.js +++ b/src/utils/EventUtils.js @@ -31,7 +31,7 @@ export function isContentActionable(mxEvent) { // status is SENT before remote-echo, null after const isSent = !eventStatus || eventStatus === EventStatus.SENT; - if (isSent) { + if (isSent && !mxEvent.isRedacted()) { if (mxEvent.getType() === 'm.room.message') { const content = mxEvent.getContent(); if (content.msgtype && content.msgtype !== 'm.bad.encrypted' && content.hasOwnProperty('body')) { From 066dd4b61140b14db91d52ae63f8b59caa32c861 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 23 May 2020 08:48:28 +0100 Subject: [PATCH 072/332] Update Modular hosting link Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/auth/ModularServerConfig.js | 3 ++- src/components/views/auth/ServerTypeSelector.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/ModularServerConfig.js b/src/components/views/auth/ModularServerConfig.js index 1216202a23..591c30ee7c 100644 --- a/src/components/views/auth/ModularServerConfig.js +++ b/src/components/views/auth/ModularServerConfig.js @@ -23,7 +23,8 @@ import AutoDiscoveryUtils from "../../../utils/AutoDiscoveryUtils"; import * as ServerType from '../../views/auth/ServerTypeSelector'; import ServerConfig from "./ServerConfig"; -const MODULAR_URL = 'https://modular.im/?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication'; +const MODULAR_URL = 'https://modular.im/services/matrix-hosting-riot' + + '?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication'; // TODO: TravisR - Can this extend ServerConfig for most things? diff --git a/src/components/views/auth/ServerTypeSelector.js b/src/components/views/auth/ServerTypeSelector.js index fe29b7f76c..a8a1dda968 100644 --- a/src/components/views/auth/ServerTypeSelector.js +++ b/src/components/views/auth/ServerTypeSelector.js @@ -22,7 +22,8 @@ import classnames from 'classnames'; import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils"; import {makeType} from "../../../utils/TypeUtils"; -const MODULAR_URL = 'https://modular.im/?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication'; +const MODULAR_URL = 'https://modular.im/services/matrix-hosting-riot' + + '?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication'; export const FREE = 'Free'; export const PREMIUM = 'Premium'; From d29ba5b597db302a457bea0574603d93474c842d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 23 May 2020 09:02:35 +0100 Subject: [PATCH 073/332] fix priority sorting to highest first Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/stores/ToastStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/ToastStore.ts b/src/stores/ToastStore.ts index 4f6d2963c5..23317a0ad3 100644 --- a/src/stores/ToastStore.ts +++ b/src/stores/ToastStore.ts @@ -55,7 +55,7 @@ export default class ToastStore extends EventEmitter { const oldIndex = this.toasts.findIndex(t => t.key === newToast.key); if (oldIndex === -1) { let newIndex = this.toasts.length; - while (newIndex > 0 && this.toasts[newIndex - 1].priority > newToast.priority) --newIndex; + while (newIndex > 0 && this.toasts[newIndex - 1].priority < newToast.priority) --newIndex; this.toasts.splice(newIndex, 0, newToast); } else { this.toasts[oldIndex] = newToast; From 6a48b548897f2bca8925575e9e911209d06b1c8b Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 22 May 2020 14:08:58 +0000 Subject: [PATCH 074/332] Translated using Weblate (Basque) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 44 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 6548ea33d1..6624fa99bb 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -783,7 +783,7 @@ "Explore Account Data": "Miatu kontuaren datuak", "All messages (noisy)": "Mezu guztiak (ozen)", "Saturday": "Larunbata", - "I understand the risks and wish to continue": "Arriskua ulertzen dut eta jarraitu nahi dut", + "I understand the risks and wish to continue": "Arriskuak ulertzen ditut eta jarraitu nahi dut", "Direct Chat": "Txat zuzena", "The server may be unavailable or overloaded": "Zerbitzaria eskuraezin edo gainezka egon daiteke", "Reject": "Baztertu", @@ -2385,5 +2385,45 @@ "Please enter your recovery passphrase a second time to confirm.": "Sartu zure berreskuratze pasa-esaldia berriro baieztatzeko.", "Repeat your recovery passphrase...": "Errepikatu zure berreskuratze pasa-esaldia...", "Secure your backup with a recovery passphrase": "Babestu zure babeskopia berreskuratze pasa-esaldi batekin", - "Currently indexing: %(currentRoom)s": "Orain indexatzen: %(currentRoom)s" + "Currently indexing: %(currentRoom)s": "Orain indexatzen: %(currentRoom)s", + "Review where you’re logged in": "Berrikusi non hasi duzun saioa", + "New login. Was this you?": "Saio berria. Zu izan zara?", + "Opens chat with the given user": "Erabiltzailearekin txata irekitzen du", + "Sends a message to the given user": "Erabiltzaileari mezua bidaltzen dio", + "You signed in to a new session without verifying it:": "Saio berria hasi duzu hau egiaztatu gabe:", + "Verify your other session using one of the options below.": "Egiaztatu zure beste saioa beheko aukeretako batekin.", + "Font scaling": "Letren eskalatzea", + "Use the improved room list (in development - refresh to apply changes)": "Erabili gelen zerrenda hobetua (garapenean, freskatu aldaketak aplikatzedko)", + "Use IRC layout": "Erabili IRC diseinua", + "Font size": "Letra-tamaina", + "Custom font size": "Letra-tamaina pertsonalizatua", + "IRC display name width": "IRC-ko pantaila izenaren zabalera", + "Waiting for your other session to verify…": "Zure beste saioak egiaztatu bitartean zain…", + "Verify all your sessions to ensure your account & messages are safe": "Egiaztatu zure saio guztiak kontua eta mezuak seguru daudela bermatzeko", + "Verify the new login accessing your account: %(name)s": "Egiaztatu zure kontuan hasitako saio berria: %(name)s", + "Size must be a number": "Tamaina zenbaki bat izan behar da", + "Custom font size can only be between %(min)s pt and %(max)s pt": "Letra tamaina pertsonalizatua %(min)s pt eta %(max)s pt bitartean egon behar du", + "Use between %(min)s pt and %(max)s pt": "Erabili %(min)s pt eta %(max)s pt bitarteko balioa", + "Appearance": "Itxura", + "Where you’re logged in": "Non hasi duzun saioa", + "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Kudeatu azpiko saioen izenak eta hauek amaitu edo egiaztatu zure erabiltzaile-profilean.", + "Create room": "Sortu gela", + "You've successfully verified your device!": "Ongi egiaztatu duzu zure gailua!", + "Message deleted": "Mezu ezabatuta", + "Message deleted by %(name)s": "Mezua ezabatu du %(name)s erabiltzaileak", + "QR Code": "QR kodea", + "To continue, use Single Sign On to prove your identity.": "Jarraitzeko, erabili Single Sign On zure identitatea frogatzeko.", + "Confirm to continue": "Berretsi jarraitzeko", + "Click the button below to confirm your identity.": "Sakatu azpiko botoia zure identitatea frogatzeko.", + "Invite someone using their name, username (like ), email address or share this room.": "Gonbidatu norbait bere izena, erabiltzaile izena (esaterako ), e-mail helbidea erabiliz, edo partekatu gela hau.", + "Restoring keys from backup": "Gakoak babes-kopiatik berrezartzen", + "Fetching keys from server...": "Gakoak zerbitzaritik eskuratzen...", + "%(completed)s of %(total)s keys restored": "%(completed)s/%(total)s gako berreskuratuta", + "Keys restored": "Gakoak berreskuratuta", + "Successfully restored %(sessionCount)s keys": "%(sessionCount)s gako ongi berreskuratuta", + "Confirm encryption setup": "Berretsi zifratze ezarpena", + "Click the button below to confirm setting up encryption.": "Sakatu azpiko botoia zifratze-ezarpena berresteko.", + "Dismiss read marker and jump to bottom": "Baztertu irakurtze-marka eta jauzi beheraino", + "Jump to oldest unread message": "Jauzi irakurri gabeko mezu zaharrenera", + "Upload a file": "Igo fitxategia" } From 020a1841c711f310c260b595f22485fe41f88843 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 23 May 2020 05:16:28 +0000 Subject: [PATCH 075/332] Translated using Weblate (Bulgarian) Currently translated at 94.6% (2196 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 56 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 347823f95c..186fb7c6db 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2211,5 +2211,59 @@ "Invite someone using their name, username (like ), email address or share this room.": "Поканете някой посредством име, потребителско име (като ), имейл адрес или като споделите тази стая.", "You added a new session '%(displayName)s', which is requesting encryption keys.": "Добавихте нова сесия '%(displayName)s', която изисква ключове за шифроване.", "Your unverified session '%(displayName)s' is requesting encryption keys.": "Непотвърдената ви сесия '%(displayName)s' изисква ключове за шифроване.", - "Loading session info...": "Зареждане на информация за сесията..." + "Loading session info...": "Зареждане на информация за сесията...", + "Opens chat with the given user": "Отваря чат с дадения потребител", + "Sends a message to the given user": "Изпраща съобщение до дадения потребител", + "Font scaling": "Мащабиране на шрифта", + "Use the improved room list (in development - refresh to apply changes)": "Използвай подобрения списък със стаи (в процес на разработка - презаредете за да приложите промените)", + "Use IRC layout": "Използвай IRC изглед", + "Font size": "Размер на шрифта", + "Custom font size": "Собствен размер на шрифта", + "IRC display name width": "Ширина на IRC името", + "Waiting for your other session to verify…": "Изчакване другата сесията да потвърди…", + "Size must be a number": "Размера трябва да е число", + "Custom font size can only be between %(min)s pt and %(max)s pt": "Собствения размер на шрифта може да бъде единствено между %(min)s pt и %(max)s pt", + "Use between %(min)s pt and %(max)s pt": "Изберете между %(min)s pt и %(max)s pt", + "Appearance": "Изглед", + "Create room": "Създай стая", + "You've successfully verified your device!": "Успешно потвърдихте устройството си!", + "Message deleted": "Съобщението беше изтрито", + "Message deleted by %(name)s": "Съобщението беше изтрито от %(name)s", + "QR Code": "QR код", + "To continue, use Single Sign On to prove your identity.": "За да продължите, използвайте Single Sign On за да потвърдите самоличността си.", + "Confirm to continue": "Потвърдете за да продължите", + "Click the button below to confirm your identity.": "Кликнете бутона по-долу за да потвърдите самоличността си.", + "a new master key signature": "нов подпис на основния ключ", + "a new cross-signing key signature": "нов подпис на ключа за кръстосано-подписване", + "a device cross-signing signature": "подпис за кръстосано-подписване на устройства", + "a key signature": "подпис на ключ", + "Riot encountered an error during upload of:": "Riot срещна проблем при качването на:", + "Upload completed": "Качването завърши", + "Cancelled signature upload": "Отказано качване на подпис", + "Unable to upload": "Неуспешно качване", + "Signature upload success": "Успешно качване на подпис", + "Signature upload failed": "Неуспешно качване на подпис", + "Confirm by comparing the following with the User Settings in your other session:": "Потвърдете чрез сравняване на следното с Потребителски Настройки в другата ви сесия:", + "Confirm this user's session by comparing the following with their User Settings:": "Потвърдете сесията на този потребител чрез сравняване на следното с техните Потребителски Настройки:", + "If they don't match, the security of your communication may be compromised.": "Ако няма съвпадение, сигурността на комуникацията ви може би е компрометирана.", + "Your account is not secure": "Профилът ви не е защитен", + "Your password": "Паролата ви", + "This session, or the other session": "Тази сесия или другата сесия", + "The internet connection either session is using": "Интернет връзката, която сесиите използват", + "We recommend you change your password and recovery key in Settings immediately": "Препоръчваме веднага да промените паролата и ключа за възстановяване от Настройки", + "New session": "Нова сесия", + "Use this session to verify your new one, granting it access to encrypted messages:": "Използвайте тази сесия за да потвърдите новата, давайки й достъп до шифрованите съобщения:", + "If you didn’t sign in to this session, your account may be compromised.": "Ако не сте се вписвали в тази сесия, профила ви може би е бил компрометиран.", + "This wasn't me": "Не бях аз", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Това ще ви позволи да се върнете в профила си след излизането от него, както и да влизате от други сесии.", + "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "В момента блокирате непотвърдени сесии; за да изпратите съобщения до тях ще трябва да ги потвърдите.", + "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Препоръчваме да минете през процеса на потвърждение за всяка една сесия и да проверите дали принадлежи на собственика си, но ако желаете, може да изпратите съобщението и без потвърждение.", + "Room contains unknown sessions": "Стаята съдържа непознати сесии", + "\"%(RoomName)s\" contains sessions that you haven't seen before.": "\"%(RoomName)s\" съдържа сесии, които не сте виждали досега.", + "Unknown sessions": "Непознати сесии", + "Verify other session": "Потвърди другата сесия", + "Enter recovery passphrase": "Въведете парола за възстановяване", + "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Неуспешен достъп до секретното складиране. Потвърдете, че сте въвели правилната парола за възстановяване.", + "Warning: You should only do this on a trusted computer.": "Внимание: трябва да правите това само от доверен компютър.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Въведете паролата си за възстановяване за да достъпите защитената история на съобщенията и самоличността си за кръстосано-подписване за потвърждаване на другите сесии." } From e751b789aa533912db22ba4701c108d5d1880853 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 23 May 2020 00:42:05 +0000 Subject: [PATCH 076/332] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 7c55826005..9495c01db7 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2444,5 +2444,6 @@ "Size must be a number": "大小必須為數字", "Custom font size can only be between %(min)s pt and %(max)s pt": "自訂字型大小僅能為 %(min)s 點至 %(max)s 點間", "Use between %(min)s pt and %(max)s pt": "使用 %(min)s 點至 %(max)s 點間", - "Appearance": "外觀" + "Appearance": "外觀", + "Use the improved room list (in development - refresh to apply changes)": "使用改進的聊天室清單(開發中 - 重新整理以套用變更)" } From 77910d2d54e15d318c26c68297c81e9ff01edd43 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Fri, 22 May 2020 17:04:51 +0000 Subject: [PATCH 077/332] Translated using Weblate (Finnish) Currently translated at 94.5% (2195 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index bf2566990c..05bf538ff9 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -421,7 +421,7 @@ "Invite new community members": "Kutsu uusia jäseniä yhteisöön", "Invite to Community": "Kutsu yhteisöön", "Which rooms would you like to add to this community?": "Mitkä huoneet haluaisit lisätä tähän yhteisöön?", - "Show these rooms to non-members on the community page and room list?": "Näytetäänkö nämä huoneet ei-jäsenille yhteisön sivulla ja huonelistassa?", + "Show these rooms to non-members on the community page and room list?": "Näytetäänkö nämä huoneet ei-jäsenille yhteisön sivulla ja huoneluettelossa?", "Add rooms to the community": "Lisää huoneita tähän yhteisöön", "Room name or alias": "Huoneen nimi tai alias", "Add to community": "Lisää yhteisöön", @@ -1343,7 +1343,7 @@ "Deny": "Kiellä", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Tunnistimme dataa, joka on lähtöisin vanhasta Riotin versiosta. Tämä aiheuttaa toimintahäiriöitä osapuolten välisessä salauksessa vanhassa versiossa. Viestejä, jotka on salattu osapuolten välisellä salauksella vanhalla versiolla, ei välttämättä voida purkaa tällä versiolla. Tämä voi myös aiheuttaa epäonnistumisia viestien välityksessä tämän version kanssa. Jos kohtaat ongelmia, kirjaudu ulos ja takaisin sisään. Säilyttääksesi viestihistoriasi, vie salausavaimesi ja tuo ne uudelleen.", "Riot failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.": "Riot epäonnistui protokollalistan hakemisessa kotipalvelimelta. Kotipalvelin saattaa olla liian vanha tukeakseen kolmannen osapuolen verkkoja.", - "Riot failed to get the public room list.": "Riot epäonnistui julkisen huonelistan haussa.", + "Riot failed to get the public room list.": "Riot ei onnistunut hakemaan julkista huoneluetteloa.", "The homeserver may be unavailable or overloaded.": "Kotipalvelin saattaa olla saavuttamattomissa tai ylikuormitettuna.", "You have %(count)s unread notifications in a prior version of this room.|other": "Sinulla on %(count)s lukematonta ilmoitusta huoneen edellisessä versiossa.", "You have %(count)s unread notifications in a prior version of this room.|one": "Sinulla on %(count)s lukematon ilmoitus huoneen edellisessä versiossa.", @@ -1374,7 +1374,7 @@ "Set up Secure Messages": "Ota käyttöön salatut viestit", "Recovery Method Removed": "Palautustapa poistettu", "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.": "Jos et poistanut palautustapaa, hyökkääjä saattaa yrittää käyttää tiliäsi. Vaihda tilisi salasana ja aseta uusi palautustapa asetuksissa välittömästi.", - "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Käytätkö 'leivänmuruja' (kuvia huonelistan yläpuolella) vai et", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Käytätkö 'leivänmuruja' (kuvia huoneluettelon yläpuolella) vai et", "Replying With Files": "Tiedostoilla vastaaminen", "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Tiedostolla vastaaminen ei onnistu tällä erää. Haluatko ladata tiedoston vastaamatta?", "The file '%(fileName)s' failed to upload.": "Tiedoston '%(fileName)s' lataaminen ei onnistunut.", @@ -2033,7 +2033,7 @@ "Support adding custom themes": "Tue mukaututettujen teemojen lisäämistä", "Enable cross-signing to verify per-user instead of per-session (in development)": "Ota ristivarmennus käyttöön varmentaaksesi käyttäjät istuntojen sijaan (kehitysversio)", "Show rooms with unread notifications first": "Näytä ensin huoneet, joissa on lukemattomia viestejä", - "Show shortcuts to recently viewed rooms above the room list": "Näytä oikotiet viimeiseksi katsottuihin huoneisiin huonelistan yläpuolella", + "Show shortcuts to recently viewed rooms above the room list": "Näytä oikotiet viimeiseksi katsottuihin huoneisiin huoneluettelon yläpuolella", "Enable message search in encrypted rooms": "Ota viestihaku salausta käyttävissä huoneissa käyttöön", "Keep secret storage passphrase in memory for this session": "Pidä salavaraston salalause muistissa tämän istunnon ajan", "How fast should messages be downloaded.": "Kuinka nopeasti viestit pitäisi ladata.", @@ -2264,5 +2264,17 @@ "You've successfully verified your device!": "Olet onnistuneesti varmentanut laitteesi!", "You've successfully verified %(deviceName)s (%(deviceId)s)!": "Olet onnistuneesti varmentanut laitteen %(deviceName)s (%(deviceId)s)!", "You've successfully verified %(displayName)s!": "Olet varmentanut käyttäjän %(displayName)s!", - "Verified": "Varmennettu" + "Verified": "Varmennettu", + "Font size": "Fonttikoko", + "Custom font size": "Mukautettu fonttikoko", + "Size must be a number": "Koon täytyy olla luku", + "Custom font size can only be between %(min)s pt and %(max)s pt": "Mukautetun fonttikoon täytyy olla vähintään %(min)s pt ja enintään %(max)s pt", + "Use between %(min)s pt and %(max)s pt": "Käytä kokoa väliltä %(min)s pt ja %(max)s pt", + "Appearance": "Ulkoasu", + "You can’t disable this later. Bridges & most bots won’t work yet.": "Et voi poistaa tätä käytöstä jatkossa. Sillat ja useimmat botit eivät vielä toimi.", + "Navigate up/down in the room list": "Siirry huoneluettelossa ylöspäin/alaspäin", + "Select room from the room list": "Valitse huone huoneluettelosta", + "Previous/next unread room or DM": "Edellinen/seuraava lukematon huone tai yksityisviesti", + "Previous/next room or DM": "Edellinen/seuraava huone tai yksityisviesti", + "Toggle this dialog": "Tämä valintaikkuna päälle/pois" } From 9dcfe6db6a1bc8418bcdbb61d8d45f889c519eaa Mon Sep 17 00:00:00 2001 From: XoseM Date: Fri, 22 May 2020 13:57:50 +0000 Subject: [PATCH 078/332] Translated using Weblate (Galician) Currently translated at 46.2% (1073 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 69 ++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 5b7dd05251..99d68ca943 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -264,8 +264,8 @@ "Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s as %(dateTime)s", "No rooms to show": "Sen salas que mostrar", "Unnamed room": "Sala sen nome", - "World readable": "Visible por todos", - "Guests can join": "Convidados pódense unir", + "World readable": "Visible para todas", + "Guests can join": "Convidadas pódense unir", "Save": "Gardar", "(~%(count)s results)|other": "(~%(count)s resultados)", "(~%(count)s results)|one": "(~%(count)s resultado)", @@ -671,7 +671,7 @@ "Passphrase must not be empty": "A frase de paso non pode quedar baldeira", "Export room keys": "Exportar chaves da sala", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Este proceso permítelle exportar a un ficheiro local as chaves para as mensaxes que recibiu en salas cifradas. Posteriormente permitiralle importar as chaves en outro cliente Matrix no futuro, así o cliente poderá descifrar esas mensaxes.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "O ficheiro exportado permitiralle a calquera que poida lelo descifrar e cifrar mensaxes que vostede ve, así que debería ter coidado e gardalo de xeito seguro. Para axudarlle, debe introducir unha frase de paso aquí abaixo que será utilizada para cifrar os datos exportados. Só será posible importar os datos utilizando a mesma frase de paso.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "O ficheiro exportado permitiralle a calquera que poida lelo descifrar e cifrar mensaxes que ti ves, así que deberías ter coidado e gardalo de xeito seguro. Para axudarche, deberías escribir unha frase de paso aquí abaixo que será usada para cifrar os datos exportados. Só será posible importar os datos utilizando a mesma frase de paso.", "Enter passphrase": "Introduza a frase de paso", "Confirm passphrase": "Confirme a frase de paso", "Export": "Exportar", @@ -701,8 +701,8 @@ "Flair": "Popularidade", "Showing flair for these communities:": "Mostrar a popularidade destas comunidades:", "Display your community flair in rooms configured to show it.": "Mostrar a popularidade da túa comunidade nas salas configuradas para que a mostren.", - "Did you know: you can use communities to filter your Riot.im experience!": "Sabía que pode utilizar as comunidades para mellorar a súa experiencia con Riot.im!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Para establecer un filtro, arrastre un avatar da comunidade sobre o panel de filtros na parte esquerda da pantalla. Pode pulsar nun avatar no panel de filtrado en calquera momento para ver só salas e xente asociada a esa comunidade.", + "Did you know: you can use communities to filter your Riot.im experience!": "Sabías que podes usar as comunidades para filtrar a túa experiencia en Riot.im!", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Para establecer un filtro, arrastra un avatar da comunidade sobre o panel de filtros na parte esquerda da pantalla. Podes premer nun avatar no panel de filtrado en calquera momento para ver só salas e xente asociada a esa comunidade.", "Deops user with given id": "Degradar o usuario con esa ID", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Visto por %(displayName)s(%(userName)s en %(dateTime)s", "Code": "Código", @@ -711,7 +711,7 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Os cambios realizados a súa comunidade name e avatar poida que non os vexan outros usuarios ate dentro de 30 minutos.", "Join this community": "Únase a esta comunidade", "Leave this community": "Deixar esta comunidade", - "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.": "Si enviou un reporte de fallo a través de GitHub, os informes poden axudarnos a examinar o problema. Os informes de fallo conteñen datos do uso do aplicativo incluíndo o seu nome de usuaria, os IDs ou alcumes das salas e grupos que visitou e os nomes de usuaria de outras persoas. Non conteñen mensaxes.", + "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.": "Se enviaches un informe de fallo a través de GitHub, os informes poden axudarnos a examinar o problema. Os informes de fallo conteñen datos do uso da aplicación incluíndo o teu nome de usuaria, os IDs ou alcumes das salas e grupos que visitaches e os nomes de usuaria de outras persoas. Non conteñen mensaxes.", "Submit debug logs": "Enviar informes de depuración", "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de desenvolvemento", "Stickerpack": "Iconas", @@ -756,7 +756,7 @@ "Please set a password!": "Por favor estableza un contrasinal!", "You have successfully set a password!": "Mudou con éxito o seu contrasinal!", "An error occurred whilst saving your email notification preferences.": "Algo fallou mentres se gardaban as súas preferencias de notificación.", - "Explore Room State": "Explorar estado da sala", + "Explore Room State": "Ollar estado da sala", "Source URL": "URL fonte", "Messages sent by bot": "Mensaxes enviadas por bot", "Filter results": "Filtrar resultados", @@ -779,7 +779,7 @@ "Developer Tools": "Ferramentas para desenvolver", "Preparing to send logs": "Preparándose para enviar informe", "Remember, you can always set an email address in user settings if you change your mind.": "Lembre que sempre poderá poñer un enderezo de correo nos axustes de usuario se cambiase de idea.", - "Explore Account Data": "Explorar datos da conta", + "Explore Account Data": "Ollar datos da conta", "All messages (noisy)": "Todas as mensaxes (alto)", "Saturday": "Sábado", "I understand the risks and wish to continue": "Entendo os riscos e desexo continuar", @@ -868,9 +868,9 @@ "Share Link to User": "Compartir a ligazón co usuario", "Share room": "Compartir sala", "Muted Users": "Usuarios silenciados", - "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).": "Mellore Riot.im enviando os datos anónimos de uso. Iso suporá o emprego dunha cookie (véxase a nosa Política de Cookies).", - "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.": "Mellore Riot.im enviando o uso de datos anónimo. Iso usará unha cookie.", - "Yes, I want to help!": "Si, quero axuda", + "Please help improve Riot.im by sending anonymous usage data. This will use a cookie (please see our Cookie Policy).": "Axuda a mellorar Riot.im enviando os datos anónimos de uso. Usaremos unha cookie (le aquí a nosa Política de Cookies).", + "Please help improve Riot.im by sending anonymous usage data. This will use a cookie.": "Axuda a mellorar Riot.im enviando datos anónimos de uso. Esto usará unha cookie.", + "Yes, I want to help!": "Si, quero axudar!", "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.": "Iso fará que a súa deixe de ter uso de xeito permanente. Non poderá acceder e ninguén vai a poder volver a rexistrar esa mesma ID de usuario. Suporá que saía de todas as salas de conversas nas que estaba e eliminará os detalles da súa conta do servidores de identificación.Isto non se poderá desfacer", "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.": "Desactivando a súa conta non supón que por defecto esquezamos as súas mensaxes enviadas. Se quere que nos esquezamos das súas mensaxes, prema na caixa de embaixo.", "To continue, please enter your password:": "Para continuar introduza o seu contrasinal:", @@ -936,7 +936,7 @@ "Whether you're using Riot on a device where touch is the primary input mechanism": "Se estás conectada utilizando Riot nun dispositivo maiormente táctil", "Whether you're using Riot as an installed Progressive Web App": "Se estás a usar Riot como unha Progressive Web App instalada", "Your user agent": "User Agent do navegador", - "The information being sent to us to help make Riot better includes:": "Información que nos envías para mellorar Riot inclúe:", + "The information being sent to us to help make Riot better includes:": "A información que nos envías para mellorar Riot inclúe:", "Please install Chrome, Firefox, or Safari for the best experience.": "Instala Chrome, Firefox, ou Safari para ter unha mellor experiencia.", "Sign In or Create Account": "Conéctate ou Crea unha Conta", "Sign In": "Conectar", @@ -1042,5 +1042,48 @@ "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s cambiou o nome da sala de %(oldRoomName)s a %(newRoomName)s.", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s actualizou esta sala.", "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s converteu en pública a sala para calquera que teña a ligazón.", - "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s fixo que a sala sexa só por convite." + "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s fixo que a sala sexa só por convite.", + "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s cambiou a regra de participación a %(rule)s", + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s permite que as convidadas se unan a sala.", + "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s non permite que as convidadas se unan a sala.", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s cambiou acceso de convidada a %(rule)s", + "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s activou a popularidade para %(groups)s nesta sala.", + "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s desactivou a popularidade para %(groups)s nesta sala.", + "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s activou a popularidade para %(newGroups)s e desactivou a popularidade para %(oldGroups)s nesta sala.", + "Capitalization doesn't help very much": "Escribir con maiúsculas non axuda moito", + "Predictable substitutions like '@' instead of 'a' don't help very much": "Substitucións predecibles como '@' no lugar de 'a' non son de gran axuda", + "Group & filter rooms by custom tags (refresh to apply changes)": "Agrupar e filtrar salas con etiquetas personalizadas (actuliza para aplicar cambios)", + "Enable Community Filter Panel": "Activar o panel de Filtro de comunidades", + "General": "Xeral", + "Discovery": "Descubrir", + "Deactivate account": "Desactivar conta", + "For help with using Riot, click here.": "Para ter axuda con Riot, preme aquí.", + "For help with using Riot, click here or start a chat with our bot using the button below.": "Se precisas axuda usando Riot, preme aquí ou inicia unha conversa co noso bot usando o botón inferior.", + "Help & About": "Axuda & Acerca de", + "Security & Privacy": "Seguridade & Privacidade", + "Where you’re logged in": "Onde estás conectada", + "Change room name": "Cambiar nome da sala", + "Roles & Permissions": "Roles & Permisos", + "Room %(name)s": "Sala %(name)s", + "Recent rooms": "Salas recentes", + "Direct Messages": "Mensaxes Directas", + "Create room": "Crear sala", + "You can use /help to list available commands. Did you mean to send this as a message?": "Podes usar axuda para ver os comandos dispoñibles. ¿Querías mellor enviar esto como unha mensaxe?", + "Error updating flair": "Fallo ao actualizar popularidade", + "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Algo fallou cando se actualizaba a popularidade da sala. Pode ser un fallo temporal ou que o servidor non o permita.", + "Enter the name of a new server you want to explore.": "Escribe o nome do novo servidor que queres explorar.", + "If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.": "Se hai contexto que cres que axudaría a analizar o problema, como o que estabas a facer, ID da sala, ID da usuaria, etc., por favor inclúeo aquí.", + "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Para evitar informes duplicados, mira os informes existentes primeiro (e engade un +1) ou crea un novo informe se non o atopas.", + "Command Help": "Comando Axuda", + "To help us prevent this in future, please send us logs.": "Para axudarnos a previr esto no futuro, envíanos o rexistro.", + "Help": "Axuda", + "Explore Public Rooms": "Explorar Salas Públicas", + "Explore": "Explorar", + "Filter": "Filtrar", + "Filter rooms…": "Filtrar salas…", + "%(creator)s created and configured the room.": "%(creator)s creou e configurou a sala.", + "Explore rooms": "Explorar salas", + "General failure": "Fallo xeral", + "This homeserver does not support login using email address.": "Este servidor non soporta a conexión usando enderezos de email.", + "Clear room list filter field": "Baleirar o campo do filtro de salas" } From dd8c65eba2c2b880b632c18c82324580d45b87b9 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Fri, 22 May 2020 14:12:09 +0000 Subject: [PATCH 079/332] Translated using Weblate (Lithuanian) Currently translated at 52.8% (1227 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 154 +++++++++++++++++++++++++++++++-------- 1 file changed, 125 insertions(+), 29 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index de8109913c..9c6a1c9a7a 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -133,7 +133,7 @@ "Reject": "Atmesti", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Jūs turbūt juos sukonfigūravote kitoje programėlėje nei Riot. Negalite jų koreguoti Riot programėlėje, bet jie vistiek yra taikomi", "Sorry, your browser is not able to run Riot.": "Atleiskite, jūsų naršyklė negali paleisti Riot.", - "Quote": "Citata", + "Quote": "Cituoti", "Messages in group chats": "Žinutės grupės pokalbiuose", "Yesterday": "Vakar", "Error encountered (%(errorDetail)s).": "Susidurta su klaida (%(errorDetail)s).", @@ -287,14 +287,14 @@ "%(senderName)s sent an image": "%(senderName)s išsiuntė paveikslą", "%(senderName)s sent a video": "%(senderName)s išsiuntė vaizdo įrašą", "%(senderName)s uploaded a file": "%(senderName)s įkėlė failą", - "Options": "Parametrai", + "Options": "Parinktys", "Key request sent.": "Rakto užklausa išsiųsta.", "device id: ": "įrenginio id: ", "Failed to mute user": "Nepavyko nutildyti naudotoją", "Are you sure?": "Ar tikrai?", "Ignore": "Ignoruoti", "Invite": "Pakviesti", - "User Options": "Naudotojo parametrai", + "User Options": "Vartotojo parinktys", "Admin Tools": "Administratoriaus įrankiai", "Attachment": "Priedas", "Voice call": "Balso skambutis", @@ -375,8 +375,8 @@ "Sent messages will be stored until your connection has returned.": "Išsiųstos žinutės bus saugomos tol, kol atsiras ryšys.", "Active call": "Aktyvus skambutis", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Čia daugiau nieko nėra! Ar norėtumėte pakviesti kitus ar išjungti įspėjimą apie tuščią kambarį?", - "You seem to be uploading files, are you sure you want to quit?": "Atrodo, kad jūs įkelinėjate failus, ar tikrai norite išeiti?", - "You seem to be in a call, are you sure you want to quit?": "Atrodo, kad dalyvaujate skambutyje, ar tikrai norite išeiti?", + "You seem to be uploading files, are you sure you want to quit?": "Panašu, kad jūs įkelinėjate failus, ar tikrai norite išeiti?", + "You seem to be in a call, are you sure you want to quit?": "Panašu, kad jūs dalyvaujate skambutyje, ar tikrai norite išeiti?", "Search failed": "Paieška nepavyko", "Server may be unavailable, overloaded, or search timed out :(": "Gali būti, kad serveris neprieinamas, perkrautas arba pasibaigė paieškai skirtas laikas :(", "No more results": "Daugiau nėra jokių rezultatų", @@ -399,7 +399,7 @@ "": "", "Check for update": "Tikrinti, ar yra atnaujinimų", "Reject all %(invitedRooms)s invites": "Atmesti visus %(invitedRooms)s pakvietimus", - "You may need to manually permit Riot to access your microphone/webcam": "Jums gali tekti rankiniu būdu leisti Riot prieigą prie savo mikrofono/kameros", + "You may need to manually permit Riot to access your microphone/webcam": "Jums gali tekti rankiniu būdu duoti leidimą Riot prieigai prie mikrofono/kameros", "No Audio Outputs detected": "Neaptikta jokių garso išvesčių", "No Microphones detected": "Neaptikta jokių mikrofonų", "No Webcams detected": "Neaptikta jokių kamerų", @@ -421,7 +421,7 @@ "Return to login screen": "Grįžti į prisijungimą", "Send Reset Email": "Siųsti atstatymo el. laišką", "Incorrect username and/or password.": "Neteisingas vartotojo vardas ir/arba slaptažodis.", - "Please note you are logging into the %(hs)s server, not matrix.org.": "Turėkite omenyje, kad jūs prisijungiate prie %(hs)s serverio, o ne matrix.org.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Atkreipkite dėmesį, kad jūs jungiatės prie %(hs)s serverio, o ne matrix.org.", "Failed to fetch avatar URL": "Nepavyko gauti avataro URL", "Commands": "Komandos", "Results from DuckDuckGo": "Rezultatai iš DuckDuckGo", @@ -529,7 +529,7 @@ "Confirm password": "Patvirtinkite slaptažodį", "Demote yourself?": "Pažeminti save?", "Demote": "Pažeminti", - "Share Link to User": "Dalintis nuoroda į naudotoją", + "Share Link to User": "Dalintis nuoroda į vartotoją", "Direct chats": "Privatūs pokalbiai", "The conversation continues here.": "Pokalbis tęsiasi čia.", "Jump to message": "Pereiti prie žinutės", @@ -641,7 +641,7 @@ "And %(count)s more...|other": "Ir dar %(count)s...", "Existing Call": "Esamas skambutis", "A call is already in progress!": "Skambutis jau vyksta!", - "Default": "Numatytasis", + "Default": "Paprastas vartotojas", "Restricted": "Apribotas", "Moderator": "Moderatorius", "Ignores a user, hiding their messages from you": "Ignoruoja vartotoją, slepiant nuo jūsų jo žinutes", @@ -775,7 +775,7 @@ "Invite new community members": "Pakviesti naujus bendruomenės narius", "Name or Matrix ID": "Vardas arba Matrix ID", "Identity server has no terms of service": "Tapatybės serveris neturi paslaugų teikimo sąlygų", - "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Šiam veiksmui reikalinga prieiti numatytąjį tapatybės serverį , kad patvirtinti el. pašto adresą arba telefono numerį, bet serveris neturi jokių paslaugos teikimo sąlygų.", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Šiam veiksmui reikalinga pasiekti numatytąjį tapatybės serverį , kad patvirtinti el. pašto adresą arba telefono numerį, bet serveris neturi jokių paslaugos teikimo sąlygų.", "Only continue if you trust the owner of the server.": "Tęskite tik tada, jei pasitikite serverio savininku.", "Trust": "Pasitikėti", "Failed to invite users to the room:": "Nepavyko pakviesti vartotojų į kambarį:", @@ -897,7 +897,7 @@ "Filter": "Filtruoti", "Filter rooms…": "Filtruoti kambarius…", "This room is not public. You will not be able to rejoin without an invite.": "Šis kambarys nėra viešas. Jūs negalėsite prie jo vėl prisijungti be pakvietimo.", - "Are you sure you want to leave the room '%(roomName)s'?": "Ar tikrai norite palikti kambarį %(roomName)s?", + "Are you sure you want to leave the room '%(roomName)s'?": "Ar tikrai norite išeiti iš kambario %(roomName)s?", "%(creator)s created and configured the room.": "%(creator)s sukūrė ir sukonfigūravo kambarį.", "Riot failed to get the public room list.": "Riot nepavyko gauti viešų kambarių sąrašą.", "General failure": "Bendras triktis", @@ -939,12 +939,12 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ar tikrai norite pašalinti (ištrinti) šį įvykį? Atkreipkite dėmesį į tai, kad jei jūs ištrinsite kambario pavadinimo arba temos keitimo įvykį, tai gali atšaukti patį pakeitimą.", "We recommend you change your password and recovery key in Settings immediately": "Mes rekomenduojame nedelsiant Nustatymuose pasikeisti jūsų slaptažodį ir atgavimo raktą", "Email (optional)": "El. paštas (neprivaloma)", - "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.": "Jei jūs nenustatėte naujo paskyros atgavimo metodo, tada gali būti, kad užpuolikas bando patekti į jūsų paskyrą. Nedelsiant Nustatymuose pakeiskite savo paskyros slaptažodį ir nustatykite naują paskyros atgavimo metodą.", - "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.": "Jei jūs nepašalinote paskyros atgavimo metodo, tada gali būti, kad užpuolikas bando patekti į jūsų paskyrą. Nedelsiant Nustatymuose pakeiskite savo paskyros slaptažodį ir nustatykite naują paskyros atgavimo metodą.", + "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.": "Jei jūs nenustatėte naujo paskyros atgavimo metodo, gali būti, kad užpuolikas bando patekti į jūsų paskyrą. Nedelsiant nustatymuose pakeiskite savo paskyros slaptažodį ir nustatykite naują atgavimo metodą.", + "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.": "Jei jūs nepašalinote paskyros atgavimo metodo, gali būti, kad užpuolikas bando patekti į jūsų paskyrą. Nedelsiant nustatymuose pakeiskite savo paskyros slaptažodį ir nustatykite naują atgavimo metodą.", "Help & About": "Pagalba ir Apie", "Direct Messages": "Privačios žinutės", "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Nustatykite adresus šiam kambariui, kad vartotojai galėtų surasti šį kambarį per jūsų serverį (%(localDomain)s)", - "Direct message": "Privati žinutė", + "Direct message": "Siųsti tiesioginę žinutę", "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s prisijungė %(count)s kartų(-us)", "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s prisijungė", "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s prisijungė %(count)s kartų(-us)", @@ -990,7 +990,7 @@ "Custom level": "Pritaikytas lygis", "Can't find this server or its room list": "Negalime rasti šio serverio arba jo kambarių sąrašo", "Matrix rooms": "Matrix kambariai", - "Recently Direct Messaged": "Neseniai siųsta privati žinutė", + "Recently Direct Messaged": "Neseniai tiesiogiai susirašyta", "Command Help": "Komandų pagalba", "Help": "Pagalba", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Sukurkite bendruomenę, kad kartu sugrupuotumėte vartotojus ir kambarius! Sukurkite pagrindinį puslapį, kad pažymėtumėte savo vietą Matrix visatoje.", @@ -1064,7 +1064,7 @@ "Server Name": "Serverio Pavadinimas", "Other servers": "Kiti serveriai", "Add room": "Sukurti kambarį", - "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.": "Slaptažodžio keitimas ištrins visų jūsų seansų šifravimo raktus, todėl nebebus galima perskaityti užšifruotos pokalbių istorijos. Nustatykite Raktų Atsarginę Kopiją arba eksportuokite savo kambarių raktus iš kito seanso prieš atstatydami slaptažodį.", + "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.": "Slaptažodžio keitimas ištrins visų jūsų seansų šifravimo raktus, todėl nebebus galima perskaityti užšifruotos pokalbių istorijos. Sukurkite atsarginę raktų kopiją arba eksportuokite savo kambarių raktus iš kito seanso prieš atstatydami slaptažodį.", "Set a display name:": "Nustatyti rodomą vardą:", "Secure your encryption keys with a passphrase. For maximum security this should be different to your account password:": "Apsaugokite savo šifravimo raktus slaptafraze. Maksimaliam saugumui užtikrinti ji turi skirtis nuo jūsų paskyros slaptažodžio:", "Enter a passphrase": "Įveskite slaptafrazę", @@ -1082,13 +1082,13 @@ "Syncing...": "Sinchronizuojama...", "Signing In...": "Prijungiama...", "If you've joined lots of rooms, this might take a while": "Jei esate prisijungę prie daug kambarių, tai gali užtrukti", - "Without completing security on this session, it won’t have access to encrypted messages.": "Neužbaigus saugumo šioje sesijoje, ji neturės priėjimo prie šifruotų žinučių.", + "Without completing security on this session, it won’t have access to encrypted messages.": "Neužbaigus saugumo šiame seanse, jis neturės prieigos prie šifruotų žinučių.", "Set a recovery passphrase to secure encrypted information and recover it if you log out. This should be different to your account password:": "Nustatykite atgavimo slaptafrazę, kad apsaugotumėte šifruotą informaciją ir atgautumėte ją jei atsijungsite. Ji turi skirtis nuo jūsų paskyros slaptažodžio:", "Enter a recovery passphrase": "Įveskite atgavimo slaptafrazę", "Back up encrypted message keys": "Padaryti atsargines šifruotų žinučių raktų kopijas", "Set up with a recovery key": "Nustatyti su atgavimo raktu", "Enter your recovery passphrase a second time to confirm it.": "Įveskite atgavimo slaptafrazę antrą kartą, kad ją patvirtintumėte.", - "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Jūsų atgavimo raktas yra atsarginė saugumo priemonė - jūs galite jį naudoti priėjimo prie jūsų šifruotų žinučių atgavimui, jei pamiršite savo atgavimo slaptafrazę.", + "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Jūsų atgavimo raktas yra atsarginė saugumo priemonė - jūs galite jį naudoti prieigos prie jūsų šifruotų žinučių atgavimui, jei pamiršite savo atgavimo slaptafrazę.", "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Laikykite šio rakto kopiją saugioje vietoje, pavyzdžiui slaptažodžių tvarkyklėje arba seife.", "Your recovery key": "Jūsų atgavimo raktas", "Copy": "Kopijuoti", @@ -1105,9 +1105,9 @@ "Not now": "Ne dabar", "Don't ask me again": "Daugiau neklausti", "Send as message": "Siųsti kaip žinutę", - "Messages in this room are end-to-end encrypted.": "Žinutės šiame kambaryje yra užšifruotos visapusiu šifravimu.", - "Messages in this room are not end-to-end encrypted.": "Žinutės šiame kambaryje nėra užšifruotos visapusiu šifravimu.", - "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Žinutės šiame kambaryje yra užšifruotos visapusiu šifravimu. Sužinokite daugiau ir patvirtinkite šį vartotoją jų profilyje.", + "Messages in this room are end-to-end encrypted.": "Žinutės šiame kambaryje yra visapusiškai užšifruotos.", + "Messages in this room are not end-to-end encrypted.": "Žinutės šiame kambaryje nėra visapusiškai užšifruotos.", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Žinutės šiame kambaryje yra visapusiškai užšifruotos. Sužinokite daugiau ir patvirtinkite vartotojus jų profilyje.", "Confirm Removal": "Patvirtinkite pašalinimą", "Manually export keys": "Eksportuoti raktus rankiniu būdu", "Send a Direct Message": "Siųsti tiesioginę žinutę", @@ -1127,15 +1127,15 @@ "Homeserver URL": "Serverio URL", "Homeserver URL does not appear to be a valid Matrix homeserver": "Serverio adresas neatrodo esantis tinkamas Matrix serveris", "This homeserver does not support login using email address.": "Šis serveris nepalaiko prisijungimo naudojant el. pašto adresą.", - "Review Sessions": "Peržiūrėti sesijas", + "Review Sessions": "Peržiūrėti seansus", "Setting up keys": "Raktų nustatymas", "Review where you’re logged in": "Peržiūrėkite kur esate prisijungę", - "Verify all your sessions to ensure your account & messages are safe": "Patvirtinkite visas savo sesijas, kad užtikrintumėte savo paskyros ir žinučių saugumą", + "Verify all your sessions to ensure your account & messages are safe": "Patvirtinkite visus savo seansus, kad užtikrintumėte savo paskyros ir žinučių saugumą", "Review": "Peržiūrėti", "Message deleted": "Žinutė ištrinta", "Message deleted by %(name)s": "Žinutė, ištrinta %(name)s", "Warning: You should only do this on a trusted computer.": "Įspėjimas: Tai atlikite tik saugiame kompiuteryje.", - "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Prieikite prie savo saugių žinučių istorijos ir kryžminio parašo kitų sesijų patvirtinimui tapatybės įvesdami savo atgavimo slaptafrazę.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Pasiekite savo saugių žinučių istoriją ir kryžminio parašo tapatybę, naudojamą kitų seansų patvirtinimui, įvesdami savo atgavimo slaptafrazę.", "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus.", "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus", "Confirm your identity by entering your account password below.": "Patvirtinkite savo tapatybę žemiau įvesdami savo paskyros slaptažodį.", @@ -1154,16 +1154,112 @@ "You can now verify your other devices, and other users to keep your chats safe.": "Jūs dabar galite patvirtinti kitus savo įrenginius ir kitus vartotojus, kad jūsų pokalbiai būtų saugūs.", "Confirm recovery passphrase": "Patvirtinkite atgavimo slaptafrazę", "You're done!": "Atlikta!", - "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.": "Slaptažodžio keitimas šiuo metu anuliuos visapusio šifravimo ranktus visose sesijose, tad šifruotų pokalbių istorija taps neperskaitoma, nebent jūs eksportuosite savo kambarių raktus ir po to importuosite juos atgal. Ateityje ši funkcija bus pataisyta.", - "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Jūsų slaptažodis buvo sėkmingai pakeistas. Jūs nematysite pranešimų kitose sesijose kol iš naujo prie jų neprisijungsite", + "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.": "Pakeitus slaptažodį šiuo metu, visuose seansuose bus anuliuoti visapusio šifravimo raktai, tad šifruotų pokalbių istorija taps neperskaitoma, nebent jūs eksportuosite savo kambarių raktus ir po to importuosite juos atgal. Ateityje ši funkcija bus pataisyta.", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Jūsų slaptažodis buvo sėkmingai pakeistas. Jūs kituose seansuose negausite pranešimų, kol iš naujo prie jų neprisijungsite", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "El. laiškas buvo išsiųstas į %(emailAddress)s. Kai paspausite jame esančią nuorodą, tada spauskite žemiau.", "Your password has been reset.": "Jūsų slaptažodis buvo iš naujo nustatytas.", - "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.": "Jūs buvote atjungtas iš visų sesijų ir nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, prisijunkite iš naujo kiekviename įrenginyje.", + "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.": "Jūs buvote atjungtas iš visų seansų ir toliau nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, iš naujo prisijunkite kiekviename įrenginyje.", "Show more": "Rodyti daugiau", - "Log in to your new account.": "Prisijunkite į savo naują paskyrą.", + "Log in to your new account.": "Prisijunkite prie naujos paskyros.", "Registration Successful": "Registracija sėkminga", "Welcome to %(appName)s": "Sveiki prisijungę į %(appName)s", "Liberate your communication": "Išlaisvinkite savo bendravimą", "Explore Public Rooms": "Žvalgyti viešus kambarius", - "Create a Group Chat": "Sukurti grupės pokalbį" + "Create a Group Chat": "Sukurti grupės pokalbį", + "New login. Was this you?": "Naujas prisijungimas. Ar tai jūs?", + "%(senderName)s placed a voice call.": "%(senderName)s pradėjo balso skambutį.", + "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s pradėjo vaizdo skambutį. (nepalaikoma šios naršyklės)", + "%(senderName)s placed a video call.": "%(senderName)s pradėjo vaizdo skambutį.", + "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s pradėjo vaizdo skambutį. (nepalaikoma šios naršyklės)", + "Verify your other session using one of the options below.": "Patvirtinkite savo kitą seansą naudodami vieną iš žemiau esančių parinkčių.", + "Messages containing @room": "Žinutės, kuriose yra @kambarys", + "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Laukiama, kol jūsų kitas seansas, %(deviceName)s (%(deviceId)s), patvirtins…", + "Waiting for your other session to verify…": "Laukiama, kol jūsų kitas seansas patvirtins…", + "To be secure, do this in person or use a trusted way to communicate.": "Norėdami būti saugūs, darykite tai asmeniškai arba naudodamiesi patikimu bendravimo būdu.", + "Verify": "Patvirtinti", + "Verify the new login accessing your account: %(name)s": "Patvirtinkite naują prisijungimą prie jūsų paskyros: %(name)s", + "Confirm deleting these sessions": "Patvirtinkite šių seansų ištrinimą", + "Delete sessions|other": "Ištrinti seansus", + "Delete sessions|one": "Ištrinti seansą", + "Delete %(count)s sessions|other": "Ištrinti %(count)s seansus(-ų)", + "Delete %(count)s sessions|one": "Ištrinti %(count)s seansą", + "ID": "ID", + "Restore from Backup": "Atkurti iš atsarginės kopijos", + "Flair": "Ženkliukai", + "Access Token:": "Prieigos talonas:", + "Preferences": "Parinktys", + "Cryptography": "Kriptografija", + "Security & Privacy": "Saugumas ir Privatumas", + "Voice & Video": "Garsas ir Vaizdas", + "Enable room encryption": "Įgalinti kambario šifravimą", + "Enable encryption?": "Įgalinti šifravimą?", + "Encryption": "Šifravimas", + "Once enabled, encryption cannot be disabled.": "Įjungus šifravimą jo nebus galima išjungti.", + "Who can access this room?": "Kas turi prieigą prie šio kambario?", + "Join as voice or video.": "Prisijungti kaip balsas arba vaizdas.", + "Deactivate user?": "Deaktyvuoti vartotoją?", + "Deactivate user": "Deaktyvuoti vartotoją", + "Failed to deactivate user": "Nepavyko deaktyvuoti vartotojo", + "Sessions": "Seansai", + "Try again later, or ask a room admin to check if you have access.": "Pabandykite vėliau arba paprašykite kambario administratoriaus patikrinti, ar turite prieigą.", + "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please submit a bug report.": "Bandant patekti į kambarį buvo gauta klaida: %(errcode)s. Jei manote, kad matote šį pranešimą per klaidą, prašome apie ją pranešti.", + "Error updating flair": "Klaida atnaujinant ženkliuką", + "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Įvyko klaida atnaujinant ženkliukus šiam kambariui. Serveris gali jų neleisti arba įvyko laikina klaida.", + "Showing flair for these communities:": "Ženkliukai rodomi šioms bendruomenėms:", + "This room is not showing flair for any communities": "Šis kambarys nerodo ženkliukų jokioms bendruomenėms", + "Waiting for you to accept on your other session…": "Laukiama kol jūs priimsite savo kitame seanse…", + "Start Verification": "Pradėti patvirtinimą", + "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Šifruotuose kambariuose jūsų žinutės yra apsaugotos ir tik jūs ir gavėjas turite unikalius raktus joms atrakinti.", + "Verify User": "Patvirtinti vartotoją", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Dėl papildomo saugumo patvirtinkite šį vartotoją patikrindami vienkartinį kodą abiejuose jūsų įrenginiuose.", + "%(count)s verified sessions|other": "%(count)s patvirtintų seansų", + "Hide verified sessions": "Slėpti patvirtintus seansus", + "%(count)s sessions|other": "%(count)s seansai(-ų)", + "Hide sessions": "Slėpti seansus", + "%(role)s in %(roomName)s": "%(role)s kambaryje %(roomName)s", + "Security": "Saugumas", + "Verify by scanning": "Patvirtinti skenuojant", + "Verify all users in a room to ensure it's secure.": "Patvirtinkite visus vartotojus kambaryje, kad užtikrintumėte jo saugumą.", + "You cancelled verification on your other session.": "Jūs atšaukėte patvirtinimą kitame savo seanse.", + "%(displayName)s cancelled verification.": "%(displayName)s atšaukė patvirtinimą.", + "You cancelled verification.": "Jūs atšaukėte patvirtinimą.", + "Verification cancelled": "Patvirtinimas atšauktas", + "Encryption enabled": "Šifravimas įgalintas", + "Encryption not enabled": "Šifravimas neįgalintas", + "Display your community flair in rooms configured to show it.": "Rodyti savo bendruomenės ženkliukus kambariuose, kuriuose nustatytas jų rodymas.", + "You're not currently a member of any communities.": "Jūs šiuo metu nesate jokios bendruomenės narys.", + "More options": "Daugiau parinkčių", + "Are you sure you want to remove %(serverName)s": "Ar tikrai norite pašalinti %(serverName)s", + "Enable end-to-end encryption": "Įgalinti visapusį šifravimą", + "You can’t disable this later. Bridges & most bots won’t work yet.": "Jūs negalėsite vėliau to išjungti. Tiltai ir dauguma bot'ų dar nėra palaikomi.", + "Are you sure you want to deactivate your account? This is irreversible.": "Ar tikrai norite deaktyvuoti savo paskyrą? Tai yra negrįžtama.", + "Verify session": "Patvirtinti seansą", + "Verify by comparing a short text string.": "Patvirtinkite palygindami trumpą teksto eilutę.", + "To verify that this session can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this session matches the key below:": "Norėdami patvirtinti, kad šis seansas yra patikimas, susisiekite su jo savininku kokiu nors kitu būdu (pvz.: asmeniškai arba telefono skambučiu) ir paklauskite ar jų Vartotojo Nustatymuose matomas šio seanso raktas sutampa su raktu esančiu žemiau:", + "Start verification": "Pradėti patvirtinimą", + "Are you sure you want to sign out?": "Ar tikrai norite atsijungti?", + "Use this session to verify your new one, granting it access to encrypted messages:": "Panaudoti šį seansą naujo patvirtinimui, suteikant jam prieigą prie šifruotų žinučių:", + "If you didn’t sign in to this session, your account may be compromised.": "Jei jūs nesijungėte prie šios sesijos, jūsų paskyra gali būti sukompromituota.", + "This wasn't me": "Tai buvau ne aš", + "If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Jei jūs susidūrėte su klaidomis arba norėtumėte palikti atsiliepimą, praneškite mums GitHub'e.", + "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Tam, kad būtų išvengta pasikartojančių problemų, pirmiausia peržiūrėkite esamas problemas (ir pridėkite +1) arba, jei nerandate, sukurkite naują svarstomą problemą.", + "Report bugs & give feedback": "Pranešti apie klaidas ir palikti atsiliepimą", + "Report Content to Your Homeserver Administrator": "Pranešti apie turinį serverio administratoriui", + "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.": "Pranešant apie šią netinkamą žinutę, serverio administratoriui bus nusiųstas unikalus 'įvykio ID'. Jei žinutės šiame kambaryje yra šifruotos, serverio administratorius negalės perskaityti žinutės teksto ar peržiūrėti failų arba paveikslėlių.", + "Send report": "Siųsti pranešimą", + "Unknown sessions": "Nežinomi seansai", + "Verify other session": "Patvirtinti kitą seansą", + "Are you sure you want to reject the invitation?": "Ar tikrai norite atšaukti pakvietimą?", + "Share Permalink": "Dalintis nuoroda", + "Report Content": "Pranešti", + "Nice, strong password!": "Puiku, stiprus slaptažodis!", + "Old cryptography data detected": "Aptikti seni kriptografijos duomenys", + "Verify this login": "Patvirtinti šį prisijungimą", + "Registration has been disabled on this homeserver.": "Registracija šiame serveryje išjungta.", + "You can now close this window or log in to your new account.": "Jūs galite uždaryti šį langą arba prisijungti į savo naują paskyrą.", + "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Patvirtinkite savo tapatybę verifikuodami šį prisijungimą viename iš kitų jūsų seansų, suteikdami jam prieigą prie šifruotų žinučių.", + "This requires the latest Riot on your other devices:": "Tam reikia naujausios Riot versijos kituose jūsų įrenginiuose:", + "or another cross-signing capable Matrix client": "arba kitas kryžminį parašą palaikantis Matrix klientas", + "Use Recovery Passphrase or Key": "Naudoti atgavimo slaptafrazę arba raktą", + "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atnaujinkite šį seansą, kad jam būtų leista patvirtinti kitus seansus, suteikiant jiems prieigą prie šifruotų žinučių ir juos pažymint kaip patikimus kitiems vartotojams." } From f6e45a040559dac5ebc35b7e84dd7303a171b757 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Sat, 23 May 2020 20:55:27 +0000 Subject: [PATCH 080/332] Translated using Weblate (Lithuanian) Currently translated at 55.2% (1281 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 75 ++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 9c6a1c9a7a..661732dd81 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -103,7 +103,7 @@ "Search": "Ieškoti", "You must specify an event type!": "Privalote nurodyti įvykio tipą!", "(HTTP status %(httpStatus)s)": "(HTTP būsena %(httpStatus)s)", - "Failed to forget room %(errCode)s": "Nepavyko pašalinti pokalbių kambario %(errCode)s", + "Failed to forget room %(errCode)s": "Nepavyko pamiršti kambario %(errCode)s", "What's New": "Kas naujo", "Wednesday": "Trečiadienis", "Send": "Siųsti", @@ -355,9 +355,9 @@ "Email address": "El. pašto adresas", "Remove from community": "Pašalinti iš bendruomenės", "Remove this user from community?": "Pašalinti šį vartotoją iš bendruomenės?", - "Failed to remove user from community": "Nepavyko pašalinti naudotoją iš bendruomenės", + "Failed to remove user from community": "Nepavyko pašalinti vartotojo iš bendruomenės", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Ar tikrai norite pašalinti \"%(roomName)s\" iš %(groupId)s?", - "Failed to remove room from community": "Nepavyko pašalinti kambarį iš bendruomenės", + "Failed to remove room from community": "Nepavyko pašalinti kambario iš bendruomenės", "Failed to remove '%(roomName)s' from %(groupId)s": "Nepavyko pašalinti \"%(roomName)s\" iš %(groupId)s", "Something went wrong!": "Kažkas nutiko!", "Visibility in Room List": "Matomumas kambarių sąraše", @@ -367,7 +367,7 @@ "Allow": "Leisti", "Delete Widget": "Ištrinti valdiklį", "Delete widget": "Ištrinti valdiklį", - "Failed to remove widget": "Nepavyko pašalinti valdiklį", + "Failed to remove widget": "Nepavyko pašalinti valdiklio", "Scroll to bottom of page": "Slinkti į puslapio apačią", "%(count)s of your messages have not been sent.|other": "Kai kurios iš jūsų žinučių nebuvo išsiųstos.", "%(count)s of your messages have not been sent.|one": "Jūsų žinutė nebuvo išsiųsta.", @@ -395,7 +395,7 @@ "Light theme": "Šviesi tema", "Dark theme": "Tamsi tema", "Success": "Pavyko", - "Unable to remove contact information": "Nepavyko pašalinti kontaktinę informaciją", + "Unable to remove contact information": "Nepavyko pašalinti kontaktinės informacijos", "": "", "Check for update": "Tikrinti, ar yra atnaujinimų", "Reject all %(invitedRooms)s invites": "Atmesti visus %(invitedRooms)s pakvietimus", @@ -624,7 +624,7 @@ "Please contact your service administrator to get this limit increased.": "Norėdami padidinti šį limitą, susisiekite su savo paslaugų administratoriumi.", "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.": "Šis namų serveris pasiekė savo mėnesinį aktyvių naudotojų limitą, taigi, kai kurie naudotojai negalės prisijungti.", "This homeserver has exceeded one of its resource limits so some users will not be able to log in.": "Šis namų serveris viršijo vieno iš savo išteklių limitą, taigi, kai kurie naudotojai negalės prisijungti.", - "An error ocurred whilst trying to remove the widget from the room": "Įvyko klaida, bandant pašalinti valdiklį iš kambario", + "An error ocurred whilst trying to remove the widget from the room": "Bandant pašalinti valdiklį iš kambario įvyko klaida", "Blacklist": "Blokuoti", "Unblacklist": "Atblokuoti", "Verify...": "Patvirtinti...", @@ -659,7 +659,7 @@ "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s nustatė pagrindinį šio kambario adresą į %(address)s.", "%(senderName)s removed the main address for this room.": "%(senderName)s pašalino pagrindinį šio kambario adresą.", "Disinvite": "Atšaukti pakvietimą", - "Disinvite this user?": "Atšaukti pakvietimą šiam naudotojui?", + "Disinvite this user?": "Atšaukti pakvietimą šiam vartotojui?", "Unknown for %(duration)s": "Nežinoma jau %(duration)s", "Unable to load! Check your network connectivity and try again.": "Nepavyko įkelti! Patikrinkite savo tinklo ryšį ir bandykite dar kartą.", "%(targetName)s joined the room.": "%(targetName)s prisijungė prie kambario.", @@ -700,7 +700,7 @@ "Publish this room to the public in %(domain)s's room directory?": "Paskelbti šį kambarį į viešąjį %(domain)s kambarių katalogą?", "Start authentication": "Pradėti tapatybės nustatymą", "Failed to load group members": "Nepavyko įkelti grupės dalyvių", - "Manage Integrations": "Tvarkyti integracijas", + "Manage Integrations": "Valdyti integracijas", "Matrix Room ID": "Matrix kambario ID", "That doesn't look like a valid email address": "Tai nepanašu į teisingą el. pašto adresą", "Preparing to send logs": "Ruošiamasi išsiųsti žurnalus", @@ -740,7 +740,7 @@ "Your Communities": "Jūsų bendruomenės", "Create a new community": "Sukurti naują bendruomenę", "You have no visible notifications": "Jūs neturite matomų pranešimų", - "Failed to perform homeserver discovery": "Nepavyko atlikti namų serverio aptikimo", + "Failed to perform homeserver discovery": "Nepavyko atlikti serverio radimo", "Error: Problem communicating with the given homeserver.": "Klaida: Problemos susisiekiant su nurodytu namų serveriu.", "This server does not support authentication with a phone number.": "Šis serveris nepalaiko tapatybės nustatymo telefono numeriu.", "Great! This passphrase looks strong enough.": "Puiku! Ši slapta frazė atrodo pakankamai stipri.", @@ -1115,7 +1115,7 @@ "Go back to set it again.": "Grįžti atgal, kad nustatyti iš naujo.", "Click the button below to confirm adding this email address.": "Paspauskite mygtuką žemiau, kad patvirtintumėte šio el. pašto pridėjimą.", "Add an email address to configure email notifications": "Pridėkite el. pašto adresą, kad nustatytumėte el. pašto pranešimus", - "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Prieš atsijungiant rekomenduojame iš identiteto serverio pašalinti savo el. pašto adresus ir telefono numerius.", + "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Rekomenduojame, prieš atsijungiant, iš tapatybės serverio pašalinti savo el. pašto adresus ir telefono numerius.", "Email addresses": "El. pašto adresai", "Account management": "Paskyros valdymas", "Deactivating your account is a permanent action - be careful!": "Paskyros deaktyvavimas yra neatšaukiamas veiksmas - būkite atsargūs!", @@ -1261,5 +1261,58 @@ "This requires the latest Riot on your other devices:": "Tam reikia naujausios Riot versijos kituose jūsų įrenginiuose:", "or another cross-signing capable Matrix client": "arba kitas kryžminį parašą palaikantis Matrix klientas", "Use Recovery Passphrase or Key": "Naudoti atgavimo slaptafrazę arba raktą", - "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atnaujinkite šį seansą, kad jam būtų leista patvirtinti kitus seansus, suteikiant jiems prieigą prie šifruotų žinučių ir juos pažymint kaip patikimus kitiems vartotojams." + "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atnaujinkite šį seansą, kad jam būtų leista patvirtinti kitus seansus, suteikiant jiems prieigą prie šifruotų žinučių ir juos pažymint kaip patikimus kitiems vartotojams.", + "Use Single Sign On to continue": "Norėdami tęsti naudokite Vieno Prisijungimo sistemą", + "Confirm adding this email address by using Single Sign On to prove your identity.": "Patvirtinkite šio el. pašto adreso pridėjimą naudodami Vieno Prisijungimo sistemą, patvirtinančią jūsų tapatybę.", + "Single Sign On": "Vieno Prisijungimo sistema", + "Confirm adding email": "Patvirtinkite el. pašto pridėjimą", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "Patvirtinkite šio telefono numerio pridėjimą naudodami Vieno Prisijungimo sistemą, patvirtinančią jūsų tapatybę.", + "Confirm adding phone number": "Patvirtinkite telefono numerio pridėjimą", + "Click the button below to confirm adding this phone number.": "Paspauskite žemiau esantį mygtuką, kad patvirtintumėte šio numerio pridėjimą.", + "The version of Riot": "Riot versija", + "Match system theme": "Suderinti su sistemos tema", + "Identity Server URL must be HTTPS": "Tapatybės serverio URL privalo būti HTTPS", + "Not a valid Identity Server (status code %(code)s)": "Netinkamas tapatybės serveris (statuso kodas %(code)s)", + "Could not connect to Identity Server": "Nepavyko prisijungti prie tapatybės serverio", + "Disconnect from the identity server and connect to instead?": "Atsijungti nuo tapatybės serverio ir jo vietoje prisijungti prie ?", + "Terms of service not accepted or the identity server is invalid.": "Nesutikta su paslaugų teikimo sąlygomis arba tapatybės serveris yra klaidingas.", + "The identity server you have chosen does not have any terms of service.": "Jūsų pasirinktas tapatybės serveris neturi jokių paslaugų teikimo sąlygų.", + "Disconnect identity server": "Atjungti tapatybės serverį", + "Disconnect from the identity server ?": "Atsijungti nuo tapatybės serverio ?", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Prieš atsijungdami jūs turėtumėte pašalinti savo asmeninius duomenis iš tapatybės serverio . Deja, tapatybės serveris šiuo metu yra išjungtas arba nepasiekiamas.", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "patikrinkite ar tarp jūsų naršyklės įskiepių nėra nieko kas galėtų blokuoti tapatybės serverį (pavyzdžiui \"Privacy Badger\")", + "contact the administrators of identity server ": "susisiekite su tapatybės serverio administratoriais", + "You are still sharing your personal data on the identity server .": "Jūs vis dar dalijatės savo asmeniniais duomenimis tapatybės serveryje .", + "Identity Server (%(server)s)": "Tapatybės serveris (%(server)s)", + "Enter a new identity server": "Pridėkite naują tapatybės serverį", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Naudokite integracijų valdiklį (%(serverName)s) botų, valdiklių ir lipdukų valdymui.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Naudokite integracijų valdiklį botų, valdiklių ir lipdukų valdymui.", + "Manage integrations": "Valdyti integracijas", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integracijų valdikliai gauna konfigūracijos duomenis ir jūsų vardu gali keisti valdiklius, siųsti kambario pakvietimus ir nustatyti galios lygius.", + "Invalid theme schema.": "Klaidinga temos schema.", + "Error downloading theme information.": "Klaida parsisiunčiant temos informaciją.", + "Theme added!": "Tema pridėta!", + "Custom theme URL": "Pasirinktinės temos URL", + "Add theme": "Pridėti temą", + "Theme": "Tema", + "Phone numbers": "Telefono numeriai", + "Language and region": "Kalba ir regionas", + "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Sutikite su tapatybės serverio (%(serverName)s) paslaugų teikimo sąlygomis, kad leistumėte kitiems rasti jus pagal el. pašto adresą ar telefono numerį.", + "Discovery": "Radimas", + "Discovery options will appear once you have added an email above.": "Radimo parinktys atsiras jums aukščiau pridėjus el. pašto adresą.", + "Unable to revoke sharing for phone number": "Neina atšaukti telefono numerio bendrinimo", + "Unable to share phone number": "Neina bendrinti telefono numerio", + "Unable to verify phone number.": "Neina patvirtinti telefono numerio.", + "Discovery options will appear once you have added a phone number above.": "Radimo parinktys atsiras jums aukščiau pridėjus telefono numerį.", + "Phone Number": "Telefono Numeris", + "Room Topic": "Kambario Tema", + "Your theme": "Jūsų tema", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Valdiklio ištrinimas pašalina jį visiems kambaryje esantiems vartotojams. Ar tikrai norite ištrinti šį valdiklį?", + "Enable 'Manage Integrations' in Settings to do this.": "Įgalinkite 'Valdyti integracijas' nustatymuose, kad tai atliktumėte.", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Jūsų Riot neleidžia jums naudoti integracijų valdiklio tam atlikti. Susisiekite su administratoriumi.", + "Enter phone number (required on this homeserver)": "Įveskite telefono numerį (privaloma šiame serveryje)", + "Doesn't look like a valid phone number": "Tai nepanašu į veikiantį telefono numerį", + "Invalid homeserver discovery response": "Klaidingas serverio radimo atsakas", + "Invalid identity server discovery response": "Klaidingas tapatybės serverio radimo atsakas", + "The phone number entered looks invalid": "Įvestas telefono numeris atrodo klaidingas" } From 490a1041088675e5778143c8906e8946173b63f5 Mon Sep 17 00:00:00 2001 From: Domant3lis Date: Sat, 23 May 2020 23:31:57 +0000 Subject: [PATCH 081/332] Translated using Weblate (Lithuanian) Currently translated at 55.2% (1281 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 661732dd81..905ac59c0d 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -1314,5 +1314,6 @@ "Doesn't look like a valid phone number": "Tai nepanašu į veikiantį telefono numerį", "Invalid homeserver discovery response": "Klaidingas serverio radimo atsakas", "Invalid identity server discovery response": "Klaidingas tapatybės serverio radimo atsakas", - "The phone number entered looks invalid": "Įvestas telefono numeris atrodo klaidingas" + "The phone number entered looks invalid": "Įvestas telefono numeris atrodo klaidingas", + "Double check that your server supports the room version chosen and try again.": "Patikrinkite ar jūsų serveris palaiko pasirinktą kambario versiją ir bandykite iš naujo." } From 5e00481639ddd2505f95db3722cd97e2c67ba385 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 13:08:29 +0100 Subject: [PATCH 082/332] Fix sentMessageAndIsAlone by dispatching `message_sent` more consistently Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/emojipicker/ReactionPicker.js | 2 ++ src/components/views/messages/ReactionsRowButton.js | 2 ++ src/components/views/rooms/EditMessageComposer.js | 1 + src/components/views/rooms/SendMessageComposer.js | 1 + 4 files changed, 6 insertions(+) diff --git a/src/components/views/emojipicker/ReactionPicker.js b/src/components/views/emojipicker/ReactionPicker.js index 96894e18d2..6f8cc46c40 100644 --- a/src/components/views/emojipicker/ReactionPicker.js +++ b/src/components/views/emojipicker/ReactionPicker.js @@ -18,6 +18,7 @@ import React from 'react'; import PropTypes from "prop-types"; import EmojiPicker from "./EmojiPicker"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; +import dis from "../../../dispatcher/dispatcher"; class ReactionPicker extends React.Component { static propTypes = { @@ -105,6 +106,7 @@ class ReactionPicker extends React.Component { "key": reaction, }, }); + dis.dispatch({action: "message_sent"}); return true; } } diff --git a/src/components/views/messages/ReactionsRowButton.js b/src/components/views/messages/ReactionsRowButton.js index a7ff7dce96..09824cd315 100644 --- a/src/components/views/messages/ReactionsRowButton.js +++ b/src/components/views/messages/ReactionsRowButton.js @@ -22,6 +22,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; +import dis from "../../../dispatcher/dispatcher"; export default class ReactionsRowButton extends React.PureComponent { static propTypes = { @@ -60,6 +61,7 @@ export default class ReactionsRowButton extends React.PureComponent { "key": content, }, }); + dis.dispatch({action: "message_sent"}); } }; diff --git a/src/components/views/rooms/EditMessageComposer.js b/src/components/views/rooms/EditMessageComposer.js index 88ed76f118..b70ef6255c 100644 --- a/src/components/views/rooms/EditMessageComposer.js +++ b/src/components/views/rooms/EditMessageComposer.js @@ -190,6 +190,7 @@ export default class EditMessageComposer extends React.Component { const roomId = editedEvent.getRoomId(); this._cancelPreviousPendingEdit(); this.context.sendMessage(roomId, editContent); + dis.dispatch({action: "message_sent"}); } // close the event editing and focus composer diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 5ea979a8ef..b81e004943 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -312,6 +312,7 @@ export default class SendMessageComposer extends React.Component { event: null, }); } + dis.dispatch({action: "message_sent"}); } this.sendHistoryManager.save(this.model); From 02ddda587b7354f90c14e082be3170117606ef6c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 14:11:25 +0100 Subject: [PATCH 083/332] Fix useEventEmitter to support passing all callback arguments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/hooks/useEventEmitter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useEventEmitter.js b/src/hooks/useEventEmitter.js index 7adc6ef2e3..6a758fb108 100644 --- a/src/hooks/useEventEmitter.js +++ b/src/hooks/useEventEmitter.js @@ -32,7 +32,7 @@ export const useEventEmitter = (emitter, eventName, handler) => { if (!emitter) return; // Create event listener that calls handler function stored in ref - const eventListener = event => savedHandler.current(event); + const eventListener = (...args) => savedHandler.current(...args); // Add event listener emitter.on(eventName, eventListener); From cf7acded501e6fb34f165de0e6ae721f0a8edcfc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 14:12:16 +0100 Subject: [PATCH 084/332] Simply BaseAvatar hooks Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/avatars/BaseAvatar.js | 38 ++++++++-------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/components/views/avatars/BaseAvatar.js b/src/components/views/avatars/BaseAvatar.js index 4fd614fbf7..d7a2aa14e5 100644 --- a/src/components/views/avatars/BaseAvatar.js +++ b/src/components/views/avatars/BaseAvatar.js @@ -30,54 +30,44 @@ const useImageUrl = ({url, urls, idName, name, defaultToInitialLetter}) => { const [imageUrls, setUrls] = useState([]); const [urlsIndex, setIndex] = useState(); - const onError = () => { - const nextIndex = urlsIndex + 1; - if (nextIndex < imageUrls.length) { - // try the next one - setIndex(nextIndex); - } - }; - - const defaultImageUrl = useMemo(() => AvatarLogic.defaultAvatarUrlForString(idName || name), [idName, name]); + const onError = useCallback(() => { + setIndex(i => i + 1); // try the next one + }, []); + const memoizedUrls = useMemo(() => urls, [JSON.stringify(urls)]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { // work out the full set of urls to try to load. This is formed like so: - // imageUrls: [ props.url, ...props.urls, default image ] + // imageUrls: [ props.url, ...props.urls ] let _urls = []; if (!SettingsStore.getValue("lowBandwidth")) { - _urls = urls || []; + _urls = memoizedUrls || []; if (url) { _urls.unshift(url); // put in urls[0] } } - if (defaultToInitialLetter) { - _urls.push(defaultImageUrl); // lowest priority - } - // deduplicate URLs _urls = Array.from(new Set(_urls)); setIndex(0); setUrls(_urls); - }, [url, ...(urls || [])]); // eslint-disable-line react-hooks/exhaustive-deps + }, [url, memoizedUrls]); // eslint-disable-line react-hooks/exhaustive-deps const cli = useContext(MatrixClientContext); const onClientSync = useCallback((syncState, prevState) => { // Consider the client reconnected if there is no error with syncing. // This means the state could be RECONNECTING, SYNCING, PREPARED or CATCHUP. const reconnected = syncState !== "ERROR" && prevState !== syncState; - if (reconnected && urlsIndex > 0 ) { // Did we fall back? - // Start from the highest priority URL again - setIndex(0); + if (reconnected) { + setIndex(i => i > 0 ? 0 : i); } - }, [urlsIndex]); + }, []); useEventEmitter(cli, "sync", onClientSync); const imageUrl = imageUrls[urlsIndex]; - return [imageUrl, imageUrl === defaultImageUrl, onError]; + return [imageUrl, onError]; }; const BaseAvatar = (props) => { @@ -96,9 +86,9 @@ const BaseAvatar = (props) => { ...otherProps } = props; - const [imageUrl, isDefault, onError] = useImageUrl({url, urls, idName, name, defaultToInitialLetter}); + const [imageUrl, onError] = useImageUrl({url, urls, idName, name, defaultToInitialLetter}); - if (isDefault) { + if (!imageUrl && defaultToInitialLetter) { const initialLetter = AvatarLogic.getInitialLetter(name); const textNode = ( { const imgNode = ( Date: Sun, 24 May 2020 14:25:31 +0100 Subject: [PATCH 085/332] fix tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- test/components/views/messages/TextualBody-test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/components/views/messages/TextualBody-test.js b/test/components/views/messages/TextualBody-test.js index 212afac5c4..07cd51edbd 100644 --- a/test/components/views/messages/TextualBody-test.js +++ b/test/components/views/messages/TextualBody-test.js @@ -205,9 +205,8 @@ describe("", () => { expect(content.html()).toBe('' + 'Hey ' + '' + - 'Member' + + 'Member' + ''); }); }); From 50b8445d4dc231fc6c815b4cebc58618bb305ded Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 15:13:53 +0100 Subject: [PATCH 086/332] fix Content Messages upload abort Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 4f5a1a1220..931cc56a34 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -258,10 +258,10 @@ function readFileAsArrayBuffer(file) { * If the file is encrypted then the object will have a "file" key. */ function uploadFile(matrixClient, roomId, file, progressHandler) { + let canceled = false; if (matrixClient.isRoomEncrypted(roomId)) { // If the room is encrypted then encrypt the file before uploading it. // First read the file into memory. - let canceled = false; let uploadPromise; let encryptInfo; const prom = readFileAsArrayBuffer(file).then(function(data) { @@ -278,9 +278,9 @@ function uploadFile(matrixClient, roomId, file, progressHandler) { progressHandler: progressHandler, includeFilename: false, }); - return uploadPromise; }).then(function(url) { + if (canceled) throw new UploadCanceledError(); // If the attachment is encrypted then bundle the URL along // with the information needed to decrypt the attachment and // add it under a file key. @@ -300,11 +300,14 @@ function uploadFile(matrixClient, roomId, file, progressHandler) { progressHandler: progressHandler, }); const promise1 = basePromise.then(function(url) { + if (canceled) throw new UploadCanceledError(); // If the attachment isn't encrypted then include the URL directly. return {"url": url}; }); - // XXX: copy over the abort method to the new promise - promise1.abort = basePromise.abort; + promise1.abort = () => { + canceled = true; + MatrixClientPeg.get().cancelUpload(basePromise); + }; return promise1; } } @@ -489,11 +492,16 @@ export default class ContentMessages { } }); + prom.abort = () => { + upload.cancelled = true; + }; + const upload = { fileName: file.name || 'Attachment', roomId: roomId, total: 0, loaded: 0, + promise: prom, }; this.inprogress.push(upload); dis.dispatch({action: 'upload_started'}); @@ -510,6 +518,7 @@ export default class ContentMessages { } return prom.then(function() { + if (upload.canceled) throw new UploadCanceledError(); // XXX: upload.promise must be the promise that // is returned by uploadFile as it has an abort() // method hacked onto it. @@ -524,6 +533,7 @@ export default class ContentMessages { // Await previous message being sent into the room return promBefore; }).then(function() { + if (upload.canceled) throw new UploadCanceledError(); return matrixClient.sendMessage(roomId, content); }, function(err) { error = err; From 0705883c8fa958e011558b30111e54973b00bbe7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 15:47:52 +0100 Subject: [PATCH 087/332] Convert ContentMessages to Typescript Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/@types/global.d.ts | 3 + ...ContentMessages.js => ContentMessages.tsx} | 223 ++++++++++-------- 2 files changed, 127 insertions(+), 99 deletions(-) rename src/{ContentMessages.js => ContentMessages.tsx} (77%) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index e6e339d067..b0e3159901 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,6 +15,7 @@ limitations under the License. */ import * as ModernizrStatic from "modernizr"; +import ContentMessages from "../ContentMessages"; declare global { interface Window { @@ -22,6 +23,8 @@ declare global { Olm: { init: () => Promise; }; + + mx_ContentMessages: ContentMessages; } // workaround for https://github.com/microsoft/TypeScript/issues/30933 diff --git a/src/ContentMessages.js b/src/ContentMessages.tsx similarity index 77% rename from src/ContentMessages.js rename to src/ContentMessages.tsx index 931cc56a34..6de318f81d 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.tsx @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2019 New Vector Ltd +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. @@ -15,11 +16,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - +import React from "react"; import extend from './extend'; import dis from './dispatcher/dispatcher'; import {MatrixClientPeg} from './MatrixClientPeg'; +import {MatrixClient} from "matrix-js-sdk/src/client"; import * as sdk from './index'; import { _t } from './languageHandler'; import Modal from './Modal'; @@ -39,6 +40,50 @@ const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01]; export class UploadCanceledError extends Error {} +type ThumbnailableElement = HTMLImageElement | HTMLVideoElement; + +interface IUpload { + fileName: string; + roomId: string; + total: number; + loaded: number; + promise: Promise; + canceled?: boolean; +} + +interface IMediaConfig { + "m.upload.size"?: number; +} + +interface IContent { + body: string; + msgtype: string; + info: { + size: number; + mimetype?: string; + }; + file?: string; + url?: string; +} + +interface IThumbnail { + info: { + thumbnail_info: { + w: number; + h: number; + mimetype: string; + size: number; + }; + w: number; + h: number; + }; + thumbnail: Blob; +} + +interface IAbortablePromise extends Promise { + abort(): void; +} + /** * Create a thumbnail for a image DOM element. * The image will be smaller than MAX_WIDTH and MAX_HEIGHT. @@ -51,13 +96,13 @@ export class UploadCanceledError extends Error {} * about the original image and the thumbnail. * * @param {HTMLElement} element The element to thumbnail. - * @param {integer} inputWidth The width of the image in the input element. - * @param {integer} inputHeight the width of the image in the input element. + * @param {number} inputWidth The width of the image in the input element. + * @param {number} inputHeight the width of the image in the input element. * @param {String} mimeType The mimeType to save the blob as. * @return {Promise} A promise that resolves with an object with an info key * and a thumbnail key. */ -function createThumbnail(element, inputWidth, inputHeight, mimeType) { +function createThumbnail(element: ThumbnailableElement, inputWidth: number, inputHeight: number, mimeType: string): Promise { return new Promise((resolve) => { let targetWidth = inputWidth; let targetHeight = inputHeight; @@ -98,7 +143,7 @@ function createThumbnail(element, inputWidth, inputHeight, mimeType) { * @param {File} imageFile The file to load in an image element. * @return {Promise} A promise that resolves with the html image element. */ -async function loadImageElement(imageFile) { +async function loadImageElement(imageFile: File) { // Load the file into an html element const img = document.createElement("img"); const objectUrl = URL.createObjectURL(imageFile); @@ -128,8 +173,7 @@ async function loadImageElement(imageFile) { for (const chunk of chunks) { if (chunk.name === 'pHYs') { if (chunk.data.byteLength !== PHYS_HIDPI.length) return; - const hidpi = chunk.data.every((val, i) => val === PHYS_HIDPI[i]); - return hidpi; + return chunk.data.every((val, i) => val === PHYS_HIDPI[i]); } } return false; @@ -152,7 +196,7 @@ async function loadImageElement(imageFile) { */ function infoForImageFile(matrixClient, roomId, imageFile) { let thumbnailType = "image/png"; - if (imageFile.type == "image/jpeg") { + if (imageFile.type === "image/jpeg") { thumbnailType = "image/jpeg"; } @@ -175,15 +219,15 @@ function infoForImageFile(matrixClient, roomId, imageFile) { * @param {File} videoFile The file to load in an video element. * @return {Promise} A promise that resolves with the video image element. */ -function loadVideoElement(videoFile) { +function loadVideoElement(videoFile): Promise { return new Promise((resolve, reject) => { // Load the file into an html element const video = document.createElement("video"); const reader = new FileReader(); - reader.onload = function(e) { - video.src = e.target.result; + reader.onload = function(ev) { + video.src = ev.target.result as string; // Once ready, returns its size // Wait until we have enough data to thumbnail the first frame. @@ -231,11 +275,11 @@ function infoForVideoFile(matrixClient, roomId, videoFile) { * @return {Promise} A promise that resolves with an ArrayBuffer when the file * is read. */ -function readFileAsArrayBuffer(file) { +function readFileAsArrayBuffer(file: File | Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = function(e) { - resolve(e.target.result); + resolve(e.target.result as ArrayBuffer); }; reader.onerror = function(e) { reject(e); @@ -257,7 +301,7 @@ function readFileAsArrayBuffer(file) { * If the file is unencrypted then the object will have a "url" key. * If the file is encrypted then the object will have a "file" key. */ -function uploadFile(matrixClient, roomId, file, progressHandler) { +function uploadFile(matrixClient: MatrixClient, roomId: string, file: File | Blob, progressHandler?: any) { let canceled = false; if (matrixClient.isRoomEncrypted(roomId)) { // If the room is encrypted then encrypt the file before uploading it. @@ -290,7 +334,7 @@ function uploadFile(matrixClient, roomId, file, progressHandler) { } return {"file": encryptInfo}; }); - prom.abort = () => { + (prom as IAbortablePromise).abort = () => { canceled = true; if (uploadPromise) MatrixClientPeg.get().cancelUpload(uploadPromise); }; @@ -313,30 +357,27 @@ function uploadFile(matrixClient, roomId, file, progressHandler) { } export default class ContentMessages { - constructor() { - this.inprogress = []; - this.nextId = 0; - this._mediaConfig = null; - } + private inprogress: IUpload[] = []; + private mediaConfig: IMediaConfig = null; static sharedInstance() { - if (global.mx_ContentMessages === undefined) { - global.mx_ContentMessages = new ContentMessages(); + if (window.mx_ContentMessages === undefined) { + window.mx_ContentMessages = new ContentMessages(); } - return global.mx_ContentMessages; + return window.mx_ContentMessages; } - _isFileSizeAcceptable(file) { - if (this._mediaConfig !== null && - this._mediaConfig["m.upload.size"] !== undefined && - file.size > this._mediaConfig["m.upload.size"]) { + _isFileSizeAcceptable(file: File) { + if (this.mediaConfig !== null && + this.mediaConfig["m.upload.size"] !== undefined && + file.size > this.mediaConfig["m.upload.size"]) { return false; } return true; } _ensureMediaConfigFetched() { - if (this._mediaConfig !== null) return; + if (this.mediaConfig !== null) return; console.log("[Media Config] Fetching"); return MatrixClientPeg.get().getMediaConfig().then((config) => { @@ -347,11 +388,11 @@ export default class ContentMessages { console.log("[Media Config] Could not fetch config, so not limiting uploads."); return {}; }).then((config) => { - this._mediaConfig = config; + this.mediaConfig = config; }); } - sendStickerContentToRoom(url, roomId, info, text, matrixClient) { + sendStickerContentToRoom(url: string, roomId: string, info: string, text: string, matrixClient: MatrixClient) { return MatrixClientPeg.get().sendStickerMessage(roomId, url, info, text).catch((e) => { console.warn(`Failed to send content with URL ${url} to room ${roomId}`, e); throw e; @@ -359,14 +400,14 @@ export default class ContentMessages { } getUploadLimit() { - if (this._mediaConfig !== null && this._mediaConfig["m.upload.size"] !== undefined) { - return this._mediaConfig["m.upload.size"]; + if (this.mediaConfig !== null && this.mediaConfig["m.upload.size"] !== undefined) { + return this.mediaConfig["m.upload.size"]; } else { return null; } } - async sendContentListToRoom(files, roomId, matrixClient) { + async sendContentListToRoom(files: File[], roomId: string, matrixClient: MatrixClient) { if (matrixClient.isGuest()) { dis.dispatch({action: 'require_registration'}); return; @@ -375,22 +416,18 @@ export default class ContentMessages { const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); if (isQuoting) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - const shouldUpload = await new Promise((resolve) => { - Modal.createTrackedDialog('Upload Reply Warning', '', QuestionDialog, { - title: _t('Replying With Files'), - description: ( -
{_t( - 'At this time it is not possible to reply with a file. ' + - 'Would you like to upload this file without replying?', - )}
- ), - hasCancelButton: true, - button: _t("Continue"), - onFinished: (shouldUpload) => { - resolve(shouldUpload); - }, - }); + const {finished} = Modal.createTrackedDialog('Upload Reply Warning', '', QuestionDialog, { + title: _t('Replying With Files'), + description: ( +
{_t( + 'At this time it is not possible to reply with a file. ' + + 'Would you like to upload this file without replying?', + )}
+ ), + hasCancelButton: true, + button: _t("Continue"), }); + const [shouldUpload]: [boolean] = await finished; if (!shouldUpload) return; } @@ -409,17 +446,12 @@ export default class ContentMessages { if (tooBigFiles.length > 0) { const UploadFailureDialog = sdk.getComponent("dialogs.UploadFailureDialog"); - const uploadFailureDialogPromise = new Promise((resolve) => { - Modal.createTrackedDialog('Upload Failure', '', UploadFailureDialog, { - badFiles: tooBigFiles, - totalFiles: files.length, - contentMessages: this, - onFinished: (shouldContinue) => { - resolve(shouldContinue); - }, - }); + const {finished} = Modal.createTrackedDialog('Upload Failure', '', UploadFailureDialog, { + badFiles: tooBigFiles, + totalFiles: files.length, + contentMessages: this, }); - const shouldContinue = await uploadFailureDialogPromise; + const [shouldContinue]: [boolean] = await finished; if (!shouldContinue) return; } @@ -431,31 +463,28 @@ export default class ContentMessages { for (let i = 0; i < okFiles.length; ++i) { const file = okFiles[i]; if (!uploadAll) { - const shouldContinue = await new Promise((resolve) => { - Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, { - file, - currentIndex: i, - totalFiles: okFiles.length, - onFinished: (shouldContinue, shouldUploadAll) => { - if (shouldUploadAll) { - uploadAll = true; - } - resolve(shouldContinue); - }, - }); + const {finished} = Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, { + file, + currentIndex: i, + totalFiles: okFiles.length, }); + const [shouldContinue, shouldUploadAll]: [boolean, boolean] = await finished; if (!shouldContinue) break; + if (shouldUploadAll) { + uploadAll = true; + } } promBefore = this._sendContentToRoom(file, roomId, matrixClient, promBefore); } } - _sendContentToRoom(file, roomId, matrixClient, promBefore) { - const content = { + _sendContentToRoom(file: File, roomId: string, matrixClient: MatrixClient, promBefore: Promise) { + const content: IContent = { body: file.name || 'Attachment', info: { size: file.size, }, + msgtype: "", // set later }; // if we have a mime type for the file, add it to the message metadata @@ -464,25 +493,25 @@ export default class ContentMessages { } const prom = new Promise((resolve) => { - if (file.type.indexOf('image/') == 0) { + if (file.type.indexOf('image/') === 0) { content.msgtype = 'm.image'; - infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ + infoForImageFile(matrixClient, roomId, file).then((imageInfo) => { extend(content.info, imageInfo); resolve(); - }, (error)=>{ - console.error(error); + }, (e) => { + console.error(e); content.msgtype = 'm.file'; resolve(); }); - } else if (file.type.indexOf('audio/') == 0) { + } else if (file.type.indexOf('audio/') === 0) { content.msgtype = 'm.audio'; resolve(); - } else if (file.type.indexOf('video/') == 0) { + } else if (file.type.indexOf('video/') === 0) { content.msgtype = 'm.video'; - infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ + infoForVideoFile(matrixClient, roomId, file).then((videoInfo) => { extend(content.info, videoInfo); resolve(); - }, (error)=>{ + }, (e) => { content.msgtype = 'm.file'; resolve(); }); @@ -492,14 +521,15 @@ export default class ContentMessages { } }); - prom.abort = () => { - upload.cancelled = true; + // create temporary abort handler for before the actual upload gets passed off to js-sdk + (prom as IAbortablePromise).abort = () => { + upload.canceled = true; }; - const upload = { + const upload: IUpload = { fileName: file.name || 'Attachment', roomId: roomId, - total: 0, + total: file.size, loaded: 0, promise: prom, }; @@ -509,14 +539,13 @@ export default class ContentMessages { // Focus the composer view dis.dispatch({action: 'focus_composer'}); - let error; - function onProgress(ev) { upload.total = ev.total; upload.loaded = ev.loaded; dis.dispatch({action: 'upload_progress', upload: upload}); } + let error; return prom.then(function() { if (upload.canceled) throw new UploadCanceledError(); // XXX: upload.promise must be the promise that @@ -529,7 +558,7 @@ export default class ContentMessages { content.file = result.file; content.url = result.url; }); - }).then((url) => { + }).then(() => { // Await previous message being sent into the room return promBefore; }).then(function() { @@ -539,7 +568,7 @@ export default class ContentMessages { error = err; if (!upload.canceled) { let desc = _t("The file '%(fileName)s' failed to upload.", {fileName: upload.fileName}); - if (err.http_status == 413) { + if (err.http_status === 413) { desc = _t( "The file '%(fileName)s' exceeds this homeserver's size limit for uploads", {fileName: upload.fileName}, @@ -552,11 +581,9 @@ export default class ContentMessages { }); } }).finally(() => { - const inprogressKeys = Object.keys(this.inprogress); for (let i = 0; i < this.inprogress.length; ++i) { - const k = inprogressKeys[i]; - if (this.inprogress[k].promise === upload.promise) { - this.inprogress.splice(k, 1); + if (this.inprogress[i].promise === upload.promise) { + this.inprogress.splice(i, 1); break; } } @@ -565,7 +592,7 @@ export default class ContentMessages { // clear the media size limit so we fetch it again next time // we try to upload if (error && error.http_status === 413) { - this._mediaConfig = null; + this.mediaConfig = null; } dis.dispatch({action: 'upload_failed', upload, error}); } else { @@ -579,13 +606,11 @@ export default class ContentMessages { return this.inprogress.filter(u => !u.canceled); } - cancelUpload(promise) { - const inprogressKeys = Object.keys(this.inprogress); + cancelUpload(promise: Promise) { let upload; for (let i = 0; i < this.inprogress.length; ++i) { - const k = inprogressKeys[i]; - if (this.inprogress[k].promise === promise) { - upload = this.inprogress[k]; + if (this.inprogress[i].promise === promise) { + upload = this.inprogress[i]; break; } } From 4a08c8cedaedd2809f0d5eae1a5719cf2e659a0f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 16:00:57 +0100 Subject: [PATCH 088/332] sort file Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.tsx | 100 ++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index 6de318f81d..bf9435914c 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -360,38 +360,6 @@ export default class ContentMessages { private inprogress: IUpload[] = []; private mediaConfig: IMediaConfig = null; - static sharedInstance() { - if (window.mx_ContentMessages === undefined) { - window.mx_ContentMessages = new ContentMessages(); - } - return window.mx_ContentMessages; - } - - _isFileSizeAcceptable(file: File) { - if (this.mediaConfig !== null && - this.mediaConfig["m.upload.size"] !== undefined && - file.size > this.mediaConfig["m.upload.size"]) { - return false; - } - return true; - } - - _ensureMediaConfigFetched() { - if (this.mediaConfig !== null) return; - - console.log("[Media Config] Fetching"); - return MatrixClientPeg.get().getMediaConfig().then((config) => { - console.log("[Media Config] Fetched config:", config); - return config; - }).catch(() => { - // Media repo can't or won't report limits, so provide an empty object (no limits). - console.log("[Media Config] Could not fetch config, so not limiting uploads."); - return {}; - }).then((config) => { - this.mediaConfig = config; - }); - } - sendStickerContentToRoom(url: string, roomId: string, info: string, text: string, matrixClient: MatrixClient) { return MatrixClientPeg.get().sendStickerMessage(roomId, url, info, text).catch((e) => { console.warn(`Failed to send content with URL ${url} to room ${roomId}`, e); @@ -431,13 +399,13 @@ export default class ContentMessages { if (!shouldUpload) return; } - await this._ensureMediaConfigFetched(); + await this.ensureMediaConfigFetched(); const tooBigFiles = []; const okFiles = []; for (let i = 0; i < files.length; ++i) { - if (this._isFileSizeAcceptable(files[i])) { + if (this.isFileSizeAcceptable(files[i])) { okFiles.push(files[i]); } else { tooBigFiles.push(files[i]); @@ -474,11 +442,30 @@ export default class ContentMessages { uploadAll = true; } } - promBefore = this._sendContentToRoom(file, roomId, matrixClient, promBefore); + promBefore = this.sendContentToRoom(file, roomId, matrixClient, promBefore); } } - _sendContentToRoom(file: File, roomId: string, matrixClient: MatrixClient, promBefore: Promise) { + getCurrentUploads() { + return this.inprogress.filter(u => !u.canceled); + } + + cancelUpload(promise: Promise) { + let upload: IUpload; + for (let i = 0; i < this.inprogress.length; ++i) { + if (this.inprogress[i].promise === promise) { + upload = this.inprogress[i]; + break; + } + } + if (upload) { + upload.canceled = true; + MatrixClientPeg.get().cancelUpload(upload.promise); + dis.dispatch({action: 'upload_canceled', upload}); + } + } + + private sendContentToRoom(file: File, roomId: string, matrixClient: MatrixClient, promBefore: Promise) { const content: IContent = { body: file.name || 'Attachment', info: { @@ -602,22 +589,35 @@ export default class ContentMessages { }); } - getCurrentUploads() { - return this.inprogress.filter(u => !u.canceled); + private isFileSizeAcceptable(file: File) { + if (this.mediaConfig !== null && + this.mediaConfig["m.upload.size"] !== undefined && + file.size > this.mediaConfig["m.upload.size"]) { + return false; + } + return true; } - cancelUpload(promise: Promise) { - let upload; - for (let i = 0; i < this.inprogress.length; ++i) { - if (this.inprogress[i].promise === promise) { - upload = this.inprogress[i]; - break; - } - } - if (upload) { - upload.canceled = true; - MatrixClientPeg.get().cancelUpload(upload.promise); - dis.dispatch({action: 'upload_canceled', upload}); + private ensureMediaConfigFetched() { + if (this.mediaConfig !== null) return; + + console.log("[Media Config] Fetching"); + return MatrixClientPeg.get().getMediaConfig().then((config) => { + console.log("[Media Config] Fetched config:", config); + return config; + }).catch(() => { + // Media repo can't or won't report limits, so provide an empty object (no limits). + console.log("[Media Config] Could not fetch config, so not limiting uploads."); + return {}; + }).then((config) => { + this.mediaConfig = config; + }); + } + + static sharedInstance() { + if (window.mx_ContentMessages === undefined) { + window.mx_ContentMessages = new ContentMessages(); } + return window.mx_ContentMessages; } } From db6853e022307bf367fe407f845e6f3d8dbdc01b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 24 May 2020 20:00:02 +0100 Subject: [PATCH 089/332] Fix Emoji Picker footer being too small if text overflows Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/emojipicker/_EmojiPicker.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/emojipicker/_EmojiPicker.scss b/res/css/views/emojipicker/_EmojiPicker.scss index 24561eeeb9..400e40e233 100644 --- a/res/css/views/emojipicker/_EmojiPicker.scss +++ b/res/css/views/emojipicker/_EmojiPicker.scss @@ -190,7 +190,7 @@ limitations under the License. .mx_EmojiPicker_footer { border-top: 1px solid $message-action-bar-border-color; - height: 72px; + min-height: 72px; display: flex; align-items: center; From 1f52b5e2036ef0c6fb1192f9db9df41a63f562bd Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 May 2020 10:59:31 +0100 Subject: [PATCH 090/332] Update Crypto Store Too New copy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/MatrixClientPeg.js | 4 +--- src/components/views/dialogs/CryptoStoreTooNewDialog.js | 6 ++---- src/i18n/strings/en_EN.json | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 21f05b9759..704f1052fc 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -158,9 +158,7 @@ class _MatrixClientPeg { // The js-sdk found a crypto DB too new for it to use const CryptoStoreTooNewDialog = sdk.getComponent("views.dialogs.CryptoStoreTooNewDialog"); - Modal.createDialog(CryptoStoreTooNewDialog, { - host: window.location.host, - }); + Modal.createDialog(CryptoStoreTooNewDialog); } // this can happen for a number of reasons, the most likely being // that the olm library was missing. It's not fatal. diff --git a/src/components/views/dialogs/CryptoStoreTooNewDialog.js b/src/components/views/dialogs/CryptoStoreTooNewDialog.js index 081e84696c..4694619601 100644 --- a/src/components/views/dialogs/CryptoStoreTooNewDialog.js +++ b/src/components/views/dialogs/CryptoStoreTooNewDialog.js @@ -42,11 +42,9 @@ export default (props) => { }; const description = - _t("You've previously used a newer version of Riot on %(host)s. " + + _t("You've previously used a newer version of Riot with this session. " + "To use this version again with end to end encryption, you will " + - "need to sign out and back in again. ", - {host: props.host}, - ); + "need to sign out and back in again."); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 96ccf1589d..67ee31e71e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1597,7 +1597,7 @@ "Create Room": "Create Room", "Sign out": "Sign out", "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 Riot to do this": "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 Riot to do this", - "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ", + "You've previously used a newer version of Riot with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "You've previously used a newer version of Riot with this session. To use this version again with end to end encryption, you will need to sign out and back in again.", "Incompatible Database": "Incompatible Database", "Continue With Encryption Disabled": "Continue With Encryption Disabled", "Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirm your account deactivation by using Single Sign On to prove your identity.", From c372e8edee78520346e778f69769bbd84b6660c5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 May 2020 11:29:06 +0100 Subject: [PATCH 091/332] fix viewGroup to actually show the group if possible Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MatrixChat.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 48dc72f4fa..b1076c6ec9 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -932,9 +932,20 @@ export default class MatrixChat extends React.PureComponent { }); } - private viewGroup(payload) { + private async viewGroup(payload) { const groupId = payload.group_id; + + // Wait for the first sync to complete + if (!this.firstSyncComplete) { + if (!this.firstSyncPromise) { + console.warn('Cannot view a group before first sync. group_id:', groupId); + return; + } + await this.firstSyncPromise.promise; + } + this.setState({ + view: Views.LOGGED_IN, currentGroupId: groupId, currentGroupIsNew: payload.group_is_new, }); From c73c3ae9271365ce94e48ae4a74436174b8697f8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 May 2020 11:35:21 +0100 Subject: [PATCH 092/332] Update confirm passphrase copy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/dialogs/keybackup/CreateKeyBackupDialog.js | 5 ++++- .../views/dialogs/secretstorage/CreateSecretStorageDialog.js | 5 ++++- src/i18n/strings/en_EN.json | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js index 532b2f960f..7c5170fab6 100644 --- a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js +++ b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js @@ -284,8 +284,10 @@ export default class CreateKeyBackupDialog extends React.PureComponent { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); let matchText; + let changeText; if (this.state.passPhraseConfirm === this.state.passPhrase) { matchText = _t("That matches!"); + changeText = _t("Use a different passphrase?"); } else if (!this.state.passPhrase.startsWith(this.state.passPhraseConfirm)) { // only tell them they're wrong if they've actually gone wrong. // Security concious readers will note that if you left riot-web unattended @@ -295,6 +297,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent { // Note that not having typed anything at all will not hit this clause and // fall through so empty box === no hint. matchText = _t("That doesn't match."); + changeText = _t("Go back to set it again."); } let passPhraseMatch = null; @@ -303,7 +306,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
{matchText}
- {_t("Go back to set it again.")} + {changeText}
; diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 12b71206d0..e6ab07c449 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -538,8 +538,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent { const Field = sdk.getComponent('views.elements.Field'); let matchText; + let changeText; if (this.state.passPhraseConfirm === this.state.passPhrase) { matchText = _t("That matches!"); + changeText = _t("Use a different passphrase?"); } else if (!this.state.passPhrase.startsWith(this.state.passPhraseConfirm)) { // only tell them they're wrong if they've actually gone wrong. // Security concious readers will note that if you left riot-web unattended @@ -549,6 +551,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { // Note that not having typed anything at all will not hit this clause and // fall through so empty box === no hint. matchText = _t("That doesn't match."); + changeText = _t("Go back to set it again."); } let passPhraseMatch = null; @@ -557,7 +560,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
{matchText}
- {_t("Go back to set it again.")} + {changeText}
; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 96ccf1589d..ded320250b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2217,6 +2217,7 @@ "Back up encrypted message keys": "Back up encrypted message keys", "Set up with a recovery key": "Set up with a recovery key", "That matches!": "That matches!", + "Use a different passphrase?": "Use a different passphrase?", "That doesn't match.": "That doesn't match.", "Go back to set it again.": "Go back to set it again.", "Enter your recovery passphrase a second time to confirm it.": "Enter your recovery passphrase a second time to confirm it.", From 63f78b0808f89dc0fbffd70cc3d176d45d1a57b3 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Mon, 25 May 2020 13:40:05 +0100 Subject: [PATCH 093/332] Move tooltip to ts --- package.json | 2 + .../views/elements/{Field.js => Field.tsx} | 159 ++++++++++-------- .../elements/{Tooltip.js => Tooltip.tsx} | 86 +++++----- .../views/settings/account/PhoneNumbers.js | 2 +- src/dispatcher/actions.ts | 5 + src/dispatcher/payloads/ViewUserPayload.ts | 17 ++ yarn.lock | 12 ++ 7 files changed, 170 insertions(+), 113 deletions(-) rename src/components/views/elements/{Field.js => Field.tsx} (67%) rename src/components/views/elements/{Tooltip.js => Tooltip.tsx} (71%) diff --git a/package.json b/package.json index 7c008d5ccc..620957dd04 100644 --- a/package.json +++ b/package.json @@ -118,9 +118,11 @@ "@peculiar/webcrypto": "^1.0.22", "@types/classnames": "^2.2.10", "@types/flux": "^3.1.9", + "@types/lodash": "^4.14.152", "@types/modernizr": "^3.5.3", "@types/qrcode": "^1.3.4", "@types/react": "16.9", + "@types/react-dom": "^16.9.8", "@types/zxcvbn": "^4.4.0", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", diff --git a/src/components/views/elements/Field.js b/src/components/views/elements/Field.tsx similarity index 67% rename from src/components/views/elements/Field.js rename to src/components/views/elements/Field.tsx index 2ebb90da26..100a6ebf56 100644 --- a/src/components/views/elements/Field.js +++ b/src/components/views/elements/Field.tsx @@ -15,10 +15,9 @@ limitations under the License. */ import React from 'react'; -import PropTypes from 'prop-types'; import classNames from 'classnames'; import * as sdk from '../../../index'; -import { debounce } from 'lodash'; +import { debounce, Cancelable } from 'lodash'; // Invoke validation from user input (when typing, etc.) at most once every N ms. const VALIDATION_THROTTLE_MS = 200; @@ -29,51 +28,88 @@ function getId() { return `${BASE_ID}_${count++}`; } -export default class Field extends React.PureComponent { - static propTypes = { - // The field's ID, which binds the input and label together. Immutable. - id: PropTypes.string, - // The element to create. Defaults to "input". - // To define options for a select, use - element: PropTypes.oneOf(["input", "select", "textarea"]), - // The field's type (when used as an ). Defaults to "text". - type: PropTypes.string, - // id of a element for suggestions - list: PropTypes.string, - // The field's label string. - label: PropTypes.string, - // The field's placeholder string. Defaults to the label. - placeholder: PropTypes.string, - // The field's value. - // This is a controlled component, so the value is required. - value: PropTypes.string.isRequired, - // Optional component to include inside the field before the input. - prefix: PropTypes.node, - // Optional component to include inside the field after the input. - postfix: PropTypes.node, - // The callback called whenever the contents of the field - // changes. Returns an object with `valid` boolean field - // and a `feedback` react component field to provide feedback - // to the user. - onValidate: PropTypes.func, - // If specified, overrides the value returned by onValidate. - flagInvalid: PropTypes.bool, - // If specified, contents will appear as a tooltip on the element and - // validation feedback tooltips will be suppressed. - tooltipContent: PropTypes.node, - // If specified alongside tooltipContent, the class name to apply to the - // tooltip itself. - tooltipClassName: PropTypes.string, - // If specified, an additional class name to apply to the field container - className: PropTypes.string, - // All other props pass through to the . - }; +interface IProps extends React.HTMLAttributes { + // The field's ID, which binds the input and label together. Immutable. + id?: string, + // The element to create. Defaults to "input". + // To define options for a select, use + element?: InputType, + // The field's type (when used as an ). Defaults to "text". + type?: string, + // id of a element for suggestions + list?: string, + // The field's label string. + label?: string, + // The field's placeholder string. Defaults to the label. + placeholder?: string, + // The field's value. + // This is a controlled component, so the value is required. + value: string, + // Optional component to include inside the field before the input. + prefixComponent?: React.ReactNode, + // Optional component to include inside the field after the input. + postfixComponent?: React.ReactNode, + // The callback called whenever the contents of the field + // changes. Returns an object with `valid` boolean field + // and a `feedback` react component field to provide feedback + // to the user. + onValidate?: ( + args: {value: string, focused: boolean, allowEmpty: boolean} + ) => {valid: boolean, feedback: React.ReactNode}, + // If specified, overrides the value returned by onValidate. + flagInvalid?: boolean, + // If specified, contents will appear as a tooltip on the element and + // validation feedback tooltips will be suppressed. + tooltipContent?: React.ReactNode, + // If specified alongside tooltipContent, the class name to apply to the + // tooltip itself. + tooltipClassName?: string, + // If specified, an additional class name to apply to the field container + className?: string, + // All other props pass through to the . +} +enum InputType { + INPUT = "input", + SELECT = "select", + TEXTAREA = "textarea", +} + +interface IState { + valid: boolean, + feedback: React.ReactNode, + feedbackVisible: boolean, + focused: boolean, +} + +export default class Field extends React.PureComponent { + private id: string; + private input: HTMLInputElement; + + /* + * This was changed from throttle to debounce: this is more traditional for + * form validation since it means that the validation doesn't happen at all + * until the user stops typing for a bit (debounce defaults to not running on + * the leading edge). If we're doing an HTTP hit on each validation, we have more + * incentive to prevent validating input that's very unlikely to be valid. + * We may find that we actually want different behaviour for registration + * fields, in which case we can add some options to control it. + */ + validateOnChange = debounce(() => { + this.validate({ + focused: true, + }); + }, VALIDATION_THROTTLE_MS); + + focus() { + this.input.focus(); + } constructor(props) { super(props); this.state = { valid: undefined, feedback: undefined, + feedbackVisible: false, focused: false, }; @@ -114,11 +150,7 @@ export default class Field extends React.PureComponent { } }; - focus() { - this.input.focus(); - } - - async validate({ focused, allowEmpty = true }) { + async validate({ focused, allowEmpty = true }: {focused: boolean, allowEmpty?: boolean}) { if (!this.props.onValidate) { return; } @@ -149,48 +181,37 @@ export default class Field extends React.PureComponent { } } - /* - * This was changed from throttle to debounce: this is more traditional for - * form validation since it means that the validation doesn't happen at all - * until the user stops typing for a bit (debounce defaults to not running on - * the leading edge). If we're doing an HTTP hit on each validation, we have more - * incentive to prevent validating input that's very unlikely to be valid. - * We may find that we actually want different behaviour for registration - * fields, in which case we can add some options to control it. - */ - validateOnChange = debounce(() => { - this.validate({ - focused: true, - }); - }, VALIDATION_THROTTLE_MS); + render() { const { - element, prefix, postfix, className, onValidate, children, + element, prefixComponent, postfixComponent, className, onValidate, children, tooltipContent, flagInvalid, tooltipClassName, list, ...inputProps} = this.props; const inputElement = element || "input"; // Set some defaults for the element inputProps.type = inputProps.type || "text"; - inputProps.ref = input => this.input = input; + const ref = input => this.input = input; inputProps.placeholder = inputProps.placeholder || inputProps.label; inputProps.id = this.id; // this overwrites the id from props inputProps.onFocus = this.onFocus; inputProps.onChange = this.onChange; inputProps.onBlur = this.onBlur; - inputProps.list = list; - const fieldInput = React.createElement(inputElement, inputProps, children); + // Appease typescript's inference + const inputProps_ = {...inputProps, ref, list}; + + const fieldInput = React.createElement(inputElement, inputProps_, children); let prefixContainer = null; - if (prefix) { - prefixContainer = {prefix}; + if (prefixComponent) { + prefixContainer = {prefixComponent}; } let postfixContainer = null; - if (postfix) { - postfixContainer = {postfix}; + if (postfixComponent) { + postfixContainer = {postfixComponent}; } const hasValidationFlag = flagInvalid !== null && flagInvalid !== undefined; @@ -198,7 +219,7 @@ export default class Field extends React.PureComponent { // If we have a prefix element, leave the label always at the top left and // don't animate it, as it looks a bit clunky and would add complexity to do // properly. - mx_Field_labelAlwaysTopLeft: prefix, + mx_Field_labelAlwaysTopLeft: prefixComponent, mx_Field_valid: onValidate && this.state.valid === true, mx_Field_invalid: hasValidationFlag ? flagInvalid diff --git a/src/components/views/elements/Tooltip.js b/src/components/views/elements/Tooltip.tsx similarity index 71% rename from src/components/views/elements/Tooltip.js rename to src/components/views/elements/Tooltip.tsx index 4807ade3db..753052717c 100644 --- a/src/components/views/elements/Tooltip.js +++ b/src/components/views/elements/Tooltip.tsx @@ -18,67 +18,68 @@ limitations under the License. */ -import React from 'react'; +import React, { Component } from 'react'; import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import createReactClass from 'create-react-class'; import dis from '../../../dispatcher/dispatcher'; import classNames from 'classnames'; +import { ViewTooltipPayload } from '../../../dispatcher/payloads/ViewUserPayload'; +import { Action } from '../../../dispatcher/actions'; const MIN_TOOLTIP_HEIGHT = 25; -export default createReactClass({ - displayName: 'Tooltip', - - propTypes: { +interface IProps { // Class applied to the element used to position the tooltip - className: PropTypes.string, + className: string, // Class applied to the tooltip itself - tooltipClassName: PropTypes.string, + tooltipClassName: string, // Whether the tooltip is visible or hidden. // The hidden state allows animating the tooltip away via CSS. // Defaults to visible if unset. - visible: PropTypes.bool, + visible: boolean, // the react element to put into the tooltip - label: PropTypes.node, - }, + label: React.ReactNode, +} - getDefaultProps() { - return { - visible: true, - }; - }, +class Tooltip extends React.Component { + private tooltipContainer: HTMLElement; + private tooltip: void | Element | Component; + private parent: Element; + + + static defaultProps = { + visible: true, + }; // Create a wrapper for the tooltip outside the parent and attach it to the body element - componentDidMount: function() { + componentDidMount() { this.tooltipContainer = document.createElement("div"); this.tooltipContainer.className = "mx_Tooltip_wrapper"; document.body.appendChild(this.tooltipContainer); - window.addEventListener('scroll', this._renderTooltip, true); + window.addEventListener('scroll', this.renderTooltip, true); - this.parent = ReactDOM.findDOMNode(this).parentNode; + this.parent = ReactDOM.findDOMNode(this).parentNode as Element; - this._renderTooltip(); - }, + this.renderTooltip(); + } - componentDidUpdate: function() { - this._renderTooltip(); - }, + componentDidUpdate() { + this.renderTooltip(); + } // Remove the wrapper element, as the tooltip has finished using it - componentWillUnmount: function() { - dis.dispatch({ - action: 'view_tooltip', + componentWillUnmount() { + dis.dispatch({ + action: Action.ViewTooltip, tooltip: null, parent: null, }); ReactDOM.unmountComponentAtNode(this.tooltipContainer); document.body.removeChild(this.tooltipContainer); - window.removeEventListener('scroll', this._renderTooltip, true); - }, + window.removeEventListener('scroll', this.renderTooltip, true); + } - _updatePosition(style) { + private updatePosition(style: {[key: string]: any}) { const parentBox = this.parent.getBoundingClientRect(); let offset = 0; if (parentBox.height > MIN_TOOLTIP_HEIGHT) { @@ -91,16 +92,15 @@ export default createReactClass({ style.top = (parentBox.top - 2) + window.pageYOffset + offset; style.left = 6 + parentBox.right + window.pageXOffset; return style; - }, + } - _renderTooltip: function() { + private renderTooltip() { // Add the parent's position to the tooltips, so it's correctly // positioned, also taking into account any window zoom // NOTE: The additional 6 pixels for the left position, is to take account of the // tooltips chevron - const parent = ReactDOM.findDOMNode(this).parentNode; - let style = {}; - style = this._updatePosition(style); + const parent = ReactDOM.findDOMNode(this).parentNode as Element; + const style = this.updatePosition({}); // Hide the entire container when not visible. This prevents flashing of the tooltip // if it is not meant to be visible on first mount. style.display = this.props.visible ? "block" : "none"; @@ -118,21 +118,21 @@ export default createReactClass({ ); // Render the tooltip manually, as we wish it not to be rendered within the parent - this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer); + this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer); // Tell the roomlist about us so it can manipulate us if it wishes - dis.dispatch({ - action: 'view_tooltip', + dis.dispatch({ + action: Action.ViewTooltip, tooltip: this.tooltip, parent: parent, }); - }, + } - render: function() { + render() { // Render a placeholder return (
); - }, -}); + } +} diff --git a/src/components/views/settings/account/PhoneNumbers.js b/src/components/views/settings/account/PhoneNumbers.js index ad2dabd8ae..02e995ac45 100644 --- a/src/components/views/settings/account/PhoneNumbers.js +++ b/src/components/views/settings/account/PhoneNumbers.js @@ -267,7 +267,7 @@ export default class PhoneNumbers extends React.Component { label={_t("Phone Number")} autoComplete="off" disabled={this.state.verifying} - prefix={phoneCountry} + prefixComponent={phoneCountry} value={this.state.newPhoneNumber} onChange={this._onChangeNewPhoneNumber} /> diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index a2f9c3efe3..9cd9f7c9ba 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -38,5 +38,10 @@ export enum Action { * Open the user settings. No additional payload information required. */ ViewUserSettings = "view_user_settings", + + /** + * Sets the current tooltip + */ + ViewTooltip = "view_tooltip", } diff --git a/src/dispatcher/payloads/ViewUserPayload.ts b/src/dispatcher/payloads/ViewUserPayload.ts index ed602d4e24..d1f6db8968 100644 --- a/src/dispatcher/payloads/ViewUserPayload.ts +++ b/src/dispatcher/payloads/ViewUserPayload.ts @@ -17,6 +17,7 @@ limitations under the License. import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { ActionPayload } from "../payloads"; import { Action } from "../actions"; +import { Component } from "react"; export interface ViewUserPayload extends ActionPayload { action: Action.ViewUser, @@ -27,3 +28,19 @@ export interface ViewUserPayload extends ActionPayload { */ member?: RoomMember; } + +export interface ViewTooltipPayload extends ActionPayload { + action: Action.ViewTooltip, + + /* + * The tooltip to render. If it's null the tooltip will not be rendered + * We need the void type because of typescript headaches. + */ + tooltip: null | void | Element | Component; + + /* + * The parent under which to render the tooltip. Can be null to remove + * the parent type. + */ + parent: null | Element +} diff --git a/yarn.lock b/yarn.lock index 93118dab22..9253442b7c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1265,6 +1265,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== +"@types/lodash@^4.14.152": + version "4.14.152" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.152.tgz#7e7679250adce14e749304cdb570969f77ec997c" + integrity sha512-Vwf9YF2x1GE3WNeUMjT5bTHa2DqgUo87ocdgTScupY2JclZ5Nn7W2RLM/N0+oreexUk8uaVugR81NnTY/jNNXg== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1292,6 +1297,13 @@ dependencies: "@types/node" "*" +"@types/react-dom@^16.9.8": + version "16.9.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" + integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA== + dependencies: + "@types/react" "*" + "@types/react@*": version "16.9.35" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.35.tgz#a0830d172e8aadd9bd41709ba2281a3124bbd368" From 10e433314c77ecfeca55ea91e15a2920a49d8670 Mon Sep 17 00:00:00 2001 From: "J. A. Durieux" Date: Sat, 23 May 2020 21:31:51 +0000 Subject: [PATCH 094/332] Translated using Weblate (Dutch) Currently translated at 91.6% (2126 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 105 +++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 5dfb779ff1..b4bb5dc5bd 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -45,7 +45,7 @@ "Continue": "Doorgaan", "Could not connect to the integration server": "Verbinding met de integratieserver is mislukt", "Cancel": "Annuleren", - "Accept": "Aanvaarden", + "Accept": "Aannemen", "Active call (%(roomName)s)": "Actieve oproep (%(roomName)s)", "Add": "Toevoegen", "Add a topic": "Voeg een onderwerp toe", @@ -140,7 +140,7 @@ "Create Room": "Gesprek aanmaken", "Curve25519 identity key": "Curve25519-identiteitssleutel", "/ddg is not a command": "/ddg is geen opdracht", - "Deactivate Account": "Account deactiveren", + "Deactivate Account": "Account sluiten", "Decline": "Weigeren", "Decrypt %(text)s": "%(text)s ontsleutelen", "Decryption error": "Ontsleutelingsfout", @@ -283,7 +283,7 @@ "The phone number entered looks invalid": "Het ingevoerde telefoonnummer ziet er ongeldig uit", "This email address is already in use": "Dit e-mailadres is al in gebruik", "This email address was not found": "Dit e-mailadres is niet gevonden", - "The email address linked to your account must be entered.": "Het e-mailadres dat met uw account verbonden is moet ingevoerd worden.", + "The email address linked to your account must be entered.": "Het aan uw account gekoppelde e-mailadres dient ingevoerd worden.", "The remote side failed to pick up": "De andere kant heeft niet opgenomen", "This room has no local addresses": "Dit gesprek heeft geen lokale adressen", "This room is not recognised.": "Dit gesprek wordt niet herkend.", @@ -378,7 +378,7 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Hiermee kunt u vanuit een andere Matrix-cliënt weggeschreven versleutelingssleutels inlezen, zodat u alle berichten die de andere cliënt kon ontcijferen ook hier kunt lezen.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Het weggeschreven bestand is beveiligd met een wachtwoord. Voer dat wachtwoord hier in om het bestand te ontsleutelen.", "You must join the room to see its files": "Slechts na toetreding tot het gesprek zult u de bestanden kunnen zien", - "Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s-uitnodigingen weigeren", + "Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s de uitnodigingen weigeren", "Failed to invite": "Uitnodigen is mislukt", "Failed to invite the following users to the %(roomName)s room:": "Kon de volgende gebruikers niet uitnodigen voor gesprek %(roomName)s:", "Confirm Removal": "Verwijdering bevestigen", @@ -584,11 +584,11 @@ "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s zijn weggegaan en weer toegetreden", "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s is %(count)s keer weggegaan en weer toegetreden", "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s is weggegaan en weer toegetreden", - "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s hebben hun uitnodigingen %(count)s keer afgewezen", - "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s hebben hun uitnodigingen afgewezen", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s hebben hun uitnodigingen %(count)s maal afgeslagen", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s hebben hun uitnodigingen afgeslagen", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s heeft de uitnodiging %(count)s maal geweigerd", "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s heeft de uitnodiging geweigerd", - "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "De uitnodigingen van %(severalUsers)s zijn %(count)s keer ingetrokken", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s hebben hun uitnodigingen %(count)s maal ingetrokken", "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "De uitnodigingen van %(severalUsers)s zijn ingetrokken", "%(oneUser)shad their invitation withdrawn %(count)s times|other": "De uitnodiging van %(oneUser)s is %(count)s keer ingetrokken", "%(oneUser)shad their invitation withdrawn %(count)s times|one": "De uitnodiging van %(oneUser)s is ingetrokken", @@ -648,7 +648,7 @@ "Failed to remove a user from the summary of %(groupId)s": "Verwijderen van gebruiker uit het overzicht van %(groupId)s is mislukt", "The user '%(displayName)s' could not be removed from the summary.": "De gebruiker ‘%(displayName)s’ kon niet uit het overzicht verwijderd worden.", "Failed to update community": "Bijwerken van gemeenschap is mislukt", - "Unable to accept invite": "Kan de uitnodiging niet aanvaarden", + "Unable to accept invite": "Kan de uitnodiging niet aannemen", "Unable to reject invite": "Kan de uitnodiging niet weigeren", "Leave Community": "Gemeenschap verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", @@ -741,7 +741,7 @@ "Send Custom Event": "Aangepaste gebeurtenis versturen", "Advanced notification settings": "Geavanceerde meldingsinstellingen", "delete the alias.": "verwijder de bijnaam.", - "To return to your account in future you need to set a password": "Tenzij u een wachtwoord instelt zult u uw account niet meer kunnen benaderen", + "To return to your account in future you need to set a password": "Om uw account te kunnen blijven gebruiken dient u een wachtwoord in te stellen", "Forget": "Vergeten", "You cannot delete this image. (%(code)s)": "U kunt deze afbeelding niet verwijderen. (%(code)s)", "Cancel Sending": "Versturen annuleren", @@ -830,7 +830,7 @@ "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen aan een gesprek op dit netwerk", "Mentions only": "Alleen vermeldingen", "Wednesday": "Woensdag", - "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", + "You can now return to your account after signing out, and sign in on other devices.": "Na afmelding kunt u terugkeren tot uw account, en u op andere apparaten aanmelden.", "Enable email notifications": "E-mailmeldingen inschakelen", "Event Type": "Gebeurtenistype", "Download this file": "Dit bestand downloaden", @@ -863,10 +863,10 @@ "Yes, I want to help!": "Ja, ik wil helpen!", "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 deze deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. Deze actie 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 deactiveren van uw account zal er standaard niet voor zorgen dat de berichten die u heeft verstuurd vergeten worden. Als u wilt dat wij de berichten vergeten, vinkt u het vakje hieronder aan.", + "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.", + "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 alle berichten die ik heb verstuurd wanneer mijn account gedeactiveerd is (Let op: dit zal er voor zorgen dat toekomstige gebruikers een onvolledig beeld krijgen van gesprekken)", + "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)", "To continue, please enter your password:": "Voer uw wachtwoord in om verder te gaan:", "Clear Storage and Sign Out": "Opslag wissen en afmelden", "Send Logs": "Logboek versturen", @@ -877,7 +877,7 @@ "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.", "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 lezen en aanvaarden.", + "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.", "Review terms and conditions": "Gebruiksvoorwaarden lezen", "Call in Progress": "Lopend gesprek", "A call is currently being placed!": "Er wordt al een oproep gemaakt!", @@ -989,7 +989,7 @@ "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 join/leave messages (invites/kicks/bans unaffected)": "Berichten over deelnamen en verlatingen tonen (dit heeft geen effect op uitnodigingen, berispingen of verbanningen)", + "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", @@ -1107,7 +1107,7 @@ "Language and region": "Taal en regio", "Theme": "Thema", "Account management": "Accountbeheer", - "Deactivating your account is a permanent action - be careful!": "Het deactiveren van uw account kan niet ongedaan gemaakt worden - wees voorzichtig!", + "Deactivating your account is a permanent action - be careful!": "Pas op! Het sluiten van uw account kan niet ongedaan gemaakt worden!", "General": "Algemeen", "Legal": "Wettelijk", "Credits": "Met dank aan", @@ -1122,7 +1122,7 @@ "Timeline": "Tijdslijn", "Room list": "Gesprekslijst", "Autocomplete delay (ms)": "Vertraging voor automatisch aanvullen (ms)", - "Accept all %(invitedRooms)s invites": "Alle %(invitedRooms)s-uitnodigingen aanvaarden", + "Accept all %(invitedRooms)s invites": "Alle %(invitedRooms)s de uitnodigingen aannemen", "Key backup": "Sleutelback-up", "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.", @@ -1210,7 +1210,7 @@ "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.", "Waiting for partner to confirm...": "Wachten op bevestiging van partner…", "Incoming Verification Request": "Inkomend verificatieverzoek", - "You've previously used Riot 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, Riot needs to resync your account.": "U heeft voorheen Riot op %(host)s gebruikt met lui laden van leden ingeschakeld. In deze versie is lui laden uitgeschakeld. Omdat de lokale cache niet compatibel is tussen deze twee instellingen, moet Riot uw account opnieuw synchroniseren.", + "You've previously used Riot 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, Riot needs to resync your account.": "U heeft voorheen Riot op %(host)s gebruikt met lui laden van leden ingeschakeld. In deze versie is lui laden uitgeschakeld. De lokale cache is niet compatibel tussen deze twee instellingen, zodat Riot uw account moet hersynchroniseren.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Indien de andere versie van Riot nog open staat in een ander tabblad kunt u dat beter sluiten, want het geeft problemen als Riot op dezelfde host gelijktijdig met lui laden ingeschakeld en uitgeschakeld draait.", "Incompatible local cache": "Incompatibele lokale cache", "Clear cache and resync": "Cache wissen en hersynchroniseren", @@ -1261,18 +1261,18 @@ "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.", - "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.": "U kunt de aangepaste serveropties gebruiken om u aan te melden bij andere Matrix-servers, door een andere thuisserver-URL op te geven. Dit biedt u de mogelijkheid om deze toepassing te gebruiken met een bestaande Matrix-account op een andere thuisserver.", - "Please review and accept all of the homeserver's policies": "Gelieve het beleid van de thuisserver te doornemen en aanvaarden", - "Please review and accept the policies of this homeserver:": "Gelieve het beleid van deze thuisserver te doornemen en aanvaarden:", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.": "Middels de aangepaste serveropties kunt u zich aanmelden bij andere Matrix-servers, door een andere thuisserver-URL op te geven. Zo kunt u deze toepassing met een bestaande Matrix-account op een andere thuisserver gebruiken.", + "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:", "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", "The username field must not be blank.": "Het gebruikersnaamveld mag niet leeg zijn.", "Username": "Gebruikersnaam", - "Not sure of your password? Set a new one": "Onzeker over uw wachtwoord? Stel er een nieuw in", + "Not sure of your password? Set a new one": "Onzeker over uw wachtwoord? Stel een nieuw in", "Sign in to your Matrix account on %(serverName)s": "Aanmelden met uw Matrix-account op %(serverName)s", "Change": "Wijzigen", - "Create your Matrix account on %(serverName)s": "Maak uw Matrix-account aan op %(serverName)s", + "Create your Matrix account on %(serverName)s": "Maak uw Matrix-account op %(serverName)s aan", "Email (optional)": "E-mailadres (optioneel)", "Phone (optional)": "Telefoonnummer (optioneel)", "Confirm": "Bevestigen", @@ -1444,7 +1444,7 @@ "Edit message": "Bericht bewerken", "View Servers in Room": "Servers in gesprek bekijken", "Unable to validate homeserver/identity server": "Kan thuis-/identiteitsserver niet valideren", - "Sign in to your Matrix account on ": "Meld u aan met uw Matrix-account op ", + "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)", "Doesn't look like a valid email address": "Dit lijkt geen geldig e-mailadres", @@ -1457,7 +1457,7 @@ "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", - "Create your Matrix account on ": "Maak uw Matrix-account aan op ", + "Create your Matrix account on ": "Maak uw Matrix-account op aan", "Add room": "Gesprek toevoegen", "Your profile": "Uw profiel", "Your Matrix account on ": "Uw Matrix-account op ", @@ -1485,7 +1485,7 @@ "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 aanmelden 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.", "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).", @@ -1509,7 +1509,7 @@ "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": "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 opnieuw toegang te verkrijgen tot uw account.", + "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?", "You're signed out": "U bent afgemeld", "Clear personal data": "Persoonlijke gegevens wissen", @@ -1521,9 +1521,9 @@ "Terms of Service": "Gebruiksvoorwaarden", "Service": "Dienst", "Summary": "Samenvatting", - "Sign in and regain access to your account.": "Meld u aan en verkrijg opnieuw 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 contact op met de beheerder van uw thuisserver voor meer informatie.", - "This account has been deactivated.": "Deze account is gedeactiveerd.", + "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.", + "This account has been deactivated.": "Deze account is gesloten.", "Messages": "Berichten", "Actions": "Acties", "Displays list of commands with usages and descriptions": "Toont een lijst van beschikbare opdrachten, met hun gebruiken en beschrijvingen", @@ -1539,7 +1539,7 @@ "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.": "De verbinding met uw identiteitsserver verbreken zal ertoe leiden dat u niet door andere gebruikers gevonden zal kunnen worden, en dat u anderen niet via e-mail of telefoon zal kunnen uitnodigen.", "Integration Manager": "Integratiebeheerder", "Discovery": "Ontdekking", - "Deactivate account": "Account deactiveren", + "Deactivate account": "Account sluiten", "Always show the window menu bar": "De venstermenubalk altijd tonen", "Unable to revoke sharing for email address": "Kan delen voor dit e-mailadres niet intrekken", "Unable to share email address": "Kan e-mailadres niet delen", @@ -1611,11 +1611,11 @@ "Strikethrough": "Doorstreept", "Code block": "Codeblok", "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Er is een fout opgetreden (%(errcode)s) bij het valideren van uw uitnodiging. U kunt deze informatie doorgeven aan een gespreksbeheerder.", - "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Deze uitnodiging tot %(roomName)s was verstuurd naar %(email)s, wat niet aan uw account gekoppeld is", - "Link this email with your account in Settings to receive invites directly in Riot.": "Koppel dit e-mailadres aan uw account in de instellingen om uitnodigingen automatisch te ontvangen in Riot.", + "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Deze uitnodiging tot %(roomName)s was verstuurd naar %(email)s, dat niet aan uw account gekoppeld is", + "Link this email with your account in Settings to receive invites directly in Riot.": "Koppel in de instellingen dit e-mailadres aan uw account om uitnodigingen direct in Riot te ontvangen.", "This invite to %(roomName)s was sent to %(email)s": "Deze uitnodiging tot %(roomName)s was verstuurd naar %(email)s", - "Use an identity server in Settings to receive invites directly in Riot.": "Gebruik een identiteitsserver in de instellingen om uitnodigingen automatisch te ontvangen in Riot.", - "Share this email in Settings to receive invites directly in Riot.": "Deel dit e-mailadres in de instellingen om uitnodigingen automatisch te ontvangen in Riot.", + "Use an identity server in Settings to receive invites directly in Riot.": "Gebruik in de instellingen een identiteitsserver om uitnodigingen direct in Riot te ontvangen.", + "Share this email in Settings to receive invites directly in Riot.": "Deel in de instellingen dit e-mailadres om uitnodigingen direct in Riot te ontvangen.", "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.", @@ -1623,8 +1623,8 @@ "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.", "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 in voor accountherstel. Gebruik optioneel een e-mailadres of telefoonnummer om vindbaar te zijn voor bestaande contacten.", - "Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Stel een e-mailadres in voor accountherstel. Gebruik optioneel een e-mailadres om vindbaar te zijn voor bestaande contacten.", + "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.", + "Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Stel een e-mailadres voor accountherstel in. Gebruik eventueel een e-mailadres om vindbaar te zijn voor bestaande contacten.", "Enter your custom homeserver URL What does this mean?": "Voer uw aangepaste thuisserver-URL in Wat betekent dit?", "Enter your custom identity server URL What does this mean?": "Voer uw aangepaste identiteitsserver-URL in Wat betekent dit?", "Explore": "Ontdekken", @@ -1864,7 +1864,7 @@ "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.", - "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Uw account heeft een identiteit voor kruiselings ondertekenen in de sleutelopslag, maar deze is nog niet vertrouwd door de huidige sessie.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Uw account heeft een identiteit voor kruiselings ondertekenen in de sleutelopslag, maar die wordt nog niet vertrouwd door de huidige sessie.", "Cross-signing and secret storage are not yet set up.": "Kruiselings ondertekenen en sleutelopslag zijn nog niet ingesteld.", "Bootstrap cross-signing and secret storage": "Kruiselings ondertekenen en sleutelopslag instellen", "Reset cross-signing and secret storage": "Kruiselings ondertekenen en sleutelopslag opnieuw instellen", @@ -1898,7 +1898,7 @@ "Homeserver feature support:": "Functies ondersteund door thuisserver:", "exists": "bestaat", "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 er een nieuwe aan om verder te gaan.", + "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", "Displays information about a user": "Geeft informatie weer over een gebruiker", "Order rooms by name": "Gesprekken sorteren op naam", @@ -1938,7 +1938,7 @@ "Send as message": "Versturen als bericht", "Failed to connect to integration manager": "Verbinding met integratiebeheerder is mislukt", "Waiting for %(displayName)s to accept…": "Wachten tot %(displayName)s aanvaardt…", - "Accepting…": "Aanvaarden…", + "Accepting…": "Toestaan…", "Start Verification": "Verificatie beginnen", "Messages in this room are end-to-end encrypted.": "De berichten in dit gesprek worden eind-tot-eind-versleuteld.", "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Uw berichten zijn beveiligd, en enkel de ontvanger en u hebben de unieke sleutels om ze te ontsleutelen.", @@ -1995,7 +1995,7 @@ "You cancelled": "U heeft geannuleerd", "%(name)s declined": "%(name)s heeft geweigerd", "%(name)s cancelled": "%(name)s heeft geannuleerd", - "Accepting …": "Aanvaarden…", + "Accepting …": "Toestaan…", "Declining …": "Weigeren…", "%(name)s wants to verify": "%(name)s wil verifiëren", "You sent a verification request": "U heeft een verificatieverzoek verstuurd", @@ -2061,14 +2061,14 @@ "You added a new session '%(displayName)s', which is requesting encryption keys.": "U heeft een nieuwe sessie ‘%(displayName)s’ toegevoegd, die om versleutelingssleutels vraagt.", "Your unverified session '%(displayName)s' is requesting encryption keys.": "Uw ongeverifieerde sessie ‘%(displayName)s’ vraagt om versleutelingssleutels.", "Loading session info...": "Sessie-info wordt geladen…", - "Your account is not secure": "Uw account is niet veilig", + "Your account is not secure": "Uw account is onveilig", "Your password": "Uw wachtwoord", "This session, or the other session": "Deze sessie, of de andere sessie", "The internet connection either session is using": "De internetverbinding gebruikt door een van de sessies", "We recommend you change your password and recovery key in Settings immediately": "We raden u aan onmiddellijk uw wachtwoord en herstelsleutel te wijzigen in de instellingen", "New session": "Nieuwe sessie", "Use this session to verify your new one, granting it access to encrypted messages:": "Gebruik deze sessie om uw nieuwe sessie te verifiëren, waardoor deze laatste toegang verkrijgt tot versleutelde berichten:", - "If you didn’t sign in to this session, your account may be compromised.": "Als u zich niet heeft aangemeld bij deze sessie, is uw account mogelijk gecompromitteerd.", + "If you didn’t sign in to this session, your account may be compromised.": "Als u zich niet heeft aangemeld bij deze sessie, is uw account wellicht geschonden.", "This wasn't me": "Dat was ik niet", "Automatically invite users": "Gebruikers automatisch uitnodigen", "Upgrade private room": "Privégesprek bijwerken", @@ -2076,7 +2076,7 @@ "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Het bijwerken van een gesprek is een gevorderde actie en wordt meestal aanbevolen wanneer een gesprek onstabiel is door fouten, ontbrekende functies of problemen met de beveiliging.", "This usually only affects how the room is processed on the server. If you're having problems with your Riot, please report a bug.": "Dit heeft meestal enkel een invloed op de manier waarop het gesprek door de server verwerkt wordt. Als u problemen met uw Riot ondervindt, dien dan een foutmelding in.", "You'll upgrade this room from to .": "U werkt dit gesprek bij van naar .", - "This will allow you to return to your account after signing out, and sign in on other sessions.": "Dit biedt u de mogelijkheid om terug te keren naar uw account nadat u zich heeft afgemeld, en om u aan te melden bij andere sessies.", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Daardoor kunt u na afmelding terugkeren tot uw account, en u bij andere sessies aanmelden.", "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "U blokkeert momenteel niet-geverifieerde sessies; om berichten te sturen naar deze sessies moet u ze verifiëren.", "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We raden u aan om het verificatieproces voor elke sessie te doorlopen om te bevestigen dat ze aan hun rechtmatige eigenaar toebehoren, maar u kunt het bericht ook opnieuw versturen zonder verificatie indien u dit wenst.", "Room contains unknown sessions": "Gesprek bevat onbekende sessies", @@ -2122,8 +2122,8 @@ "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.", - "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.": "Verkrijg opnieuw de toegang tot uw account en herstel de versleutelingssleutels die in deze sessie opgeslagen zijn. Hierzonder zult u niet al uw beveiligde berichten in al uw sessies kunnen lezen.", - "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 (versleutelingssleutels inbegrepen) worden 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.", + "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", "DuckDuckGo Results": "DuckDuckGo-resultaten", "Sender session information": "Sessie-informatie van afzender", @@ -2177,7 +2177,7 @@ "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 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.", - "Review Sessions": "Sessieverificatie", + "Review Sessions": "Sessies nazien", "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?", @@ -2200,5 +2200,14 @@ "Verify your other session using one of the options below.": "Verifieer uw andere sessie op een van onderstaande wijzen.", "Manually Verify by Text": "Handmatig middels een tekst", "Interactively verify by Emoji": "Interactief middels emojis", - "Support adding custom themes": "Sta maatwerkthema's toe" + "Support adding custom themes": "Sta maatwerkthema's toe", + "Opens chat with the given user": "Start een tweegesprek met die gebruiker", + "Sends a message to the given user": "Zendt die gebruiker een bericht", + "Font scaling": "Lettergrootte", + "Use the improved room list (in development - refresh to apply changes)": "Gebruik de verbeterde gesprekslijst (in ontwikkeling - ververs om veranderingen te zien)", + "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.", + "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" } From 2a2967d88b386696f42942da0b25af861cb80ff9 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sat, 23 May 2020 18:30:36 +0000 Subject: [PATCH 095/332] Translated using Weblate (Esperanto) Currently translated at 100.0% (2322 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index f201d5a117..983ba9e7db 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -385,7 +385,7 @@ "Communities": "Komunumoj", "Home": "Hejmo", "Could not connect to the integration server": "Malsukcesis konektiĝi al la kuniga servilo", - "Manage Integrations": "Administri integrojn", + "Manage Integrations": "Administri kunigojn", "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s%(count)s-foje aliĝis", "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)saliĝis", @@ -882,7 +882,7 @@ "Delete Backup": "Forigi savkopion", "Language and region": "Lingvo kaj regiono", "Theme": "Haŭto", - "General": "Ĝenerala", + "General": "Ĝeneralaj", "In reply to ": "Responde al ", "Share Message": "Diskonigi", "Whether or not you're logged in (we don't record your username)": "Ĉu vi salutis aŭ ne (ni ne registras vian uzantonomon)", @@ -974,9 +974,9 @@ "Room list": "Ĉambrolisto", "Ignored users": "Malatentaj uzantoj", "Key backup": "Sekurkopio de ŝlosilo", - "Security & Privacy": "Sekureco & Privateco", + "Security & Privacy": "Sekureco kaj Privateco", "Voice & Video": "Voĉo kaj vido", - "Room information": "Ĉambraj informoj", + "Room information": "Informoj pri ĉambro", "Internal room ID:": "Ena ĉambra identigilo:", "Room version": "Ĉambra versio", "Room version:": "Ĉambra versio:", @@ -998,7 +998,7 @@ "Remove messages": "Forigi mesaĝojn", "Notify everyone": "Sciigi ĉiujn", "Muted Users": "Silentigitaj uzantoj", - "Roles & Permissions": "Roloj & Permesoj", + "Roles & Permissions": "Roloj kaj Permesoj", "Enable encryption?": "Ĉu ŝalti ĉifradon?", "Share Link to User": "Kunhavigi ligilon al uzanto", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vidita de %(displayName)s (%(userName)s) je %(dateTime)s", @@ -1017,7 +1017,7 @@ "To continue, please enter your password:": "Por daŭrigi, bonvoluenigi vian pasvorton:", "Updating Riot": "Ĝisdatigante Riot", "Go back": "Reen iri", - "Room Settings - %(roomName)s": "Ĉambraj agordoj — %(roomName)s", + "Room Settings - %(roomName)s": "Agordoj de ĉambro – %(roomName)s", "Failed to upgrade room": "Malsukcesis gradaltigi ĉambron", "Refresh": "Aktualigi", "Checking...": "Kontrolante…", @@ -1025,7 +1025,7 @@ "Share User": "Kunhavigi uzanton", "Share Community": "Kunhavigi komunumon", "Share Room Message": "Kunhavigi ĉambran mesaĝon", - "COPY": "KOPIO", + "COPY": "KOPII", "Next": "Sekva", "Clear status": "Vakigi staton", "Update status": "Ĝisdatigi staton", @@ -1386,7 +1386,7 @@ "The conversation continues here.": "La interparolo pluas ĉi tie.", "This room has been replaced and is no longer active.": "Ĉi tiu ĉambro estas anstataŭita, kaj ne plu aktivas.", "Loading room preview": "Preparas antaŭrigardon al la ĉambro", - "Only room administrators will see this warning": "Nur ĉambraj administrantoj vidos ĉi tiun averton", + "Only room administrators will see this warning": "Nur administrantoj de ĉambro vidos ĉi tiun averton", "Error updating flair": "Eraris ĝisdatigo de etikedo", "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Eraris ĝisdatigo de etikedo por ĉi tiu ĉambro. Aŭ la servilo ne permesas ĝin, aŭ dumtempa eraro okazis.", "Showing flair for these communities:": "Montras etikedojn de la jenaj komunumoj:", @@ -2055,7 +2055,7 @@ "%(displayName)s cancelled verification. Start verification again from their profile.": "%(displayName)s nuligis la kontrolon. Rekomencu ĝin de ĝia profilo.", "You cancelled verification. Start verification again from their profile.": "Vi nuligis la kontrolon. Rekomencu ĝin de ĝia profilo.", "Encryption enabled": "Ĉifrado estas ŝaltita", - "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Mesaĝojn en ĉi tiu ĉambro estas tutvoje ĉifrataj. Eksciu plion kaj kontrolu ĉi tiun uzanton el ĝia profilo.", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Mesaĝoj en ĉi tiu ĉambro estas tutvoje ĉifrataj. Eksciu plion kaj kontrolu ĉi tiun uzanton per ĝia profilo.", "Encryption not enabled": "Ĉifrado ne estas ŝaltita", "The encryption used by this room isn't supported.": "La ĉifro uzata de ĉi tiu ĉambro ne estas subtenata.", "You have ignored this user, so their message is hidden. Show anyways.": "Vi malatentis ĉi tiun uzanton, ĝia mesaĝo estas do kaŝita. Tamen montri.", From 4395c59eb1a9919582e5983b98b0b3a7d57e35be Mon Sep 17 00:00:00 2001 From: Samu Voutilainen Date: Mon, 25 May 2020 04:38:28 +0000 Subject: [PATCH 096/332] Translated using Weblate (Finnish) Currently translated at 96.1% (2232 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 05bf538ff9..66c07d3722 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -2276,5 +2276,42 @@ "Select room from the room list": "Valitse huone huoneluettelosta", "Previous/next unread room or DM": "Edellinen/seuraava lukematon huone tai yksityisviesti", "Previous/next room or DM": "Edellinen/seuraava huone tai yksityisviesti", - "Toggle this dialog": "Tämä valintaikkuna päälle/pois" + "Toggle this dialog": "Tämä valintaikkuna päälle/pois", + "Use the improved room list (in development - refresh to apply changes)": "Käytä parannettua huoneluetteloa (kehitysversio — päivitä sivu ottaaksesi muutokset käyttöön)", + "Start verification again from the notification.": "Aloita varmennus uudelleen ilmoituksesta.", + "Start verification again from their profile.": "Aloita varmennus uudelleen hänen profiilista.", + "Verification timed out.": "Varmennuksessa kesti liikaa.", + "You cancelled verification on your other session.": "Peruutit varmennuksen toisessa istunnossasi.", + "%(displayName)s cancelled verification.": "%(displayName)s peruutti varmennuksen.", + "You cancelled verification.": "Peruutit varmennuksen.", + "Verification cancelled": "Varmennus peruutettu", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Tämän huoneen viestit ovat salattuja osapuolten välisellä salauksella. Lue lisää ja varmenna tämä käyttäjä hänen profiilistaan.", + "Enter the name of a new server you want to explore.": "Syötä sen uuden palvelimen nimi, jota hauat tutkia.", + "%(networkName)s rooms": "Verkon %(networkName)s huoneet", + "Destroy cross-signing keys?": "Tuhoa ristivarmennuksen avaimet?", + "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.": "Ristivarmennuksen avainten tuhoamista ei voi kumota. Jokainen, jonka olet varmentanut, tulee näkemään turvallisuushälytyksiä. Et todennäköisesti halua tehdä tätä, ellet ole hukannut kaikkia laitteitasi, joista pystyt ristivarmentamaan.", + "Clear cross-signing keys": "Tyhjennä ristivarmennuksen avaimet", + "Enable end-to-end encryption": "Ota osapuolten välinen salaus käyttöön", + "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Jotta tähän istuntoon voitaisiin luottaa, tarkista, että käyttäjän asetuksissa näkyvä avain täsmää alapuolella olevaan avaimeen:", + "To verify that this session can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this session matches the key below:": "Jotta tähän istuntoon voitaisiin luottaa, ota yhteyttä sen omistajaan jotain muuta kautta (esim. kasvotusten tai puhelimitse) ja kysy, että täsmääkö hänen käyttäjäasetuksissa näkemänsä istunnon avain alla olevaan:", + "Session key": "Istunnon tunnus", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.": "Jos se täsmää, paina varmennuspainiketta alapuolella. Jos se ei täsmää, joku häiritsee tätä istuntoa ja haluat luultavasti painaa estä -painiketta sen sijaan.", + "Verification Requests": "Varmennuspyynnöt", + "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Tämän käyttäjän varmentaminen merkitsee hänen istuntonsa luotetuksi, ja myös merkkaa sinun istuntosi luotetuksi hänen laitteissaan.", + "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.": "Varmenna tämä laite merkataksesi se luotetuksi. Tähän laitteeseen luottaminen antaa sinulle ja muille käyttäjille ylimääräistä mielenrauhaa, kun käytätte osapuolten välistä salausta.", + "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Tämän laitteen varmentaminen merkkaa sen luotetuksi, ja sinut varmentaneet käyttäjät luottavat automaattisesti tähän laitteeseen.", + "Confirm to continue": "Haluan jatkaa", + "Click the button below to confirm your identity.": "Paina alapuolella olevaa painiketta varmistaaksesi identiteettisi.", + "We couldn't create your DM. Please check the users you want to invite and try again.": "Emme onnistuneet luomaan yksityisviestiä. Tarkista, että kutsumasi henkilöt haluavat kutsusi ja yritä uudelleen.", + "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Seuraavat käyttäjät eivät välttämättä ole olemassa tai ne ovat epäkelpoja, joten niitä ei voida kutsua: %(csvNames)s", + "Recently Direct Messaged": "Viimeaikaiset yksityisviestit", + "Start a conversation with someone using their name, username (like ) or email address.": "Aloita keskustelu jonkun kanssa käyttäen hänen nimeä, käyttäjätunnus (kuten ) tai sähköpostiosoitetta.", + "Invite someone using their name, username (like ), email address or share this room.": "Kutsu tähän huoneeseen käyttäen nimeä, käyttäjätunnusta (kuten ), sähköpostiosoitetta tai jaa tämä huone.", + "Your unverified session '%(displayName)s' is requesting encryption keys.": "Varmentamaton istuntosi '%(displayName)s' pyytää salausavaimia.", + "Riot encountered an error during upload of:": "Riot kohtasi virheen lähettäessään:", + "Upload completed": "Lähetys valmis", + "Cancelled signature upload": "Allekirjoituksen lähetys peruutettu", + "Unable to upload": "Lähettäminen ei ole mahdollista", + "Signature upload success": "Allekirjoituksen lähettäminen onnistui", + "Signature upload failed": "Allekirjoituksen lähettäminen epäonnistui" } From 0ef0f81fc66865ddb9f1a40842032c189d20ffbe Mon Sep 17 00:00:00 2001 From: MamasLT Date: Sat, 23 May 2020 23:33:18 +0000 Subject: [PATCH 097/332] Translated using Weblate (Lithuanian) Currently translated at 61.7% (1432 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 201 ++++++++++++++++++++++++++++++++++----- 1 file changed, 176 insertions(+), 25 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 905ac59c0d..bb4f6cc7a4 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -149,7 +149,7 @@ "remove %(name)s from the directory.": "pašalinti %(name)s iš katalogo.", "You can now return to your account after signing out, and sign in on other devices.": "Po atsijungimo galite grįžti prie savo paskyros ir prisijungti kituose įrenginiuose.", "Continue": "Tęsti", - "Enable email notifications": "Įjungti pranešimus el. paštu", + "Enable email notifications": "Įjungti el. pašto pranešimus", "Event Type": "Įvykio tipas", "No rooms to show": "Nėra kambarių rodymui", "Add rooms to this community": "Įtraukti kambarius į šią bendruomenę", @@ -216,7 +216,7 @@ "Failed to add the following rooms to %(groupId)s:": "Nepavyko pridėti šių kambarių į %(groupId)s:", "Riot does not have permission to send you notifications - please check your browser settings": "Riot neturi leidimo siųsti jums pranešimus - patikrinkite savo naršyklės nustatymus", "Riot was not given permission to send notifications - please try again": "Riot nebuvo suteiktas leidimas siųsti pranešimus - bandykite dar kartą", - "Unable to enable Notifications": "Nepavyko įjungti Pranešimus", + "Unable to enable Notifications": "Nepavyko įjungti pranešimų", "This email address was not found": "Šis el. pašto adresas nebuvo rastas", "Admin": "Administratorius", "Start a chat": "Pradėti pokalbį", @@ -523,9 +523,9 @@ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s pakeitė prisegtas kambario žinutes.", "Sorry, your homeserver is too old to participate in this room.": "Atleiskite, jūsų serverio versija yra per sena dalyvauti šiame kambaryje.", "Please contact your homeserver administrator.": "Prašome susisiekti su savo serverio administratoriumi.", - "Enable inline URL previews by default": "Įjungti tiesiogines URL nuorodų peržiūras pagal numatymą", + "Enable inline URL previews by default": "Įjungti URL nuorodų peržiūras kaip numatytasias", "Enable URL previews for this room (only affects you)": "Įjungti URL nuorodų peržiūras šiame kambaryje (įtakoja tik jus)", - "Enable URL previews by default for participants in this room": "Įjungti URL nuorodų peržiūras pagal numatymą dalyviams šiame kambaryje", + "Enable URL previews by default for participants in this room": "Įjungti URL nuorodų peržiūras kaip numatytasias šiame kambaryje esantiems dalyviams", "Confirm password": "Patvirtinkite slaptažodį", "Demote yourself?": "Pažeminti save?", "Demote": "Pažeminti", @@ -539,10 +539,10 @@ "Who can read history?": "Kas gali skaityti istoriją?", "Only room administrators will see this warning": "Šį įspėjimą matys tik kambario administratoriai", "Remote addresses for this room:": "Nuotoliniai šio kambario adresai:", - "You have enabled URL previews by default.": "Jūs esate įjungę URL nuorodų peržiūras pagal numatymą.", - "You have disabled URL previews by default.": "Jūs esate išjungę URL nuorodų peržiūras pagal numatymą.", - "URL previews are enabled by default for participants in this room.": "URL nuorodų peržiūros yra įjungtos pagal numatymą šio kambario dalyviams.", - "URL previews are disabled by default for participants in this room.": "URL nuorodų peržiūros yra išjungtos pagal numatymą šio kambario dalyviams.", + "You have enabled URL previews by default.": "Jūs esate įjungę URL nuorodų peržiūras kaip numatytasias.", + "You have disabled URL previews by default.": "Jūs esate išjungę URL nuorodų peržiūras kaip numatytasias.", + "URL previews are enabled by default for participants in this room.": "URL nuorodų peržiūros yra įjungtos kaip numatytasios šio kambario dalyviams.", + "URL previews are disabled by default for participants in this room.": "URL nuorodų peržiūros yra išjungtos kaip numatytosios šio kambario dalyviams.", "Invalid file%(extra)s": "Neteisingas failas %(extra)s", "This room is a continuation of another conversation.": "Šis kambarys yra kito pokalbio pratęsimas.", "Click here to see older messages.": "Spustelėkite čia, norėdami matyti senesnes žinutes.", @@ -599,7 +599,7 @@ "This homeserver has hit its Monthly Active User limit.": "Šis serveris pasiekė savo mėnesinį aktyvių naudotojų limitą.", "This homeserver has exceeded one of its resource limits.": "Šis serveris viršijo vieno iš savo išteklių limitą.", "Unable to connect to Homeserver. Retrying...": "Nepavyksta prisijungti prie serverio. Bandoma iš naujo...", - "Enable widget screenshots on supported widgets": "Palaikomuose valdikliuose įjungti valdiklių ekrano kopijas", + "Enable widget screenshots on supported widgets": "Įjungti valdiklių ekrano kopijas palaikomuose valdikliuose", "Export E2E room keys": "Eksportuoti E2E kambario raktus", "Last seen": "Paskutinį kartą matytas", "Unignore": "Nebeignoruoti", @@ -611,7 +611,7 @@ "System Alerts": "Sistemos įspėjimai", "Failed to unban": "Nepavyko atblokuoti", "not specified": "nenurodyta", - "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.": "Šifruotuose kambariuose, tokiuose kaip šis, URL nuorodų peržiūra pagal numatymą yra išjungta, kad būtų užtikrinta, jog jūsų namų serveris (kuriame yra generuojamos peržiūros) negalės rinkti informacijos apie šiame kambaryje matomas nuorodas.", + "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.": "Šifruotuose kambariuose, tokiuose kaip šis, URL nuorodų peržiūros pagal numatymą yra išjungtos, kad būtų užtikrinta, jog jūsų serveris (kur yra generuojamos peržiūros) negali rinkti informacijos apie jūsų šiame kambaryje peržiūrėtas nuorodas.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s pakeitė %(roomName)s avatarą", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s pašalino kambario avatarą.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s pakeitė kambario avatarą į ", @@ -641,7 +641,7 @@ "And %(count)s more...|other": "Ir dar %(count)s...", "Existing Call": "Esamas skambutis", "A call is already in progress!": "Skambutis jau vyksta!", - "Default": "Paprastas vartotojas", + "Default": "Numatytas", "Restricted": "Apribotas", "Moderator": "Moderatorius", "Ignores a user, hiding their messages from you": "Ignoruoja vartotoją, slepiant nuo jūsų jo žinutes", @@ -797,7 +797,7 @@ "This room has no topic.": "Šis kambarys neturi temos.", "Sets the room name": "Nustato kambario pavadinimą", "Use an identity server": "Naudoti tapatybės serverį", - "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tam, kad būtų naudojamas numatytasis tapatybės serveris %(defaultIdentityServerName)s, spauskite tęsti, arba tvarkykite nustatymuose.", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tam, kad toliau būtų naudojamas numatytasis tapatybės serveris %(defaultIdentityServerName)s, spauskite tęsti, arba tvarkykite nustatymuose.", "Use an identity server to invite by email. Manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tvarkykite nustatymuose.", "Joins room with given alias": "Prisijungia prie kambario su nurodytu slapyvardžiu", "Unbans user with given ID": "Atblokuoja vartotoją su nurodytu id", @@ -831,8 +831,8 @@ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s išsiuntė pakvietimą %(targetDisplayName)s prisijungti prie kambario.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s padarė būsimą kambario istoriją matomą visiems kambario dalyviams, nuo pat jų prisijungimo.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s padarė būsimą kambario istoriją matomą nežinomam (%(visibility)s).", - "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s iš %(fromPowerLevel)s į %(toPowerLevel)s", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s pakeitė %(powerLevelDiffText)s galios lygį.", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s galios lygį iš %(fromPowerLevel)s į %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s pakeitė %(powerLevelDiffText)s.", "%(displayName)s is typing …": "%(displayName)s rašo …", "%(names)s and %(count)s others are typing …|other": "%(names)s ir %(count)s kiti rašo …", "%(names)s and %(count)s others are typing …|one": "%(names)s ir dar vienas rašo …", @@ -1135,7 +1135,7 @@ "Message deleted": "Žinutė ištrinta", "Message deleted by %(name)s": "Žinutė, ištrinta %(name)s", "Warning: You should only do this on a trusted computer.": "Įspėjimas: Tai atlikite tik saugiame kompiuteryje.", - "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Pasiekite savo saugių žinučių istoriją ir kryžminio parašo tapatybę, naudojamą kitų seansų patvirtinimui, įvesdami savo atgavimo slaptafrazę.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery passphrase.": "Pasiekite savo saugių žinučių istoriją ir kryžminio pasirašymo tapatybę, naudojamą kitų seansų patvirtinimui, įvesdami savo atgavimo slaptafrazę.", "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options.": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus.", "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Jei pamiršote savo atgavimo slaptafrazę jūs galite naudoti savo atgavimo raktą arba nustatyti naujus atgavimo nustatymus", "Confirm your identity by entering your account password below.": "Patvirtinkite savo tapatybę žemiau įvesdami savo paskyros slaptažodį.", @@ -1158,7 +1158,7 @@ "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Jūsų slaptažodis buvo sėkmingai pakeistas. Jūs kituose seansuose negausite pranešimų, kol iš naujo prie jų neprisijungsite", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "El. laiškas buvo išsiųstas į %(emailAddress)s. Kai paspausite jame esančią nuorodą, tada spauskite žemiau.", "Your password has been reset.": "Jūsų slaptažodis buvo iš naujo nustatytas.", - "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.": "Jūs buvote atjungtas iš visų seansų ir toliau nebegausite pranešimų. Tam, kad vėl aktyvuotumėte pranešimus, iš naujo prisijunkite kiekviename įrenginyje.", + "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.": "Jūs buvote atjungtas iš visų seansų ir toliau nebegausite pranešimų. Tam, kad vėl įjungtumėte pranešimus, iš naujo prisijunkite kiekviename įrenginyje.", "Show more": "Rodyti daugiau", "Log in to your new account.": "Prisijunkite prie naujos paskyros.", "Registration Successful": "Registracija sėkminga", @@ -1191,8 +1191,8 @@ "Cryptography": "Kriptografija", "Security & Privacy": "Saugumas ir Privatumas", "Voice & Video": "Garsas ir Vaizdas", - "Enable room encryption": "Įgalinti kambario šifravimą", - "Enable encryption?": "Įgalinti šifravimą?", + "Enable room encryption": "Įjungti kambario šifravimą", + "Enable encryption?": "Įjungti šifravimą?", "Encryption": "Šifravimas", "Once enabled, encryption cannot be disabled.": "Įjungus šifravimą jo nebus galima išjungti.", "Who can access this room?": "Kas turi prieigą prie šio kambario?", @@ -1207,7 +1207,7 @@ "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Įvyko klaida atnaujinant ženkliukus šiam kambariui. Serveris gali jų neleisti arba įvyko laikina klaida.", "Showing flair for these communities:": "Ženkliukai rodomi šioms bendruomenėms:", "This room is not showing flair for any communities": "Šis kambarys nerodo ženkliukų jokioms bendruomenėms", - "Waiting for you to accept on your other session…": "Laukiama kol jūs priimsite savo kitame seanse…", + "Waiting for you to accept on your other session…": "Laukiama kol jūs priimsite kitame savo seanse…", "Start Verification": "Pradėti patvirtinimą", "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Šifruotuose kambariuose jūsų žinutės yra apsaugotos ir tik jūs ir gavėjas turite unikalius raktus joms atrakinti.", "Verify User": "Patvirtinti vartotoją", @@ -1224,13 +1224,13 @@ "%(displayName)s cancelled verification.": "%(displayName)s atšaukė patvirtinimą.", "You cancelled verification.": "Jūs atšaukėte patvirtinimą.", "Verification cancelled": "Patvirtinimas atšauktas", - "Encryption enabled": "Šifravimas įgalintas", + "Encryption enabled": "Šifravimas įjungtas", "Encryption not enabled": "Šifravimas neįgalintas", "Display your community flair in rooms configured to show it.": "Rodyti savo bendruomenės ženkliukus kambariuose, kuriuose nustatytas jų rodymas.", "You're not currently a member of any communities.": "Jūs šiuo metu nesate jokios bendruomenės narys.", "More options": "Daugiau parinkčių", "Are you sure you want to remove %(serverName)s": "Ar tikrai norite pašalinti %(serverName)s", - "Enable end-to-end encryption": "Įgalinti visapusį šifravimą", + "Enable end-to-end encryption": "Įjungti visapusį šifravimą", "You can’t disable this later. Bridges & most bots won’t work yet.": "Jūs negalėsite vėliau to išjungti. Tiltai ir dauguma bot'ų dar nėra palaikomi.", "Are you sure you want to deactivate your account? This is irreversible.": "Ar tikrai norite deaktyvuoti savo paskyrą? Tai yra negrįžtama.", "Verify session": "Patvirtinti seansą", @@ -1240,7 +1240,7 @@ "Are you sure you want to sign out?": "Ar tikrai norite atsijungti?", "Use this session to verify your new one, granting it access to encrypted messages:": "Panaudoti šį seansą naujo patvirtinimui, suteikant jam prieigą prie šifruotų žinučių:", "If you didn’t sign in to this session, your account may be compromised.": "Jei jūs nesijungėte prie šios sesijos, jūsų paskyra gali būti sukompromituota.", - "This wasn't me": "Tai buvau ne aš", + "This wasn't me": "Tai ne aš", "If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Jei jūs susidūrėte su klaidomis arba norėtumėte palikti atsiliepimą, praneškite mums GitHub'e.", "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Tam, kad būtų išvengta pasikartojančių problemų, pirmiausia peržiūrėkite esamas problemas (ir pridėkite +1) arba, jei nerandate, sukurkite naują svarstomą problemą.", "Report bugs & give feedback": "Pranešti apie klaidas ir palikti atsiliepimą", @@ -1259,7 +1259,7 @@ "You can now close this window or log in to your new account.": "Jūs galite uždaryti šį langą arba prisijungti į savo naują paskyrą.", "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Patvirtinkite savo tapatybę verifikuodami šį prisijungimą viename iš kitų jūsų seansų, suteikdami jam prieigą prie šifruotų žinučių.", "This requires the latest Riot on your other devices:": "Tam reikia naujausios Riot versijos kituose jūsų įrenginiuose:", - "or another cross-signing capable Matrix client": "arba kitas kryžminį parašą palaikantis Matrix klientas", + "or another cross-signing capable Matrix client": "arba kitą kryžminį pasirašymą palaikantį Matrix klientą", "Use Recovery Passphrase or Key": "Naudoti atgavimo slaptafrazę arba raktą", "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atnaujinkite šį seansą, kad jam būtų leista patvirtinti kitus seansus, suteikiant jiems prieigą prie šifruotų žinučių ir juos pažymint kaip patikimus kitiems vartotojams.", "Use Single Sign On to continue": "Norėdami tęsti naudokite Vieno Prisijungimo sistemą", @@ -1308,12 +1308,163 @@ "Room Topic": "Kambario Tema", "Your theme": "Jūsų tema", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Valdiklio ištrinimas pašalina jį visiems kambaryje esantiems vartotojams. Ar tikrai norite ištrinti šį valdiklį?", - "Enable 'Manage Integrations' in Settings to do this.": "Įgalinkite 'Valdyti integracijas' nustatymuose, kad tai atliktumėte.", + "Enable 'Manage Integrations' in Settings to do this.": "Įjunkite 'Valdyti integracijas' nustatymuose, kad tai atliktumėte.", "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Jūsų Riot neleidžia jums naudoti integracijų valdiklio tam atlikti. Susisiekite su administratoriumi.", "Enter phone number (required on this homeserver)": "Įveskite telefono numerį (privaloma šiame serveryje)", "Doesn't look like a valid phone number": "Tai nepanašu į veikiantį telefono numerį", "Invalid homeserver discovery response": "Klaidingas serverio radimo atsakas", "Invalid identity server discovery response": "Klaidingas tapatybės serverio radimo atsakas", "The phone number entered looks invalid": "Įvestas telefono numeris atrodo klaidingas", - "Double check that your server supports the room version chosen and try again.": "Patikrinkite ar jūsų serveris palaiko pasirinktą kambario versiją ir bandykite iš naujo." + "Double check that your server supports the room version chosen and try again.": "Dar kartą įsitikinkite, kad jūsų serveris palaiko pasirinktą kambario versiją ir bandykite iš naujo.", + "Whether you're using Riot on a device where touch is the primary input mechanism": "Nesvarbu, ar naudojate „Riot“ įrenginyje, kuriame pagrindinis įvesties mechanizmas yra lietimas", + "Session already verified!": "Seansas jau patvirtintas!", + "WARNING: Session already verified, but keys do NOT MATCH!": "ĮSPĖJIMAS: Seansas jau patvirtintas, bet raktai NESUTAMPA!", + "Enable cross-signing to verify per-user instead of per-session": "Įjunkite kryžminį pasirašymą, kad patvirtintumėte vartotoją, o ne seansą", + "Enable Emoji suggestions while typing": "Įjungti emoji pasiūlymus rašant", + "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Rodyti priminimą įjungti saugų žinučių atgavimą šifruotuose kambariuose", + "Enable automatic language detection for syntax highlighting": "Įjungti automatinį kalbos aptikimą sintaksės paryškinimui", + "Enable big emoji in chat": "Įjungti didelius emoji pokalbiuose", + "Enable Community Filter Panel": "Įjungti bendruomenės filtrų skydelį", + "Enable message search in encrypted rooms": "Įjungti žinučių paiešką užšifruotuose kambariuose", + "Verified!": "Patvirtinta!", + "You've successfully verified this user.": "Jūs sėkmingai patvirtinote šį vartotoją.", + "Got It": "Supratau", + "Verify this session by completing one of the following:": "Patvirtinkite šį seansą atlikdami vieną iš šių veiksmų:", + "Scan this unique code": "Nuskaitykite šį unikalų kodą", + "Compare unique emoji": "Palyginkite unikalius emoji", + "Compare a unique set of emoji if you don't have a camera on either device": "Palyginkite unikalų emoji rinkinį, jei neturite fotoaparato nei viename įrenginyje", + "Confirm the emoji below are displayed on both sessions, in the same order:": "Patvirtinkite, kad žemiau esantys emoji yra rodomi abiejuose seansuose, ta pačia tvarka:", + "Waiting for %(displayName)s to verify…": "Laukiama kol %(displayName)s patvirtins…", + "Cancelling…": "Atšaukiama…", + "They match": "Jie sutampa", + "They don't match": "Jie nesutampa", + "Dog": "Šuo", + "Cat": "Katė", + "Lion": "Liūtas", + "Horse": "Arklys", + "Unicorn": "Vienaragis", + "Pig": "Kiaulė", + "Elephant": "Dramblys", + "Rabbit": "Triušis", + "Panda": "Panda", + "Rooster": "Gaidys", + "Penguin": "Pingvinas", + "Turtle": "Vėžlys", + "Fish": "Žuvis", + "Octopus": "Aštunkojis", + "Butterfly": "Drugelis", + "Flower": "Gėlė", + "Tree": "Medis", + "Cactus": "Kaktusas", + "Mushroom": "Grybas", + "Globe": "Gaublys", + "Moon": "Mėnulis", + "Cloud": "Debesis", + "Fire": "Ugnis", + "Banana": "Bananas", + "Apple": "Obuolys", + "Strawberry": "Braškė", + "Corn": "Kukurūzas", + "Pizza": "Pica", + "Cake": "Tortas", + "Heart": "Širdis", + "Smiley": "Šypsenėlė", + "Robot": "Robotas", + "Hat": "Skrybėlė", + "Glasses": "Akiniai", + "Spanner": "Veržliaraktis", + "Santa": "Santa", + "Thumbs up": "Liuks", + "Umbrella": "Skėtis", + "Hourglass": "Smėlio laikrodis", + "Clock": "Laikrodis", + "Gift": "Dovana", + "Light bulb": "Lemputė", + "Book": "Knyga", + "Pencil": "Pieštukas", + "Paperclip": "Sąvaržėlė", + "Scissors": "Žirklės", + "Lock": "Spyna", + "Key": "Raktas", + "Hammer": "Plaktukas", + "Telephone": "Telefonas", + "Flag": "Vėliava", + "Train": "Traukinys", + "Bicycle": "Dviratis", + "Aeroplane": "Lėktuvas", + "Rocket": "Raketa", + "Trophy": "Trofėjus", + "Ball": "Kamuolys", + "Guitar": "Gitara", + "Trumpet": "Trimitas", + "Bell": "Varpas", + "Anchor": "Inkaras", + "Headphones": "Ausinės", + "Folder": "Aplankas", + "Pin": "Smeigtukas", + "Other users may not trust it": "Kiti vartotojai gali nepasitikėti", + "Upgrade": "Atnaujinti", + "From %(deviceName)s (%(deviceId)s)": "Iš %(deviceName)s (%(deviceId)s)", + "Decline (%(counter)s)": "Atsisakyti (%(counter)s)", + "Accept to continue:": "Sutikite su , kad tęstumėte:", + "Upload": "Įkelti", + "Your homeserver does not support cross-signing.": "Jūsų serveris nepalaiko kryžminio pasirašymo.", + "Cross-signing and secret storage are enabled.": "Kryžminis pasirašymas ir slapta saugykla yra įjungta.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Jūsų paskyra slaptoje saugykloje turi kryžminio pasirašymo tapatybę, bet šis seansas dar ja nepasitiki.", + "Cross-signing and secret storage are not yet set up.": "Kryžminis pasirašymas ir slapta saugykla dar nėra nustatyti.", + "Reset cross-signing and secret storage": "Atstatyti kryžminį pasirašymą ir slaptą saugyklą", + "Bootstrap cross-signing and secret storage": "Prikabinti kryžminį pasirašymą ir slaptą saugyklą", + "Cross-signing public keys:": "Kryžminio pasirašymo vieši raktai:", + "Cross-signing private keys:": "Kryžminio pasirašymo privatūs raktai:", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individualiai patikrinkite kiekvieną vartotojo naudojamą seansą, kad pažymėtumėte jį kaip patikimą, nepasitikint kryžminiu pasirašymu patvirtintais įrenginiais.", + "Enable": "Įjungti", + "Backup has a valid signature from verified session ": "Atsarginė kopija turi galiojantį parašą iš patikrinto seanso ", + "Backup has a valid signature from unverified session ": "Atsarginė kopija turi galiojantį parašą iš nepatikrinto seanso ", + "Backup has an invalid signature from verified session ": "Atsarginė kopija turi negaliojantį parašą iš patikrinto seanso ", + "Backup has an invalid signature from unverified session ": "Atsarginė kopija turi negaliojantį parašą iš nepatikrinto seanso ", + "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Atsarginė rakto kopija saugoma slaptoje saugykloje, bet ši funkcija nėra įjungta šiame seanse. Įjunkite kryžminį pasirašymą Laboratorijose, kad galėtumėte keisti atsarginės rakto kopijos būseną.", + "Enable desktop notifications for this session": "Įjungti darbalaukio pranešimus šiam seansui", + "Enable audible notifications for this session": "Įjungti garsinius pranešimus šiam seansui", + "wait and try again later": "palaukite ir bandykite vėliau dar kartą", + "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Jei jūs nenorite naudoti radimui ir tam, kad būtumėte randamas esamų, jums žinomų kontaktų, žemiau įveskite kitą tapatybės serverį.", + "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.": "Tapatybės serverio naudojimas yra pasirinktinis. Jei jūs pasirinksite jo nenaudoti, jūs nebūsite randamas kitų vartotojų ir neturėsite galimybės pakviesti kitų nurodydamas el. paštą ar telefoną.", + "Do not use an identity server": "Nenaudoti tapatybės serverio", + "Cross-signing": "Kryžminis pasirašymas", + "Error changing power level requirement": "Klaida keičiant galios lygio reikalavimą", + "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Keičiant kambario galios lygio reikalavimus įvyko klaida. Įsitikinkite, kad turite tam leidimą ir bandykite dar kartą.", + "Error changing power level": "Klaida keičiant galios lygį", + "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "Keičiant vartotojo galios lygį įvyko klaida. Įsitikinkite, kad turite tam leidimą ir bandykite dar kartą.", + "Default role": "Numatytoji rolė", + "This user has not verified all of their sessions.": "Šis vartotojas nepatvirtino visų savo seansų.", + "You have not verified this user.": "Jūs nepatvirtinote šio vartotojo.", + "You have verified this user. This user has verified all of their sessions.": "Jūs patvirtinote šį vartotoją. Šis vartotojas patvirtino visus savo seansus.", + "Everyone in this room is verified": "Visi šiame kambaryje yra patvirtinti", + "Encrypted by a deleted session": "Užšifruota ištrintos sesijos", + "Use an identity server in Settings to receive invites directly in Riot.": "Nustatymuose naudokite tapatybės serverį, kad gautumėte pakvietimus tiesiai į Riot.", + "%(count)s verified sessions|one": "1 patvirtintas seansas", + "If you can't scan the code above, verify by comparing unique emoji.": "Jei nuskaityti aukščiau esančio kodo negalite, patvirtinkite palygindami unikalius emoji.", + "You've successfully verified your device!": "Jūs sėkmingai patvirtinote savo įrenginį!", + "You've successfully verified %(deviceName)s (%(deviceId)s)!": "Jūs sėkmingai patvirtinote %(deviceName)s (%(deviceId)s)!", + "You've successfully verified %(displayName)s!": "Jūs sėkmingai patvirtinote %(displayName)s!", + "Verified": "Patvirtinta", + "Got it": "Supratau", + "Start verification again from the notification.": "Pradėkite patvirtinimą iš naujo pranešime.", + "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Naudokite numatytajį (%(defaultIdentityServerName)s) arba tvarkykite Nustatymuose.", + "Use an identity server to invite by email. Manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tvarkykite Nustatymuose.", + "Destroy cross-signing keys?": "Sunaikinti kryžminio pasirašymo raktus?", + "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.": "Kryžminio pasirašymo raktų ištrinimas yra neatšaukiamas. Visi, kurie buvo jais patvirtinti, matys saugumo įspėjimus. Jūs greičiausiai nenorite to daryti, nebent praradote visus įrenginius, iš kurių galite patvirtinti kryžminiu pasirašymu.", + "Clear cross-signing keys": "Valyti kryžminio pasirašymo raktus", + "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Tam, kad patvirtintumėte šio seanso patikimumą, patikrinkite ar raktas, kurį matote Vartotojo Nustatymuose tame įrenginyje, sutampa su raktu esančiu žemiau:", + "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.": "Patvirtinkite šį įrenginį, kad pažymėtumėte jį kaip patikimą. Pasitikėjimas šiuo įrenginiu suteikia jums ir kitiems vartotojams papildomos ramybės, kai naudojate visapusiškai užšifruotas žinutes.", + "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Šio įrenginio patvirtinimas pažymės jį kaip patikimą ir vartotojai, kurie patvirtino su jumis, pasitikės šiuo įrenginiu.", + "a new cross-signing key signature": "naujas kryžminio pasirašymo rakto parašas", + "a device cross-signing signature": "įrenginio kryžminio pasirašymo parašas", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Pasiekite savo saugių žinučių istoriją ir kryžminio pasirašymo tapatybę, naudojamą kitų seansų patvirtinimui, įvesdami savo atgavimo raktą.", + "Session verified": "Seansas patvirtintas", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neįmanoma prisijungti prie serverio per HTTP, kai naršyklės juostoje yra HTTPS URL. Naudokite HTTPS arba įjunkite nesaugias rašmenas.", + "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Jūsų naujas seansas dabar yra patvirtintas. Jis turi prieigą prie jūsų šifruotų žinučių ir kiti vartotojai matys jį kaip patikimą.", + "Your new session is now verified. Other users will see it as trusted.": "Jūsų naujas seansas dabar yra patvirtintas. Kiti vartotojai matys jį kaip patikimą.", + "NOT verified": "Nepatvirtinta", + "verified": "patvirtinta", + "If you don't want to set this up now, you can later in Settings.": "Jei jūs dabar nenorite to nustatyti, galite padaryti tai vėliau Nustatymuose." } From cec8fa3595468d699994bbcac9d64c7cb18894ae Mon Sep 17 00:00:00 2001 From: strix aluco Date: Sat, 23 May 2020 16:58:41 +0000 Subject: [PATCH 098/332] Translated using Weblate (Ukrainian) Currently translated at 27.9% (647 of 2322 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index bdef596b88..fb6657d6c1 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -77,7 +77,7 @@ "Email": "е-пошта", "Email address": "Адреса е-пошти", "Failed to send email": "Помилка відправки е-почти", - "Edit": "Редактувати", + "Edit": "Редагувати", "Unpin Message": "Відкріпити повідомлення", "Register": "Зареєструватися", "Rooms": "Кімнати", From 457f4c82db9de47ce3b4d6449e6794e6385b1cdc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 May 2020 14:59:03 +0100 Subject: [PATCH 099/332] Make some ARIA promises Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/emojipicker/Category.js | 8 +++++- src/components/views/emojipicker/Emoji.js | 11 +++++--- src/components/views/emojipicker/Header.js | 25 +++++++++++++------ .../views/emojipicker/QuickReactions.js | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/components/views/emojipicker/Category.js b/src/components/views/emojipicker/Category.js index 3c4352105e..eb3f83dcdf 100644 --- a/src/components/views/emojipicker/Category.js +++ b/src/components/views/emojipicker/Category.js @@ -67,7 +67,13 @@ class Category extends React.PureComponent { const localScrollTop = Math.max(0, scrollTop - listTop); return ( -
+

{name}

diff --git a/src/components/views/emojipicker/Emoji.js b/src/components/views/emojipicker/Emoji.js index 75f23c5761..36aa4ff782 100644 --- a/src/components/views/emojipicker/Emoji.js +++ b/src/components/views/emojipicker/Emoji.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import {MenuItem} from "../../structures/ContextMenu"; class Emoji extends React.PureComponent { static propTypes = { @@ -30,14 +31,18 @@ class Emoji extends React.PureComponent { const { onClick, onMouseEnter, onMouseLeave, emoji, selectedEmojis } = this.props; const isSelected = selectedEmojis && selectedEmojis.has(emoji.unicode); return ( -
  • onClick(emoji)} + onClick(emoji)} onMouseEnter={() => onMouseEnter(emoji)} onMouseLeave={() => onMouseLeave(emoji)} - className="mx_EmojiPicker_item_wrapper"> + className="mx_EmojiPicker_item_wrapper" + label={emoji.unicode} + >
    {emoji.unicode}
    -
  • + ); } } diff --git a/src/components/views/emojipicker/Header.js b/src/components/views/emojipicker/Header.js index b98e90e9b1..b3951c9ea5 100644 --- a/src/components/views/emojipicker/Header.js +++ b/src/components/views/emojipicker/Header.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import classNames from "classnames"; class Header extends React.PureComponent { static propTypes = { @@ -26,13 +27,23 @@ class Header extends React.PureComponent { render() { return ( - ); } diff --git a/src/components/views/emojipicker/QuickReactions.js b/src/components/views/emojipicker/QuickReactions.js index 0bc799d356..8a20a4659b 100644 --- a/src/components/views/emojipicker/QuickReactions.js +++ b/src/components/views/emojipicker/QuickReactions.js @@ -72,7 +72,7 @@ class QuickReactions extends React.Component { } -