From eec63574e6223058f470668207b399735f236a27 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 22 Jul 2021 09:26:26 -0600 Subject: [PATCH 1/9] Move src/voice to src/audio for better naming Many of these files are used by Audio and Voice messages. Fixes https://github.com/vector-im/element-web/issues/18131 --- src/{voice => audio}/ManagedPlayback.ts | 0 src/{voice => audio}/Playback.ts | 0 src/{voice => audio}/PlaybackClock.ts | 0 src/{voice => audio}/PlaybackManager.ts | 0 src/{voice => audio}/RecorderWorklet.ts | 0 src/{voice => audio}/VoiceRecording.ts | 0 src/{voice => audio}/compat.ts | 0 src/{voice => audio}/consts.ts | 0 src/components/views/audio_messages/AudioPlayer.tsx | 2 +- src/components/views/audio_messages/DurationClock.tsx | 2 +- src/components/views/audio_messages/LiveRecordingClock.tsx | 2 +- src/components/views/audio_messages/LiveRecordingWaveform.tsx | 2 +- src/components/views/audio_messages/PlayPauseButton.tsx | 2 +- src/components/views/audio_messages/PlaybackClock.tsx | 2 +- src/components/views/audio_messages/PlaybackWaveform.tsx | 2 +- src/components/views/audio_messages/RecordingPlayback.tsx | 2 +- src/components/views/audio_messages/SeekBar.tsx | 2 +- src/components/views/messages/MAudioBody.tsx | 4 ++-- src/components/views/rooms/MessageComposer.tsx | 2 +- src/components/views/rooms/VoiceRecordComposerTile.tsx | 2 +- src/stores/VoiceRecordingStore.ts | 2 +- 21 files changed, 14 insertions(+), 14 deletions(-) rename src/{voice => audio}/ManagedPlayback.ts (100%) rename src/{voice => audio}/Playback.ts (100%) rename src/{voice => audio}/PlaybackClock.ts (100%) rename src/{voice => audio}/PlaybackManager.ts (100%) rename src/{voice => audio}/RecorderWorklet.ts (100%) rename src/{voice => audio}/VoiceRecording.ts (100%) rename src/{voice => audio}/compat.ts (100%) rename src/{voice => audio}/consts.ts (100%) diff --git a/src/voice/ManagedPlayback.ts b/src/audio/ManagedPlayback.ts similarity index 100% rename from src/voice/ManagedPlayback.ts rename to src/audio/ManagedPlayback.ts diff --git a/src/voice/Playback.ts b/src/audio/Playback.ts similarity index 100% rename from src/voice/Playback.ts rename to src/audio/Playback.ts diff --git a/src/voice/PlaybackClock.ts b/src/audio/PlaybackClock.ts similarity index 100% rename from src/voice/PlaybackClock.ts rename to src/audio/PlaybackClock.ts diff --git a/src/voice/PlaybackManager.ts b/src/audio/PlaybackManager.ts similarity index 100% rename from src/voice/PlaybackManager.ts rename to src/audio/PlaybackManager.ts diff --git a/src/voice/RecorderWorklet.ts b/src/audio/RecorderWorklet.ts similarity index 100% rename from src/voice/RecorderWorklet.ts rename to src/audio/RecorderWorklet.ts diff --git a/src/voice/VoiceRecording.ts b/src/audio/VoiceRecording.ts similarity index 100% rename from src/voice/VoiceRecording.ts rename to src/audio/VoiceRecording.ts diff --git a/src/voice/compat.ts b/src/audio/compat.ts similarity index 100% rename from src/voice/compat.ts rename to src/audio/compat.ts diff --git a/src/voice/consts.ts b/src/audio/consts.ts similarity index 100% rename from src/voice/consts.ts rename to src/audio/consts.ts diff --git a/src/components/views/audio_messages/AudioPlayer.tsx b/src/components/views/audio_messages/AudioPlayer.tsx index fb9270765e..3c0e5c1143 100644 --- a/src/components/views/audio_messages/AudioPlayer.tsx +++ b/src/components/views/audio_messages/AudioPlayer.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Playback, PlaybackState } from "../../../voice/Playback"; +import { Playback, PlaybackState } from "../../../audio/Playback"; import React, { createRef, ReactNode, RefObject } from "react"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import PlayPauseButton from "./PlayPauseButton"; diff --git a/src/components/views/audio_messages/DurationClock.tsx b/src/components/views/audio_messages/DurationClock.tsx index 81852b5944..15bc6c98a4 100644 --- a/src/components/views/audio_messages/DurationClock.tsx +++ b/src/components/views/audio_messages/DurationClock.tsx @@ -17,7 +17,7 @@ limitations under the License. import React from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import Clock from "./Clock"; -import { Playback } from "../../../voice/Playback"; +import { Playback } from "../../../audio/Playback"; interface IProps { playback: Playback; diff --git a/src/components/views/audio_messages/LiveRecordingClock.tsx b/src/components/views/audio_messages/LiveRecordingClock.tsx index a9dbd3c52f..e7330efc1d 100644 --- a/src/components/views/audio_messages/LiveRecordingClock.tsx +++ b/src/components/views/audio_messages/LiveRecordingClock.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React from "react"; -import { IRecordingUpdate, VoiceRecording } from "../../../voice/VoiceRecording"; +import { IRecordingUpdate, VoiceRecording } from "../../../audio/VoiceRecording"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import Clock from "./Clock"; import { MarkedExecution } from "../../../utils/MarkedExecution"; diff --git a/src/components/views/audio_messages/LiveRecordingWaveform.tsx b/src/components/views/audio_messages/LiveRecordingWaveform.tsx index b9c5f80f05..9c33889884 100644 --- a/src/components/views/audio_messages/LiveRecordingWaveform.tsx +++ b/src/components/views/audio_messages/LiveRecordingWaveform.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React from "react"; -import { IRecordingUpdate, RECORDING_PLAYBACK_SAMPLES, VoiceRecording } from "../../../voice/VoiceRecording"; +import { IRecordingUpdate, RECORDING_PLAYBACK_SAMPLES, VoiceRecording } from "../../../audio/VoiceRecording"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { arrayFastResample } from "../../../utils/arrays"; import { percentageOf } from "../../../utils/numbers"; diff --git a/src/components/views/audio_messages/PlayPauseButton.tsx b/src/components/views/audio_messages/PlayPauseButton.tsx index a4f1e770f2..de2822cc39 100644 --- a/src/components/views/audio_messages/PlayPauseButton.tsx +++ b/src/components/views/audio_messages/PlayPauseButton.tsx @@ -18,7 +18,7 @@ import React, { ReactNode } from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import { _t } from "../../../languageHandler"; -import { Playback, PlaybackState } from "../../../voice/Playback"; +import { Playback, PlaybackState } from "../../../audio/Playback"; import classNames from "classnames"; // omitted props are handled by render function diff --git a/src/components/views/audio_messages/PlaybackClock.tsx b/src/components/views/audio_messages/PlaybackClock.tsx index 374d47c31d..affb025d86 100644 --- a/src/components/views/audio_messages/PlaybackClock.tsx +++ b/src/components/views/audio_messages/PlaybackClock.tsx @@ -17,7 +17,7 @@ limitations under the License. import React from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import Clock from "./Clock"; -import { Playback, PlaybackState } from "../../../voice/Playback"; +import { Playback, PlaybackState } from "../../../audio/Playback"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; interface IProps { diff --git a/src/components/views/audio_messages/PlaybackWaveform.tsx b/src/components/views/audio_messages/PlaybackWaveform.tsx index ea1b846c01..96fd3f5ae2 100644 --- a/src/components/views/audio_messages/PlaybackWaveform.tsx +++ b/src/components/views/audio_messages/PlaybackWaveform.tsx @@ -18,7 +18,7 @@ import React from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { arraySeed, arrayTrimFill } from "../../../utils/arrays"; import Waveform from "./Waveform"; -import { Playback, PLAYBACK_WAVEFORM_SAMPLES } from "../../../voice/Playback"; +import { Playback, PLAYBACK_WAVEFORM_SAMPLES } from "../../../audio/Playback"; import { percentageOf } from "../../../utils/numbers"; interface IProps { diff --git a/src/components/views/audio_messages/RecordingPlayback.tsx b/src/components/views/audio_messages/RecordingPlayback.tsx index ca0ed83d84..9a45101efc 100644 --- a/src/components/views/audio_messages/RecordingPlayback.tsx +++ b/src/components/views/audio_messages/RecordingPlayback.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Playback, PlaybackState } from "../../../voice/Playback"; +import { Playback, PlaybackState } from "../../../audio/Playback"; import React, { ReactNode } from "react"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import PlayPauseButton from "./PlayPauseButton"; diff --git a/src/components/views/audio_messages/SeekBar.tsx b/src/components/views/audio_messages/SeekBar.tsx index 5231a2fb79..f0c03bb032 100644 --- a/src/components/views/audio_messages/SeekBar.tsx +++ b/src/components/views/audio_messages/SeekBar.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Playback, PlaybackState } from "../../../voice/Playback"; +import { Playback, PlaybackState } from "../../../audio/Playback"; import React, { ChangeEvent, CSSProperties, ReactNode } from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { MarkedExecution } from "../../../utils/MarkedExecution"; diff --git a/src/components/views/messages/MAudioBody.tsx b/src/components/views/messages/MAudioBody.tsx index 1f0b0f25f4..823198f44d 100644 --- a/src/components/views/messages/MAudioBody.tsx +++ b/src/components/views/messages/MAudioBody.tsx @@ -16,14 +16,14 @@ limitations under the License. import React from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; -import { Playback } from "../../../voice/Playback"; +import { Playback } from "../../../audio/Playback"; import InlineSpinner from '../elements/InlineSpinner'; import { _t } from "../../../languageHandler"; import AudioPlayer from "../audio_messages/AudioPlayer"; import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent"; import MFileBody from "./MFileBody"; import { IBodyProps } from "./IBodyProps"; -import { PlaybackManager } from "../../../voice/PlaybackManager"; +import { PlaybackManager } from "../../../audio/PlaybackManager"; interface IState { error?: Error; diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index b16d22b416..ee1ff7d17d 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -35,7 +35,7 @@ import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import VoiceRecordComposerTile from "./VoiceRecordComposerTile"; import { VoiceRecordingStore } from "../../../stores/VoiceRecordingStore"; -import { RecordingState } from "../../../voice/VoiceRecording"; +import { RecordingState } from "../../../audio/VoiceRecording"; import Tooltip, { Alignment } from "../elements/Tooltip"; import ResizeNotifier from "../../../utils/ResizeNotifier"; import { E2EStatus } from '../../../utils/ShieldUtils'; diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index f0df64fcb4..4c40d218b0 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -20,7 +20,7 @@ import React, { ReactNode } from "react"; import { RecordingState, VoiceRecording, -} from "../../../voice/VoiceRecording"; +} from "../../../audio/VoiceRecording"; import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import classNames from "classnames"; diff --git a/src/stores/VoiceRecordingStore.ts b/src/stores/VoiceRecordingStore.ts index 81c19e7e82..df837fec88 100644 --- a/src/stores/VoiceRecordingStore.ts +++ b/src/stores/VoiceRecordingStore.ts @@ -17,7 +17,7 @@ limitations under the License. import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; import defaultDispatcher from "../dispatcher/dispatcher"; import { ActionPayload } from "../dispatcher/payloads"; -import { VoiceRecording } from "../voice/VoiceRecording"; +import { VoiceRecording } from "../audio/VoiceRecording"; interface IState { recording?: VoiceRecording; From e1bb04f45a071318872bed0623bba3c5b59ce8db Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 22 Jul 2021 09:27:38 -0600 Subject: [PATCH 2/9] Remove answered TODOs --- src/components/views/messages/MAudioBody.tsx | 2 -- src/components/views/messages/MVoiceMessageBody.tsx | 2 -- src/components/views/rooms/VoiceRecordComposerTile.tsx | 1 - 3 files changed, 5 deletions(-) diff --git a/src/components/views/messages/MAudioBody.tsx b/src/components/views/messages/MAudioBody.tsx index 823198f44d..288ad16d88 100644 --- a/src/components/views/messages/MAudioBody.tsx +++ b/src/components/views/messages/MAudioBody.tsx @@ -76,7 +76,6 @@ export default class MAudioBody extends React.PureComponent public render() { if (this.state.error) { - // TODO: @@TR: Verify error state return ( @@ -86,7 +85,6 @@ export default class MAudioBody extends React.PureComponent } if (!this.state.playback) { - // TODO: @@TR: Verify loading/decrypting state return ( diff --git a/src/components/views/messages/MVoiceMessageBody.tsx b/src/components/views/messages/MVoiceMessageBody.tsx index f184caf448..55b608cf2d 100644 --- a/src/components/views/messages/MVoiceMessageBody.tsx +++ b/src/components/views/messages/MVoiceMessageBody.tsx @@ -27,7 +27,6 @@ export default class MVoiceMessageBody extends MAudioBody { // A voice message is an audio file but rendered in a special way. public render() { if (this.state.error) { - // TODO: @@TR: Verify error state return ( @@ -37,7 +36,6 @@ export default class MVoiceMessageBody extends MAudioBody { } if (!this.state.playback) { - // TODO: @@TR: Verify loading/decrypting state return ( diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 4c40d218b0..8323320520 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -189,7 +189,6 @@ export default class VoiceRecordComposerTile extends React.PureComponent; } From c427612c241a5f5e34439c0b672c0dac047a9fe3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 22 Jul 2021 12:14:38 -0600 Subject: [PATCH 3/9] de-dupe audio player Fixes https://github.com/vector-im/element-web/issues/18161 --- .../views/audio_messages/AudioPlayer.tsx | 47 ++----------- .../views/audio_messages/AudioPlayerBase.tsx | 70 +++++++++++++++++++ .../audio_messages/RecordingPlayback.tsx | 48 ++----------- 3 files changed, 80 insertions(+), 85 deletions(-) create mode 100644 src/components/views/audio_messages/AudioPlayerBase.tsx diff --git a/src/components/views/audio_messages/AudioPlayer.tsx b/src/components/views/audio_messages/AudioPlayer.tsx index 3c0e5c1143..b83f89fe5b 100644 --- a/src/components/views/audio_messages/AudioPlayer.tsx +++ b/src/components/views/audio_messages/AudioPlayer.tsx @@ -14,9 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Playback, PlaybackState } from "../../../audio/Playback"; import React, { createRef, ReactNode, RefObject } from "react"; -import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import PlayPauseButton from "./PlayPauseButton"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { formatBytes } from "../../../utils/FormattingUtils"; @@ -25,47 +23,13 @@ import { Key } from "../../../Keyboard"; import { _t } from "../../../languageHandler"; import SeekBar from "./SeekBar"; import PlaybackClock from "./PlaybackClock"; - -interface IProps { - // Playback instance to render. Cannot change during component lifecycle: create - // an all-new component instead. - playback: Playback; - - mediaName: string; -} - -interface IState { - playbackPhase: PlaybackState; - error?: boolean; -} +import AudioPlayerBase from "./AudioPlayerBase"; @replaceableComponent("views.audio_messages.AudioPlayer") -export default class AudioPlayer extends React.PureComponent { +export default class AudioPlayer extends AudioPlayerBase { private playPauseRef: RefObject = createRef(); private seekRef: RefObject = createRef(); - constructor(props: IProps) { - super(props); - - this.state = { - playbackPhase: PlaybackState.Decoding, // default assumption - }; - - // We don't need to de-register: the class handles this for us internally - this.props.playback.on(UPDATE_EVENT, this.onPlaybackUpdate); - - // Don't wait for the promise to complete - it will emit a progress update when it - // is done, and it's not meant to take long anyhow. - this.props.playback.prepare().catch(e => { - console.error("Error processing audio file:", e); - this.setState({ error: true }); - }); - } - - private onPlaybackUpdate = (ev: PlaybackState) => { - this.setState({ playbackPhase: ev }); - }; - private onKeyDown = (ev: React.KeyboardEvent) => { // stopPropagation() prevents the FocusComposer catch-all from triggering, // but we need to do it on key down instead of press (even though the user @@ -91,10 +55,10 @@ export default class AudioPlayer extends React.PureComponent { return `(${formatBytes(bytes)})`; } - public render(): ReactNode { + protected renderComponent(): ReactNode { // tabIndex=0 to ensure that the whole component becomes a tab stop, where we handle keyboard // events for accessibility - return <> + return (
{
- { this.state.error &&
{ _t("Error downloading audio") }
} - ; + ); } } diff --git a/src/components/views/audio_messages/AudioPlayerBase.tsx b/src/components/views/audio_messages/AudioPlayerBase.tsx new file mode 100644 index 0000000000..d8fc9d507f --- /dev/null +++ b/src/components/views/audio_messages/AudioPlayerBase.tsx @@ -0,0 +1,70 @@ +/* +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 { Playback, PlaybackState } from "../../../audio/Playback"; +import { TileShape } from "../rooms/EventTile"; +import React, { ReactNode } from "react"; +import { UPDATE_EVENT } from "../../../stores/AsyncStore"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { _t } from "../../../languageHandler"; + +interface IProps { + // Playback instance to render. Cannot change during component lifecycle: create + // an all-new component instead. + playback: Playback; + + mediaName?: string; + tileShape?: TileShape; +} + +interface IState { + playbackPhase: PlaybackState; + error?: boolean; +} + +@replaceableComponent("views.audio_messages.AudioPlayerBase") +export default abstract class AudioPlayerBase extends React.PureComponent { + constructor(props: IProps) { + super(props); + + this.state = { + playbackPhase: PlaybackState.Decoding, // default assumption + }; + + // We don't need to de-register: the class handles this for us internally + this.props.playback.on(UPDATE_EVENT, this.onPlaybackUpdate); + + // Don't wait for the promise to complete - it will emit a progress update when it + // is done, and it's not meant to take long anyhow. + this.props.playback.prepare().catch(e => { + console.error("Error processing audio file:", e); + this.setState({ error: true }); + }); + } + + private onPlaybackUpdate = (ev: PlaybackState) => { + this.setState({ playbackPhase: ev }); + }; + + protected abstract renderComponent(): ReactNode; + + public render(): ReactNode { + return <> + { this.renderComponent() } + { this.state.error &&
{ _t("Error downloading audio") }
} + ; + } +} diff --git a/src/components/views/audio_messages/RecordingPlayback.tsx b/src/components/views/audio_messages/RecordingPlayback.tsx index 9a45101efc..e3f612c9b6 100644 --- a/src/components/views/audio_messages/RecordingPlayback.tsx +++ b/src/components/views/audio_messages/RecordingPlayback.tsx @@ -14,68 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Playback, PlaybackState } from "../../../audio/Playback"; import React, { ReactNode } from "react"; -import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import PlayPauseButton from "./PlayPauseButton"; import PlaybackClock from "./PlaybackClock"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { TileShape } from "../rooms/EventTile"; import PlaybackWaveform from "./PlaybackWaveform"; -import { _t } from "../../../languageHandler"; - -interface IProps { - // Playback instance to render. Cannot change during component lifecycle: create - // an all-new component instead. - playback: Playback; - - tileShape?: TileShape; -} - -interface IState { - playbackPhase: PlaybackState; - error?: boolean; -} +import AudioPlayerBase from "./AudioPlayerBase"; @replaceableComponent("views.audio_messages.RecordingPlayback") -export default class RecordingPlayback extends React.PureComponent { - constructor(props: IProps) { - super(props); - - this.state = { - playbackPhase: PlaybackState.Decoding, // default assumption - }; - - // We don't need to de-register: the class handles this for us internally - this.props.playback.on(UPDATE_EVENT, this.onPlaybackUpdate); - - // Don't wait for the promise to complete - it will emit a progress update when it - // is done, and it's not meant to take long anyhow. - this.props.playback.prepare().catch(e => { - console.error("Error processing audio file:", e); - this.setState({ error: true }); - }); - } - +export default class RecordingPlayback extends AudioPlayerBase { private get isWaveformable(): boolean { return this.props.tileShape !== TileShape.Notif && this.props.tileShape !== TileShape.FileGrid && this.props.tileShape !== TileShape.Pinned; } - private onPlaybackUpdate = (ev: PlaybackState) => { - this.setState({ playbackPhase: ev }); - }; - - public render(): ReactNode { + protected renderComponent(): ReactNode { const shapeClass = !this.isWaveformable ? 'mx_VoiceMessagePrimaryContainer_noWaveform' : ''; - return <> + return (
{ this.isWaveformable && }
- { this.state.error &&
{ _t("Error downloading audio") }
} - ; + ); } } From f5630acea77b24af819172b61d250201d9a8009d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 10:23:45 +0100 Subject: [PATCH 4/9] Adhere to better eslint rules --- src/Registration.js | 13 ++- .../dialogs/security/CreateKeyBackupDialog.js | 2 +- .../security/CreateSecretStorageDialog.js | 7 +- .../dialogs/security/ExportE2eKeysDialog.js | 14 ++- .../dialogs/security/ImportE2eKeysDialog.js | 5 +- src/components/structures/EmbeddedPage.js | 3 +- src/components/structures/GroupView.js | 41 +++++--- src/components/structures/MyGroups.js | 3 +- src/components/structures/RoomStatusBar.js | 8 +- src/components/structures/RoomView.tsx | 3 +- src/components/structures/SearchBox.js | 4 +- src/components/structures/SpaceRoomView.tsx | 16 ++-- .../structures/auth/ForgotPassword.tsx | 10 +- src/components/structures/auth/Login.tsx | 4 +- .../structures/auth/Registration.tsx | 16 ++-- .../views/audio_messages/Waveform.tsx | 10 +- .../auth/InteractiveAuthEntryComponents.tsx | 10 +- src/components/views/avatars/BaseAvatar.tsx | 6 +- src/components/views/avatars/MemberAvatar.tsx | 8 +- .../context_menus/DialpadContextMenu.tsx | 6 +- .../context_menus/StatusMessageContextMenu.js | 23 +++-- .../views/context_menus/WidgetContextMenu.tsx | 3 +- .../dialogs/AddExistingToSpaceDialog.tsx | 14 ++- .../views/dialogs/AddressPickerDialog.tsx | 12 ++- src/components/views/dialogs/BaseDialog.js | 4 +- .../views/dialogs/BetaFeedbackDialog.tsx | 13 ++- .../views/dialogs/BugReportDialog.tsx | 4 +- .../CommunityPrototypeInviteDialog.tsx | 14 ++- .../views/dialogs/ConfirmRedactDialog.tsx | 4 +- .../views/dialogs/ConfirmUserActionDialog.tsx | 4 +- .../CreateCommunityPrototypeDialog.tsx | 6 +- .../views/dialogs/CreateGroupDialog.tsx | 11 ++- .../views/dialogs/CreateRoomDialog.tsx | 4 +- .../views/dialogs/CryptoStoreTooNewDialog.tsx | 2 +- .../views/dialogs/DevtoolsDialog.tsx | 94 ++++++++++++++----- .../dialogs/EditCommunityPrototypeDialog.tsx | 6 +- .../views/dialogs/ForwardDialog.tsx | 18 ++-- .../views/dialogs/IncomingSasDialog.js | 13 ++- src/components/views/dialogs/InfoDialog.js | 3 +- src/components/views/dialogs/InviteDialog.tsx | 39 +++++--- .../dialogs/SessionRestoreErrorDialog.js | 4 +- .../views/dialogs/StorageEvictedDialog.js | 4 +- .../security/AccessSecretStorageDialog.tsx | 3 +- .../security/RestoreKeyBackupDialog.js | 2 +- src/components/views/elements/AddressTile.tsx | 2 +- .../elements/DesktopCapturerSourcePicker.tsx | 3 +- src/components/views/elements/ImageView.tsx | 29 +++--- .../views/elements/MiniAvatarUploader.tsx | 2 +- src/components/views/elements/Pill.js | 5 +- .../views/elements/PowerSelector.js | 15 ++- src/components/views/elements/Tooltip.tsx | 3 +- src/components/views/emojipicker/Category.tsx | 10 +- .../views/groups/GroupMemberList.js | 18 +++- .../views/groups/GroupMemberTile.js | 11 ++- src/components/views/groups/GroupRoomList.js | 24 +++-- src/components/views/groups/GroupRoomTile.js | 6 +- src/components/views/messages/CallEvent.tsx | 2 +- src/components/views/messages/MImageBody.tsx | 23 +++-- src/components/views/messages/MVideoBody.tsx | 3 +- .../views/messages/RoomAvatarEvent.js | 7 +- src/components/views/right_panel/UserInfo.tsx | 30 +++--- src/components/views/rooms/EventTile.tsx | 13 ++- .../views/rooms/JumpToBottomButton.js | 7 +- src/components/views/rooms/MemberList.tsx | 22 +++-- .../views/rooms/MessageComposer.tsx | 7 +- src/components/views/rooms/NewRoomIntro.tsx | 13 ++- .../views/rooms/ReadReceiptMarker.js | 4 +- .../views/rooms/RoomBreadcrumbs.tsx | 4 +- src/components/views/rooms/RoomDetailRow.js | 8 +- src/components/views/rooms/RoomList.tsx | 4 +- src/components/views/rooms/RoomPreviewBar.js | 6 +- .../views/rooms/SimpleRoomHeader.js | 8 +- src/components/views/rooms/Stickerpicker.js | 6 +- .../views/rooms/TopUnreadMessagesBar.js | 14 +-- src/components/views/settings/BridgeTile.tsx | 2 +- src/components/views/settings/ChangeAvatar.js | 15 ++- .../views/settings/EventIndexPanel.tsx | 19 ++-- .../views/settings/ProfileSettings.js | 6 +- src/components/views/settings/SetIdServer.tsx | 4 +- .../tabs/room/GeneralRoomSettingsTab.js | 9 +- .../tabs/room/RolesRoomSettingsTab.tsx | 7 +- .../tabs/room/SecurityRoomSettingsTab.tsx | 13 ++- .../tabs/user/AppearanceUserSettingsTab.tsx | 7 +- .../tabs/user/GeneralUserSettingsTab.js | 8 +- .../tabs/user/HelpUserSettingsTab.tsx | 50 ++++++---- .../settings/tabs/user/LabsUserSettingsTab.js | 7 +- .../views/spaces/SpaceBasicSettings.tsx | 39 +++++--- src/components/views/voip/CallView.tsx | 14 ++- src/components/views/voip/DialPad.tsx | 12 ++- src/components/views/voip/DialPadModal.tsx | 8 +- src/components/views/voip/VideoFeed.tsx | 2 +- .../structures/MessagePanel-test.js | 34 +++++-- 92 files changed, 710 insertions(+), 348 deletions(-) diff --git a/src/Registration.js b/src/Registration.js index 70dcd38454..c59d244149 100644 --- a/src/Registration.js +++ b/src/Registration.js @@ -51,10 +51,15 @@ export async function startAnyRegistrationFlow(options) { description: _t("Use your account or create a new one to continue."), button: _t("Create Account"), extraButtons: [ - , + , ], onFinished: (proceed) => { if (proceed) { diff --git a/src/async-components/views/dialogs/security/CreateKeyBackupDialog.js b/src/async-components/views/dialogs/security/CreateKeyBackupDialog.js index 412194ab43..2cef1c0e41 100644 --- a/src/async-components/views/dialogs/security/CreateKeyBackupDialog.js +++ b/src/async-components/views/dialogs/security/CreateKeyBackupDialog.js @@ -269,7 +269,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
{ _t("Advanced") } - + { _t("Set up with a Security Key") }
diff --git a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js index aa78d68830..641df4f897 100644 --- a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js @@ -474,7 +474,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { outlined >
- + { _t("Generate a Security Key") }
{ _t("We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.") }
@@ -493,7 +493,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { outlined >
- + { _t("Enter a Security Phrase") }
{ _t("Use a secret phrase only you know, and optionally save a Security Key to use for backup.") }
@@ -701,7 +701,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent { { this._recoveryKey.encodedPrivateKey }
- diff --git a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js index 0435d81968..dbed9f3968 100644 --- a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js @@ -148,8 +148,12 @@ export default class ExportE2eKeysDialog extends React.Component {
-
@@ -161,8 +165,10 @@ export default class ExportE2eKeysDialog extends React.Component {
-
diff --git a/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js b/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js index 6017d07047..0936ad696d 100644 --- a/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js @@ -174,7 +174,10 @@ export default class ImportE2eKeysDialog extends React.Component {
- ; + submitButton = ; } return ( @@ -616,7 +618,9 @@ export class MsisdnAuthEntry extends React.Component
- diff --git a/src/components/views/avatars/BaseAvatar.tsx b/src/components/views/avatars/BaseAvatar.tsx index 87cdbe7512..6aaef29854 100644 --- a/src/components/views/avatars/BaseAvatar.tsx +++ b/src/components/views/avatars/BaseAvatar.tsx @@ -187,7 +187,8 @@ const BaseAvatar = (props: IProps) => { width: toPx(width), height: toPx(height), }} - title={title} alt={_t("Avatar")} + title={title} + alt={_t("Avatar")} inputRef={inputRef} {...otherProps} /> ); @@ -201,7 +202,8 @@ const BaseAvatar = (props: IProps) => { width: toPx(width), height: toPx(height), }} - title={title} alt="" + title={title} + alt="" ref={inputRef} {...otherProps} /> ); diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 61155e3880..11c24a5981 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -102,8 +102,12 @@ export default class MemberAvatar extends React.Component { } return ( - + ); } } diff --git a/src/components/views/context_menus/DialpadContextMenu.tsx b/src/components/views/context_menus/DialpadContextMenu.tsx index 39dfd50795..aead3a266e 100644 --- a/src/components/views/context_menus/DialpadContextMenu.tsx +++ b/src/components/views/context_menus/DialpadContextMenu.tsx @@ -60,8 +60,10 @@ export default class DialpadContextMenu extends React.Component
-
diff --git a/src/components/views/context_menus/StatusMessageContextMenu.js b/src/components/views/context_menus/StatusMessageContextMenu.js index f90d9cc005..e05b05116c 100644 --- a/src/components/views/context_menus/StatusMessageContextMenu.js +++ b/src/components/views/context_menus/StatusMessageContextMenu.js @@ -109,8 +109,10 @@ export default class StatusMessageContextMenu extends React.Component { ; } } else { - actionButton = { _t("Set status") } ; @@ -121,12 +123,19 @@ export default class StatusMessageContextMenu extends React.Component { spinner = ; } - const form =
-
diff --git a/src/components/views/context_menus/WidgetContextMenu.tsx b/src/components/views/context_menus/WidgetContextMenu.tsx index b21efdceb9..26d7b640a4 100644 --- a/src/components/views/context_menus/WidgetContextMenu.tsx +++ b/src/components/views/context_menus/WidgetContextMenu.tsx @@ -76,7 +76,8 @@ const WidgetContextMenu: React.FC = ({ onFinished(); }; streamAudioStreamButton = ; } diff --git a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx index 0f78b971eb..89f7c8596f 100644 --- a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx +++ b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx @@ -211,10 +211,16 @@ export const AddExistingToSpace: React.FC = ({ function overflowTile(overflowCount, totalCount) { const text = _t("and %(count)s others...", { count: overflowCount }); return ( - - } name={text} presenceState="online" suppressOnHover={true} - onClick={() => setTruncateAt(totalCount)} /> + + } + name={text} + presenceState="online" + suppressOnHover={true} + onClick={() => setTruncateAt(totalCount)} + /> ); } diff --git a/src/components/views/dialogs/AddressPickerDialog.tsx b/src/components/views/dialogs/AddressPickerDialog.tsx index 1a976918bd..6b239ee570 100644 --- a/src/components/views/dialogs/AddressPickerDialog.tsx +++ b/src/components/views/dialogs/AddressPickerDialog.tsx @@ -665,8 +665,8 @@ export default class AddressPickerDialog extends React.Component onChange={this.onQueryChanged} placeholder={this.getPlaceholder()} defaultValue={this.props.value} - autoFocus={this.props.focus}> - , + autoFocus={this.props.focus} + />, ); const filteredSuggestedList = this.getFilteredSuggestions(); @@ -727,8 +727,12 @@ export default class AddressPickerDialog extends React.Component } return ( - + { inputLabel }
{ query }
diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 8ccc485d7c..42b21ec743 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -118,9 +118,7 @@ export default class BaseDialog extends React.Component { let headerImage; if (this.props.headerImage) { - headerImage = ; + headerImage = ; } return ( diff --git a/src/components/views/dialogs/BetaFeedbackDialog.tsx b/src/components/views/dialogs/BetaFeedbackDialog.tsx index 917004dbc7..34218a3399 100644 --- a/src/components/views/dialogs/BetaFeedbackDialog.tsx +++ b/src/components/views/dialogs/BetaFeedbackDialog.tsx @@ -71,13 +71,16 @@ const BetaFeedbackDialog: React.FC = ({ featureId, onFinished }) => {   { _t("Your platform and username will be noted to help us use your feedback as much as we can.") } - { - onFinished(false); - defaultDispatcher.dispatch({ + { + onFinished(false); + defaultDispatcher.dispatch({ action: Action.ViewUserSettings, initialTabId: UserTab.Labs, - }); - }}> + }); + }} + > { _t("To leave the beta, visit your settings.") }
diff --git a/src/components/views/dialogs/BugReportDialog.tsx b/src/components/views/dialogs/BugReportDialog.tsx index 64e984fe20..3df05dac6e 100644 --- a/src/components/views/dialogs/BugReportDialog.tsx +++ b/src/components/views/dialogs/BugReportDialog.tsx @@ -188,7 +188,9 @@ export default class BugReportDialog extends React.Component { } return ( - diff --git a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx index 73fd4def25..6a8773ce45 100644 --- a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx +++ b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx @@ -205,9 +205,12 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent< people.push(( { _t("Show more") } + > + { _t("Show more") } + )); } } @@ -240,10 +243,13 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent< { peopleIntro } { people } { buttonText } + > + { buttonText } +
diff --git a/src/components/views/dialogs/ConfirmRedactDialog.tsx b/src/components/views/dialogs/ConfirmRedactDialog.tsx index a2f2b10144..b346d2d44c 100644 --- a/src/components/views/dialogs/ConfirmRedactDialog.tsx +++ b/src/components/views/dialogs/ConfirmRedactDialog.tsx @@ -37,8 +37,8 @@ export default class ConfirmRedactDialog extends React.Component { "Note that if you delete a room name or topic change, it could undo the change.")} placeholder={_t("Reason (optional)")} focus - button={_t("Remove")}> - + button={_t("Remove")} + /> ); } } diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.tsx b/src/components/views/dialogs/ConfirmUserActionDialog.tsx index cbef474c69..7099556ac6 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.tsx +++ b/src/components/views/dialogs/ConfirmUserActionDialog.tsx @@ -104,7 +104,9 @@ export default class ConfirmUserActionDialog extends React.Component { } return ( - diff --git a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx index 392ab9edad..ccac45fbcc 100644 --- a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx @@ -204,8 +204,10 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent<
{ } return ( -
@@ -133,8 +135,11 @@ export default class CreateGroupDialog extends React.Component {
- { title = _t("Create a room in %(communityName)s", { communityName: name }); } return ( - diff --git a/src/components/views/dialogs/CryptoStoreTooNewDialog.tsx b/src/components/views/dialogs/CryptoStoreTooNewDialog.tsx index 134c4ab79e..d03b668cd9 100644 --- a/src/components/views/dialogs/CryptoStoreTooNewDialog.tsx +++ b/src/components/views/dialogs/CryptoStoreTooNewDialog.tsx @@ -72,7 +72,7 @@ const CryptoStoreTooNewDialog: React.FC = (props: IProps) => { hasCancel={false} onPrimaryButtonClick={props.onFinished} > - diff --git a/src/components/views/dialogs/DevtoolsDialog.tsx b/src/components/views/dialogs/DevtoolsDialog.tsx index 61cda796ee..8ae9d0654f 100644 --- a/src/components/views/dialogs/DevtoolsDialog.tsx +++ b/src/components/views/dialogs/DevtoolsDialog.tsx @@ -182,14 +182,23 @@ export class SendCustomEvent extends GenericEditor - +
{ !this.state.message && } { showTglFlip &&
- - +
{ !this.state.message && } { !this.state.message &&
- - + key={this.props.children[0] ? this.props.children[0].key : ''} + /> ; + }} + />; } return
@@ -594,7 +625,9 @@ class AccountDataExplorer extends React.PureComponent; + }} + forceMode={true} + />; } return
@@ -631,7 +664,9 @@ class AccountDataExplorer extends React.PureComponent
-
@@ -1040,7 +1080,9 @@ class SettingsExplorer extends React.PureComponent this.onViewClick(e, i)}> { i } - this.onEditClick(e, i)} + this.onEditClick(e, i)} className='mx_DevTools_SettingsExplorer_edit' > ✏ @@ -1104,18 +1146,26 @@ class SettingsExplorer extends React.PureComponent
diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx index 1eabb68081..a0e6046d71 100644 --- a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx @@ -144,8 +144,10 @@ export default class EditCommunityPrototypeDialog extends React.PureComponent
= ({ room, event, matrixClient: cli, onFinish className = "mx_ForwardList_sending"; disabled = true; title = _t("Sending"); - icon =
; + icon =
; } else if (sendState === SendState.Sent) { className = "mx_ForwardList_sent"; disabled = true; title = _t("Sent"); - icon =
; + icon =
; } else { className = "mx_ForwardList_sendFailed"; disabled = true; @@ -204,10 +204,16 @@ const ForwardDialog: React.FC = ({ matrixClient: cli, event, permalinkCr function overflowTile(overflowCount, totalCount) { const text = _t("and %(count)s others...", { count: overflowCount }); return ( - - } name={text} presenceState="online" suppressOnHover={true} - onClick={() => setTruncateAt(totalCount)} /> + + } + name={text} + presenceState="online" + suppressOnHover={true} + onClick={() => setTruncateAt(totalCount)} + /> ); } diff --git a/src/components/views/dialogs/IncomingSasDialog.js b/src/components/views/dialogs/IncomingSasDialog.js index 963d98ef3f..a5c9f2107f 100644 --- a/src/components/views/dialogs/IncomingSasDialog.js +++ b/src/components/views/dialogs/IncomingSasDialog.js @@ -133,18 +133,23 @@ export default class IncomingSasDialog extends React.Component { ? mediaFromMxc(oppProfile.avatar_url).getSquareThumbnailHttp(48) : null; profile =
-

{ oppProfile.displayname }

; } else if (this.state.opponentProfileError) { profile =
-

{ this.props.verifier.userId }

; diff --git a/src/components/views/dialogs/InfoDialog.js b/src/components/views/dialogs/InfoDialog.js index 8207d334d3..ff8c3645ca 100644 --- a/src/components/views/dialogs/InfoDialog.js +++ b/src/components/views/dialogs/InfoDialog.js @@ -63,8 +63,7 @@ export default class InfoDialog extends React.Component { { this.props.button !== false && - } + /> } ); } diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 46f140fd39..609829b833 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -196,7 +196,9 @@ class DMUserTile extends React.PureComponent { ? + width={avatarSize} + height={avatarSize} + /> : { className='mx_InviteDialog_userTile_remove' onClick={this.onRemove} > - {_t('Remove')} ); @@ -297,7 +302,9 @@ class DMRoomTile extends React.PureComponent { const avatar = (this.props.member as ThreepidMember).isEmail ? + width={avatarSize} + height={avatarSize} + /> : + width={14} + height={14} /> { " " + _t("Invited people will be able to read old messages.") }

; } @@ -1534,14 +1542,18 @@ export default class InviteDialog extends React.PureComponent; } else { - dialPadField = { dialPadField } -
; tabs.push(new Tab(TabId.DialPad, _td("Dial pad"), 'mx_InviteDialog_dialPadIcon', dialPadSection)); dialogContent = - { consultConnectSection } ; diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index b7037d1f4f..eeeadbbfe5 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -85,7 +85,9 @@ export default class SessionRestoreErrorDialog extends React.Component { } return ( - { _t("Forgotten or lost all recovery methods?
Reset all", null, { a: (sub) => { sub }, }) }
diff --git a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js index e8bd8af01c..2b272a3b88 100644 --- a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js +++ b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js @@ -399,7 +399,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { let keyStatus; if (this.state.recoveryKey.length === 0) { - keyStatus =
; + keyStatus =
; } else if (this.state.recoveryKeyValid) { keyStatus =
{ "\uD83D\uDC4D " }{ _t("This looks like a valid Security Key!") } diff --git a/src/components/views/elements/AddressTile.tsx b/src/components/views/elements/AddressTile.tsx index cdeb7cacd6..52c0d84ac2 100644 --- a/src/components/views/elements/AddressTile.tsx +++ b/src/components/views/elements/AddressTile.tsx @@ -122,7 +122,7 @@ export default class AddressTile extends React.Component { let dismiss; if (this.props.canDismiss) { dismiss = ( -
+
); diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx index 82d0aa4976..20ecf08a5f 100644 --- a/src/components/views/elements/DesktopCapturerSourcePicker.tsx +++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx @@ -51,7 +51,8 @@ export class ExistingSource extends React.Component + onClick={this.onClick} + > { const avatar = ( ); @@ -403,7 +404,7 @@ export default class ImageView extends React.Component { // an empty div here, since the panel uses space-between // and we want the same placement of elements info = ( -
+
); } @@ -427,15 +428,15 @@ export default class ImageView extends React.Component { - + onClick={this.onZoomOutClick} + /> ); zoomInButton = ( - + onClick={this.onZoomInClick} + /> ); } @@ -457,24 +458,24 @@ export default class ImageView extends React.Component { - + onClick={this.onRotateCounterClockwiseClick} + /> - + onClick={this.onRotateClockwiseClick} + /> - + onClick={this.onDownloadClick} + /> { contextMenuButton } - + onClick={this.props.onFinished} + /> { this.renderContextMenu() }
diff --git a/src/components/views/elements/MiniAvatarUploader.tsx b/src/components/views/elements/MiniAvatarUploader.tsx index 47bcd845ba..22ff4bf4b3 100644 --- a/src/components/views/elements/MiniAvatarUploader.tsx +++ b/src/components/views/elements/MiniAvatarUploader.tsx @@ -92,7 +92,7 @@ const MiniAvatarUploader: React.FC = ({ hasAvatar, hasAvatarLabel, noAva
{ busy ? : -
} +
}
- diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 9e7d9ca205..080816df14 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -428,7 +428,9 @@ export default class RoomList extends React.PureComponent { groupId={g.groupId} groupName={g.name} groupAvatarUrl={g.avatarUrl} - width={32} height={32} resizeMethod='crop' + width={32} + height={32} + resizeMethod='crop' /> ); const openGroup = () => { diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js index 3cd34b1966..b8a4315e2d 100644 --- a/src/components/views/rooms/RoomPreviewBar.js +++ b/src/components/views/rooms/RoomPreviewBar.js @@ -536,8 +536,10 @@ export default class RoomPreviewBar extends React.Component { "If you think you're seeing this message in error, please " + "submit a bug report.", { errcode: this.props.error.errcode }, - { issueLink: label => { label } }, + { issueLink: label => { label } }, ), ]; break; diff --git a/src/components/views/rooms/SimpleRoomHeader.js b/src/components/views/rooms/SimpleRoomHeader.js index 768a456b35..a2b5566e39 100644 --- a/src/components/views/rooms/SimpleRoomHeader.js +++ b/src/components/views/rooms/SimpleRoomHeader.js @@ -35,13 +35,15 @@ export default class SimpleRoomHeader extends React.Component { let icon; if (this.props.icon) { icon = ; } return ( -
+
{ icon } { this.props.title } diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index c0e6826ba5..6649948331 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -403,8 +403,7 @@ export default class Stickerpicker extends React.PureComponent { onClick={this._onHideStickersClick} active={this.state.showStickers.toString()} title={_t("Hide Stickers")} - > - ; + />; const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); stickerPicker = - ; + />; } return { stickersButton } diff --git a/src/components/views/rooms/TopUnreadMessagesBar.js b/src/components/views/rooms/TopUnreadMessagesBar.js index 0f632e7128..d2a3e3a303 100644 --- a/src/components/views/rooms/TopUnreadMessagesBar.js +++ b/src/components/views/rooms/TopUnreadMessagesBar.js @@ -32,14 +32,16 @@ export default class TopUnreadMessagesBar extends React.Component { render() { return (
- - - + - + onClick={this.props.onCloseClick} + />
); } diff --git a/src/components/views/settings/BridgeTile.tsx b/src/components/views/settings/BridgeTile.tsx index 7228e4b939..5dd5ed9ba1 100644 --- a/src/components/views/settings/BridgeTile.tsx +++ b/src/components/views/settings/BridgeTile.tsx @@ -124,7 +124,7 @@ export default class BridgeTile extends React.PureComponent { url={avatarUrl} />; } else { - networkIcon =
; + networkIcon =
; } let networkItem = null; if (network) { diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index 36d5d4aa0c..c3a1544cdc 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -148,13 +148,22 @@ export default class ChangeAvatar extends React.Component { if (this.props.room && !this.avatarSet) { const RoomAvatar = sdk.getComponent('avatars.RoomAvatar'); avatarImg = ; } else { const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); // XXX: FIXME: once we track in the JS what our own displayname is(!) then use it here rather than ? - avatarImg = ; + avatarImg = ; } let uploadSection; diff --git a/src/components/views/settings/EventIndexPanel.tsx b/src/components/views/settings/EventIndexPanel.tsx index de49c2a980..9966e38de8 100644 --- a/src/components/views/settings/EventIndexPanel.tsx +++ b/src/components/views/settings/EventIndexPanel.tsx @@ -178,8 +178,11 @@ export default class EventIndexPanel extends React.Component<{}, IState> { "appear in search results.", ) }
- + { _t("Enable") } { this.state.enabling ? :
} @@ -203,8 +206,10 @@ export default class EventIndexPanel extends React.Component<{}, IState> { brand, }, { - nativeLink: sub => { sub }, }, ) }
@@ -219,8 +224,10 @@ export default class EventIndexPanel extends React.Component<{}, IState> { brand, }, { - desktopLink: sub => { sub }, }, ) }
diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js index 02eaaaeea8..d05fca983c 100644 --- a/src/components/views/settings/ProfileSettings.js +++ b/src/components/views/settings/ProfileSettings.js @@ -172,7 +172,8 @@ export default class ProfileSettings extends React.Component { > @@ -181,7 +182,8 @@ export default class ProfileSettings extends React.Component { { _t("Profile") } diff --git a/src/components/views/settings/SetIdServer.tsx b/src/components/views/settings/SetIdServer.tsx index fd8abc0dbe..1f488f1e67 100644 --- a/src/components/views/settings/SetIdServer.tsx +++ b/src/components/views/settings/SetIdServer.tsx @@ -426,7 +426,9 @@ export default class SetIdServer extends React.Component { disabled={this.state.busy} forceValidity={this.state.error ? false : null} /> - { _t("Change") } diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js index e2f30192b9..b90fb310e0 100644 --- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js @@ -97,9 +97,12 @@ export default class GeneralRoomSettingsTab extends React.Component {
{ _t("Room Addresses") }
- +
{ _t("Other") }
{ flairSection } diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx index edc0220921..9225bc6b94 100644 --- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx @@ -346,8 +346,11 @@ export default class RolesRoomSettingsTab extends React.Component { let bannedBy = member.events.member.getSender(); // start by falling back to mxid if (sender) bannedBy = sender.name; return ( - ); diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx index 88bc2046ce..99ae2e52ab 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx @@ -133,8 +133,10 @@ export default class SecurityRoomSettingsTab extends React.ComponentLearn more about encryption.", {}, { - a: sub => { sub }, }, ), @@ -424,8 +426,11 @@ export default class SecurityRoomSettingsTab extends React.Component { _t("Once enabled, encryption cannot be disabled.") }
-
{ encryptionSettings } diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index d1c497b351..44873816dc 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -303,9 +303,12 @@ export default class AppearanceUserSettingsTab extends React.Component { _t("Add theme") } + > + { _t("Add theme") } + { messageElement }
diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 2a6e8937a3..238d6cca21 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -426,9 +426,13 @@ export default class GeneralUserSettingsTab extends React.Component { const supportsMultiLanguageSpellCheck = plaf.supportsMultiLanguageSpellCheck(); const discoWarning = this.state.requiredPolicyInfo.hasTerms - ? {_t("Warning")} + width="18" + height="18" + alt={_t("Warning")} + /> : null; let accountManagementSection; diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx index 33de634611..eaf52e6062 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx @@ -134,28 +134,39 @@ export default class HelpUserSettingsTab extends React.Component { _t("Credits") } @@ -254,7 +265,8 @@ export default class HelpUserSettingsTab extends React.Component "Security Disclosure Policy.", {}, { a: sub => { sub }, }, ) } diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js index aace4ca557..fa854fc4d8 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js @@ -86,8 +86,11 @@ export default class LabsUserSettingsTab extends React.Component { 'test out new features and help shape them before they actually launch. ' + 'Learn more.', {}, { 'a': (sub) => { - return { sub }; + return { sub }; }, }) } diff --git a/src/components/views/spaces/SpaceBasicSettings.tsx b/src/components/views/spaces/SpaceBasicSettings.tsx index 6d2cc1f5db..9d3696c5a9 100644 --- a/src/components/views/spaces/SpaceBasicSettings.tsx +++ b/src/components/views/spaces/SpaceBasicSettings.tsx @@ -57,11 +57,15 @@ export const SpaceAvatar = ({ src={avatar} alt="" /> - { - avatarUploadRef.current.value = ""; - setAvatarDataUrl(undefined); - setAvatar(undefined); - }} kind="link" className="mx_SpaceBasicSettings_avatar_remove"> + { + avatarUploadRef.current.value = ""; + setAvatarDataUrl(undefined); + setAvatar(undefined); + }} + kind="link" + className="mx_SpaceBasicSettings_avatar_remove" + > { _t("Delete") } ; @@ -77,16 +81,21 @@ export const SpaceAvatar = ({ return
{ avatarSection } - { - if (!e.target.files?.length) return; - const file = e.target.files[0]; - setAvatar(file); - const reader = new FileReader(); - reader.onload = (ev) => { - setAvatarDataUrl(ev.target.result as string); - }; - reader.readAsDataURL(file); - }} accept="image/*" /> + { + if (!e.target.files?.length) return; + const file = e.target.files[0]; + setAvatar(file); + const reader = new FileReader(); + reader.onload = (ev) => { + setAvatarDataUrl(ev.target.result as string); + }; + reader.readAsDataURL(file); + }} + accept="image/*" + />
; }; diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 8bdd6e0f55..e53c2f4823 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -665,15 +665,19 @@ export default class CallView extends React.Component { let fullScreenButton; if (this.props.call.type === CallType.Video && !this.props.pipMode) { - fullScreenButton =
; } let expandButton; if (this.props.pipMode) { - expandButton =
; } @@ -685,7 +689,7 @@ export default class CallView extends React.Component { let header: React.ReactNode; if (!this.props.pipMode) { header =
-
+
{ callTypeText } { headerControls }
; diff --git a/src/components/views/voip/DialPad.tsx b/src/components/views/voip/DialPad.tsx index 2af8bd6989..3b4a29b3f9 100644 --- a/src/components/views/voip/DialPad.tsx +++ b/src/components/views/voip/DialPad.tsx @@ -68,13 +68,19 @@ export default class Dialpad extends React.PureComponent { for (let i = 0; i < BUTTONS.length; i++) { const button = BUTTONS[i]; const digitSubtext = BUTTON_LETTERS[i]; - buttonNodes.push(); } if (this.props.hasDial) { - buttonNodes.push(); } diff --git a/src/components/views/voip/DialPadModal.tsx b/src/components/views/voip/DialPadModal.tsx index 0bba65e44f..a36fc37dff 100644 --- a/src/components/views/voip/DialPadModal.tsx +++ b/src/components/views/voip/DialPadModal.tsx @@ -81,14 +81,18 @@ export default class DialpadModal extends React.PureComponent { // Only show the backspace button if the field has content let dialPadField; if (this.state.value.length !== 0) { - dialPadField = ; } else { - dialPadField = { const avatarSize = this.props.pipMode ? 76 : 160; return ( -
+
, + , ); const tiles = TestUtils.scryRenderedComponentsWithType( @@ -330,8 +334,12 @@ describe('MessagePanel', function() { it('should show the read-marker that fall in summarised events after the summary', function() { const melsEvents = mkMelsEvents(); const res = TestUtils.renderIntoDocument( - , + , ); const summary = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_EventListSummary'); @@ -348,8 +356,12 @@ describe('MessagePanel', function() { it('should hide the read-marker at the end of summarised events', function() { const melsEvents = mkMelsEventsOnly(); const res = TestUtils.renderIntoDocument( - , + , ); const summary = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_EventListSummary'); @@ -371,7 +383,10 @@ describe('MessagePanel', function() { // first render with the RM in one place let mp = ReactDOM.render( - , parentDiv); @@ -387,7 +402,10 @@ describe('MessagePanel', function() { // now move the RM mp = ReactDOM.render( - , parentDiv); From 4a4ec596bd90b117df5da5e495a06dc628fd1f0c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 11:27:00 +0100 Subject: [PATCH 5/9] Fix position of the space hierarchy spinner --- res/css/structures/_SpaceRoomView.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index 48b565be7f..3119d2fe6e 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -234,6 +234,9 @@ $SpaceRoomViewInnerWidth: 428px; } .mx_SpaceRoomView_landing { + display: flex; + flex-direction: column; + > .mx_BaseAvatar_image, > .mx_BaseAvatar > .mx_BaseAvatar_image { border-radius: 12px; @@ -340,6 +343,7 @@ $SpaceRoomViewInnerWidth: 428px; .mx_SearchBox { margin: 0 0 20px; + flex: 0; } .mx_SpaceFeedbackPrompt { From 2b133deb63db689a373bddabe48125e16233e09a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 12:19:54 +0100 Subject: [PATCH 6/9] fix scroll behaviour to match that of prior to the spinner fix --- res/css/structures/_SpaceRoomView.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index 3119d2fe6e..e4832d9430 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -354,6 +354,11 @@ $SpaceRoomViewInnerWidth: 428px; display: none; } } + + .mx_SpaceRoomDirectory_list { + // we don't want this container to get forced into the flexbox layout + display: contents; + } } .mx_SpaceRoomView_privateScope { From 3c1902c26a69c463bcaff95f48a23b6b3d608f34 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 16:09:41 +0100 Subject: [PATCH 7/9] Update matrix-org-eslint-plugin --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5283f5778a..c576148e19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3234,8 +3234,8 @@ eslint-config-google@^0.14.0: integrity sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw== "eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main": - version "0.3.2" - resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/8529f1d77863db6327cf1a1a4fa65d06cc26f91b" + version "0.3.3" + resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/50d6bdf6704dd95016d5f1f824f00cac6eaa64e1" eslint-plugin-react-hooks@^4.2.0: version "4.2.0" From 5f2582395ffcf07d8edf6a384ba2d9db084a666b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 16:21:59 +0100 Subject: [PATCH 8/9] Fix blurhash rounded corners missing regression --- res/css/views/messages/_MImageBody.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss index f5d8131e6e..42565a76d0 100644 --- a/res/css/views/messages/_MImageBody.scss +++ b/res/css/views/messages/_MImageBody.scss @@ -28,7 +28,7 @@ $timelineImageBorderRadius: 4px; justify-content: center; align-items: center; - > canvas { + > div > canvas { border-radius: $timelineImageBorderRadius; } } From 4fe0e216d6417ad15559d57ed9ef1720b8c705be Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 16:22:35 +0100 Subject: [PATCH 9/9] Use div instead of span for mx_MImageBody to not violate spec --- res/css/views/messages/_MImageBody.scss | 4 ---- src/components/views/messages/MImageBody.tsx | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss index 42565a76d0..a748435cd8 100644 --- a/res/css/views/messages/_MImageBody.scss +++ b/res/css/views/messages/_MImageBody.scss @@ -16,10 +16,6 @@ limitations under the License. $timelineImageBorderRadius: 4px; -.mx_MImageBody { - display: block; -} - .mx_MImageBody_thumbnail { object-fit: contain; border-radius: $timelineImageBorderRadius; diff --git a/src/components/views/messages/MImageBody.tsx b/src/components/views/messages/MImageBody.tsx index c24f014d84..945994d964 100644 --- a/src/components/views/messages/MImageBody.tsx +++ b/src/components/views/messages/MImageBody.tsx @@ -416,10 +416,10 @@ export default class MImageBody extends React.Component { if (this.state.error !== null) { return ( - +
{ _t("Error decrypting image") } - +
); } @@ -434,10 +434,10 @@ export default class MImageBody extends React.Component { const thumbnail = this.messageContent(contentUrl, thumbUrl, content); const fileBody = this.getFileBody(); - return + return
{ thumbnail } { fileBody } - ; +
; } }