From d589c6100069c5ddae0c7372760c63d40ecd84ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:09:14 +0100 Subject: [PATCH 001/164] Added send message button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 5 +++++ src/components/views/rooms/MessageComposer.js | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 71c0db947e..897167f745 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -239,6 +239,7 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/call/video-call.svg'); } + .mx_MessageComposer_emoji::before { mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg'); } @@ -247,6 +248,10 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/composer/sticker.svg'); } +.mx_MessageComposer_sendMessage::before { + mask-image: url('$(res)/img/element-icons/call/video-call.svg'); +} + .mx_MessageComposer_formatting { cursor: pointer; margin: 0 11px; diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 4ddff8f4b0..86ad3ddbdd 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -393,6 +393,10 @@ export default class MessageComposer extends React.Component { }); } + sendMessage = () => { + this.messageComposerInput._sendMessage(); + } + render() { const controls = [ this.state.me ? : null, @@ -450,6 +454,16 @@ export default class MessageComposer extends React.Component { ); } } + + if (true) { + controls.push(( + + )); + } } else if (this.state.tombstone) { const replacementRoomId = this.state.tombstone.getContent()['replacement_room']; From c64b2a585f3c2d1e75392657995d6b1813250f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:17:40 +0100 Subject: [PATCH 002/164] Added option to disable send button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 2 +- .../views/settings/tabs/user/PreferencesUserSettingsTab.js | 1 + src/settings/Settings.ts | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 86ad3ddbdd..315b1b78c7 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -455,7 +455,7 @@ export default class MessageComposer extends React.Component { } } - if (true) { + if (SettingsStore.getValue("MessageComposerInput.sendButton")) { controls.push(( Date: Sat, 9 Jan 2021 09:18:10 +0100 Subject: [PATCH 003/164] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ac18ccb23e..6baccf95de 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -799,6 +799,7 @@ "Show typing notifications": "Show typing notifications", "Use Command + Enter to send a message": "Use Command + Enter to send a message", "Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message", + "Show send message button": "Show send message button", "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", @@ -1412,6 +1413,7 @@ "Send a reply…": "Send a reply…", "Send an encrypted message…": "Send an encrypted message…", "Send a message…": "Send a message…", + "Send message": "Send message", "The conversation continues here.": "The conversation continues here.", "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", "You do not have permission to post to this room": "You do not have permission to post to this room", From 4538274e74938294f840abcae070ac75d052d311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:25:29 +0100 Subject: [PATCH 004/164] Added send message icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 2 +- res/img/element-icons/send-message.svg | 54 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 res/img/element-icons/send-message.svg diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 897167f745..8c2a997490 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -249,7 +249,7 @@ limitations under the License. } .mx_MessageComposer_sendMessage::before { - mask-image: url('$(res)/img/element-icons/call/video-call.svg'); + mask-image: url('$(res)/img/element-icons/send-message.svg'); } .mx_MessageComposer_formatting { diff --git a/res/img/element-icons/send-message.svg b/res/img/element-icons/send-message.svg new file mode 100644 index 0000000000..2e74745e21 --- /dev/null +++ b/res/img/element-icons/send-message.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + + From 263f2136502c657c4dcbb07674e965576ad562ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:27:02 +0100 Subject: [PATCH 005/164] Remove an empty line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 8c2a997490..8b34318f1d 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -239,7 +239,6 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/call/video-call.svg'); } - .mx_MessageComposer_emoji::before { mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg'); } From 7d120f7183eef575f16d78b1e9b4fdfabf7d2848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 9 Jan 2021 09:33:11 +0100 Subject: [PATCH 006/164] Simplifie svg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/img/element-icons/send-message.svg | 55 +------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/res/img/element-icons/send-message.svg b/res/img/element-icons/send-message.svg index 2e74745e21..ce35bf8bc8 100644 --- a/res/img/element-icons/send-message.svg +++ b/res/img/element-icons/send-message.svg @@ -1,54 +1,3 @@ - - - - - - image/svg+xml - - - - - - - - + + From 9f1113b3bd47295d1e6f0d2e897bcb93773a06cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 16 Jan 2021 16:35:50 +0100 Subject: [PATCH 007/164] Watch setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 315b1b78c7..a18dded04f 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -263,6 +263,7 @@ export default class MessageComposer extends React.Component { tombstone: this._getRoomTombstone(), canSendMessages: this.props.room.maySendMessage(), showCallButtons: SettingsStore.getValue("showCallButtonsInComposer"), + showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), }; @@ -280,6 +281,12 @@ export default class MessageComposer extends React.Component { } }; + onSendButtonChanged = () => { + this.setState({ + showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + }); + } + _onWidgetUpdate = () => { this.setState({hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room)}); }; @@ -292,6 +299,8 @@ export default class MessageComposer extends React.Component { this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); + this.showSendButtonRef = SettingsStore.watchSetting( + "MessageComposerInput.sendButton", null, this.onSendButtonChanged); } _waitForOwnMember() { @@ -317,6 +326,7 @@ export default class MessageComposer extends React.Component { WidgetStore.instance.removeListener(UPDATE_EVENT, this._onWidgetUpdate); ActiveWidgetStore.removeListener('update', this._onActiveWidgetUpdate); dis.unregister(this.dispatcherRef); + SettingsStore.unwatchSetting(this.showSendButtonRef); } _onRoomStateEvents(ev, state) { @@ -455,7 +465,7 @@ export default class MessageComposer extends React.Component { } } - if (SettingsStore.getValue("MessageComposerInput.sendButton")) { + if (this.state.showSendButton) { controls.push(( Date: Sat, 16 Jan 2021 16:37:50 +0100 Subject: [PATCH 008/164] Rename setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 6 +++--- .../views/settings/tabs/user/PreferencesUserSettingsTab.js | 2 +- src/settings/Settings.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index a18dded04f..1e43aa6652 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -263,7 +263,7 @@ export default class MessageComposer extends React.Component { tombstone: this._getRoomTombstone(), canSendMessages: this.props.room.maySendMessage(), showCallButtons: SettingsStore.getValue("showCallButtonsInComposer"), - showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), }; @@ -283,7 +283,7 @@ export default class MessageComposer extends React.Component { onSendButtonChanged = () => { this.setState({ - showSendButton: SettingsStore.getValue("MessageComposerInput.sendButton"), + showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), }); } @@ -300,7 +300,7 @@ export default class MessageComposer extends React.Component { MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); this.showSendButtonRef = SettingsStore.watchSetting( - "MessageComposerInput.sendButton", null, this.onSendButtonChanged); + "MessageComposerInput.showSendButton", null, this.onSendButtonChanged); } _waitForOwnMember() { diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js index 31971b7167..eff0824d59 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js @@ -34,7 +34,7 @@ export default class PreferencesUserSettingsTab extends React.Component { 'MessageComposerInput.suggestEmoji', 'sendTypingNotifications', 'MessageComposerInput.ctrlEnterToSend', - `MessageComposerInput.sendButton`, + `MessageComposerInput.showSendButton`, ]; static TIMELINE_SETTINGS = [ diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 50d0f919e6..2d8385240c 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -336,7 +336,7 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: isMac ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"), default: false, }, - "MessageComposerInput.sendButton": { + "MessageComposerInput.showSendButton": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td("Show send message button"), default: false, From c9f5c90047e0140da31050d97d0f831bf50858c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 16 Jan 2021 16:43:47 +0100 Subject: [PATCH 009/164] Rename method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 1e43aa6652..9683c4c79e 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -281,7 +281,7 @@ export default class MessageComposer extends React.Component { } }; - onSendButtonChanged = () => { + onShowSendButtonChanged = () => { this.setState({ showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), }); @@ -300,7 +300,7 @@ export default class MessageComposer extends React.Component { MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); this.showSendButtonRef = SettingsStore.watchSetting( - "MessageComposerInput.showSendButton", null, this.onSendButtonChanged); + "MessageComposerInput.showSendButton", null, this.onShowSendButtonChanged); } _waitForOwnMember() { From 0c09158f2a1be05b6a80d8aa393af351b4f4f785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 22 Jan 2021 08:41:39 +0100 Subject: [PATCH 010/164] Comment out unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- .../settings/tabs/user/AppearanceUserSettingsTab.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index 209f245b11..c2f010695b 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -28,13 +28,13 @@ import { FontWatcher } from "../../../../../settings/watchers/FontWatcher"; import { RecheckThemePayload } from '../../../../../dispatcher/payloads/RecheckThemePayload'; import { Action } from '../../../../../dispatcher/actions'; import { IValidationResult, IFieldState } from '../../../elements/Validation'; -import StyledRadioButton from '../../../elements/StyledRadioButton'; +//import StyledRadioButton from '../../../elements/StyledRadioButton'; import StyledCheckbox from '../../../elements/StyledCheckbox'; import SettingsFlag from '../../../elements/SettingsFlag'; import Field from '../../../elements/Field'; import EventTilePreview from '../../../elements/EventTilePreview'; import StyledRadioGroup from "../../../elements/StyledRadioGroup"; -import classNames from 'classnames'; +//import classNames from 'classnames'; import { SettingLevel } from "../../../../../settings/SettingLevel"; import {UIFeature} from "../../../../../settings/UIFeature"; @@ -213,7 +213,7 @@ export default class AppearanceUserSettingsTab extends React.Component): void => { + /*private onLayoutChange = (e: React.ChangeEvent): void => { const val = e.target.value === "true"; this.setState({ @@ -221,7 +221,7 @@ export default class AppearanceUserSettingsTab extends React.Component; } - private renderLayoutSection = () => { + /*private renderLayoutSection = () => { return
{_t("Message layout")} @@ -384,7 +384,7 @@ export default class AppearanceUserSettingsTab extends React.Component
; - }; + };*/ private renderAdvancedSection() { if (!SettingsStore.getValue(UIFeature.AdvancedSettings)) return null; From c69cc550ea00c9bf16a8d773f91c6733dec80a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 22 Jan 2021 13:41:21 +0100 Subject: [PATCH 011/164] Added layout enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/settings/Layout.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/settings/Layout.ts diff --git a/src/settings/Layout.ts b/src/settings/Layout.ts new file mode 100644 index 0000000000..bfb86170e8 --- /dev/null +++ b/src/settings/Layout.ts @@ -0,0 +1,5 @@ +/* TODO: This should be later reworked into something more generic */ +export enum Layout { + IRC = "irc", + Group = "group" +} From 972c9470494ee571f9d2077bb2d1a54be1d1211f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 22 Jan 2021 13:44:45 +0100 Subject: [PATCH 012/164] More generic layout setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/MessagePanel.js | 10 +++--- src/components/structures/RoomView.tsx | 15 +++++---- src/components/structures/TimelinePanel.js | 7 ++-- .../views/elements/EventTilePreview.tsx | 9 +++--- src/components/views/elements/ReplyThread.js | 9 +++--- src/components/views/rooms/EventTile.js | 18 ++++++----- .../tabs/user/AppearanceUserSettingsTab.tsx | 32 +++++++++++++------ src/contexts/RoomContext.ts | 3 +- src/settings/Settings.ts | 8 ++--- 9 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 375545f819..7b40980714 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -26,6 +26,7 @@ import * as sdk from '../../index'; import {MatrixClientPeg} from '../../MatrixClientPeg'; import SettingsStore from '../../settings/SettingsStore'; +import {Layout} from "../../settings/Layout"; import {_t} from "../../languageHandler"; import {haveTileForEvent} from "../views/rooms/EventTile"; import {textForEvent} from "../../TextForEvent"; @@ -135,14 +136,13 @@ export default class MessagePanel extends React.Component { // whether to show reactions for an event showReactions: PropTypes.bool, - // whether to use the irc layout - useIRCLayout: PropTypes.bool, + // which layout to use + layout: Layout, // whether or not to show flair at all enableFlair: PropTypes.bool, }; - // Force props to be loaded for useIRCLayout constructor(props) { super(props); @@ -612,7 +612,7 @@ export default class MessagePanel extends React.Component { isSelectedEvent={highlight} getRelationsForEvent={this.props.getRelationsForEvent} showReactions={this.props.showReactions} - useIRCLayout={this.props.useIRCLayout} + layout={this.props.layout} enableFlair={this.props.enableFlair} /> @@ -810,7 +810,7 @@ export default class MessagePanel extends React.Component { } let ircResizer = null; - if (this.props.useIRCLayout) { + if (this.props.layout == Layout.IRC) { ircResizer = { statusBarVisible: false, canReact: false, canReply: false, - useIRCLayout: SettingsStore.getValue("useIRCLayout"), + layout: SettingsStore.getValue("layout"), matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), }; @@ -263,7 +264,7 @@ export default class RoomView extends React.Component { this.showReadReceiptsWatchRef = SettingsStore.watchSetting("showReadReceipts", null, this.onReadReceiptsChange); - this.layoutWatcherRef = SettingsStore.watchSetting("useIRCLayout", null, this.onLayoutChange); + this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, this.onLayoutChange); } // TODO: [REACT-WARNING] Move into constructor @@ -624,7 +625,7 @@ export default class RoomView extends React.Component { private onLayoutChange = () => { this.setState({ - useIRCLayout: SettingsStore.getValue("useIRCLayout"), + layout: SettingsStore.getValue("layout"), }); }; @@ -1915,8 +1916,8 @@ export default class RoomView extends React.Component { const messagePanelClassNames = classNames( "mx_RoomView_messagePanel", { - "mx_IRCLayout": this.state.useIRCLayout, - "mx_GroupLayout": !this.state.useIRCLayout, + "mx_IRCLayout": this.state.layout == Layout.IRC, + "mx_GroupLayout": this.state.layout == Layout.Group, }); // console.info("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview); @@ -1939,7 +1940,7 @@ export default class RoomView extends React.Component { permalinkCreator={this.getPermalinkCreatorForRoom(this.state.room)} resizeNotifier={this.props.resizeNotifier} showReactions={true} - useIRCLayout={this.state.useIRCLayout} + layout={this.state.layout} />); let topUnreadMessagesBar = null; diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 27a384ddb2..2d322b378d 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -18,6 +18,7 @@ limitations under the License. */ import SettingsStore from "../../settings/SettingsStore"; +import {Layout} from "../../settings/Layout"; import React, {createRef} from 'react'; import ReactDOM from "react-dom"; import PropTypes from 'prop-types'; @@ -111,8 +112,8 @@ class TimelinePanel extends React.Component { // whether to show reactions for an event showReactions: PropTypes.bool, - // whether to use the irc layout - useIRCLayout: PropTypes.bool, + // which layout to use + layout: Layout, } // a map from room id to read marker event timestamp @@ -1442,7 +1443,7 @@ class TimelinePanel extends React.Component { getRelationsForEvent={this.getRelationsForEvent} editState={this.state.editState} showReactions={this.props.showReactions} - useIRCLayout={this.props.useIRCLayout} + layout={this.props.layout} enableFlair={SettingsStore.getValue(UIFeature.Flair)} /> ); diff --git a/src/components/views/elements/EventTilePreview.tsx b/src/components/views/elements/EventTilePreview.tsx index 20cca35d62..49c97831bc 100644 --- a/src/components/views/elements/EventTilePreview.tsx +++ b/src/components/views/elements/EventTilePreview.tsx @@ -22,6 +22,7 @@ import * as Avatar from '../../../Avatar'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import EventTile from '../rooms/EventTile'; import SettingsStore from "../../../settings/SettingsStore"; +import {Layout} from "../../../settings/Layout"; import {UIFeature} from "../../../settings/UIFeature"; interface IProps { @@ -33,7 +34,7 @@ interface IProps { /** * Whether to use the irc layout or not */ - useIRCLayout: boolean; + layout: Layout; /** * classnames to apply to the wrapper of the preview @@ -121,14 +122,14 @@ export default class EventTilePreview extends React.Component { const event = this.fakeEvent(this.state); const className = classnames(this.props.className, { - "mx_IRCLayout": this.props.useIRCLayout, - "mx_GroupLayout": !this.props.useIRCLayout, + "mx_IRCLayout": this.props.layout == Layout.IRC, + "mx_GroupLayout": this.props.layout == Layout.Group, }); return
; diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 24b49f2b13..74aa715642 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -24,6 +24,7 @@ import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import SettingsStore from "../../../settings/SettingsStore"; +import {Layout} from "../../../settings/Layout"; import escapeHtml from "escape-html"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; @@ -42,7 +43,7 @@ export default class ReplyThread extends React.Component { onHeightChanged: PropTypes.func.isRequired, permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired, // Specifies which layout to use. - useIRCLayout: PropTypes.bool, + layout: Layout, }; static contextType = MatrixClientContext; @@ -209,7 +210,7 @@ export default class ReplyThread extends React.Component { }; } - static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, useIRCLayout) { + static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, layout) { if (!ReplyThread.getParentEventId(parentEv)) { return
; } @@ -218,7 +219,7 @@ export default class ReplyThread extends React.Component { onHeightChanged={onHeightChanged} ref={ref} permalinkCreator={permalinkCreator} - useIRCLayout={useIRCLayout} + layout={layout} />; } @@ -386,7 +387,7 @@ export default class ReplyThread extends React.Component { permalinkCreator={this.props.permalinkCreator} isRedacted={ev.isRedacted()} isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")} - useIRCLayout={this.props.useIRCLayout} + layout={this.props.layout} enableFlair={SettingsStore.getValue(UIFeature.Flair)} replacingEventId={ev.replacingEventId()} /> diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 11277daa57..17ba61732a 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -27,6 +27,7 @@ import * as TextForEvent from "../../../TextForEvent"; import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; +import {Layout} from "../../../settings/Layout"; import {EventStatus} from 'matrix-js-sdk'; import {formatTime} from "../../../DateUtils"; import {MatrixClientPeg} from '../../../MatrixClientPeg'; @@ -225,8 +226,8 @@ export default class EventTile extends React.Component { // whether to show reactions for this event showReactions: PropTypes.bool, - // whether to use the irc layout - useIRCLayout: PropTypes.bool, + // which layout to use + layout: Layout, // whether or not to show flair at all enableFlair: PropTypes.bool, @@ -732,7 +733,7 @@ export default class EventTile extends React.Component { // joins/parts/etc avatarSize = 14; needsSenderProfile = false; - } else if (this.props.useIRCLayout) { + } else if (this.props.layout == Layout.IRC) { avatarSize = 14; needsSenderProfile = true; } else if (this.props.continuation && this.props.tileShape !== "file_grid") { @@ -843,10 +844,11 @@ export default class EventTile extends React.Component { { timestamp } ; - const groupTimestamp = !this.props.useIRCLayout ? linkedTimestamp : null; - const ircTimestamp = this.props.useIRCLayout ? linkedTimestamp : null; - const groupPadlock = !this.props.useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); - const ircPadlock = this.props.useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); + const useIRCLayout = this.props.layout == Layout.IRC; + const groupTimestamp = !useIRCLayout ? linkedTimestamp : null; + const ircTimestamp = useIRCLayout ? linkedTimestamp : null; + const groupPadlock = !useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); + const ircPadlock = useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); switch (this.props.tileShape) { case 'notif': { @@ -941,7 +943,7 @@ export default class EventTile extends React.Component { this.props.onHeightChanged, this.props.permalinkCreator, this._replyThread, - this.props.useIRCLayout, + this.props.layout, ); // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index c2f010695b..5d3596911f 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -37,6 +37,7 @@ import StyledRadioGroup from "../../../elements/StyledRadioGroup"; //import classNames from 'classnames'; import { SettingLevel } from "../../../../../settings/SettingLevel"; import {UIFeature} from "../../../../../settings/UIFeature"; +import {Layout} from "../../../../../settings/Layout"; interface IProps { } @@ -62,7 +63,7 @@ interface IState extends IThemeState { useSystemFont: boolean; systemFont: string; showAdvanced: boolean; - useIRCLayout: boolean; + layout: Layout; } @@ -83,7 +84,7 @@ export default class AppearanceUserSettingsTab extends React.Component { + if (enabled) { + this.setState({layout: Layout.IRC}); + SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC); + } else { + this.setState({layout: Layout.Group}); + SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group); + } + } + private renderThemeSection() { const themeWatcher = new ThemeWatcher(); let systemThemeSection: JSX.Element; @@ -306,7 +317,7 @@ export default class AppearanceUserSettingsTab extends React.Component
Aa
@@ -409,14 +420,15 @@ export default class AppearanceUserSettingsTab extends React.Component - this.setState({useIRCLayout: checked})} + disabled={this.state.layout == Layout.IRC} /> + this.onIRCLayoutChange(ev.target.checked)} + > + {_t("Enable experimental, compact IRC style layout")} + + ({ roomLoading: true, @@ -40,7 +41,7 @@ const RoomContext = createContext({ statusBarVisible: false, canReact: false, canReply: false, - useIRCLayout: false, + layout: Layout.Group, matrixClientIsReady: false, }); RoomContext.displayName = "RoomContext"; diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 6ca009df61..3651e43d7d 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -36,6 +36,7 @@ import { isMac } from '../Keyboard'; import UIFeatureController from "./controllers/UIFeatureController"; import { UIFeature } from "./UIFeature"; import { OrderedMultiController } from "./controllers/OrderedMultiController"; +import {Layout} from "./Layout"; // These are just a bunch of helper arrays to avoid copy/pasting a bunch of times const LEVELS_ROOM_SETTINGS = [ @@ -623,10 +624,9 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td("IRC display name width"), default: 80, }, - "useIRCLayout": { - supportedLevels: LEVELS_ACCOUNT_SETTINGS, - displayName: _td("Enable experimental, compact IRC style layout"), - default: false, + "layout": { + supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM, + default: Layout.Group, }, "showChatEffects": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, From 90ad3360b628136f4e5dfc69db2c4fd81e07f0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 24 Jan 2021 09:15:11 +0100 Subject: [PATCH 013/164] Fixed read receipts? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_EventTile.scss | 8 +------- src/components/views/rooms/EventTile.js | 6 +++--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 429ac7ed4b..e2cff70841 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -258,17 +258,11 @@ $left-gutter: 64px; display: inline-block; width: 14px; height: 14px; - top: 29px; + top: -20px; user-select: none; z-index: 1; } -.mx_EventTile_continuation .mx_EventTile_readAvatars, -.mx_EventTile_info .mx_EventTile_readAvatars, -.mx_EventTile_emote .mx_EventTile_readAvatars { - top: 7px; -} - .mx_EventTile_readAvatars .mx_BaseAvatar { position: absolute; display: inline-block; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 4df74f77ce..7a2047af70 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -950,9 +950,6 @@ export default class EventTile extends React.Component { return (
{ ircTimestamp } -
- { readAvatars } -
{ sender } { ircPadlock }
@@ -971,6 +968,9 @@ export default class EventTile extends React.Component { { reactionsRow } { actionBar }
+
+ { readAvatars } +
{ // The avatar goes after the event tile as it's absolutely positioned to be over the // event tile line, so needs to be later in the DOM so it appears on top (this avoids From 7efbd50e316f1d61b6aec98c6b451982e9d509b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 26 Jan 2021 13:30:34 +0100 Subject: [PATCH 014/164] Handle migration from useIRCLayout to layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- .../handlers/DeviceSettingsHandler.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/settings/handlers/DeviceSettingsHandler.ts b/src/settings/handlers/DeviceSettingsHandler.ts index 2096203598..208a265e04 100644 --- a/src/settings/handlers/DeviceSettingsHandler.ts +++ b/src/settings/handlers/DeviceSettingsHandler.ts @@ -20,6 +20,7 @@ import SettingsHandler from "./SettingsHandler"; import {MatrixClientPeg} from "../../MatrixClientPeg"; import {SettingLevel} from "../SettingLevel"; import { CallbackFn, WatchManager } from "../WatchManager"; +import { Layout } from "../Layout"; /** * Gets and sets settings at the "device" level for the current device. @@ -67,6 +68,13 @@ export default class DeviceSettingsHandler extends SettingsHandler { return val['value']; } + // Special case for old useIRCLayout setting + if (settingName === "layout") { + const settings = this.getSettings() || {}; + if (settings["useIRCLayout"]) return Layout.IRC; + return settings[settingName]; + } + const settings = this.getSettings() || {}; return settings[settingName]; } @@ -106,6 +114,18 @@ export default class DeviceSettingsHandler extends SettingsHandler { return Promise.resolve(); } + // Special case for old useIRCLayout setting + if (settingName === "layout") { + const settings = this.getSettings() || {}; + + delete settings["useIRCLayout"]; + settings["layout"] = newValue; + localStorage.setItem("mx_local_settings", JSON.stringify(settings)); + + this.watchers.notifyUpdate(settingName, null, SettingLevel.DEVICE, newValue); + return Promise.resolve(); + } + const settings = this.getSettings() || {}; settings[settingName] = newValue; localStorage.setItem("mx_local_settings", JSON.stringify(settings)); From 554c18cabdfbf79ce36108392e48cb6e7469a0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 26 Jan 2021 13:36:47 +0100 Subject: [PATCH 015/164] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 274bd247e2..6e34bbdf1e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -828,7 +828,6 @@ "How fast should messages be downloaded.": "How fast should messages be downloaded.", "Manually verify all remote sessions": "Manually verify all remote sessions", "IRC display name width": "IRC display name width", - "Enable experimental, compact IRC style layout": "Enable experimental, compact IRC style layout", "Show chat effects": "Show chat effects", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", @@ -1148,12 +1147,10 @@ "Custom theme URL": "Custom theme URL", "Add theme": "Add theme", "Theme": "Theme", - "Message layout": "Message layout", - "Compact": "Compact", - "Modern": "Modern", "Hide advanced": "Hide advanced", "Show advanced": "Show advanced", "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Set the name of a font installed on your system & %(brand)s will attempt to use it.", + "Enable experimental, compact IRC style layout": "Enable experimental, compact IRC style layout", "Customise your appearance": "Customise your appearance", "Appearance Settings only affect this %(brand)s session.": "Appearance Settings only affect this %(brand)s session.", "Flair": "Flair", From dea1faecfe6b0718268692c4826550d82864229c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 4 Feb 2021 18:15:15 +0100 Subject: [PATCH 016/164] Added license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/settings/Layout.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/settings/Layout.ts b/src/settings/Layout.ts index bfb86170e8..e8d6e67797 100644 --- a/src/settings/Layout.ts +++ b/src/settings/Layout.ts @@ -1,3 +1,19 @@ +/* +Copyright 2021 Šimon Brandner + +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. +*/ + /* TODO: This should be later reworked into something more generic */ export enum Layout { IRC = "irc", From 20193ad7fed0f8ccb54b56424820ea431a9fc1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 5 Feb 2021 08:16:06 +0100 Subject: [PATCH 017/164] Added LayoutPropType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/settings/Layout.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/settings/Layout.ts b/src/settings/Layout.ts index e8d6e67797..3a42b2b510 100644 --- a/src/settings/Layout.ts +++ b/src/settings/Layout.ts @@ -14,8 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +import PropTypes from 'prop-types'; + /* TODO: This should be later reworked into something more generic */ export enum Layout { IRC = "irc", Group = "group" } + +/* We need this because multiple components are still using JavaScript */ +export const LayoutPropType = PropTypes.oneOf(Object.values(Layout)); From f2d236d429a6272fed848d30b1ae05dc10d89903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 5 Feb 2021 08:17:30 +0100 Subject: [PATCH 018/164] Use LayoutPropType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/MessagePanel.js | 4 ++-- src/components/structures/TimelinePanel.js | 4 ++-- src/components/views/elements/ReplyThread.js | 4 ++-- src/components/views/rooms/EventTile.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 7b40980714..5e6b94b9f8 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -26,7 +26,7 @@ import * as sdk from '../../index'; import {MatrixClientPeg} from '../../MatrixClientPeg'; import SettingsStore from '../../settings/SettingsStore'; -import {Layout} from "../../settings/Layout"; +import {Layout, LayoutPropType} from "../../settings/Layout"; import {_t} from "../../languageHandler"; import {haveTileForEvent} from "../views/rooms/EventTile"; import {textForEvent} from "../../TextForEvent"; @@ -137,7 +137,7 @@ export default class MessagePanel extends React.Component { showReactions: PropTypes.bool, // which layout to use - layout: Layout, + layout: LayoutPropType, // whether or not to show flair at all enableFlair: PropTypes.bool, diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 2d322b378d..e8da5c42d0 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -18,7 +18,7 @@ limitations under the License. */ import SettingsStore from "../../settings/SettingsStore"; -import {Layout} from "../../settings/Layout"; +import {LayoutPropType} from "../../settings/Layout"; import React, {createRef} from 'react'; import ReactDOM from "react-dom"; import PropTypes from 'prop-types'; @@ -113,7 +113,7 @@ class TimelinePanel extends React.Component { showReactions: PropTypes.bool, // which layout to use - layout: Layout, + layout: LayoutPropType, } // a map from room id to read marker event timestamp diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 74aa715642..27d773b099 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -24,7 +24,7 @@ import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import SettingsStore from "../../../settings/SettingsStore"; -import {Layout} from "../../../settings/Layout"; +import {LayoutPropType} from "../../../settings/Layout"; import escapeHtml from "escape-html"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; @@ -43,7 +43,7 @@ export default class ReplyThread extends React.Component { onHeightChanged: PropTypes.func.isRequired, permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired, // Specifies which layout to use. - layout: Layout, + layout: LayoutPropType, }; static contextType = MatrixClientContext; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 17ba61732a..bb10825b6e 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -27,7 +27,7 @@ import * as TextForEvent from "../../../TextForEvent"; import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; -import {Layout} from "../../../settings/Layout"; +import {Layout, LayoutPropType} from "../../../settings/Layout"; import {EventStatus} from 'matrix-js-sdk'; import {formatTime} from "../../../DateUtils"; import {MatrixClientPeg} from '../../../MatrixClientPeg'; @@ -227,7 +227,7 @@ export default class EventTile extends React.Component { showReactions: PropTypes.bool, // which layout to use - layout: Layout, + layout: LayoutPropType, // whether or not to show flair at all enableFlair: PropTypes.bool, From e72a7567f7ded00d8d0b353506479775f1affef3 Mon Sep 17 00:00:00 2001 From: William Kray Date: Fri, 15 Jan 2021 11:59:32 -0800 Subject: [PATCH 019/164] drop video preview max-height to 300px --- res/css/views/messages/_MVideoBody.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/messages/_MVideoBody.scss b/res/css/views/messages/_MVideoBody.scss index ac3491bc8f..2be15447f7 100644 --- a/res/css/views/messages/_MVideoBody.scss +++ b/res/css/views/messages/_MVideoBody.scss @@ -17,7 +17,7 @@ limitations under the License. span.mx_MVideoBody { video.mx_MVideoBody { max-width: 100%; - height: auto; + max-height: 300px; border-radius: 4px; } } From cd1a99186b0af27367ec47eda875d077aa90dc5b Mon Sep 17 00:00:00 2001 From: William Kray Date: Wed, 25 Nov 2020 11:41:57 -0800 Subject: [PATCH 020/164] change image rendering size max height --- src/components/views/messages/MImageBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index a8cdc17abf..8456a5bd09 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -362,7 +362,7 @@ export default class MImageBody extends React.Component { } // The maximum height of the thumbnail as it is rendered as an - const maxHeight = Math.min(this.props.maxImageHeight || 600, infoHeight); + const maxHeight = Math.min(this.props.maxImageHeight || 240, infoHeight); // The maximum width of the thumbnail, as dictated by its natural // maximum height. const maxWidth = infoWidth * maxHeight / infoHeight; From b459395d6ddf6011e4044278bacde2097c3502ed Mon Sep 17 00:00:00 2001 From: William Kray Date: Wed, 25 Nov 2020 12:11:05 -0800 Subject: [PATCH 021/164] increase size of url preview thumbnail --- src/components/views/rooms/LinkPreviewWidget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js index 2a053bf467..8581a9d444 100644 --- a/src/components/views/rooms/LinkPreviewWidget.js +++ b/src/components/views/rooms/LinkPreviewWidget.js @@ -107,7 +107,7 @@ export default class LinkPreviewWidget extends React.Component { if (!SettingsStore.getValue("showImages")) { image = null; // Don't render a button to show the image, just hide it outright } - const imageMaxWidth = 100; const imageMaxHeight = 100; + const imageMaxWidth = 320; const imageMaxHeight = 240; if (image && image.startsWith("mxc://")) { image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight); } From 03c30b0338b44704cd9a42835718c643e585b162 Mon Sep 17 00:00:00 2001 From: William Kray Date: Thu, 26 Nov 2020 08:42:55 -0800 Subject: [PATCH 022/164] change link previews to vertical flow --- res/css/views/rooms/_LinkPreviewWidget.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/css/views/rooms/_LinkPreviewWidget.scss b/res/css/views/rooms/_LinkPreviewWidget.scss index 022cf3ed28..659b0111dd 100644 --- a/res/css/views/rooms/_LinkPreviewWidget.scss +++ b/res/css/views/rooms/_LinkPreviewWidget.scss @@ -19,6 +19,8 @@ limitations under the License. margin-right: 15px; margin-bottom: 15px; display: flex; + flex-direction: column; + max-width: 360px border-left: 4px solid $preview-widget-bar-color; color: $preview-widget-fg-color; } From 9260b031e958d9c48d6acc5144715f87c6bd54d1 Mon Sep 17 00:00:00 2001 From: William Kray Date: Thu, 26 Nov 2020 09:09:41 -0800 Subject: [PATCH 023/164] oops missed a semicolon --- res/css/views/rooms/_LinkPreviewWidget.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_LinkPreviewWidget.scss b/res/css/views/rooms/_LinkPreviewWidget.scss index 659b0111dd..d06cd65502 100644 --- a/res/css/views/rooms/_LinkPreviewWidget.scss +++ b/res/css/views/rooms/_LinkPreviewWidget.scss @@ -20,7 +20,7 @@ limitations under the License. margin-bottom: 15px; display: flex; flex-direction: column; - max-width: 360px + max-width: 360px; border-left: 4px solid $preview-widget-bar-color; color: $preview-widget-fg-color; } From 99be8ccd88375d36ce74f400069231818ae9e101 Mon Sep 17 00:00:00 2001 From: William Kray Date: Fri, 27 Nov 2020 12:08:59 -0800 Subject: [PATCH 024/164] move close-preview button to top --- src/components/views/rooms/LinkPreviewWidget.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js index 8581a9d444..458b3e7054 100644 --- a/src/components/views/rooms/LinkPreviewWidget.js +++ b/src/components/views/rooms/LinkPreviewWidget.js @@ -134,6 +134,10 @@ export default class LinkPreviewWidget extends React.Component { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); return (
+ + + { img }
@@ -142,10 +146,6 @@ export default class LinkPreviewWidget extends React.Component { { description }
- - -
); } From e6da146b21c3e4df169cf90a189cb700ab8ac052 Mon Sep 17 00:00:00 2001 From: William Kray Date: Sun, 29 Nov 2020 16:53:50 -0800 Subject: [PATCH 025/164] pad url preview close button a bit --- res/css/views/rooms/_LinkPreviewWidget.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/rooms/_LinkPreviewWidget.scss b/res/css/views/rooms/_LinkPreviewWidget.scss index d06cd65502..27453cf352 100644 --- a/res/css/views/rooms/_LinkPreviewWidget.scss +++ b/res/css/views/rooms/_LinkPreviewWidget.scss @@ -57,6 +57,7 @@ limitations under the License. cursor: pointer; width: 18px; height: 18px; + padding: 0px 5px 5px 5px; img { flex: 0 0 40px; From fec230945129dea9074547b24e24112a4b658eb2 Mon Sep 17 00:00:00 2001 From: William Kray Date: Fri, 29 Jan 2021 01:30:08 -0800 Subject: [PATCH 026/164] move cancel button to the right --- res/css/views/rooms/_LinkPreviewWidget.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/css/views/rooms/_LinkPreviewWidget.scss b/res/css/views/rooms/_LinkPreviewWidget.scss index 27453cf352..5310bd3bbb 100644 --- a/res/css/views/rooms/_LinkPreviewWidget.scss +++ b/res/css/views/rooms/_LinkPreviewWidget.scss @@ -58,6 +58,8 @@ limitations under the License. width: 18px; height: 18px; padding: 0px 5px 5px 5px; + margin-left: auto; + margin-right: 0px; img { flex: 0 0 40px; From 392b47e200c91773144e68d86aaaf0e5e6dc33d2 Mon Sep 17 00:00:00 2001 From: PunitLodha Date: Tue, 9 Feb 2021 11:39:36 +0530 Subject: [PATCH 027/164] Add email only if the verification is complete --- .../views/settings/account/EmailAddresses.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/views/settings/account/EmailAddresses.js b/src/components/views/settings/account/EmailAddresses.js index ca66d5df65..07d2133e95 100644 --- a/src/components/views/settings/account/EmailAddresses.js +++ b/src/components/views/settings/account/EmailAddresses.js @@ -178,19 +178,21 @@ export default class EmailAddresses extends React.Component { e.preventDefault(); this.setState({continueDisabled: true}); - this.state.addTask.checkEmailLinkClicked().then(() => { - const email = this.state.newEmailAddress; + this.state.addTask.checkEmailLinkClicked().then(([finished]) => { + if (finished) { + const email = this.state.newEmailAddress; + const emails = [ + ...this.props.emails, + { address: email, medium: "email" }, + ]; + this.props.onEmailsChange(emails); + } this.setState({ addTask: null, continueDisabled: false, verifying: false, newEmailAddress: "", }); - const emails = [ - ...this.props.emails, - { address: email, medium: "email" }, - ]; - this.props.onEmailsChange(emails); }).catch((err) => { this.setState({continueDisabled: false}); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); From 673717d6c0675c6756beba822f679af9b8375214 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 10 Feb 2021 15:57:57 +0000 Subject: [PATCH 028/164] Upgrade matrix-js-sdk to 9.7.0-rc.1 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2263c7de32..65201a1083 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "9.7.0-rc.1", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "pako": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index 1a350f697a..e3d7a5ac28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5577,9 +5577,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "9.6.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/6ad3fb16b3813c717943f6bc8bca5a55fe325477" +matrix-js-sdk@9.7.0-rc.1: + version "9.7.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-9.7.0-rc.1.tgz#30cabda3f2b416d09c95afc4fe138bba44534c76" + integrity sha512-y6D2bXYKQqGrtf1PLHjjHf6wW67DIhdrwQ77nKOhEd/rfaEqcMf99wqSvF/nzFexbG1Y7PG4IdM4YTdOQ9UD+g== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 1dfbc73d4adcced75a258ecc55b9adc09770c303 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 10 Feb 2021 16:51:52 +0000 Subject: [PATCH 029/164] Prepare changelog for v3.14.0-rc.1 --- CHANGELOG.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a1494497..50880b1d53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,79 @@ +Changes in [3.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.14.0-rc.1) (2021-02-10) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.13.1...v3.14.0-rc.1) + + * Upgrade to JS SDK 9.7.0-rc.1 + * Translations update from Weblate + [\#5636](https://github.com/matrix-org/matrix-react-sdk/pull/5636) + * Add host signup modal with iframe + [\#5450](https://github.com/matrix-org/matrix-react-sdk/pull/5450) + * Fix duplication of codeblock elements + [\#5633](https://github.com/matrix-org/matrix-react-sdk/pull/5633) + * Handle undefined call stats + [\#5632](https://github.com/matrix-org/matrix-react-sdk/pull/5632) + * Avoid delayed displaying of sources in source picker + [\#5631](https://github.com/matrix-org/matrix-react-sdk/pull/5631) + * Give breadcrumbs toolbar an accessibility label. + [\#5628](https://github.com/matrix-org/matrix-react-sdk/pull/5628) + * Fix the %s in logs + [\#5627](https://github.com/matrix-org/matrix-react-sdk/pull/5627) + * Fix jumpy notifications settings UI + [\#5625](https://github.com/matrix-org/matrix-react-sdk/pull/5625) + * Improve displaying of code blocks + [\#5559](https://github.com/matrix-org/matrix-react-sdk/pull/5559) + * Fix desktop Matrix screen sharing and add a screen/window picker + [\#5525](https://github.com/matrix-org/matrix-react-sdk/pull/5525) + * Call "MatrixClientPeg.get()" only once in method "findOverrideMuteRule" + [\#5498](https://github.com/matrix-org/matrix-react-sdk/pull/5498) + * Close current modal when session is logged out + [\#5616](https://github.com/matrix-org/matrix-react-sdk/pull/5616) + * Switch room explorer list to CSS grid + [\#5551](https://github.com/matrix-org/matrix-react-sdk/pull/5551) + * Improve SSO login start screen and 3pid invite handling somewhat + [\#5622](https://github.com/matrix-org/matrix-react-sdk/pull/5622) + * Don't jump to bottom on reaction + [\#5621](https://github.com/matrix-org/matrix-react-sdk/pull/5621) + * Fix several profile settings oddities + [\#5620](https://github.com/matrix-org/matrix-react-sdk/pull/5620) + * Add option to hide the stickers button in the composer + [\#5530](https://github.com/matrix-org/matrix-react-sdk/pull/5530) + * Fix confusing right panel button behaviour + [\#5598](https://github.com/matrix-org/matrix-react-sdk/pull/5598) + * Fix jumping timestamp if hovering a message with e2e indicator bar + [\#5601](https://github.com/matrix-org/matrix-react-sdk/pull/5601) + * Fix avatar and trash alignment + [\#5614](https://github.com/matrix-org/matrix-react-sdk/pull/5614) + * Fix z-index of stickerpicker + [\#5617](https://github.com/matrix-org/matrix-react-sdk/pull/5617) + * Fix permalink via parsing for rooms + [\#5615](https://github.com/matrix-org/matrix-react-sdk/pull/5615) + * Fix "Terms and Conditions" checkbox alignment + [\#5613](https://github.com/matrix-org/matrix-react-sdk/pull/5613) + * Fix flair height after accent changes + [\#5611](https://github.com/matrix-org/matrix-react-sdk/pull/5611) + * Iterate Social Logins work around edge cases and branding + [\#5609](https://github.com/matrix-org/matrix-react-sdk/pull/5609) + * Lock widget room ID when added + [\#5607](https://github.com/matrix-org/matrix-react-sdk/pull/5607) + * Better errors for SSO failures + [\#5605](https://github.com/matrix-org/matrix-react-sdk/pull/5605) + * Increase language search bar width + [\#5549](https://github.com/matrix-org/matrix-react-sdk/pull/5549) + * Scroll to bottom on message_sent + [\#5565](https://github.com/matrix-org/matrix-react-sdk/pull/5565) + * Fix new rooms being titled 'Empty Room' + [\#5587](https://github.com/matrix-org/matrix-react-sdk/pull/5587) + * Fix saving the collapsed state of the left panel + [\#5593](https://github.com/matrix-org/matrix-react-sdk/pull/5593) + * Fix app-url hint in the e2e-test run script output + [\#5600](https://github.com/matrix-org/matrix-react-sdk/pull/5600) + * Fix RoomView re-mounting breaking peeking + [\#5602](https://github.com/matrix-org/matrix-react-sdk/pull/5602) + * Tweak a few room ID checks + [\#5592](https://github.com/matrix-org/matrix-react-sdk/pull/5592) + * Remove pills from event permalinks with text + [\#5575](https://github.com/matrix-org/matrix-react-sdk/pull/5575) + Changes in [3.13.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.13.1) (2021-02-04) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.13.0...v3.13.1) From d1524b2e9d243806e2ab55ebc414f2c17609629d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 10 Feb 2021 16:51:52 +0000 Subject: [PATCH 030/164] v3.14.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 65201a1083..5beb383791 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.13.1", + "version": "3.14.0-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -27,7 +27,7 @@ "matrix-gen-i18n": "scripts/gen-i18n.js", "matrix-prune-i18n": "scripts/prune-i18n.js" }, - "main": "./src/index.js", + "main": "./lib/index.js", "matrix_src_main": "./src/index.js", "matrix_lib_main": "./lib/index.js", "matrix_lib_typings": "./lib/index.d.ts", @@ -190,5 +190,6 @@ "transformIgnorePatterns": [ "/node_modules/(?!matrix-js-sdk).+$" ] - } + }, + "typings": "./lib/index.d.ts" } From a61462bc8559815a4ea08d599268b773b681483c Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Feb 2021 16:34:15 -0500 Subject: [PATCH 031/164] use the default SSSS key if the default is set implements MSC2874 --- src/SecurityManager.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/SecurityManager.ts b/src/SecurityManager.ts index 220320470a..11d228e7ab 100644 --- a/src/SecurityManager.ts +++ b/src/SecurityManager.ts @@ -98,11 +98,24 @@ async function getSecretStorageKey( { keys: keyInfos }: { keys: Record }, ssssItemName, ): Promise<[string, Uint8Array]> { - const keyInfoEntries = Object.entries(keyInfos); - if (keyInfoEntries.length > 1) { - throw new Error("Multiple storage key requests not implemented"); + const cli = MatrixClientPeg.get(); + let keyId = await cli.getDefaultSecretStorageKeyId(); + let keyInfo; + if (keyId) { + // use the default SSSS key if set + keyInfo = keyInfos[keyId]; + if (!keyInfo) { + throw new Error("Unable to use default SSSS key"); + } + } else { + // if no default SSSS key is set, fall back to a heuristic of using the + // only available key, if only one key is set + const keyInfoEntries = Object.entries(keyInfos); + if (keyInfoEntries.length > 1) { + throw new Error("Multiple storage key requests not implemented"); + } + [keyId, keyInfo] = keyInfoEntries[0]; } - const [keyId, keyInfo] = keyInfoEntries[0]; // Check the in-memory cache if (isCachingAllowed() && secretStorageKeys[keyId]) { From 17f09d3b7a4eb800d0d2076cc906500aeb914cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:16:07 +0100 Subject: [PATCH 032/164] Added onIsEmptyChanged prop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/SendMessageComposer.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 553fb44c04..99761ec8ba 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -117,6 +117,7 @@ export default class SendMessageComposer extends React.Component { placeholder: PropTypes.string, permalinkCreator: PropTypes.object.isRequired, replyToEvent: PropTypes.object, + onIsEmptyChanged: PropTypes.func, }; static contextType = MatrixClientContext; @@ -534,10 +535,15 @@ export default class SendMessageComposer extends React.Component { } } + onChange = () => { + this.props.onIsEmptyChanged(this.model.isEmpty); + } + render() { return (
Date: Fri, 12 Feb 2021 15:35:04 +0100 Subject: [PATCH 033/164] Extract send button into a function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 9683c4c79e..0ea5d80c92 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -50,6 +50,22 @@ ComposerAvatar.propTypes = { me: PropTypes.object.isRequired, }; +function SendButton(props) { + return ( +
+ +
+ ); +} + +SendButton.propTypes = { + onClick: PropTypes.func.isRequired, +}; + function CallButton(props) { const onVoiceCallClick = (ev) => { dis.dispatch({ @@ -466,13 +482,9 @@ export default class MessageComposer extends React.Component { } if (this.state.showSendButton) { - controls.push(( - - )); + controls.push( + , + ); } } else if (this.state.tombstone) { const replacementRoomId = this.state.tombstone.getContent()['replacement_room']; From 42a48ee27d8e902e7f4835d8e221ae530af76570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:39:54 +0100 Subject: [PATCH 034/164] Added composerEmpty property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 0ea5d80c92..8c13fa4dc8 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -282,6 +282,7 @@ export default class MessageComposer extends React.Component { showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), + composerEmpty: true, }; } @@ -423,6 +424,12 @@ export default class MessageComposer extends React.Component { this.messageComposerInput._sendMessage(); } + onIsEmptyChanged = (isEmpty) => { + this.setState({ + composerEmpty: isEmpty, + }); + } + render() { const controls = [ this.state.me ? : null, @@ -448,6 +455,7 @@ export default class MessageComposer extends React.Component { resizeNotifier={this.props.resizeNotifier} permalinkCreator={this.props.permalinkCreator} replyToEvent={this.props.replyToEvent} + onIsEmptyChanged={this.onIsEmptyChanged} />, , , From 50b0a78132298fb906976b4f1e2824f1195c1fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:41:43 +0100 Subject: [PATCH 035/164] Renamed composerEmpty to isComposerEmpty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 8c13fa4dc8..7918243631 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -282,7 +282,7 @@ export default class MessageComposer extends React.Component { showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), - composerEmpty: true, + isComposerEmpty: true, }; } @@ -426,7 +426,7 @@ export default class MessageComposer extends React.Component { onIsEmptyChanged = (isEmpty) => { this.setState({ - composerEmpty: isEmpty, + isComposerEmpty: isEmpty, }); } From 35c0cb99d04690f2465f7b4eb69aa5b006ccd7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:42:30 +0100 Subject: [PATCH 036/164] Use isComposerEmpty for send button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 7918243631..61d61b8f42 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -489,7 +489,7 @@ export default class MessageComposer extends React.Component { } } - if (this.state.showSendButton) { + if (!this.state.isComposerEmpty) { controls.push( , ); From ba2c68819f9d2108efb6d44ff1afe73397b4feae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:42:59 +0100 Subject: [PATCH 037/164] Removed showSendButton setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 10 ---------- .../settings/tabs/user/PreferencesUserSettingsTab.js | 1 - src/settings/Settings.ts | 5 ----- 3 files changed, 16 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 61d61b8f42..f6fc8af55d 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -279,7 +279,6 @@ export default class MessageComposer extends React.Component { tombstone: this._getRoomTombstone(), canSendMessages: this.props.room.maySendMessage(), showCallButtons: SettingsStore.getValue("showCallButtonsInComposer"), - showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room), joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room), isComposerEmpty: true, @@ -298,12 +297,6 @@ export default class MessageComposer extends React.Component { } }; - onShowSendButtonChanged = () => { - this.setState({ - showSendButton: SettingsStore.getValue("MessageComposerInput.showSendButton"), - }); - } - _onWidgetUpdate = () => { this.setState({hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room)}); }; @@ -316,8 +309,6 @@ export default class MessageComposer extends React.Component { this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); this._waitForOwnMember(); - this.showSendButtonRef = SettingsStore.watchSetting( - "MessageComposerInput.showSendButton", null, this.onShowSendButtonChanged); } _waitForOwnMember() { @@ -343,7 +334,6 @@ export default class MessageComposer extends React.Component { WidgetStore.instance.removeListener(UPDATE_EVENT, this._onWidgetUpdate); ActiveWidgetStore.removeListener('update', this._onActiveWidgetUpdate); dis.unregister(this.dispatcherRef); - SettingsStore.unwatchSetting(this.showSendButtonRef); } _onRoomStateEvents(ev, state) { diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js index eff0824d59..4d8493401e 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js @@ -34,7 +34,6 @@ export default class PreferencesUserSettingsTab extends React.Component { 'MessageComposerInput.suggestEmoji', 'sendTypingNotifications', 'MessageComposerInput.ctrlEnterToSend', - `MessageComposerInput.showSendButton`, ]; static TIMELINE_SETTINGS = [ diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 2d8385240c..b239b809fe 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -336,11 +336,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: isMac ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"), default: false, }, - "MessageComposerInput.showSendButton": { - supportedLevels: LEVELS_ACCOUNT_SETTINGS, - displayName: _td("Show send message button"), - default: false, - }, "MessageComposerInput.autoReplaceEmoji": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Automatically replace plain text Emoji'), From daff94ecbcdfb1592c483112289412296c8720b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:47:33 +0100 Subject: [PATCH 038/164] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/i18n/strings/en_EN.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6baccf95de..27ec207dda 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -799,7 +799,6 @@ "Show typing notifications": "Show typing notifications", "Use Command + Enter to send a message": "Use Command + Enter to send a message", "Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message", - "Show send message button": "Show send message button", "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", @@ -1404,6 +1403,7 @@ "Invited": "Invited", "Filter room members": "Filter room members", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", + "Send message": "Send message", "Voice call": "Voice call", "Video call": "Video call", "Hangup": "Hangup", @@ -1413,7 +1413,6 @@ "Send a reply…": "Send a reply…", "Send an encrypted message…": "Send an encrypted message…", "Send a message…": "Send a message…", - "Send message": "Send message", "The conversation continues here.": "The conversation continues here.", "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", "You do not have permission to post to this room": "You do not have permission to post to this room", From b26951714938a40a73f23c77db44d4a2b98769bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 15:52:42 +0100 Subject: [PATCH 039/164] Removed wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/MessageComposer.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index f6fc8af55d..a78cf323c6 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -52,13 +52,11 @@ ComposerAvatar.propTypes = { function SendButton(props) { return ( -
- -
+ ); } From 97f5b6920c8d25588390aa6ff2c6f9dd54b379e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 16:48:46 +0100 Subject: [PATCH 040/164] Check if the method is defined before calling it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/rooms/SendMessageComposer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index ca27141c02..9a14e33d05 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -538,7 +538,9 @@ export default class SendMessageComposer extends React.Component { } onChange = () => { - this.props.onIsEmptyChanged(this.model.isEmpty); + if (this.props.onIsEmptyChanged) { + this.props.onIsEmptyChanged(this.model.isEmpty); + } } render() { From 130e4f7bfddffb48d35a4a5a5adaf090d889905b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 17:06:02 +0100 Subject: [PATCH 041/164] Added some styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 26 +++++++++++++++++-- src/components/views/rooms/MessageComposer.js | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 8b34318f1d..c24e4912d4 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -247,8 +247,30 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/composer/sticker.svg'); } -.mx_MessageComposer_sendMessage::before { - mask-image: url('$(res)/img/element-icons/send-message.svg'); +.mx_MessageComposer_sendMessage { + cursor: pointer; + position: relative; + margin-right: 6px; + width: 32px; + height: 32px; + border-radius: 100%; + background-color: $button-bg-color; + + &:before { + position: absolute; + height: 16px; + width: 16px; + top: 8px; + left: 9px; + + mask-image: url('$(res)/img/element-icons/send-message.svg'); + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + + background-color: $button-fg-color; + content: ''; + } } .mx_MessageComposer_formatting { diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index d023d334c3..d70f273be2 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -53,7 +53,7 @@ ComposerAvatar.propTypes = { function SendButton(props) { return ( From 3983c15302772ebfd3bc04670bf4d3dd7b7b1762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Feb 2021 17:11:24 +0100 Subject: [PATCH 042/164] Delint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_MessageComposer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index c24e4912d4..2789ffdfb7 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -256,7 +256,7 @@ limitations under the License. border-radius: 100%; background-color: $button-bg-color; - &:before { + &::before { position: absolute; height: 16px; width: 16px; From 196507a730a6e64665fbac54f2d1c682c311783d Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Feb 2021 20:55:54 +0000 Subject: [PATCH 043/164] VoIP virtual rooms, mk II Does a thirdparty protocol lookup to the homeserver to get the corresponding native/virtual user for a matrix ID. Stores the mappings in room account data. Involves some slightly nasty workarounds for that fact that room account data has no local echo. --- src/@types/global.d.ts | 2 + src/CallHandler.tsx | 88 +++++++++--- src/SlashCommands.tsx | 4 +- src/VoipUserMapper.ts | 127 +++++++++++------- src/components/views/voip/DialPadModal.tsx | 5 +- src/dispatcher/actions.ts | 7 + src/stores/room-list/RoomListStore.ts | 37 +++++ .../room-list/filters/VisibilityProvider.ts | 8 +- test/VoipUserMapper-test.ts | 31 ----- 9 files changed, 208 insertions(+), 101 deletions(-) delete mode 100644 test/VoipUserMapper-test.ts diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 2a28c8e43f..28f22780a2 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -37,6 +37,7 @@ import CountlyAnalytics from "../CountlyAnalytics"; import UserActivity from "../UserActivity"; import {ModalWidgetStore} from "../stores/ModalWidgetStore"; import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; +import VoipUserMapper from "../VoipUserMapper"; declare global { interface Window { @@ -66,6 +67,7 @@ declare global { mxCountlyAnalytics: typeof CountlyAnalytics; mxUserActivity: UserActivity; mxModalWidgetStore: ModalWidgetStore; + mxVoipUserMapper: VoipUserMapper; } interface Document { diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index a6d3534fa1..ca9f96c7c2 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -84,10 +84,17 @@ import { CallError } from "matrix-js-sdk/src/webrtc/call"; import { logger } from 'matrix-js-sdk/src/logger'; import DesktopCapturerSourcePicker from "./components/views/elements/DesktopCapturerSourcePicker" import { Action } from './dispatcher/actions'; -import { roomForVirtualRoom, getOrCreateVirtualRoomForRoom } from './VoipUserMapper'; +import VoipUserMapper from './VoipUserMapper'; import { addManagedHybridWidget, isManagedHybridWidgetEnabled } from './widgets/ManagedHybrid'; -const CHECK_PSTN_SUPPORT_ATTEMPTS = 3; +export const PROTOCOL_PSTN = 'm.protocol.pstn'; +export const PROTOCOL_PSTN_PREFIXED = 'im.vector.protocol.pstn'; +export const PROTOCOL_SIP_NATIVE = 'im.vector.protocol.sip_native'; +export const PROTOCOL_SIP_VIRTUAL = 'im.vector.protocol.sip_virtual'; + +const CHECK_PROTOCOLS_ATTEMPTS = 3; +// Event type for room account data used to mark rooms as virtual rooms (and store the ID of their native room) +export const VIRTUAL_ROOM_EVENT_TYPE = 'im.vector.is_virtual_room'; enum AudioID { Ring = 'ringAudio', @@ -96,6 +103,12 @@ enum AudioID { Busy = 'busyAudio', } +interface ThirpartyLookupResponse { + userid: string, + protocol: string, + fields: {[key: string]: any}, +} + // Unlike 'CallType' in js-sdk, this one includes screen sharing // (because a screen sharing call is only a screen sharing call to the caller, // to the callee it's just a video call, at least as far as the current impl @@ -126,7 +139,12 @@ export default class CallHandler { private audioPromises = new Map>(); private dispatcherRef: string = null; private supportsPstnProtocol = null; + private pstnSupportPrefixed = null; // True if the server only support the prefixed pstn protocol + private supportsSipNativeVirtual = null; // im.vector.protocol.sip_virtual and im.vector.protocol.sip_native private pstnSupportCheckTimer: NodeJS.Timeout; // number actually because we're in the browser + // For rooms we've been invited to, true if they're from virtual user, false if we've checked and they aren't. + private invitedRoomsAreVirtual = new Map(); + private invitedRoomCheckInProgress = false; static sharedInstance() { if (!window.mxCallHandler) { @@ -140,9 +158,9 @@ export default class CallHandler { * Gets the user-facing room associated with a call (call.roomId may be the call "virtual room" * if a voip_mxid_translate_pattern is set in the config) */ - public static roomIdForCall(call: MatrixCall) { + public static roomIdForCall(call: MatrixCall): string { if (!call) return null; - return roomForVirtualRoom(call.roomId) || call.roomId; + return VoipUserMapper.sharedInstance().nativeRoomForVirtualRoom(call.roomId) || call.roomId; } start() { @@ -163,7 +181,7 @@ export default class CallHandler { MatrixClientPeg.get().on('Call.incoming', this.onCallIncoming); } - this.checkForPstnSupport(CHECK_PSTN_SUPPORT_ATTEMPTS); + this.checkProtocols(CHECK_PROTOCOLS_ATTEMPTS); } stop() { @@ -177,33 +195,73 @@ export default class CallHandler { } } - private async checkForPstnSupport(maxTries) { + private async checkProtocols(maxTries) { try { const protocols = await MatrixClientPeg.get().getThirdpartyProtocols(); - if (protocols['im.vector.protocol.pstn'] !== undefined) { - this.supportsPstnProtocol = protocols['im.vector.protocol.pstn']; - } else if (protocols['m.protocol.pstn'] !== undefined) { - this.supportsPstnProtocol = protocols['m.protocol.pstn']; + + if (protocols[PROTOCOL_PSTN] !== undefined) { + this.supportsPstnProtocol = Boolean(protocols[PROTOCOL_PSTN]); + if (this.supportsPstnProtocol) this.pstnSupportPrefixed = false; + } else if (protocols[PROTOCOL_PSTN_PREFIXED] !== undefined) { + this.supportsPstnProtocol = Boolean(protocols[PROTOCOL_PSTN_PREFIXED]); + if (this.supportsPstnProtocol) this.pstnSupportPrefixed = true; } else { this.supportsPstnProtocol = null; } + dis.dispatch({action: Action.PstnSupportUpdated}); + + if (protocols[PROTOCOL_SIP_NATIVE] !== undefined && protocols[PROTOCOL_SIP_VIRTUAL] !== undefined) { + this.supportsSipNativeVirtual = Boolean( + protocols[PROTOCOL_SIP_NATIVE] && protocols[PROTOCOL_SIP_VIRTUAL], + ); + } + + dis.dispatch({action: Action.VirtualRoomSupportUpdated}); } catch (e) { if (maxTries === 1) { - console.log("Failed to check for pstn protocol support and no retries remain: assuming no support", e); + console.log("Failed to check for protocol support and no retries remain: assuming no support", e); } else { - console.log("Failed to check for pstn protocol support: will retry", e); + console.log("Failed to check for protocol support: will retry", e); this.pstnSupportCheckTimer = setTimeout(() => { - this.checkForPstnSupport(maxTries - 1); + this.checkProtocols(maxTries - 1); }, 10000); } } } - getSupportsPstnProtocol() { + public getSupportsPstnProtocol() { return this.supportsPstnProtocol; } + public getSupportsVirtualRooms() { + return this.supportsPstnProtocol; + } + + public pstnLookup(phoneNumber: string): Promise { + return MatrixClientPeg.get().getThirdpartyUser( + this.pstnSupportPrefixed ? PROTOCOL_PSTN_PREFIXED : PROTOCOL_PSTN, { + 'm.id.phone': phoneNumber, + }, + ); + } + + public sipVirtualLookup(nativeMxid: string): Promise { + return MatrixClientPeg.get().getThirdpartyUser( + PROTOCOL_SIP_VIRTUAL, { + 'native_mxid': nativeMxid, + }, + ); + } + + public sipNativeLookup(virtualMxid: string): Promise { + return MatrixClientPeg.get().getThirdpartyUser( + PROTOCOL_SIP_NATIVE, { + 'virtual_mxid': virtualMxid, + }, + ); + } + private onCallIncoming = (call) => { // we dispatch this synchronously to make sure that the event // handlers on the call are set up immediately (so that if @@ -543,7 +601,7 @@ export default class CallHandler { Analytics.trackEvent('voip', 'placeCall', 'type', type); CountlyAnalytics.instance.trackStartCall(roomId, type === PlaceCallType.Video, false); - const mappedRoomId = (await getOrCreateVirtualRoomForRoom(roomId)) || roomId; + const mappedRoomId = (await VoipUserMapper.sharedInstance().getOrCreateVirtualRoomForRoom(roomId)) || roomId; logger.debug("Mapped real room " + roomId + " to room ID " + mappedRoomId); const call = createNewMatrixCall(MatrixClientPeg.get(), mappedRoomId); diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index a39ad33b04..8f20754027 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -1040,9 +1040,7 @@ export const Commands = [ return success((async () => { if (isPhoneNumber) { - const results = await MatrixClientPeg.get().getThirdpartyUser('im.vector.protocol.pstn', { - 'm.id.phone': userId, - }); + const results = await CallHandler.sharedInstance().pstnLookup(this.state.value); if (!results || results.length === 0 || !results[0].userid) { throw new Error("Unable to find Matrix ID for phone number"); } diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index a4f5822065..c317402327 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -17,63 +17,96 @@ limitations under the License. import { ensureDMExists, findDMForUser } from './createRoom'; import { MatrixClientPeg } from "./MatrixClientPeg"; import DMRoomMap from "./utils/DMRoomMap"; -import SdkConfig from "./SdkConfig"; +import CallHandler, { VIRTUAL_ROOM_EVENT_TYPE } from './CallHandler'; +import RoomListStore from './stores/room-list/RoomListStore'; +import { Room } from 'matrix-js-sdk/src/models/room'; -// Functions for mapping users & rooms for the voip_mxid_translate_pattern -// config option +// Functions for mapping virtual users & rooms. Currently the only lookup +// is sip virtual: there could be others in the future. -export function voipUserMapperEnabled(): boolean { - return SdkConfig.get()['voip_mxid_translate_pattern'] !== undefined; -} +export default class VoipUserMapper { + private virtualRoomIdCache = new Set(); -// only exported for tests -export function userToVirtualUser(userId: string, templateString?: string): string { - if (templateString === undefined) templateString = SdkConfig.get()['voip_mxid_translate_pattern']; - if (!templateString) return null; - return templateString.replace('${mxid}', encodeURIComponent(userId).replace(/%/g, '=').toLowerCase()); -} + public static sharedInstance(): VoipUserMapper { + if (window.mxVoipUserMapper === undefined) window.mxVoipUserMapper = new VoipUserMapper(); + return window.mxVoipUserMapper; + } -// only exported for tests -export function virtualUserToUser(userId: string, templateString?: string): string { - if (templateString === undefined) templateString = SdkConfig.get()['voip_mxid_translate_pattern']; - if (!templateString) return null; + private async userToVirtualUser(userId: string): Promise { + const results = await CallHandler.sharedInstance().sipVirtualLookup(userId); + if (results.length === 0) return null; + return results[0].userid; + } - const regexString = templateString.replace('${mxid}', '(.+)'); + public async getOrCreateVirtualRoomForRoom(roomId: string):Promise { + const userId = DMRoomMap.shared().getUserIdForRoomId(roomId); + if (!userId) return null; - const match = userId.match('^' + regexString + '$'); - if (!match) return null; + const virtualUser = await this.userToVirtualUser(userId); + if (!virtualUser) return null; - return decodeURIComponent(match[1].replace(/=/g, '%')); -} + // There's quite a bit of acromatics here to prevent the virtual room being shown + // while it's being created: forstly, we have to stop the RoomListStore from showing + // new rooms for a bit, because we can't set the room account data to say it's a virtual + // room until we have the room ID. Secondly, once we have the new room ID, we have to + // temporarily cache the fact it's a virtual room because there's no local echo on + // room account data so it won't show up in the room model until it comes down the + // sync stream again. Ick. + RoomListStore.instance.startHoldingNewRooms(); + try { + const virtualRoomId = await ensureDMExists(MatrixClientPeg.get(), virtualUser); + MatrixClientPeg.get().setRoomAccountData(virtualRoomId, VIRTUAL_ROOM_EVENT_TYPE, { + native_room: roomId, + }); + this.virtualRoomIdCache.add(virtualRoomId); -async function getOrCreateVirtualRoomForUser(userId: string):Promise { - const virtualUser = userToVirtualUser(userId); - if (!virtualUser) return null; + return virtualRoomId; + } finally { + RoomListStore.instance.stopHoldingNewRooms(); + } + } - return await ensureDMExists(MatrixClientPeg.get(), virtualUser); -} + public nativeRoomForVirtualRoom(roomId: string):string { + const virtualRoom = MatrixClientPeg.get().getRoom(roomId); + if (!virtualRoom) return null; + const virtualRoomEvent = virtualRoom.getAccountData(VIRTUAL_ROOM_EVENT_TYPE); + if (!virtualRoomEvent || !virtualRoomEvent.getContent()) return null; + return virtualRoomEvent.getContent()['native_room'] || null; + } -export async function getOrCreateVirtualRoomForRoom(roomId: string):Promise { - const user = DMRoomMap.shared().getUserIdForRoomId(roomId); - if (!user) return null; - return getOrCreateVirtualRoomForUser(user); -} + public isVirtualRoom(roomId: string):boolean { + if (this.nativeRoomForVirtualRoom(roomId)) return true; -export function roomForVirtualRoom(roomId: string):string { - const virtualUser = DMRoomMap.shared().getUserIdForRoomId(roomId); - if (!virtualUser) return null; - const realUser = virtualUserToUser(virtualUser); - const room = findDMForUser(MatrixClientPeg.get(), realUser); - if (room) { - return room.roomId; - } else { - return null; + return this.virtualRoomIdCache.has(roomId); + } + + public async onNewInvitedRoom(invitedRoom: Room) { + const inviterId = invitedRoom.getDMInviter(); + console.log(`Checking virtual-ness of room ID ${invitedRoom.roomId}, invited by ${inviterId}`); + const result = await CallHandler.sharedInstance().sipNativeLookup(inviterId); + if (result.length === 0) { + return true; + } + + if (result[0].fields.is_virtual) { + const nativeUser = result[0].userid; + const nativeRoom = findDMForUser(MatrixClientPeg.get(), nativeUser); + if (nativeRoom) { + // It's a virtual room with a matching native room, so set the room account data. This + // will make sure we know where how to map calls and also allow us know not to display + // it in the future. + MatrixClientPeg.get().setRoomAccountData(invitedRoom.roomId, VIRTUAL_ROOM_EVENT_TYPE, { + native_room: nativeRoom.roomId, + }); + // also auto-join the virtual room if we have a matching native room + // (possibly we should only join if we've also joined the native room, then we'd also have + // to make sure we joined virtual rooms on joining a native one) + MatrixClientPeg.get().joinRoom(invitedRoom.roomId); + } + + // also put this room in the virtual room ID cache so isVirtualRoom return the right answer + // in however long it takes for the echo of setAccountData to come down the sync + this.virtualRoomIdCache.add(invitedRoom.roomId); + } } } - -export function isVirtualRoom(roomId: string):boolean { - const virtualUser = DMRoomMap.shared().getUserIdForRoomId(roomId); - if (!virtualUser) return null; - const realUser = virtualUserToUser(virtualUser); - return Boolean(realUser); -} diff --git a/src/components/views/voip/DialPadModal.tsx b/src/components/views/voip/DialPadModal.tsx index 74b39e0721..9f031a48a3 100644 --- a/src/components/views/voip/DialPadModal.tsx +++ b/src/components/views/voip/DialPadModal.tsx @@ -24,6 +24,7 @@ import DialPad from './DialPad'; import dis from '../../../dispatcher/dispatcher'; import Modal from "../../../Modal"; import ErrorDialog from "../../views/dialogs/ErrorDialog"; +import CallHandler from "../../../CallHandler"; interface IProps { onFinished: (boolean) => void; @@ -64,9 +65,7 @@ export default class DialpadModal extends React.PureComponent { } onDialPress = async () => { - const results = await MatrixClientPeg.get().getThirdpartyUser('im.vector.protocol.pstn', { - 'm.id.phone': this.state.value, - }); + const results = await CallHandler.sharedInstance().pstnLookup(this.state.value); if (!results || results.length === 0 || !results[0].userid) { Modal.createTrackedDialog('', '', ErrorDialog, { title: _t("Unable to look up phone number"), diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index ce27f9b289..12bf4c57a3 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -106,4 +106,11 @@ export enum Action { * XXX: Is an action the right thing for this? */ PstnSupportUpdated = "pstn_support_updated", + + /** + * Similar to PstnSupportUpdated, fired when CallHandler has checked for virtual room support + * payload: none + * XXX: Ditto + */ + VirtualRoomSupportUpdated = "virtual_room_support_updated", } diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 24a75c53e7..15e385f7e4 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -35,6 +35,7 @@ import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; import { NameFilterCondition } from "./filters/NameFilterCondition"; import { RoomNotificationStateStore } from "../notifications/RoomNotificationStateStore"; import { VisibilityProvider } from "./filters/VisibilityProvider"; +import VoipUserMapper from "../../VoipUserMapper"; interface IState { tagsEnabled?: boolean; @@ -63,6 +64,9 @@ export class RoomListStoreClass extends AsyncStoreWithClient { } this.emit(LISTS_UPDATE_EVENT); }); + // When new rooms arrive, we may hold them here until we have enough info to know whether we should before display them. + private roomHoldingPen: Room[] = []; + private holdNewRooms = false; private readonly watchedSettings = [ 'feature_custom_tags', @@ -126,6 +130,24 @@ export class RoomListStoreClass extends AsyncStoreWithClient { this.updateFn.trigger(); } + // After calling this, any new rooms that appear are not displayed until stopHoldingNewRooms() + // is called. Be sure to always call this in a try/finally block to ensure stopHoldingNewRooms + // is called afterwards. + public startHoldingNewRooms() { + console.log("hold-new-rooms mode enabled."); + this.holdNewRooms = true; + } + + public stopHoldingNewRooms() { + console.log("hold-new-rooms mode disabled: processing " + this.roomHoldingPen.length + " held rooms"); + this.holdNewRooms = false; + for (const heldRoom of this.roomHoldingPen) { + console.log("Processing held room: " + heldRoom.roomId); + this.handleRoomUpdate(heldRoom, RoomUpdateCause.NewRoom); + } + this.roomHoldingPen = []; + } + private checkLoggingEnabled() { if (SettingsStore.getValue("advancedRoomListLogging")) { console.warn("Advanced room list logging is enabled"); @@ -398,6 +420,21 @@ export class RoomListStoreClass extends AsyncStoreWithClient { } private async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise { + if (cause === RoomUpdateCause.NewRoom) { + if (this.holdNewRooms) { + console.log("Room updates are held: putting room " + room.roomId + " into the holding pen"); + this.roomHoldingPen.push(room); + return; + } else { + // we call straight out to VoipUserMapper here which is a bit of a hack: probably this + // should be calling the visibility provider which in turn farms out to various visibility + // providers? Anyway, the point of this is that we delay doing anything about this room + // until the VoipUserMapper had had a chance to do the things it needs to do to decide + // if we should show this room or not. + await VoipUserMapper.sharedInstance().onNewInvitedRoom(room); + } + } + if (!VisibilityProvider.instance.isRoomVisible(room)) { return; // don't do anything on rooms that aren't visible } diff --git a/src/stores/room-list/filters/VisibilityProvider.ts b/src/stores/room-list/filters/VisibilityProvider.ts index 6bc790bb1e..45233357c1 100644 --- a/src/stores/room-list/filters/VisibilityProvider.ts +++ b/src/stores/room-list/filters/VisibilityProvider.ts @@ -15,8 +15,9 @@ */ import {Room} from "matrix-js-sdk/src/models/room"; +import CallHandler from "../../../CallHandler"; import { RoomListCustomisations } from "../../../customisations/RoomList"; -import { isVirtualRoom, voipUserMapperEnabled } from "../../../VoipUserMapper"; +import VoipUserMapper from "../../../VoipUserMapper"; export class VisibilityProvider { private static internalInstance: VisibilityProvider; @@ -35,7 +36,10 @@ export class VisibilityProvider { let isVisible = true; // Returned at the end of this function let forced = false; // When true, this function won't bother calling the customisation points - if (voipUserMapperEnabled() && isVirtualRoom(room.roomId)) { + if ( + CallHandler.sharedInstance().getSupportsVirtualRooms() && + VoipUserMapper.sharedInstance().isVirtualRoom(room.roomId) + ) { isVisible = false; forced = true; } diff --git a/test/VoipUserMapper-test.ts b/test/VoipUserMapper-test.ts deleted file mode 100644 index ee45379e4c..0000000000 --- a/test/VoipUserMapper-test.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2021 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { userToVirtualUser, virtualUserToUser } from '../src/VoipUserMapper'; - -const templateString = '@_greatappservice_${mxid}:frooble.example'; -const realUser = '@alice:boop.example'; -const virtualUser = "@_greatappservice_=40alice=3aboop.example:frooble.example"; - -describe('VoipUserMapper', function() { - it('translates users to virtual users', function() { - expect(userToVirtualUser(realUser, templateString)).toEqual(virtualUser); - }); - - it('translates users to virtual users', function() { - expect(virtualUserToUser(virtualUser, templateString)).toEqual(realUser); - }); -}); From 8afb74d0e16883f24a24fa2466efafdde74c772f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 13 Feb 2021 08:53:25 +0100 Subject: [PATCH 044/164] Fix border radius when the panel is collapsed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/rooms/_RoomSublist.scss | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss index 27c7c7d0f7..92a475694e 100644 --- a/res/css/views/rooms/_RoomSublist.scss +++ b/res/css/views/rooms/_RoomSublist.scss @@ -197,6 +197,9 @@ limitations under the License. .mx_RoomSublist_resizerHandles { flex: 0 0 4px; + display: flex; + justify-content: center; + width: 100%; } // Class name comes from the ResizableBox component @@ -207,17 +210,12 @@ limitations under the License. border-radius: 3px; // Override styles from library - width: unset !important; + max-width: 64px; height: 4px !important; // Update RESIZE_HANDLE_HEIGHT if this changes // This is positioned directly below the 'show more' button. - position: absolute; + position: relative !important; bottom: 0 !important; // override from library - - // Together, these make the bar 64px wide - // These are also overridden from the library - left: calc(50% - 32px) !important; - right: calc(50% - 32px) !important; } &:hover, &.mx_RoomSublist_hasMenuOpen { From 82474074f22bedd27c69e60d53fde373ac19c0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 13 Feb 2021 13:03:26 +0100 Subject: [PATCH 045/164] Fix scrollbar color for non-Firefox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/themes/dark/css/_dark.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index 612b8e03bd..a878aa3cdd 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -259,6 +259,11 @@ $composer-shadow-color: rgba(0, 0, 0, 0.28); .mx_EventTile_content .markdown-body pre:hover { border-color: #808080 !important; // inverted due to rules below scrollbar-color: rgba(0, 0, 0, 0.2) transparent; // copied from light theme due to inversion below + // the code above works only in Firefox, this is for other browsers + // see https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); // copied from light theme due to inversion below + } } .mx_EventTile_content .markdown-body { pre, code { From 7dc6029f19502b9a450d998db5364d39b8872d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 13 Feb 2021 15:29:38 +0100 Subject: [PATCH 046/164] Move icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This tweaks the icon positions to look a bit better. Espacially with a scrollbar on the side Signed-off-by: Šimon Brandner --- res/css/views/rooms/_EventTile.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 42df3211de..60b7bb08d8 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -531,14 +531,14 @@ $left-gutter: 64px; display: inline-block; visibility: hidden; cursor: pointer; - top: 6px; - right: 12px; + top: 8px; + right: 8px; width: 19px; height: 19px; background-color: $message-action-bar-fg-color; } .mx_EventTile_buttonBottom { - top: 31px; + top: 33px; } .mx_EventTile_copyButton { mask-image: url($copy-button-url); From 74a6c1e8d887f793cdd078d8e5634e948f5cae8c Mon Sep 17 00:00:00 2001 From: PunitLodha Date: Sun, 14 Feb 2021 18:21:12 +0530 Subject: [PATCH 047/164] Dont clear email if verification cancelled by user --- src/components/views/settings/account/EmailAddresses.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/account/EmailAddresses.js b/src/components/views/settings/account/EmailAddresses.js index 07d2133e95..a8de7693a9 100644 --- a/src/components/views/settings/account/EmailAddresses.js +++ b/src/components/views/settings/account/EmailAddresses.js @@ -179,6 +179,7 @@ export default class EmailAddresses extends React.Component { this.setState({continueDisabled: true}); this.state.addTask.checkEmailLinkClicked().then(([finished]) => { + let newEmailAddress = this.state.newEmailAddress; if (finished) { const email = this.state.newEmailAddress; const emails = [ @@ -186,12 +187,13 @@ export default class EmailAddresses extends React.Component { { address: email, medium: "email" }, ]; this.props.onEmailsChange(emails); + newEmailAddress = ""; } this.setState({ addTask: null, continueDisabled: false, verifying: false, - newEmailAddress: "", + newEmailAddress, }); }).catch((err) => { this.setState({continueDisabled: false}); From 0902936d3973581ae0464c4299d7b692ed04878f Mon Sep 17 00:00:00 2001 From: PunitLodha Date: Sun, 14 Feb 2021 18:21:39 +0530 Subject: [PATCH 048/164] Add phone number only if verification is complete --- .../views/settings/account/PhoneNumbers.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/views/settings/account/PhoneNumbers.js b/src/components/views/settings/account/PhoneNumbers.js index 02e995ac45..df54b5ca1f 100644 --- a/src/components/views/settings/account/PhoneNumbers.js +++ b/src/components/views/settings/account/PhoneNumbers.js @@ -177,21 +177,25 @@ export default class PhoneNumbers extends React.Component { this.setState({continueDisabled: true}); const token = this.state.newPhoneNumberCode; const address = this.state.verifyMsisdn; - this.state.addTask.haveMsisdnToken(token).then(() => { + this.state.addTask.haveMsisdnToken(token).then(([finished]) => { + let newPhoneNumber = this.state.newPhoneNumber; + if (finished) { + const msisdns = [ + ...this.props.msisdns, + { address, medium: "msisdn" }, + ]; + this.props.onMsisdnsChange(msisdns); + newPhoneNumber = ""; + } this.setState({ addTask: null, continueDisabled: false, verifying: false, verifyMsisdn: "", verifyError: null, - newPhoneNumber: "", + newPhoneNumber, newPhoneNumberCode: "", }); - const msisdns = [ - ...this.props.msisdns, - { address, medium: "msisdn" }, - ]; - this.props.onMsisdnsChange(msisdns); }).catch((err) => { this.setState({continueDisabled: false}); if (err.errcode !== 'M_THREEPID_AUTH_FAILED') { From f343aaa05a16d7cb185eff9b4ba996fc841f2e6f Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sun, 14 Feb 2021 18:37:06 +0100 Subject: [PATCH 049/164] fix context menu padding calculation Signed-off-by: Michael Weimann --- src/components/structures/ContextMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index aab7701f26..473b90ad77 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -299,7 +299,7 @@ export class ContextMenu extends React.PureComponent { // such that it does not leave the (padded) window. if (contextMenuRect) { const padding = 10; - adjusted = Math.min(position.top, document.body.clientHeight - contextMenuRect.height + padding); + adjusted = Math.min(position.top, document.body.clientHeight - contextMenuRect.height - padding); } position.top = adjusted; From d73648dfb03594e0a1a8e9772b9b15fd8cdcbe20 Mon Sep 17 00:00:00 2001 From: Jaiwanth Date: Mon, 15 Feb 2021 17:46:32 +0530 Subject: [PATCH 050/164] Modified regex to account for an immediate new line after slash commands Signed-off-by: Jaiwanth --- src/SlashCommands.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index a39ad33b04..38e5a95f7f 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -1182,7 +1182,7 @@ export function parseCommandString(input: string) { input = input.replace(/\s+$/, ''); if (input[0] !== '/') return {}; // not a command - const bits = input.match(/^(\S+?)(?: +((.|\n)*))?$/); + const bits = input.match(/^(\S+?)(?:[ \n]+((.|\n)*))?$/); let cmd; let args; if (bits) { From d7bf57af13de7aeb03bed98df0649071ca6a0b17 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 15:04:01 +0000 Subject: [PATCH 051/164] Add missing 'd' --- src/CallHandler.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index ca9f96c7c2..6cebae1093 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -103,7 +103,7 @@ enum AudioID { Busy = 'busyAudio', } -interface ThirpartyLookupResponse { +interface ThirdpartyLookupResponse { userid: string, protocol: string, fields: {[key: string]: any}, @@ -238,7 +238,7 @@ export default class CallHandler { return this.supportsPstnProtocol; } - public pstnLookup(phoneNumber: string): Promise { + public pstnLookup(phoneNumber: string): Promise { return MatrixClientPeg.get().getThirdpartyUser( this.pstnSupportPrefixed ? PROTOCOL_PSTN_PREFIXED : PROTOCOL_PSTN, { 'm.id.phone': phoneNumber, @@ -246,7 +246,7 @@ export default class CallHandler { ); } - public sipVirtualLookup(nativeMxid: string): Promise { + public sipVirtualLookup(nativeMxid: string): Promise { return MatrixClientPeg.get().getThirdpartyUser( PROTOCOL_SIP_VIRTUAL, { 'native_mxid': nativeMxid, @@ -254,7 +254,7 @@ export default class CallHandler { ); } - public sipNativeLookup(virtualMxid: string): Promise { + public sipNativeLookup(virtualMxid: string): Promise { return MatrixClientPeg.get().getThirdpartyUser( PROTOCOL_SIP_NATIVE, { 'virtual_mxid': virtualMxid, From 554dfdb6bf58a82f9f09b047f2cca6835a733d57 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 15:05:01 +0000 Subject: [PATCH 052/164] Typo Co-authored-by: J. Ryan Stinnett --- src/VoipUserMapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index c317402327..bf592de001 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -45,7 +45,7 @@ export default class VoipUserMapper { const virtualUser = await this.userToVirtualUser(userId); if (!virtualUser) return null; - // There's quite a bit of acromatics here to prevent the virtual room being shown + // There's quite a bit of acrobatics here to prevent the virtual room being shown // while it's being created: forstly, we have to stop the RoomListStore from showing // new rooms for a bit, because we can't set the room account data to say it's a virtual // room until we have the room ID. Secondly, once we have the new room ID, we have to From 65ef4f2f221fce653828a636131ebe202950f2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 15 Feb 2021 16:05:14 +0100 Subject: [PATCH 053/164] Removed the commented out code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- .../tabs/user/AppearanceUserSettingsTab.tsx | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index 5d3596911f..80a20d8afa 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -28,13 +28,11 @@ import { FontWatcher } from "../../../../../settings/watchers/FontWatcher"; import { RecheckThemePayload } from '../../../../../dispatcher/payloads/RecheckThemePayload'; import { Action } from '../../../../../dispatcher/actions'; import { IValidationResult, IFieldState } from '../../../elements/Validation'; -//import StyledRadioButton from '../../../elements/StyledRadioButton'; import StyledCheckbox from '../../../elements/StyledCheckbox'; import SettingsFlag from '../../../elements/SettingsFlag'; import Field from '../../../elements/Field'; import EventTilePreview from '../../../elements/EventTilePreview'; import StyledRadioGroup from "../../../elements/StyledRadioGroup"; -//import classNames from 'classnames'; import { SettingLevel } from "../../../../../settings/SettingLevel"; import {UIFeature} from "../../../../../settings/UIFeature"; import {Layout} from "../../../../../settings/Layout"; @@ -214,16 +212,6 @@ export default class AppearanceUserSettingsTab extends React.Component): void => { - const val = e.target.value === "true"; - - this.setState({ - useIRCLayout: val, - }); - - SettingsStore.setValue("useIRCLayout", null, SettingLevel.DEVICE, val); - };*/ - private onIRCLayoutChange = (enabled: boolean) => { if (enabled) { this.setState({layout: Layout.IRC}); @@ -353,50 +341,6 @@ export default class AppearanceUserSettingsTab extends React.Component; } - /*private renderLayoutSection = () => { - return
- {_t("Message layout")} - -
-
- - - {_t("Compact")} - -
-
-
- - - {_t("Modern")} - -
-
-
; - };*/ - private renderAdvancedSection() { if (!SettingsStore.getValue(UIFeature.AdvancedSettings)) return null; From 0b574327d77e267422eb9929358315e8810c52f9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 15:05:16 +0000 Subject: [PATCH 054/164] More typo Co-authored-by: J. Ryan Stinnett --- src/VoipUserMapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index bf592de001..ceb87c1829 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -46,7 +46,7 @@ export default class VoipUserMapper { if (!virtualUser) return null; // There's quite a bit of acrobatics here to prevent the virtual room being shown - // while it's being created: forstly, we have to stop the RoomListStore from showing + // while it's being created: firstly, we have to stop the RoomListStore from showing // new rooms for a bit, because we can't set the room account data to say it's a virtual // room until we have the room ID. Secondly, once we have the new room ID, we have to // temporarily cache the fact it's a virtual room because there's no local echo on From 064afab239adec142ee8c410378f2fb7adbecbcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 15 Feb 2021 16:06:38 +0100 Subject: [PATCH 055/164] Use LEVELS_ACCOUNT_SETTINGS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/settings/Settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 3651e43d7d..d7d5ab8490 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -625,7 +625,7 @@ export const SETTINGS: {[setting: string]: ISetting} = { default: 80, }, "layout": { - supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM, + supportedLevels: LEVELS_ACCOUNT_SETTINGS, default: Layout.Group, }, "showChatEffects": { From d339dc447f83ab82c9f135e355eb140e237f0678 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 15:25:07 +0000 Subject: [PATCH 056/164] Add specific fields to third party lookup response fields --- src/CallHandler.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 6cebae1093..63b849af4b 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -103,10 +103,27 @@ enum AudioID { Busy = 'busyAudio', } +interface ThirdpartyLookupResponseFields { + /* eslint-disable camelcase */ + + // im.vector.sip_native + virtual_mxid: string; + is_virtual: boolean; + + // im.vector.sip_virtual + native_mxid: string; + is_native: boolean; + + // common + lookup_success: boolean; + + /* eslint-enable camelcase */ +} + interface ThirdpartyLookupResponse { userid: string, protocol: string, - fields: {[key: string]: any}, + fields: ThirdpartyLookupResponseFields, } // Unlike 'CallType' in js-sdk, this one includes screen sharing From cd82d97c3eb3c1035cbbe73f6f4741665b3f3b45 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Feb 2021 08:53:37 -0700 Subject: [PATCH 057/164] Use randomly generated conference names for Jitsi Fixes https://github.com/vector-im/element-web/issues/15205 Replaces https://github.com/matrix-org/matrix-react-sdk/pull/5322 This change uses a random ID for the Jitsi conference name to avoid any badly-named Jitsi calls, and overrides the "subject" (title) of the call so end users aren't typically exposed to the random ID. --- package.json | 1 - src/CallHandler.tsx | 5 +++-- src/utils/NamingUtils.ts | 29 ----------------------------- src/utils/WidgetUtils.ts | 1 + yarn.lock | 13 ------------- 5 files changed, 4 insertions(+), 45 deletions(-) delete mode 100644 src/utils/NamingUtils.ts diff --git a/package.json b/package.json index 2263c7de32..61c8cb7a2c 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "pako": "^2.0.3", "parse5": "^6.0.1", "png-chunks-extract": "^1.0.0", - "project-name-generator": "^2.1.9", "prop-types": "^15.7.2", "qrcode": "^1.4.4", "qs": "^6.9.6", diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 41a5941092..e09a47cf97 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -64,7 +64,6 @@ import dis from './dispatcher/dispatcher'; import WidgetUtils from './utils/WidgetUtils'; import WidgetEchoStore from './stores/WidgetEchoStore'; import SettingsStore from './settings/SettingsStore'; -import {generateHumanReadableId} from "./utils/NamingUtils"; import {Jitsi} from "./widgets/Jitsi"; import {WidgetType} from "./widgets/WidgetType"; import {SettingLevel} from "./settings/SettingLevel"; @@ -86,6 +85,7 @@ import DesktopCapturerSourcePicker from "./components/views/elements/DesktopCapt import { Action } from './dispatcher/actions'; import { roomForVirtualRoom, getOrCreateVirtualRoomForRoom } from './VoipUserMapper'; import { addManagedHybridWidget, isManagedHybridWidgetEnabled } from './widgets/ManagedHybrid'; +import { randomString } from "matrix-js-sdk/lib/randomstring"; const CHECK_PSTN_SUPPORT_ATTEMPTS = 3; @@ -780,7 +780,7 @@ export default class CallHandler { confId = base32.stringify(Buffer.from(roomId), { pad: false }); } else { // Create a random human readable conference ID - confId = `JitsiConference${generateHumanReadableId()}`; + confId = `JitsiConference${randomString(32)}`; } let widgetUrl = WidgetUtils.getLocalJitsiWrapperUrl({auth: jitsiAuth}); @@ -796,6 +796,7 @@ export default class CallHandler { isAudioOnly: type === 'voice', domain: jitsiDomain, auth: jitsiAuth, + roomName: room.name, }; const widgetId = ( diff --git a/src/utils/NamingUtils.ts b/src/utils/NamingUtils.ts deleted file mode 100644 index 44ccb9b030..0000000000 --- a/src/utils/NamingUtils.ts +++ /dev/null @@ -1,29 +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 * as projectNameGenerator from "project-name-generator"; - -/** - * Generates a human readable identifier. This should not be used for anything - * which needs secure/cryptographic random: just a level uniquness that is offered - * by something like Date.now(). - * @returns {string} The randomly generated ID - */ -export function generateHumanReadableId(): string { - return projectNameGenerator({words: 3}).raw.map(w => { - return w[0].toUpperCase() + w.substring(1).toLowerCase(); - }).join(''); -} diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index db2b10b295..c67f3bad13 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -477,6 +477,7 @@ export default class WidgetUtils { 'userId=$matrix_user_id', 'roomId=$matrix_room_id', 'theme=$theme', + 'roomName=$roomName', ]; if (opts.auth) { queryStringParts.push(`auth=${opts.auth}`); diff --git a/yarn.lock b/yarn.lock index 1a350f697a..9bd51f16a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2477,11 +2477,6 @@ commander@^4.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -6453,14 +6448,6 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -project-name-generator@^2.1.9: - version "2.1.9" - resolved "https://registry.yarnpkg.com/project-name-generator/-/project-name-generator-2.1.9.tgz#959177f1feb2355d74fa98745d72a65a5f75b674" - integrity sha512-QmLHqz2C4VHmAyDEAFlVfnuWAHr4vwZhK2bbm4IrwuHNzNKOdG9b4U+NmQbsm1uOoV4kGWv7+FVLsu7Bb/ieYQ== - dependencies: - commander "^6.1.0" - lodash "^4.17.20" - promise@^7.0.3, promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" From cb757b5b50a645932547a94f7b46d851ea34e9c1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Feb 2021 08:56:38 -0700 Subject: [PATCH 058/164] Fix import --- src/CallHandler.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index e09a47cf97..f106d75f8b 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -85,7 +85,7 @@ import DesktopCapturerSourcePicker from "./components/views/elements/DesktopCapt import { Action } from './dispatcher/actions'; import { roomForVirtualRoom, getOrCreateVirtualRoomForRoom } from './VoipUserMapper'; import { addManagedHybridWidget, isManagedHybridWidgetEnabled } from './widgets/ManagedHybrid'; -import { randomString } from "matrix-js-sdk/lib/randomstring"; +import { randomString } from "matrix-js-sdk/src/randomstring"; const CHECK_PSTN_SUPPORT_ATTEMPTS = 3; From d96043d5ab3e246cec1f6891352066ed2782a932 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 15 Feb 2021 17:34:28 +0000 Subject: [PATCH 059/164] Use config for host signup branding --- res/css/structures/_UserMenu.scss | 2 +- src/components/structures/HostSignupAction.tsx | 13 ++++++++++++- src/i18n/strings/en_EN.json | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_UserMenu.scss b/res/css/structures/_UserMenu.scss index f2577938e5..2a4453df70 100644 --- a/res/css/structures/_UserMenu.scss +++ b/res/css/structures/_UserMenu.scss @@ -128,7 +128,7 @@ limitations under the License. } .mx_UserMenu_contextMenu { - width: 247px; + width: 258px; // These override the styles already present on the user menu rather than try to // define a new menu. They are specifically for the stacked menu when a community diff --git a/src/components/structures/HostSignupAction.tsx b/src/components/structures/HostSignupAction.tsx index 39185acd05..9cf84a9379 100644 --- a/src/components/structures/HostSignupAction.tsx +++ b/src/components/structures/HostSignupAction.tsx @@ -21,6 +21,7 @@ import { } from "../views/context_menus/IconizedContextMenu"; import { _t } from "../../languageHandler"; import { HostSignupStore } from "../../stores/HostSignupStore"; +import SdkConfig from "../../SdkConfig"; interface IProps {} @@ -32,11 +33,21 @@ export default class HostSignupAction extends React.PureComponent diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a9d31bb9f2..d023984f7d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2450,7 +2450,7 @@ "Send a Direct Message": "Send a Direct Message", "Explore Public Rooms": "Explore Public Rooms", "Create a Group Chat": "Create a Group Chat", - "Upgrade to pro": "Upgrade to pro", + "Upgrade to %(hostSignupBrand)s": "Upgrade to %(hostSignupBrand)s", "Explore rooms": "Explore rooms", "Failed to reject invitation": "Failed to reject invitation", "Cannot create rooms in this community": "Cannot create rooms in this community", From 234f1bf2c47369c86d8c1a437c959dff828a1cb5 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 15 Feb 2021 17:38:11 +0000 Subject: [PATCH 060/164] Test domains in config directly --- src/components/structures/UserMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 5b34d36d09..7f96e2d142 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -300,7 +300,7 @@ export default class UserMenu extends React.Component { const hostSignupDomains = hostSignupConfig.domains || []; const mxDomain = MatrixClientPeg.get().getDomain(); const validDomains = hostSignupDomains.filter(d => (d === mxDomain || mxDomain.endsWith(`.${d}`))); - if (!hostSignupDomains || validDomains.length > 0) { + if (!hostSignupConfig.domains || validDomains.length > 0) { topSection =
; From 3919fcd80e6f709ae74ec4cf7b93d36ea3d2f651 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 15 Feb 2021 17:34:28 +0000 Subject: [PATCH 061/164] Use config for host signup branding --- res/css/structures/_UserMenu.scss | 2 +- src/components/structures/HostSignupAction.tsx | 13 ++++++++++++- src/i18n/strings/en_EN.json | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_UserMenu.scss b/res/css/structures/_UserMenu.scss index f2577938e5..2a4453df70 100644 --- a/res/css/structures/_UserMenu.scss +++ b/res/css/structures/_UserMenu.scss @@ -128,7 +128,7 @@ limitations under the License. } .mx_UserMenu_contextMenu { - width: 247px; + width: 258px; // These override the styles already present on the user menu rather than try to // define a new menu. They are specifically for the stacked menu when a community diff --git a/src/components/structures/HostSignupAction.tsx b/src/components/structures/HostSignupAction.tsx index 39185acd05..9cf84a9379 100644 --- a/src/components/structures/HostSignupAction.tsx +++ b/src/components/structures/HostSignupAction.tsx @@ -21,6 +21,7 @@ import { } from "../views/context_menus/IconizedContextMenu"; import { _t } from "../../languageHandler"; import { HostSignupStore } from "../../stores/HostSignupStore"; +import SdkConfig from "../../SdkConfig"; interface IProps {} @@ -32,11 +33,21 @@ export default class HostSignupAction extends React.PureComponent diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a9d31bb9f2..d023984f7d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2450,7 +2450,7 @@ "Send a Direct Message": "Send a Direct Message", "Explore Public Rooms": "Explore Public Rooms", "Create a Group Chat": "Create a Group Chat", - "Upgrade to pro": "Upgrade to pro", + "Upgrade to %(hostSignupBrand)s": "Upgrade to %(hostSignupBrand)s", "Explore rooms": "Explore rooms", "Failed to reject invitation": "Failed to reject invitation", "Cannot create rooms in this community": "Cannot create rooms in this community", From b2834d7f919ff655ad1a85fcc8931d1ffd40260b Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 15 Feb 2021 17:38:11 +0000 Subject: [PATCH 062/164] Test domains in config directly --- src/components/structures/UserMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 5b34d36d09..7f96e2d142 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -300,7 +300,7 @@ export default class UserMenu extends React.Component { const hostSignupDomains = hostSignupConfig.domains || []; const mxDomain = MatrixClientPeg.get().getDomain(); const validDomains = hostSignupDomains.filter(d => (d === mxDomain || mxDomain.endsWith(`.${d}`))); - if (!hostSignupDomains || validDomains.length > 0) { + if (!hostSignupConfig.domains || validDomains.length > 0) { topSection =
; From 89b2dae035f33728c45a8193d234d688b6ba209b Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 18:13:13 +0000 Subject: [PATCH 063/164] Send onNewInvitedRoom via VisibilityProvider --- src/stores/room-list/RoomListStore.ts | 12 ++++++------ src/stores/room-list/filters/VisibilityProvider.ts | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 15e385f7e4..a050442eae 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -426,12 +426,12 @@ export class RoomListStoreClass extends AsyncStoreWithClient { this.roomHoldingPen.push(room); return; } else { - // we call straight out to VoipUserMapper here which is a bit of a hack: probably this - // should be calling the visibility provider which in turn farms out to various visibility - // providers? Anyway, the point of this is that we delay doing anything about this room - // until the VoipUserMapper had had a chance to do the things it needs to do to decide - // if we should show this room or not. - await VoipUserMapper.sharedInstance().onNewInvitedRoom(room); + // Let the visibility provider know that there is a new invited room. It would be nice + // if this could just be an event that things listen for but the point of this is that + // we delay doing anything about this room until the VoipUserMapper had had a chance + // to do the things it needs to do to decide if we should show this room or not, so + // an even wouldn't et us do that. + await VisibilityProvider.instance.onNewInvitedRoom(room); } } diff --git a/src/stores/room-list/filters/VisibilityProvider.ts b/src/stores/room-list/filters/VisibilityProvider.ts index 45233357c1..2239f9e1ac 100644 --- a/src/stores/room-list/filters/VisibilityProvider.ts +++ b/src/stores/room-list/filters/VisibilityProvider.ts @@ -32,6 +32,10 @@ export class VisibilityProvider { return VisibilityProvider.internalInstance; } + public async onNewInvitedRoom(room: Room) { + await VoipUserMapper.sharedInstance().onNewInvitedRoom(room); + } + public isRoomVisible(room: Room): boolean { let isVisible = true; // Returned at the end of this function let forced = false; // When true, this function won't bother calling the customisation points From 79455d99b477d42f1738120780a34f83e903b1a2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Feb 2021 19:38:17 +0000 Subject: [PATCH 064/164] Unused import --- src/stores/room-list/RoomListStore.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index a050442eae..f420dd2b08 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -35,7 +35,6 @@ import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; import { NameFilterCondition } from "./filters/NameFilterCondition"; import { RoomNotificationStateStore } from "../notifications/RoomNotificationStateStore"; import { VisibilityProvider } from "./filters/VisibilityProvider"; -import VoipUserMapper from "../../VoipUserMapper"; interface IState { tagsEnabled?: boolean; From f9d4d679ee6cdb3fb66bd54e4a89d755c3b21f68 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Feb 2021 10:59:39 +0000 Subject: [PATCH 065/164] Upgrade matrix-js-sdk to 9.7.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5beb383791..4700f6d0cb 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "9.7.0-rc.1", + "matrix-js-sdk": "9.7.0", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "pako": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index e3d7a5ac28..6aff5fecdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5577,10 +5577,10 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@9.7.0-rc.1: - version "9.7.0-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-9.7.0-rc.1.tgz#30cabda3f2b416d09c95afc4fe138bba44534c76" - integrity sha512-y6D2bXYKQqGrtf1PLHjjHf6wW67DIhdrwQ77nKOhEd/rfaEqcMf99wqSvF/nzFexbG1Y7PG4IdM4YTdOQ9UD+g== +matrix-js-sdk@9.7.0: + version "9.7.0" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-9.7.0.tgz#fbd03c188546f9733b28ea1752476b22ca63d2f2" + integrity sha512-cVBHhQVGk2WWQ2kv0Ov8CTcgZVJhMuZBejXZnKqp6qEgSpmb4xQRxewbxjF53ixO7uRUzGFtAlDiW4BeHZnN/g== dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From a99f080e97acf82ed774b98b7eb62ccdf16a0127 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Feb 2021 11:05:24 +0000 Subject: [PATCH 066/164] Prepare changelog for v3.14.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50880b1d53..c87f1c62e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Changes in [3.14.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.14.0) (2021-02-16) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.14.0-rc.1...v3.14.0) + + * Upgrade to JS SDK 9.7.0 + * [Release] Use config for host signup branding + [\#5651](https://github.com/matrix-org/matrix-react-sdk/pull/5651) + Changes in [3.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.14.0-rc.1) (2021-02-10) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.13.1...v3.14.0-rc.1) From e70085ed2e14a74dc4f482645b89bbb82101de38 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Feb 2021 11:05:25 +0000 Subject: [PATCH 067/164] v3.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4700f6d0cb..203673eef4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.14.0-rc.1", + "version": "3.14.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From df3a9526a5780c4a71e8c951cf47991bbd43b9ec Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Feb 2021 11:06:42 +0000 Subject: [PATCH 068/164] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c05a007d70..9b2f60655c 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "matrix-gen-i18n": "scripts/gen-i18n.js", "matrix-prune-i18n": "scripts/prune-i18n.js" }, - "main": "./lib/index.js", + "main": "./src/index.js", "matrix_src_main": "./src/index.js", "matrix_lib_main": "./lib/index.js", "matrix_lib_typings": "./lib/index.d.ts", @@ -189,6 +189,5 @@ "transformIgnorePatterns": [ "/node_modules/(?!matrix-js-sdk).+$" ] - }, - "typings": "./lib/index.d.ts" + } } From b6a4876c8a6d6b12b5eaad93ee91869422f02837 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Feb 2021 11:06:55 +0000 Subject: [PATCH 069/164] Reset matrix-js-sdk back to develop branch --- package.json | 2 +- yarn.lock | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9b2f60655c..d4f931d811 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "9.7.0", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "matrix-widget-api": "^0.1.0-beta.13", "minimist": "^1.2.5", "pako": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index 4108c0499c..01450908cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5572,10 +5572,9 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -matrix-js-sdk@9.7.0: +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": version "9.7.0" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-9.7.0.tgz#fbd03c188546f9733b28ea1752476b22ca63d2f2" - integrity sha512-cVBHhQVGk2WWQ2kv0Ov8CTcgZVJhMuZBejXZnKqp6qEgSpmb4xQRxewbxjF53ixO7uRUzGFtAlDiW4BeHZnN/g== + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/c82bc35202f93efa2cb9b27b140f83df37c64ab2" dependencies: "@babel/runtime" "^7.12.5" another-json "^0.2.0" From 75d789bb4330b497c9cd43cbe7b38c6e1c1d4f19 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Tue, 16 Feb 2021 12:07:36 +0000 Subject: [PATCH 070/164] Translated using Weblate (Czech) Currently translated at 100.0% (2764 of 2764 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 229 +++++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 108 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index c304623544..864c6208fa 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -55,7 +55,7 @@ "Custom Server Options": "Vlastní nastavení serveru", "Add a widget": "Přidat widget", "Accept": "Přijmout", - "%(targetName)s accepted an invitation.": "%(targetName)s přijal/a pozvání.", + "%(targetName)s accepted an invitation.": "%(targetName)s přijal(a) pozvání.", "Account": "Účet", "Access Token:": "Přístupový token:", "Add": "Přidat", @@ -86,10 +86,10 @@ "Bans user with given id": "Vykáže uživatele s daným id", "Cannot add any more widgets": "Nelze přidat žádné další widgety", "Change Password": "Změnit heslo", - "%(senderName)s changed their profile picture.": "%(senderName)s změnil/a svůj profilový obrázek.", - "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s změnil/a název místnosti na %(roomName)s.", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s odstranil/a název místnosti.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s změnil/a téma na „%(topic)s“.", + "%(senderName)s changed their profile picture.": "%(senderName)s změnil(a) svůj profilový obrázek.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s změnil(a) název místnosti na %(roomName)s.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s odstranil(a) název místnosti.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s změnil(a) téma na „%(topic)s“.", "Changes your display nickname": "Změní vaši zobrazovanou přezdívku", "Command error": "Chyba příkazu", "Commands": "Příkazy", @@ -113,8 +113,8 @@ "Email address": "E-mailová adresa", "Emoji": "Emoji", "Enable automatic language detection for syntax highlighting": "Zapnout automatické rozpoznávání jazyků pro zvýrazňování syntaxe", - "%(senderName)s ended the call.": "%(senderName)s ukončil/a hovor.", - "Enter passphrase": "Zadejte heslo", + "%(senderName)s ended the call.": "%(senderName)s ukončil(a) hovor.", + "Enter passphrase": "Zadejte přístupovou frázi", "Error decrypting attachment": "Chyba při dešifrování přílohy", "Error: Problem communicating with the given homeserver.": "Chyba: problém v komunikaci s daným domovským serverem.", "Existing Call": "Probíhající hovor", @@ -136,18 +136,18 @@ "Forget room": "Zapomenout místnost", "For security, this session has been signed out. Please sign in again.": "Z bezpečnostních důvodů bylo toto přihlášení ukončeno. Přihlašte se prosím znovu.", "and %(count)s others...|other": "a %(count)s další...", - "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s upravil/a widget %(widgetName)s", - "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s odstranil/a widget %(widgetName)s", - "%(widgetName)s widget added by %(senderName)s": "%(senderName)s přidal/a widget %(widgetName)s", + "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s upravil(a) widget %(widgetName)s", + "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s odstranil(a) widget %(widgetName)s", + "%(widgetName)s widget added by %(senderName)s": "%(senderName)s přidal(a) widget %(widgetName)s", "Automatically replace plain text Emoji": "Automaticky nahrazovat textové emoji", "Failed to upload image": "Obrázek se nepodařilo nahrát", - "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", + "%(senderName)s answered the call.": "%(senderName)s přijal(a) hovor.", "Click to mute audio": "Klepněte pro vypnutí zvuku", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste klepli na odkaz v e-mailové zprávě", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Homeserver is": "Domovský server je", "Identity Server is": "Server identity je", - "I have verified my email address": "Ověřil/a jsem svou e-mailovou adresu", + "I have verified my email address": "Ověřil(a) jsem svou e-mailovou adresu", "Import": "Importovat", "Import E2E room keys": "Importovat end-to-end klíče místností", "Incoming call from %(name)s": "Příchozí hovor od %(name)s", @@ -156,12 +156,12 @@ "Incorrect username and/or password.": "Nesprávné uživatelské jméno nebo heslo.", "Incorrect verification code": "Nesprávný ověřovací kód", "Invalid Email Address": "Neplatná e-mailová adresa", - "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval/a uživatele %(targetName)s.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval(a) uživatele %(targetName)s.", "Invites": "Pozvánky", "Invites user with given id to current room": "Pozve do aktuální místnosti uživatele s daným id", "Join Room": "Vstoupit do místnosti", - "%(targetName)s joined the room.": "%(targetName)s vstoupil/a do místnosti.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s vykopl/a uživatele %(targetName)s.", + "%(targetName)s joined the room.": "%(targetName)s vstoupil(a) do místnosti.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s vykopl(a) uživatele %(targetName)s.", "Kick": "Vykopnout", "Kicks user with given id": "Vykopne uživatele s daným id", "Last seen": "Naposledy aktivní", @@ -184,7 +184,7 @@ "Passwords can't be empty": "Hesla nemohou být prázdná", "Permissions": "Oprávnění", "Phone": "Telefon", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s změnil/a úroveň oprávnění o %(powerLevelDiffText)s.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s změnil(a) úroveň oprávnění o %(powerLevelDiffText)s.", "Define the power level of a user": "Stanovte úroveň oprávnění uživatele", "Failed to change power level": "Nepodařilo se změnit úroveň oprávnění", "Power level must be positive integer.": "Úroveň oprávnění musí být kladné celé číslo.", @@ -201,15 +201,15 @@ "%(roomName)s is not accessible at this time.": "Místnost %(roomName)s není v tuto chvíli dostupná.", "Save": "Uložit", "Send Reset Email": "Poslat resetovací e-mail", - "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s poslal/a obrázek.", - "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s pozval/a uživatele %(targetDisplayName)s ke vstupu do místnosti.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s poslal(a) obrázek.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s pozval(a) uživatele %(targetDisplayName)s ke vstupu do místnosti.", "Server error": "Chyba serveru", "Server may be unavailable, overloaded, or search timed out :(": "Server může být nedostupný, přetížený nebo vyhledávání vypršelo :(", "Server may be unavailable, overloaded, or you hit a bug.": "Server může být nedostupný, přetížený nebo jste narazili na chybu.", "Server unavailable, overloaded, or something else went wrong.": "Server je nedostupný, přetížený nebo se něco pokazilo.", "Session ID": "ID sezení", - "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", + "%(senderName)s set a profile picture.": "%(senderName)s si nastavil(a) profilový obrázek.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil(a) zobrazované jméno na %(displayName)s.", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat čas v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", "Sign out": "Odhlásit", @@ -235,9 +235,9 @@ "Online": "Online", "Offline": "Offline", "Check for update": "Zkontrolovat aktualizace", - "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s přijal/a pozvání pro %(displayName)s.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s přijal(a) pozvání pro %(displayName)s.", "Active call (%(roomName)s)": "Probíhající hovor (%(roomName)s)", - "%(senderName)s banned %(targetName)s.": "%(senderName)s vykázal/a uživatele %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s vykázal(a) uživatele %(targetName)s.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nelze se připojit k domovskému serveru přes HTTP, pokud je v adresním řádku HTTPS. Buď použijte HTTPS, nebo povolte nezabezpečené skripty.", "Click here to fix": "Pro opravu klepněte zde", "Click to mute video": "Klepněte pro zakázání videa", @@ -258,7 +258,7 @@ "Unable to remove contact information": "Nepodařilo se smazat kontaktní údaje", "Unable to verify email address.": "Nepodařilo se ověřit e-mailovou adresu.", "Unban": "Přijmout zpět", - "%(senderName)s unbanned %(targetName)s.": "%(senderName)s přijal/a zpět uživatele %(targetName)s.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s přijal(a) zpět uživatele %(targetName)s.", "Unable to capture screen": "Nepodařilo se zachytit obrazovku", "Unable to enable Notifications": "Nepodařilo se povolit oznámení", "unknown caller": "neznámý volající", @@ -305,11 +305,11 @@ "Reason": "Důvod", "VoIP conference started.": "VoIP konference započata.", "VoIP conference finished.": "VoIP konference ukončena.", - "%(targetName)s left the room.": "%(targetName)s opustil/a místnost.", + "%(targetName)s left the room.": "%(targetName)s opustil(a) místnost.", "You are already in a call.": "Již máte probíhající hovor.", "%(senderName)s requested a VoIP conference.": "Uživatel %(senderName)s požádal o VoIP konferenci.", - "%(senderName)s removed their profile picture.": "%(senderName)s odstranil/a svůj profilový obrázek.", - "%(targetName)s rejected the invitation.": "%(targetName)s odmítl/a pozvání.", + "%(senderName)s removed their profile picture.": "%(senderName)s odstranil(a) svůj profilový obrázek.", + "%(targetName)s rejected the invitation.": "%(targetName)s odmítl(a) pozvání.", "Communities": "Skupiny", "Message Pinning": "Připíchnutí zprávy", "Your browser does not support the required cryptography extensions": "Váš prohlížeč nepodporuje požadovaná kryptografická rozšíření", @@ -320,20 +320,20 @@ "Admin Tools": "Nástroje pro správce", "No pinned messages.": "Žádné připíchnuté zprávy.", "Pinned Messages": "Připíchnuté zprávy", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s odstranil/a své zobrazované jméno (%(oldDisplayName)s).", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s zrušil/a pozvání pro uživatele %(targetName)s.", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s nastavil/a viditelnost budoucích zpráv v této místnosti pro všechny její členy, a to od chvíle jejich pozvání.", - "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s nastavil/a viditelnost budoucích zpráv v této místnosti pro všechny její členy, a to od chvíle jejich vstupu.", - "%(senderName)s made future room history visible to all room members.": "%(senderName)s nastavil/a viditelnost budoucích zpráv v této místnosti pro všechny její členy.", - "%(senderName)s made future room history visible to anyone.": "%(senderName)s nastavil/a viditelnost budoucích zpráv pro kohokoliv.", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s změnil/a připíchnuté zprávy této místnosti.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s odstranil(a) své zobrazované jméno (%(oldDisplayName)s).", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s zrušil(a) pozvání pro uživatele %(targetName)s.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s nastavil(a) viditelnost budoucích zpráv v této místnosti pro všechny její členy, a to od chvíle jejich pozvání.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s nastavil(a) viditelnost budoucích zpráv v této místnosti pro všechny její členy, a to od chvíle jejich vstupu.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s nastavil(a) viditelnost budoucích zpráv v této místnosti pro všechny její členy.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s nastavil(a) viditelnost budoucích zpráv pro kohokoliv.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s změnil(a) připíchnuté zprávy této místnosti.", "Authentication check failed: incorrect password?": "Kontrola ověření selhala: špatné heslo?", "You need to be able to invite users to do that.": "Pro tuto akci musíte mít právo zvát uživatele.", "Delete Widget": "Smazat widget", "Error decrypting image": "Chyba při dešifrování obrázku", "Error decrypting video": "Chyba při dešifrování videa", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstranil/a avatar místnosti.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s změnil/a avatar místnosti na ", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstranil(a) avatar místnosti.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s změnil(a) avatar místnosti na ", "Copied!": "Zkopírováno!", "Failed to copy": "Nepodařilo se zkopírovat", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Smazáním widgetu ho odstraníte všem uživatelům v této místnosti. Opravdu chcete tento widget smazat?", @@ -384,9 +384,9 @@ "Invalid community ID": "Neplatné ID skupiny", "'%(groupId)s' is not a valid community ID": "'%(groupId)s' není platné ID skupiny", "New community ID (e.g. +foo:%(localDomain)s)": "Nové ID skupiny (např. +neco:%(localDomain)s)", - "%(senderName)s sent an image": "%(senderName)s poslal/a obrázek", - "%(senderName)s sent a video": "%(senderName)s poslal/a video", - "%(senderName)s uploaded a file": "%(senderName)s nahrál/a soubor", + "%(senderName)s sent an image": "%(senderName)s poslal(a) obrázek", + "%(senderName)s sent a video": "%(senderName)s poslal(a) video", + "%(senderName)s uploaded a file": "%(senderName)s nahrál(a) soubor", "Disinvite this user?": "Odvolat pozvání tohoto uživatele?", "Kick this user?": "Vykopnout tohoto uživatele?", "Unban this user?": "Přijmout zpět tohoto uživatele?", @@ -398,16 +398,16 @@ "You have disabled URL previews by default.": "Vypnuli jste automatické náhledy webových adres.", "You have enabled URL previews by default.": "Zapnuli jste automatické náhledy webových adres.", "URL Previews": "Náhledy webových adres", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s změnil/a avatar místnosti %(roomName)s", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s změnil(a) avatar místnosti %(roomName)s", "Add an Integration": "Přidat začlenění", "An email has been sent to %(emailAddress)s": "Na adresu %(emailAddress)s jsme poslali e-mail", "File to import": "Soubor k importu", - "Passphrases must match": "Hesla se musí shodovat", - "Passphrase must not be empty": "Heslo nesmí být prázdné", + "Passphrases must match": "Přístupové fráze se musí shodovat", + "Passphrase must not be empty": "Přístupová fráze nesmí být prázdná", "Export room keys": "Exportovat klíče místnosti", "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ám umožňuje exportovat do souboru klíče ke zprávám, které jste dostali v šifrovaných místnostech. Když pak tento soubor importujete do jiného Matrix klienta, všechny tyto zprávy bude možné opět dešifrovat.", - "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.": "Kdokoliv, kdo získá přístup k exportovanému souboru, bude moci dešifrovat všechny vaše přijaté zprávy, a proto je třeba dbát zvýšenou pozornost jeho zabezpečení. Z toho důvodu byste měli do kolonky níže zadat heslo, se kterým exportovaná data zašifrujeme. Import pak bude možný pouze se znalostí zadaného hesla.", - "Confirm passphrase": "Potvrďte heslo", + "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.": "Kdokoliv, kdo získá přístup k exportovanému souboru, bude moci dešifrovat všechny vaše přijaté zprávy, a proto je třeba dbát zvýšenou pozornost jeho zabezpečení. Z toho důvodu byste měli do kolonky níže zadat přístupovou frázi, se kterým exportovaná data zašifrujeme. Import pak bude možný pouze se znalostí zadané přístupové fráze.", + "Confirm passphrase": "Potvrďte přístupovou frázi", "Import room keys": "Importovat klíče místnosti", "Call Timeout": "Časový limit hovoru", "Show these rooms to non-members on the community page and room list?": "Zobrazovat tyto místnosti na domovské stránce skupiny a v seznamu místností i pro nečleny?", @@ -466,18 +466,18 @@ "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s%(count)s krát vstoupili", "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)svstoupili", - "%(oneUser)sjoined %(count)s times|one": "%(oneUser)svstoupil/a", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)svstoupil(a)", "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s %(count)s krát opustili", "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sopustili", "%(oneUser)sleft %(count)s times|other": "%(oneUser)s %(count)s krát opustil", "%(oneUser)sleft %(count)s times|one": "%(oneUser)sopustil", "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s %(count)s krát vstoupili a opustili", "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)svstoupili a opustili", - "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil/a a opustil/a", - "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)svstoupil/a a opustil/a", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil(a) a opustil(a)", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)svstoupil(a) a opustil(a)", "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s %(count)s krát opustili a znovu vstoupili", "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sopustili a znovu vstoupili", - "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s %(count)s krát opustil/a a znovu vstoupil/a", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s %(count)s krát opustil(a) a znovu vstoupil(a)", "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sopustil a znovu vstoupil", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s %(count)s krát odmítli pozvání", "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sodmítli pozvání", @@ -505,12 +505,12 @@ "was kicked %(count)s times|one": "byl vyhozen", "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s si %(count)s krát změnili jméno", "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s si změnili jméno", - "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s si %(count)s krát změnil/a jméno", - "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s si změnil/ jméno", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s si %(count)s krát změnil(a) jméno", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s si změnil(a) jméno", "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát změnili avatary", "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi změnili avatary", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s si %(count)s krát změnil/a avatar", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s si změnil/a avatar", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s si %(count)s krát změnil(a) avatar", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s si změnil(a) avatar", "%(items)s and %(count)s others|other": "%(items)s a %(count)s další", "%(items)s and %(count)s others|one": "%(items)s a jeden další", "%(items)s and %(lastItem)s": "%(items)s a také %(lastItem)s", @@ -539,7 +539,7 @@ "To get started, please pick a username!": "Začněte tím, že si zvolíte uživatelské jméno!", "This will be your account name on the homeserver, or you can pick a different server.": "Toto bude název vašeho účtu na domovském serveru , anebo si můžete zvolit jiný server.", "If you already have a Matrix account you can log in instead.": "Pokud už účet v síti Matrix máte, můžete se ihned Přihlásit.", - "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil/a", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil(a)", "Private Chat": "Soukromá konverzace", "Public Chat": "Veřejná konverzace", "You must register to use this functionality": "Pro využívání této funkce se zaregistrujte", @@ -564,7 +564,7 @@ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tyto místnosti se zobrazují všem členům na stránce skupiny. Členové skupiny mohou vstoupit do místnosti klepnutím.", "Featured Rooms:": "Hlavní místnosti:", "Featured Users:": "Významní uživatelé:", - "%(inviter)s has invited you to join this community": "%(inviter)s vás pozval/a do této skupiny", + "%(inviter)s has invited you to join this community": "%(inviter)s vás pozval(a) do této skupiny", "You are an administrator of this community": "Jste správcem této skupiny", "You are a member of this community": "Jste členem této skupiny", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Vaše skupina nemá vyplněný dlouhý popis, který je součástí HTML stránky skupiny a která se zobrazuje jejím členům.
Klepnutím zde otevřete nastavení, kde ho můžete doplnit!", @@ -606,7 +606,7 @@ "Notify the whole room": "Oznámení pro celou místnost", "Room Notification": "Oznámení místnosti", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tento proces vás provede importem šifrovacích klíčů, které jste si stáhli z jiného Matrix klienta. Po úspěšném naimportování budete v tomto klientovi moci dešifrovat všechny zprávy, které jste mohli dešifrovat v původním klientovi.", - "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn přístupovou frází. Soubor můžete naimportovat pouze pokud zadáte odpovídající přístupovou frázi.", "Call Failed": "Hovor selhal", "Send": "Odeslat", "collapse": "sbalit", @@ -753,7 +753,7 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "Missing roomId.": "Chybějící ID místnosti.", "Opens the Developer Tools dialog": "Otevře dialog nástrojů pro vývojáře", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s si změnil/a zobrazované jméno na %(displayName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s si změnil(a) zobrazované jméno na %(displayName)s.", "Always show encryption icons": "Vždy zobrazovat ikonu stavu šifrovaní", "Send analytics data": "Odesílat analytická data", "Enable widget screenshots on supported widgets": "Povolit screenshot widgetu pro podporované widgety", @@ -943,14 +943,14 @@ "Upgrades a room to a new version": "Upgraduje místnost na novou verzi", "This room has no topic.": "Tato místnost nemá žádné specifické téma.", "Sets the room name": "Nastaví název místnosti", - "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s upgradoval/a místnost.", - "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s zveřejnil/a místnost pro všechny s odkazem.", - "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s zpřístupnil/a místnost pouze na pozvání.", - "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s změnil/a pravidlo k připojení na %(rule)s", - "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s povolil/a přístup hostům.", - "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s zakázal/a přístup hostům.", - "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s změnil/a pravidlo pro přístup hostů na %(rule)s", - "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s nastavil/a hlavní adresu této místnosti na %(address)s.", + "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s upgradoval(a) místnost.", + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s zveřejnil(a) místnost pro všechny s odkazem.", + "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s zpřístupnil(a) místnost pouze na pozvání.", + "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s změnil(a) pravidlo k připojení na %(rule)s", + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s povolil(a) přístup hostům.", + "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s zakázal(a) přístup hostům.", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s změnil(a) pravidlo pro přístup hostů na %(rule)s", + "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s nastavil(a) hlavní adresu této místnosti na %(address)s.", "%(senderName)s removed the main address for this room.": "%(senderName)s zrušil hlavní adresu této místnosti.", "%(displayName)s is typing …": "%(displayName)s píše …", "%(names)s and %(count)s others are typing …|other": "%(names)s a %(count)s dalších píše …", @@ -1231,10 +1231,10 @@ "You cannot modify widgets in this room.": "V této místnosti nemůžete manipulovat s widgety.", "Sends the given message coloured as a rainbow": "Pošle zprávu v barvách duhy", "Sends the given emote coloured as a rainbow": "Pošle reakci v barvách duhy", - "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s přidal/a této místnosti příslušnost ke skupině %(groups)s.", - "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s odebral/a této místnosti příslušnost ke skupině %(groups)s.", - "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s přidal/a této místnosti příslušnost ke skupině %(newGroups)s a odebral/a k %(oldGroups)s.", - "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s zrušil/a pozvání do této místnosti pro uživatele %(targetDisplayName)s.", + "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s přidal(a) této místnosti příslušnost ke skupině %(groups)s.", + "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s odebral(a) této místnosti příslušnost ke skupině %(groups)s.", + "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s přidal(a) této místnosti příslušnost ke skupině %(newGroups)s a odebral(a) k %(oldGroups)s.", + "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s zrušil(a) pozvání do této místnosti pro uživatele %(targetDisplayName)s.", "No homeserver URL provided": "Nebyla zadána URL adresa domovského server", "Unexpected error resolving homeserver configuration": "Chyba při zjišťování konfigurace domovského serveru", "The user's homeserver does not support the version of the room.": "Uživatelův domovský server nepodporuje verzi této místnosti.", @@ -1253,11 +1253,11 @@ "Join the conversation with an account": "Připojte se ke konverzaci s účtem", "Sign Up": "Zaregistrovat se", "Sign In": "Přihlásit se", - "You were kicked from %(roomName)s by %(memberName)s": "%(memberName)s vás vykopl/a z místnosti %(roomName)s", + "You were kicked from %(roomName)s by %(memberName)s": "%(memberName)s vás vykopl(a) z místnosti %(roomName)s", "Reason: %(reason)s": "Důvod: %(reason)s", "Forget this room": "Zapomenout na tuto místnost", "Re-join": "Znovu vstoupit", - "You were banned from %(roomName)s by %(memberName)s": "%(memberName)s vás vykázal/a z místnosti %(roomName)s", + "You were banned from %(roomName)s by %(memberName)s": "%(memberName)s vás vykázal(a) z místnosti %(roomName)s", "Something went wrong with your invite to %(roomName)s": "S vaší pozvánkou do místnosti %(roomName)s se něco pokazilo", "You can only join it with a working invite.": "Vstoupit můžete jen s funkční pozvánkou.", "You can still join it because this is a public room.": "I přesto můžete vstoupit, protože tato místnost je veřejná.", @@ -1265,7 +1265,7 @@ "Try to join anyway": "Stejně se pokusit vstoupit", "Do you want to chat with %(user)s?": "Chcete si povídat s %(user)s?", "Do you want to join %(roomName)s?": "Chcete vstoupit do místnosti %(roomName)s?", - " invited you": " vás pozval/a", + " invited you": " vás pozval(a)", "You're previewing %(roomName)s. Want to join it?": "Nahlížíte do místnosti %(roomName)s. Chcete do ní vstoupit?", "%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s si nelze jen tak prohlížet. Chcete do ní vstoupit?", "This room doesn't exist. Are you sure you're at the right place?": "Tato místnost neexistuje. Jste si jistí, že jste na správném místě?", @@ -1280,7 +1280,7 @@ "Invited by %(sender)s": "Pozván od uživatele %(sender)s", "Error updating flair": "Nepovedlo se změnit příslušnost ke skupině", "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Pro tuto místnost se nepovedlo změnit příslušnost ke skupině. Možná to server neumožňuje, nebo došlo k dočasné chybě.", - "reacted with %(shortName)s": " reagoval/a s %(shortName)s", + "reacted with %(shortName)s": " reagoval(a) s %(shortName)s", "edited": "upraveno", "Maximize apps": "Maximalizovat aplikace", "Rotate Left": "Otočit doleva", @@ -1509,11 +1509,11 @@ "Show image": "Zobrazit obrázek", "You verified %(name)s": "Ověřili jste %(name)s", "You cancelled verifying %(name)s": "Zrušili jste ověření %(name)s", - "%(name)s cancelled verifying": "%(name)s zrušil/a ověření", + "%(name)s cancelled verifying": "%(name)s zrušil(a) ověření", "You accepted": "Přijali jste", - "%(name)s accepted": "%(name)s přijal/a", + "%(name)s accepted": "%(name)s přijal(a)", "You cancelled": "Zrušili jste", - "%(name)s cancelled": "%(name)s zrušil/a", + "%(name)s cancelled": "%(name)s zrušil(a)", "%(name)s wants to verify": "%(name)s chce ověřit", "You sent a verification request": "Poslali jste požadavek na ověření", "Show all": "Zobrazit vše", @@ -1532,8 +1532,8 @@ "Please create a new issue on GitHub so that we can investigate this bug.": "Vyrobte prosím nové issue na GitHubu abychom mohli chybu opravit.", "%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)s neudělali %(count)s krát žádnou změnu", "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)s neudělali žádnou změnu", - "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s neudělal/a %(count)s krát žádnou změnu", - "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)s neudělal/a žádnou změnu", + "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s neudělal(a) %(count)s krát žádnou změnu", + "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)s neudělal(a) žádnou změnu", "e.g. my-room": "např. moje-mistnost", "Use bots, bridges, widgets and sticker packs": "Použít roboty, propojení, widgety a balíky samolepek", "Terms of Service": "Podmínky použití", @@ -1555,7 +1555,7 @@ "Explore": "Procházet", "Filter": "Filtr místností", "Filter rooms…": "Najít místnost…", - "%(creator)s created and configured the room.": "%(creator)s vytvořil/a a nakonfiguroval/a místnost.", + "%(creator)s created and configured the room.": "%(creator)s vytvořil(a) a nakonfiguroval(a) místnost.", "Preview": "Náhled", "View": "Zobrazit", "Find a room…": "Najít místnost…", @@ -1593,23 +1593,23 @@ "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s spustil hovor. (není podporováno tímto prohlížečem)", "%(senderName)s placed a video call.": "%(senderName)s spustil videohovor.", "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s spustil videohovor. (není podporováno tímto prohlížečem)", - "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s odstranil/a pravidlo blokující uživatele odpovídající %(glob)s", + "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s odstranil(a) pravidlo blokující uživatele odpovídající %(glob)s", "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s odstranil pravidlo blokující místnosti odpovídající %(glob)s", "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s odstranil pravidlo blokující servery odpovídající %(glob)s", "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s odstranil blokující pravidlo %(glob)s", "%(senderName)s updated an invalid ban rule": "%(senderName)s aktualizoval neplatné pravidlo blokování", - "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s aktualizoval/a pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s", + "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s aktualizoval(a) pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s aktualizoval pravidlo blokující místnosti odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s aktualizoval pravidlo blokující servery odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s aktualizoval blokovací pravidlo odpovídající %(glob)s z důvodu %(reason)s", - "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s vytvořil/a pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s", + "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s vytvořil(a) pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s vytvořil pravidlo blokující místnosti odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s vytvořil pravidlo blokující servery odpovídající %(glob)s z důvodu %(reason)s", "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s vytvořil blokovací pravidlo odpovídající %(glob)s z důvodu %(reason)s", - "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil/a pravidlo blokující uživatele odpovídající %(oldGlob)s na uživatele odpovídající %(newGlob)s z důvodu %(reason)s", - "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil/a pravidlo blokující místnosti odpovídající %(oldGlob)s na místnosti odpovídající %(newGlob)s z důvodu %(reason)s", - "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil/a pravidlo blokující servery odpovídající %(oldGlob)s na servery odpovídající %(newGlob)s z důvodu %(reason)s", - "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil/a blokovací pravidlo odpovídající %(oldGlob)s na odpovídající %(newGlob)s z důvodu %(reason)s", + "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil(a) pravidlo blokující uživatele odpovídající %(oldGlob)s na uživatele odpovídající %(newGlob)s z důvodu %(reason)s", + "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil(a) pravidlo blokující místnosti odpovídající %(oldGlob)s na místnosti odpovídající %(newGlob)s z důvodu %(reason)s", + "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil(a) pravidlo blokující servery odpovídající %(oldGlob)s na servery odpovídající %(newGlob)s z důvodu %(reason)s", + "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil(a) blokovací pravidlo odpovídající %(oldGlob)s na odpovídající %(newGlob)s z důvodu %(reason)s", "Try out new ways to ignore people (experimental)": "Vyzkoušejte nové metody ignorování lidí (experimentální)", "Match system theme": "Nastavit podle vzhledu systému", "My Ban List": "Můj seznam zablokovaných", @@ -1873,7 +1873,7 @@ "New session": "Nová relace", "Use this session to verify your new one, granting it access to encrypted messages:": "Použijte tuto relaci pro ověření nové a udělení jí přístupu k vašim šifrovaným zprávám:", "If you didn’t sign in to this session, your account may be compromised.": "Pokud jste se do této nové relace nepřihlásili, váš účet může být kompromitován.", - "This wasn't me": "To jsem nebyl/a já", + "This wasn't me": "To jsem nebyl(a) já", "This will allow you to return to your account after signing out, and sign in on other sessions.": "Toto vám umožní se přihlásit do dalších relací a vrátit se ke svému účtu poté, co se odhlásíte.", "Recovery key mismatch": "Obnovovací klíč neodpovídá", "Incorrect recovery passphrase": "Nesprávné heslo pro obnovení", @@ -1893,7 +1893,7 @@ "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.": "Varování: Vaše osobní data (včetně šifrovacích klíčů) jsou tu pořád uložena. Smažte je, pokud chcete tuto relaci zahodit, nebo se přihlaste pod jiný účet.", "If you cancel now, you won't complete verifying the other user.": "Pokud teď proces zrušíte, tak nebude druhý uživatel ověřen.", "If you cancel now, you won't complete verifying your other session.": "Pokud teď proces zrušíte, tak nebude druhá relace ověřena.", - "Cancel entering passphrase?": "Zrušit zadávání hesla?", + "Cancel entering passphrase?": "Zrušit zadávání přístupové fráze?", "Setting up keys": "Příprava klíčů", "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)su chybí nějaké komponenty, které jsou potřeba pro vyhledávání v zabezpečených místnostech. Pokud chcete s touto funkcí experimentovat, tak si pořiďte vlastní %(brand)s Desktop s přidanými komponentami.", "Subscribing to a ban list will cause you to join it!": "Odebíráním seznamu zablokovaných uživatelů se přidáte do jeho místnosti!", @@ -1922,7 +1922,7 @@ "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "Relace, kterou se snažíte ověřit, neumožňuje ověření QR kódem ani pomocí emoji, což je to, co %(brand)s podporuje. Zkuste použít jiného klienta.", "Verify by scanning": "Ověřte naskenováním", "You declined": "Odmítli jste", - "%(name)s declined": "%(name)s odmítl/a", + "%(name)s declined": "%(name)s odmítl(a)", "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Uschovejte si kopii na bezpečném místě, například ve správci hesel nebo v trezoru.", "Your recovery key": "Váš obnovovací klíč", "Copy": "Zkopírovat", @@ -1948,7 +1948,7 @@ "Show shortcuts to recently viewed rooms above the room list": "Zobrazovat zkratky do nedávno zobrazených místností navrchu", "Cancelling…": "Rušení…", "Your homeserver does not support cross-signing.": "Váš domovský server nepodporuje cross-signing.", - "Homeserver feature support:": "Funkce podporované domovským serverem:", + "Homeserver feature support:": "Funkce podporovaná domovským serverem:", "Accepting…": "Přijímání…", "Accepting …": "Přijímání…", "Declining …": "Odmítání…", @@ -1963,14 +1963,14 @@ "Mark all as read": "Označit vše jako přečtené", "Not currently indexing messages for any room.": "Aktuálně neindexujeme žádné zprávy.", "%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s z %(totalRooms)s", - "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s změnil/a jméno místnosti z %(oldRoomName)s na %(newRoomName)s.", - "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s přidal/a této místnosti alternativní adresy %(addresses)s.", - "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s přidal/a této místnosti alternativní adresu %(addresses)s.", - "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s odebral/a této místnosti alternativní adresy %(addresses)s.", - "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s odebral/a této místnosti alternativní adresu %(addresses)s.", - "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s změnil/a alternativní adresy této místnosti.", - "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s změnil/a hlavní a alternativní adresy této místnosti.", - "%(senderName)s changed the addresses for this room.": "%(senderName)s změnil/a adresy této místnosti.", + "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s změnil(a) jméno místnosti z %(oldRoomName)s na %(newRoomName)s.", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s přidal(a) této místnosti alternativní adresy %(addresses)s.", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s přidal(a) této místnosti alternativní adresu %(addresses)s.", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s odebral(a) této místnosti alternativní adresy %(addresses)s.", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s odebral(a) této místnosti alternativní adresu %(addresses)s.", + "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s změnil(a) alternativní adresy této místnosti.", + "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s změnil(a) hlavní a alternativní adresy této místnosti.", + "%(senderName)s changed the addresses for this room.": "%(senderName)s změnil(a) adresy této místnosti.", "Manually Verify by Text": "Manuální textové ověření", "Interactively verify by Emoji": "Interaktivní ověření s emotikonami", "Support adding custom themes": "Umožnit přidání vlastního vzhledu", @@ -2044,7 +2044,7 @@ "Start verification again from their profile.": "Proces ověření začněte znovu z profilu kontaktu.", "Verification timed out.": "Ověření vypršelo.", "You cancelled verification on your other session.": "Na druhé relace jste proces ověření zrušili.", - "%(displayName)s cancelled verification.": "%(displayName)s zrušil/a proces ověření.", + "%(displayName)s cancelled verification.": "%(displayName)s zrušil(a) proces ověření.", "You cancelled verification.": "Zrušili jste proces ověření.", "Message deleted": "Zpráva smazána", "Message deleted by %(name)s": "Zpráva smazána uživatelem %(name)s", @@ -2104,7 +2104,7 @@ "Restart": "Restartovat", "Upgrade your %(brand)s": "Aktualizovat %(brand)s", "A new version of %(brand)s is available!": "Je dostupná nová verze %(brand)su!", - "Are you sure you want to cancel entering passphrase?": "Chcete určitě zrušit zadávání hesla?", + "Are you sure you want to cancel entering passphrase?": "Chcete určitě zrušit zadávání přístupové fráze?", "Use your account to sign in to the latest version": "Přihlašte se za pomoci svého účtu do nejnovější verze", "Riot is now Element!": "Riot je nyní Element!", "Learn More": "Zjistit více", @@ -2172,7 +2172,7 @@ "%(senderName)s left the call": "%(senderName)s opustil/a hovor", "Call ended": "Hovor skončil", "You started a call": "Začali jste hovor", - "%(senderName)s started a call": "%(senderName)s začal/a hovor", + "%(senderName)s started a call": "%(senderName)s začal(a) hovor", "Waiting for answer": "Čekání na odpověď", "%(senderName)s is calling": "%(senderName)s volá", "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", @@ -2193,7 +2193,7 @@ "Incoming call": "Příchozí hovor", "Your server isn't responding to some requests.": "Váš server neodpovídá na některé požadavky.", "Master private key:": "Hlavní soukromý klíč:", - "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s nemůže v prohlížeči lokálně bezpečně uložit zprávy. Použijte %(brand)s Desktop aby fungovalo vyhledávání v šifrovaných zprávách.", + "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s nemůže bezpečně ukládat šifrované zprávy lokálně v prohlížeči. Pro zobrazení šifrovaných zpráv ve výsledcích vyhledávání použijte %(brand)s Desktop.", "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Váš administrátor vypnul šifrování ve výchozím nastavení soukromých místností a přímých chatů.", "To link to this room, please add an address.": "Přidejte prosím místnosti adresu aby na ní šlo odkazovat.", "The authenticity of this encrypted message can't be guaranteed on this device.": "Pravost této šifrované zprávy nelze na tomto zařízení ověřit.", @@ -2256,7 +2256,7 @@ "Start a new chat": "Založit novou konverzaci", "Which officially provided instance you are using, if any": "Kterou oficiální instanci Riot.im používáte (a jestli vůbec)", "Change the topic of this room": "Změnit téma této místnosti", - "%(senderName)s declined the call.": "%(senderName)s odmítl/a hovor.", + "%(senderName)s declined the call.": "%(senderName)s odmítl(a) hovor.", "(an error occurred)": "(došlo k chybě)", "(their device couldn't start the camera / microphone)": "(zařízení druhé strany nemohlo spustit kameru / mikrofon)", "(connection failed)": "(spojení selhalo)", @@ -2295,7 +2295,7 @@ "Attach files from chat or just drag and drop them anywhere in a room.": "Připojte soubory z chatu nebo je jednoduše přetáhněte kamkoli do místnosti.", "No files visible in this room": "V této místnosti nejsou viditelné žádné soubory", "Show files": "Zobrazit soubory", - "%(count)s people|other": "%(count)s lidé/í", + "%(count)s people|other": "%(count)s lidí", "About": "O", "You’re all caught up": "Vše vyřízeno", "You have no visible notifications in this room.": "V této místnosti nemáte žádná viditelná oznámení.", @@ -2333,10 +2333,10 @@ "Switch to light mode": "Přepnout do světlého režimu", "User settings": "Uživatelská nastavení", "Community settings": "Nastavení skupiny", - "Confirm your recovery passphrase": "Potvrďte vaši frázi pro obnovení", + "Confirm your recovery passphrase": "Potvrďte vaši přístupovou frázi pro obnovení", "Repeat your recovery passphrase...": "Opakujte přístupovou frázi pro obnovení...", "Please enter your recovery passphrase a second time to confirm.": "Potvrďte prosím podruhé svou frázi pro obnovení.", - "Use a different passphrase?": "Použít jinou frázi?", + "Use a different passphrase?": "Použít jinou přístupovou frázi?", "Great! This recovery passphrase looks strong enough.": "Skvělé! Tato fráze pro obnovení vypadá dostatečně silně.", "Enter a recovery passphrase": "Zadejte frázi pro obnovení", "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s nebo %(usernamePassword)s", @@ -2439,7 +2439,7 @@ "There are two ways you can provide feedback and help us improve %(brand)s.": "Jsou dva způsoby, jak můžete poskytnout zpětnou vazbu a pomoci nám vylepšit %(brand)s.", "Rate %(brand)s": "Ohodnotit %(brand)s", "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "V této relaci jste již dříve používali novější verzi %(brand)s. Chcete-li tuto verzi znovu použít s šifrováním, budete se muset odhlásit a znovu přihlásit.", - "Homeserver": "Homeserver", + "Homeserver": "Domovský server", "Continue with %(provider)s": "Pokračovat s %(provider)s", "Server Options": "Možnosti serveru", "This version of %(brand)s does not support viewing some encrypted files": "Tato verze %(brand)s nepodporuje zobrazení některých šifrovaných souborů", @@ -2789,7 +2789,7 @@ "Fill Screen": "Vyplnit obrazovku", "Voice Call": "Hlasový hovor", "Video Call": "Videohovor", - "%(senderName)s ended the call": "%(senderName)s ukončil/a hovor", + "%(senderName)s ended the call": "%(senderName)s ukončil(a) hovor", "You ended the call": "Ukončili jste hovor", "New version of %(brand)s is available": "K dispozici je nová verze %(brand)s", "Error leaving room": "Při opouštění místnosti došlo k chybě", @@ -2879,7 +2879,7 @@ "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Vloží (╯°□°)╯︵ ┻━┻ na začátek zprávy", "Remain on your screen while running": "Při běhu zůstává na obrazovce", "Remain on your screen when viewing another room, when running": "Při prohlížení jiné místnosti zůstává při běhu na obrazovce", - "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s změnil/a seznam přístupů serveru pro tuto místnost.", + "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s změnil(a) seznam přístupů serveru pro tuto místnost.", "Offline encrypted messaging using dehydrated devices": "Offline šifrovaná komunikace pomocí dehydrovaných zařízení", "See emotes posted to your active room": "Prohlédněte si emoji zveřejněné ve vaší aktivní místnosti", "See emotes posted to this room": "Prohlédněte si emoji zveřejněné v této místnosti", @@ -2968,5 +2968,18 @@ "Share your screen": "Sdílejte svou obrazovku", "Expand code blocks by default": "Ve výchozím nastavení rozbalit bloky kódu", "Show line numbers in code blocks": "Zobrazit čísla řádků v blocích kódu", - "Recently visited rooms": "Nedávno navštívené místnosti" + "Recently visited rooms": "Nedávno navštívené místnosti", + "Upgrade to pro": "Upgradujte na profesionální verzi", + "Minimize dialog": "Minimalizovat dialog", + "Maximize dialog": "Maximalizovat dialog", + "%(hostSignupBrand)s Setup": "Nastavení %(hostSignupBrand)s", + "You should know": "Měli byste vědět", + "Privacy Policy": "Zásady ochrany osobních údajů", + "Cookie Policy": "Zásady používání souborů cookie", + "Learn more in our , and .": "Další informace najdete v našich , a .", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Dočasné pokračování umožňuje procesu nastavení %(hostSignupBrand)s přístup k vašemu účtu za účelem načtení ověřených e-mailových adres. Tato data se neukládají.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Připojení k domovskému serveru se nezdařilo. Zavřete toto dialogové okno a zkuste to znovu.", + "Abort": "Přerušit", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Opravdu chcete přerušit vytváření hostitele? Proces nemůže být navázán.", + "Confirm abort of host creation": "Potvrďte přerušení vytváření hostitele" } From 5535d7fb97da0af2e1bdd776c6ded1030e5392ee Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Feb 2021 14:52:11 +0000 Subject: [PATCH 071/164] Prepare to encrypt when a call arrives So we're ready to send an answer straight away if the user answers --- src/CallHandler.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index f106d75f8b..2be1c34a9f 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -681,6 +681,12 @@ export default class CallHandler { Analytics.trackEvent('voip', 'receiveCall', 'type', call.type); this.calls.set(mappedRoomId, call) this.setCallListeners(call); + + // get ready to send encrypted events in the room, so if the user does answer + // the call, we'll be ready to send. NB. This is the protocol-level room ID not + // the mapped one: that's where we'll send the events. + const cli = MatrixClientPeg.get(); + cli.prepareToEncrypt(cli.getRoom(call.roomId)); } break; case 'hangup': From bb6659f9839b87e94e4235ce113c6102bf7f1cc8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Feb 2021 15:48:58 +0000 Subject: [PATCH 072/164] Set ICE candidate pool size option So we can start candidate gathering in advance --- src/MatrixClientPeg.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index bb4be663b6..98ca446532 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -279,6 +279,10 @@ class _MatrixClientPeg implements IMatrixClientPeg { timelineSupport: true, forceTURN: !SettingsStore.getValue('webRtcAllowPeerToPeer'), fallbackICEServerAllowed: !!SettingsStore.getValue('fallbackICEServerAllowed'), + // Gather up to 20 ICE candidates when a call arrives: this should be more than we'd + // ever normally need, so effectively this should make all the gathering happen when + // the call arrives. + iceCandidatePoolSize: 20, verificationMethods: [ verificationMethods.SAS, SHOW_QR_CODE_METHOD, From 6cb3381df59d576389ac69f1e4b01c99515fb0e6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 16 Feb 2021 18:03:12 +0000 Subject: [PATCH 073/164] Remove redundant lockOrigin parameter from usercontent now that each Element has its own, and not usercontent.riot.im it only has to permit its own origin --- src/components/views/messages/MFileBody.js | 2 +- src/usercontent/index.js | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index d17a1c4ce3..770cd4fff3 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -288,7 +288,7 @@ export default class MFileBody extends React.Component {