From cf25e15eb6d3071dccb92c07e1f96bd726d56755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sat, 12 Jun 2021 12:49:15 +0200 Subject: [PATCH 01/27] Make call control buttons accessible to screen reader users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- src/components/views/voip/CallView.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index c084dacaa8..178df246d1 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -441,6 +441,7 @@ export default class CallView extends React.Component { const vidMuteButton = this.props.call.type === CallType.Video ? : null; // The dial pad & 'more' button actions are only relevant in a connected call @@ -450,6 +451,7 @@ export default class CallView extends React.Component { inputRef={this.dialpadButton} onClick={this.onDialpadClick} isExpanded={this.state.showDialpad} + aria-label={_t("Dialpad")} /> :
; const contextMenuButton = this.state.callState === CallState.Connected ? { onClick={this.onMoreClick} inputRef={this.contextMenuButton} isExpanded={this.state.showMoreMenu} + aria-label={_t("More")} /> :
; // in the near future, the dial pad button will go on the left. For now, it's the nothing button @@ -466,6 +469,7 @@ export default class CallView extends React.Component { Date: Sat, 12 Jun 2021 13:53:44 +0200 Subject: [PATCH 02/27] i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- src/i18n/strings/en_EN.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 874dc11bd2..7df22432de 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -889,6 +889,12 @@ "sends snowfall": "sends snowfall", "Sends the given message with a space themed effect": "Sends the given message with a space themed effect", "sends space invaders": "sends space invaders", + "Start the camera": "Start the camera", + "Stop the camera": "Stop the camera", + "Dialpad": "Dialpad", + "More": "More", + "Unmute the microphone": "Unmute the microphone", + "Mute the microphone": "Mute the microphone", "unknown person": "unknown person", "Consulting with %(transferTarget)s. Transfer to %(transferee)s": "Consulting with %(transferTarget)s. Transfer to %(transferee)s", "You held the call Switch": "You held the call Switch", From a94d11235ed5352b8da0ae87964abf2a00eddb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sat, 12 Jun 2021 14:17:10 +0200 Subject: [PATCH 03/27] Changed the buttons to TooltipButtons and added the tooltip for the hangup button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- src/components/views/voip/CallView.tsx | 21 ++++++++++++--------- src/i18n/strings/en_EN.json | 1 + 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 178df246d1..66b3f6b2d4 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -25,6 +25,8 @@ import RoomAvatar from "../avatars/RoomAvatar"; import { CallState, CallType, MatrixCall, CallEvent } from 'matrix-js-sdk/src/webrtc/call'; import classNames from 'classnames'; import AccessibleButton from '../elements/AccessibleButton'; +import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; +import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton"; import {isOnlyCtrlOrCmdKeyEvent, Key} from '../../../Keyboard'; import {alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton} from '../../structures/ContextMenu'; import CallContextMenu from '../context_menus/CallContextMenu'; @@ -438,40 +440,40 @@ export default class CallView extends React.Component { mx_CallView_callControls_hidden: !this.state.controlsVisible, }); - const vidMuteButton = this.props.call.type === CallType.Video ? : null; // The dial pad & 'more' button actions are only relevant in a connected call // When not connected, we have to put something there to make the flexbox alignment correct - const dialpadButton = this.state.callState === CallState.Connected ? :
; - const contextMenuButton = this.state.callState === CallState.Connected ? :
; // in the near future, the dial pad button will go on the left. For now, it's the nothing button // because something needs to have margin-right: auto to make the alignment correct. const callControls =
{dialpadButton} - - { dis.dispatch({ @@ -479,6 +481,7 @@ export default class CallView extends React.Component { room_id: callRoomId, }); }} + title={_t("Hangup")} /> {vidMuteButton}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7df22432de..d50348954a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -895,6 +895,7 @@ "More": "More", "Unmute the microphone": "Unmute the microphone", "Mute the microphone": "Mute the microphone", + "Hangup": "Hangup", "unknown person": "unknown person", "Consulting with %(transferTarget)s. Transfer to %(transferee)s": "Consulting with %(transferTarget)s. Transfer to %(transferee)s", "You held the call Switch": "You held the call Switch", From fd7eaddb2d4c170084fbfc6ca3ca4c26f40a57b9 Mon Sep 17 00:00:00 2001 From: pvagner Date: Wed, 16 Jun 2021 10:18:35 +0200 Subject: [PATCH 04/27] Update src/components/views/voip/CallView.tsx Co-authored-by: Michael Telatynski <7t3chguy@googlemail.com> --- src/components/views/voip/CallView.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 66b3f6b2d4..f7f82d4300 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -26,9 +26,13 @@ import { CallState, CallType, MatrixCall, CallEvent } from 'matrix-js-sdk/src/we import classNames from 'classnames'; import AccessibleButton from '../elements/AccessibleButton'; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; -import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton"; import {isOnlyCtrlOrCmdKeyEvent, Key} from '../../../Keyboard'; -import {alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton} from '../../structures/ContextMenu'; +import { + alwaysAboveLeftOf, + alwaysAboveRightOf, + ChevronFace, + ContextMenuTooltipButton, +} from '../../structures/ContextMenu'; import CallContextMenu from '../context_menus/CallContextMenu'; import { avatarUrlForMember } from '../../../Avatar'; import DialpadContextMenu from '../context_menus/DialpadContextMenu'; From b2292268bc9a551a1b9ecfe535eafd3b823789d4 Mon Sep 17 00:00:00 2001 From: pvagner Date: Wed, 30 Jun 2021 07:06:10 +0200 Subject: [PATCH 05/27] Update src/components/views/voip/CallView.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Šimon Brandner --- src/components/views/voip/CallView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 6cb245f7b1..3f959622e7 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -26,7 +26,7 @@ import { CallState, CallType, MatrixCall, CallEvent } from 'matrix-js-sdk/src/we import classNames from 'classnames'; import AccessibleButton from '../elements/AccessibleButton'; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; -import { isOnlyCtrlOrCmdKeyEvent, Key} from '../../../Keyboard'; +import { isOnlyCtrlOrCmdKeyEvent, Key } from '../../../Keyboard'; import { alwaysAboveLeftOf, alwaysAboveRightOf, From caefefc2c22704fc4f678a680592d885880193d0 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Tue, 27 Jul 2021 17:22:49 -0400 Subject: [PATCH 06/27] Add regional indicators to emoji picker Signed-off-by: Robin Townsend --- src/emoji.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/emoji.ts b/src/emoji.ts index 321eae63f6..1445f737d6 100644 --- a/src/emoji.ts +++ b/src/emoji.ts @@ -35,6 +35,9 @@ export const EMOTICON_TO_EMOJI = new Map(); export const getEmojiFromUnicode = unicode => UNICODE_TO_EMOJI.get(stripVariation(unicode)); +const isRegionalIndicator = (x: string) => + Array.from(x).length === 1 && x >= '\u{1f1e6}' && x <= '\u{1f1ff}'; + const EMOJIBASE_GROUP_ID_TO_CATEGORY = [ "people", // smileys "people", // actually people @@ -72,7 +75,11 @@ export const EMOJI: IEmoji[] = EMOJIBASE.map((emojiData: Omit Date: Tue, 27 Jul 2021 17:35:34 -0400 Subject: [PATCH 07/27] Add more types Signed-off-by: Robin Townsend --- src/emoji.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emoji.ts b/src/emoji.ts index 1445f737d6..e871e0bb58 100644 --- a/src/emoji.ts +++ b/src/emoji.ts @@ -35,7 +35,7 @@ export const EMOTICON_TO_EMOJI = new Map(); export const getEmojiFromUnicode = unicode => UNICODE_TO_EMOJI.get(stripVariation(unicode)); -const isRegionalIndicator = (x: string) => +const isRegionalIndicator = (x: string): boolean => Array.from(x).length === 1 && x >= '\u{1f1e6}' && x <= '\u{1f1ff}'; const EMOJIBASE_GROUP_ID_TO_CATEGORY = [ From f16b1d46b72430715a75bac495b6ac19e94efe44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 28 Jul 2021 20:58:24 +0200 Subject: [PATCH 08/27] Fix sizing issue of the screen picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/elements/_DesktopCapturerSourcePicker.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/css/views/elements/_DesktopCapturerSourcePicker.scss b/res/css/views/elements/_DesktopCapturerSourcePicker.scss index 49a0a44417..bd81aafef3 100644 --- a/res/css/views/elements/_DesktopCapturerSourcePicker.scss +++ b/res/css/views/elements/_DesktopCapturerSourcePicker.scss @@ -35,7 +35,6 @@ limitations under the License. .mx_desktopCapturerSourcePicker_source_thumbnail { margin: 4px; padding: 4px; - width: 312px; border-width: 2px; border-radius: 8px; border-style: solid; @@ -53,6 +52,5 @@ limitations under the License. white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - width: 312px; } } From c5d11a9f17b9e523ecffe28c31102b0a3b4d63e9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 2 Aug 2021 23:29:46 -0600 Subject: [PATCH 09/27] Improve voice messages uploading state Fixes https://github.com/vector-im/element-web/issues/18226 Fixes https://github.com/vector-im/element-web/issues/18224 --- .../views/rooms/_VoiceRecordComposerTile.scss | 11 ++++ .../views/rooms/VoiceRecordComposerTile.tsx | 54 ++++++++++++++----- src/i18n/strings/en_EN.json | 3 +- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/res/css/views/rooms/_VoiceRecordComposerTile.scss b/res/css/views/rooms/_VoiceRecordComposerTile.scss index 5501ab343e..3d8d0e5ecc 100644 --- a/res/css/views/rooms/_VoiceRecordComposerTile.scss +++ b/res/css/views/rooms/_VoiceRecordComposerTile.scss @@ -46,6 +46,17 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/trashcan.svg'); } +.mx_VoiceRecordComposerTile_uploadState { + margin-right: 21px; + color: $secondary-fg-color; + + .mx_VoiceRecordComposerTile_uploadState_badge { + display: inline-block; + margin-right: 4px; + vertical-align: middle; + } +} + .mx_MessageComposer_row .mx_VoiceMessagePrimaryContainer { // Note: remaining class properties are in the PlayerContainer CSS. diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 8323320520..490d6b2231 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -17,10 +17,7 @@ limitations under the License. import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import { _t } from "../../../languageHandler"; import React, { ReactNode } from "react"; -import { - RecordingState, - VoiceRecording, -} from "../../../audio/VoiceRecording"; +import { IUpload, RecordingState, VoiceRecording } from "../../../audio/VoiceRecording"; import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import classNames from "classnames"; @@ -34,6 +31,10 @@ import { MsgType } from "matrix-js-sdk/src/@types/event"; import Modal from "../../../Modal"; import ErrorDialog from "../dialogs/ErrorDialog"; import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../MediaDeviceHandler"; +import NotificationBadge from "./NotificationBadge"; +import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState"; +import { NotificationColor } from "../../../stores/notifications/NotificationColor"; +import InlineSpinner from "../elements/InlineSpinner"; interface IProps { room: Room; @@ -42,6 +43,7 @@ interface IProps { interface IState { recorder?: VoiceRecording; recordingPhase?: RecordingState; + didUploadFail?: boolean; } /** @@ -69,9 +71,19 @@ export default class VoiceRecordComposerTile extends React.PureComponent { @@ -234,7 +245,26 @@ export default class VoiceRecordComposerTile extends React.PureComponent; } + let uploadIndicator; + if (this.state.recordingPhase === RecordingState.Uploading) { + uploadIndicator = + + { _t("Uploading...") } + ; + } else if (this.state.didUploadFail && this.state.recordingPhase === RecordingState.Ended) { + uploadIndicator = + + { /* Need to stick the badge in a span to ensure it doesn't create a block component */ } + + + { _t("Failed to upload voice message") } + ; + } + return (<> + { uploadIndicator } { deleteButton } { this.renderWaveformArea() } { recordingInfo } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87cd9afb5b..c929bd683b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1701,7 +1701,6 @@ "Invited by %(sender)s": "Invited by %(sender)s", "Jump to first unread message.": "Jump to first unread message.", "Mark all as read": "Mark all as read", - "The voice message failed to upload.": "The voice message failed to upload.", "Unable to access your microphone": "Unable to access your microphone", "We were unable to access your microphone. Please check your browser settings and try again.": "We were unable to access your microphone. Please check your browser settings and try again.", "No microphone found": "No microphone found", @@ -1709,6 +1708,8 @@ "Record a voice message": "Record a voice message", "Stop the recording": "Stop the recording", "Delete recording": "Delete recording", + "Uploading...": "Uploading...", + "Failed to upload voice message": "Failed to upload voice message", "Error updating main address": "Error updating main address", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.", "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.", From 7b565db02dacc067ae0d3b9adc7fbf3a277f8ee3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Aug 2021 12:52:21 -0600 Subject: [PATCH 10/27] Update uploading state designs --- res/css/views/rooms/_VoiceRecordComposerTile.scss | 8 ++++++-- src/components/views/rooms/VoiceRecordComposerTile.tsx | 9 ++++----- src/i18n/strings/en_EN.json | 2 -- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/res/css/views/rooms/_VoiceRecordComposerTile.scss b/res/css/views/rooms/_VoiceRecordComposerTile.scss index 3d8d0e5ecc..7acec5a133 100644 --- a/res/css/views/rooms/_VoiceRecordComposerTile.scss +++ b/res/css/views/rooms/_VoiceRecordComposerTile.scss @@ -46,9 +46,13 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/trashcan.svg'); } -.mx_VoiceRecordComposerTile_uploadState { - margin-right: 21px; +.mx_VoiceRecordComposerTile_uploadingState { + margin-right: 10px; color: $secondary-fg-color; +} + +.mx_VoiceRecordComposerTile_failedState { + margin-right: 21px; .mx_VoiceRecordComposerTile_uploadState_badge { display: inline-block; diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 490d6b2231..1f481d7531 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -246,20 +246,19 @@ export default class VoiceRecordComposerTile extends React.PureComponent + if (this.state.recordingPhase === RecordingState.Uploading || true) { + uploadIndicator = - { _t("Uploading...") } ; } else if (this.state.didUploadFail && this.state.recordingPhase === RecordingState.Ended) { - uploadIndicator = + uploadIndicator = { /* Need to stick the badge in a span to ensure it doesn't create a block component */ } - { _t("Failed to upload voice message") } + { _t("Failed to send") } ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c929bd683b..9a717e31a4 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1708,8 +1708,6 @@ "Record a voice message": "Record a voice message", "Stop the recording": "Stop the recording", "Delete recording": "Delete recording", - "Uploading...": "Uploading...", - "Failed to upload voice message": "Failed to upload voice message", "Error updating main address": "Error updating main address", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.", "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.", From c4e6cc797302fd12af7c33c05a7b91cf11226524 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Aug 2021 12:57:16 -0600 Subject: [PATCH 11/27] Remove debugging --- src/components/views/rooms/VoiceRecordComposerTile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 1f481d7531..b980b9295b 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -246,7 +246,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent ; From 32442068cf53144f101523d56b3dcd7ab80a82ce Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Aug 2021 13:26:27 -0600 Subject: [PATCH 12/27] Use a default waveform when recording to ease component pop-in Fixes https://github.com/vector-im/element-web/issues/18225 --- src/components/views/audio_messages/LiveRecordingWaveform.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/audio_messages/LiveRecordingWaveform.tsx b/src/components/views/audio_messages/LiveRecordingWaveform.tsx index 9c33889884..9f981e8ca2 100644 --- a/src/components/views/audio_messages/LiveRecordingWaveform.tsx +++ b/src/components/views/audio_messages/LiveRecordingWaveform.tsx @@ -17,7 +17,7 @@ limitations under the License. import React from "react"; import { IRecordingUpdate, RECORDING_PLAYBACK_SAMPLES, VoiceRecording } from "../../../audio/VoiceRecording"; import { replaceableComponent } from "../../../utils/replaceableComponent"; -import { arrayFastResample } from "../../../utils/arrays"; +import { arrayFastResample, arraySeed } from "../../../utils/arrays"; import { percentageOf } from "../../../utils/numbers"; import Waveform from "./Waveform"; import { MarkedExecution } from "../../../utils/MarkedExecution"; @@ -48,7 +48,7 @@ export default class LiveRecordingWaveform extends React.PureComponent Date: Tue, 3 Aug 2021 13:33:42 -0600 Subject: [PATCH 13/27] Improve hover states (tooltips) for voice message interactions Fixes https://github.com/vector-im/element-web/issues/18375 --- src/components/views/rooms/VoiceRecordComposerTile.tsx | 6 +++--- src/i18n/strings/en_EN.json | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 8323320520..7949f41784 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -209,9 +209,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3ad8daa85c..cf06112b14 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1705,9 +1705,8 @@ "We were unable to access your microphone. Please check your browser settings and try again.": "We were unable to access your microphone. Please check your browser settings and try again.", "No microphone found": "No microphone found", "We didn't find a microphone on your device. Please check your settings and try again.": "We didn't find a microphone on your device. Please check your settings and try again.", - "Record a voice message": "Record a voice message", - "Stop the recording": "Stop the recording", - "Delete recording": "Delete recording", + "Send voice message": "Send voice message", + "Stop recording": "Stop recording", "Error updating main address": "Error updating main address", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.", "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.", From 24da0291a05a4ddfc4c008415b3ea6688836a73a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Aug 2021 13:33:58 -0600 Subject: [PATCH 14/27] Re-center recording LED Fixes https://github.com/vector-im/element-web/issues/18375 --- res/css/views/rooms/_VoiceRecordComposerTile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_VoiceRecordComposerTile.scss b/res/css/views/rooms/_VoiceRecordComposerTile.scss index 5501ab343e..8c13018c51 100644 --- a/res/css/views/rooms/_VoiceRecordComposerTile.scss +++ b/res/css/views/rooms/_VoiceRecordComposerTile.scss @@ -68,7 +68,7 @@ limitations under the License. height: 10px; position: absolute; left: 12px; // 12px from the left edge for container padding - top: 18px; // vertically center (middle align with clock) + top: 16px; // vertically center (middle align with clock) border-radius: 10px; } } From 1b9fe46733f8ae587ee592786a80a8b5b42a3ac7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Aug 2021 13:51:11 -0600 Subject: [PATCH 15/27] Remove unnecessary rescaling of voice waveforms Fixes https://github.com/vector-im/element-web/issues/18364 --- src/audio/Playback.ts | 14 +++----------- .../views/audio_messages/LiveRecordingWaveform.tsx | 9 ++------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/audio/Playback.ts b/src/audio/Playback.ts index 33d346629a..9dad828a79 100644 --- a/src/audio/Playback.ts +++ b/src/audio/Playback.ts @@ -38,17 +38,9 @@ function makePlaybackWaveform(input: number[]): number[] { // First, convert negative amplitudes to positive so we don't detect zero as "noisy". const noiseWaveform = input.map(v => Math.abs(v)); - // Next, we'll resample the waveform using a smoothing approach so we can keep the same rough shape. - // We also rescale the waveform to be 0-1 for the remaining function logic. - const resampled = arrayRescale(arraySmoothingResample(noiseWaveform, PLAYBACK_WAVEFORM_SAMPLES), 0, 1); - - // Then, we'll do a high and low pass filter to isolate actual speaking volumes within the rescaled - // waveform. Most speech happens below the 0.5 mark. - const filtered = resampled.map(v => clamp(v, 0.1, 0.5)); - - // Finally, we'll rescale the filtered waveform (0.1-0.5 becomes 0-1 again) so the user sees something - // sensible. This is what we return to keep our contract of "values between zero and one". - return arrayRescale(filtered, 0, 1); + // Then, we'll resample the waveform using a smoothing approach so we can keep the same rough shape. + // We also rescale the waveform to be 0-1 so we end up with a clamped waveform to rely upon. + return arrayRescale(arraySmoothingResample(noiseWaveform, PLAYBACK_WAVEFORM_SAMPLES), 0, 1); } export class Playback extends EventEmitter implements IDestroyable { diff --git a/src/components/views/audio_messages/LiveRecordingWaveform.tsx b/src/components/views/audio_messages/LiveRecordingWaveform.tsx index 9f981e8ca2..73e18626fe 100644 --- a/src/components/views/audio_messages/LiveRecordingWaveform.tsx +++ b/src/components/views/audio_messages/LiveRecordingWaveform.tsx @@ -18,7 +18,6 @@ import React from "react"; import { IRecordingUpdate, RECORDING_PLAYBACK_SAMPLES, VoiceRecording } from "../../../audio/VoiceRecording"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { arrayFastResample, arraySeed } from "../../../utils/arrays"; -import { percentageOf } from "../../../utils/numbers"; import Waveform from "./Waveform"; import { MarkedExecution } from "../../../utils/MarkedExecution"; @@ -54,12 +53,8 @@ export default class LiveRecordingWaveform extends React.PureComponent { - const bars = arrayFastResample(Array.from(update.waveform), RECORDING_PLAYBACK_SAMPLES); - // The incoming data is between zero and one, but typically even screaming into a - // microphone won't send you over 0.6, so we artificially adjust the gain for the - // waveform. This results in a slightly more cinematic/animated waveform for the - // user. - this.waveform = bars.map(b => percentageOf(b, 0, 0.50)); + // The incoming data is between zero and one, so we don't need to clamp/rescale it. + this.waveform = arrayFastResample(Array.from(update.waveform), RECORDING_PLAYBACK_SAMPLES); this.scheduledUpdate.mark(); }); } From fe643b2401d38457deb891af17bd6543ec5526c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 4 Aug 2021 17:09:48 +0200 Subject: [PATCH 16/27] Use flex-start as it has more universal support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/auth/_InteractiveAuthEntryComponents.scss | 2 +- res/css/views/rooms/_EventBubbleTile.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/auth/_InteractiveAuthEntryComponents.scss b/res/css/views/auth/_InteractiveAuthEntryComponents.scss index ffaad3cd7a..ec07b765fd 100644 --- a/res/css/views/auth/_InteractiveAuthEntryComponents.scss +++ b/res/css/views/auth/_InteractiveAuthEntryComponents.scss @@ -85,7 +85,7 @@ limitations under the License. .mx_InteractiveAuthEntryComponents_termsPolicy { display: flex; flex-direction: row; - justify-content: start; + justify-content: flex-start; align-items: center; } diff --git a/res/css/views/rooms/_EventBubbleTile.scss b/res/css/views/rooms/_EventBubbleTile.scss index 1e25deba26..c6170bf7c0 100644 --- a/res/css/views/rooms/_EventBubbleTile.scss +++ b/res/css/views/rooms/_EventBubbleTile.scss @@ -271,7 +271,7 @@ limitations under the License. display: flex; align-items: center; - justify-content: start; + justify-content: flex-start; padding: 5px 0; .mx_EventTile_avatar { From e2bc76a1294158a9f149b3e6048b0586bbfedd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 4 Aug 2021 17:17:21 +0200 Subject: [PATCH 17/27] Fix voice feed cut-off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- res/css/views/voip/_CallView.scss | 2 -- res/css/views/voip/_CallViewSidebar.scss | 2 -- res/css/views/voip/_VideoFeed.scss | 1 + 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss index 60b7aa69ea..fb18c6a5ee 100644 --- a/res/css/views/voip/_CallView.scss +++ b/res/css/views/voip/_CallView.scss @@ -75,8 +75,6 @@ limitations under the License. height: 100%; &.mx_VideoFeed_voice { - // We don't want to collide with the call controls that have 52px of height - margin-bottom: 52px; background-color: $inverted-bg-color; display: flex; justify-content: center; diff --git a/res/css/views/voip/_CallViewSidebar.scss b/res/css/views/voip/_CallViewSidebar.scss index 892a137a32..dbadc22028 100644 --- a/res/css/views/voip/_CallViewSidebar.scss +++ b/res/css/views/voip/_CallViewSidebar.scss @@ -40,8 +40,6 @@ limitations under the License. display: flex; align-items: center; justify-content: center; - - aspect-ratio: 16 / 9; } .mx_VideoFeed_video { diff --git a/res/css/views/voip/_VideoFeed.scss b/res/css/views/voip/_VideoFeed.scss index 3a0f62636e..7a8d39dfe3 100644 --- a/res/css/views/voip/_VideoFeed.scss +++ b/res/css/views/voip/_VideoFeed.scss @@ -20,6 +20,7 @@ limitations under the License. &.mx_VideoFeed_voice { background-color: $inverted-bg-color; + aspect-ratio: 16 / 9; } .mx_VideoFeed_video { From 99adbfd1ea896e6fbaf6417d6ecf8aab50d58a8b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Aug 2021 13:04:20 +0100 Subject: [PATCH 18/27] Skip sending a thumbnail if it is not a sufficient saving over the original --- src/ContentMessages.tsx | 49 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index c5bcb226ff..8973219b49 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -209,6 +209,14 @@ async function loadImageElement(imageFile: File) { return { width, height, img }; } +// Minimum size for image files before we generate a thumbnail for them. +const IMAGE_SIZE_THRESHOLD_THUMBNAIL = 1 << 15; // 32KB +// Minimum size improvement for image thumbnails, if both are not met then don't bother uploading thumbnail. +const IMAGE_THUMBNAIL_MIN_REDUCTION_SIZE = 1 << 16; // 1MB +const IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT = 0.1; // 10% +// We don't apply these thresholds to video thumbnails as a poster image is always useful +// and videos tend to be much larger. + /** * Read the metadata for an image file and create and upload a thumbnail of the image. * @@ -217,23 +225,40 @@ async function loadImageElement(imageFile: File) { * @param {File} imageFile The image to read and thumbnail. * @return {Promise} A promise that resolves with the attachment info. */ -function infoForImageFile(matrixClient, roomId, imageFile) { +async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imageFile: File) { + if (imageFile.size <= IMAGE_SIZE_THRESHOLD_THUMBNAIL) { + // don't bother generating a thumbnail, image is small enough already + return {}; + } + let thumbnailType = "image/png"; if (imageFile.type === "image/jpeg") { thumbnailType = "image/jpeg"; } - let imageInfo; - return loadImageElement(imageFile).then((r) => { - return createThumbnail(r.img, r.width, r.height, thumbnailType); - }).then((result) => { - imageInfo = result.info; - return uploadFile(matrixClient, roomId, result.thumbnail); - }).then((result) => { - imageInfo.thumbnail_url = result.url; - imageInfo.thumbnail_file = result.file; - return imageInfo; - }); + const imageElement = await loadImageElement(imageFile); + + if (imageElement.width < MAX_WIDTH && imageElement.height < MAX_HEIGHT) { + // don't bother uploading thumbnail as it'd be the same resolution as the original. + return {}; + } + + const result = await createThumbnail(imageElement.img, imageElement.width, imageElement.height, thumbnailType); + const imageInfo = result.info; + + const sizeDifference = imageFile.size - imageInfo.thumbnail_info.size; + if (sizeDifference <= IMAGE_THUMBNAIL_MIN_REDUCTION_SIZE && + sizeDifference <= (imageFile.size * IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT) + ) { + // don't bother uploading thumbnail as it not sufficiently smaller than the original. + return {}; + } + + const uploadResult = await uploadFile(matrixClient, roomId, result.thumbnail); + + imageInfo["thumbnail_url"] = uploadResult.url; + imageInfo["thumbnail_file"] = uploadResult.file; + return imageInfo; } /** From 980b284642cbbdbcb88920b8dd1e89bf312cc820 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Aug 2021 13:12:01 +0100 Subject: [PATCH 19/27] Fix image & blurhash info when skipping thumbnail due to thresholds --- src/ContentMessages.tsx | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index 8973219b49..14a0c1ed51 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -226,11 +226,6 @@ const IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT = 0.1; // 10% * @return {Promise} A promise that resolves with the attachment info. */ async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imageFile: File) { - if (imageFile.size <= IMAGE_SIZE_THRESHOLD_THUMBNAIL) { - // don't bother generating a thumbnail, image is small enough already - return {}; - } - let thumbnailType = "image/png"; if (imageFile.type === "image/jpeg") { thumbnailType = "image/jpeg"; @@ -238,20 +233,18 @@ async function infoForImageFile(matrixClient: MatrixClient, roomId: string, imag const imageElement = await loadImageElement(imageFile); - if (imageElement.width < MAX_WIDTH && imageElement.height < MAX_HEIGHT) { - // don't bother uploading thumbnail as it'd be the same resolution as the original. - return {}; - } - const result = await createThumbnail(imageElement.img, imageElement.width, imageElement.height, thumbnailType); const imageInfo = result.info; + // we do all sizing checks here because we still rely on thumbnail generation for making a blurhash from. const sizeDifference = imageFile.size - imageInfo.thumbnail_info.size; - if (sizeDifference <= IMAGE_THUMBNAIL_MIN_REDUCTION_SIZE && - sizeDifference <= (imageFile.size * IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT) + if ( + imageFile.size <= IMAGE_SIZE_THRESHOLD_THUMBNAIL || // image is small enough already + (sizeDifference <= IMAGE_THUMBNAIL_MIN_REDUCTION_SIZE && // thumbnail is not sufficiently smaller than original + sizeDifference <= (imageFile.size * IMAGE_THUMBNAIL_MIN_REDUCTION_PERCENT)) ) { - // don't bother uploading thumbnail as it not sufficiently smaller than the original. - return {}; + delete imageInfo["thumbnail_info"]; + return imageInfo; } const uploadResult = await uploadFile(matrixClient, roomId, result.thumbnail); From a8b050a385f8831904c083f7ef555a083e26eeff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Aug 2021 13:37:23 +0100 Subject: [PATCH 20/27] Post-merge conflict resolution and improve alignment of tooltips --- src/components/views/voip/CallView.tsx | 50 ++++++++++++++++++++------ 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 356e642d65..3178566e68 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -23,11 +23,16 @@ import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { _t, _td } from '../../../languageHandler'; import VideoFeed from './VideoFeed'; import RoomAvatar from "../avatars/RoomAvatar"; -import { CallState, CallType, MatrixCall, CallEvent } from 'matrix-js-sdk/src/webrtc/call'; +import { CallEvent, CallState, CallType, MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import classNames from 'classnames'; import AccessibleButton from '../elements/AccessibleButton'; import { isOnlyCtrlOrCmdKeyEvent, Key } from '../../../Keyboard'; -import { alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton } from '../../structures/ContextMenu'; +import { + alwaysAboveLeftOf, + alwaysAboveRightOf, + ChevronFace, + ContextMenuTooltipButton, +} from '../../structures/ContextMenu'; import CallContextMenu from '../context_menus/CallContextMenu'; import { avatarUrlForMember } from '../../../Avatar'; import DialpadContextMenu from '../context_menus/DialpadContextMenu'; @@ -37,6 +42,8 @@ import DesktopCapturerSourcePicker from "../elements/DesktopCapturerSourcePicker import Modal from '../../../Modal'; import { SDPStreamMetadataPurpose } from 'matrix-js-sdk/src/webrtc/callEventTypes'; import CallViewSidebar from './CallViewSidebar'; +import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; +import { Alignment } from "../elements/Tooltip"; interface IProps { // The call for us to display @@ -115,7 +122,6 @@ export default class CallView extends React.Component { private controlsHideTimer: number = null; private dialpadButton = createRef(); private contextMenuButton = createRef(); - private contextMenu = createRef(); constructor(props: IProps) { super(props); @@ -479,9 +485,12 @@ export default class CallView extends React.Component { let vidMuteButton; if (this.props.call.type === CallType.Video) { vidMuteButton = ( - ); } @@ -496,9 +505,15 @@ export default class CallView extends React.Component { this.props.call.state === CallState.Connected ) { screensharingButton = ( - ); } @@ -518,6 +533,7 @@ export default class CallView extends React.Component { ); } @@ -526,22 +542,28 @@ export default class CallView extends React.Component { let contextMenuButton; if (this.state.callState === CallState.Connected) { contextMenuButton = ( - ); } let dialpadButton; if (this.state.callState === CallState.Connected && this.props.call.opponentSupportsDTMF()) { dialpadButton = ( - ); } @@ -583,9 +605,12 @@ export default class CallView extends React.Component { { dialPad } { contextMenu } { dialpadButton } - { vidMuteButton }
@@ -593,9 +618,12 @@ export default class CallView extends React.Component { { screensharingButton } { sidebarButton } { contextMenuButton } -
); @@ -820,7 +848,7 @@ export default class CallView extends React.Component { let fullScreenButton; if (!this.props.pipMode) { fullScreenButton = ( -
{ let expandButton; if (this.props.pipMode) { - expandButton =
Date: Thu, 5 Aug 2021 13:50:50 +0100 Subject: [PATCH 21/27] i18n --- src/i18n/strings/en_EN.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9664b2ca14..41ef0cc04f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -906,8 +906,12 @@ "sends space invaders": "sends space invaders", "Start the camera": "Start the camera", "Stop the camera": "Stop the camera", - "Dialpad": "Dialpad", + "Stop sharing your screen": "Stop sharing your screen", + "Start sharing your screen": "Start sharing your screen", + "Hide sidebar": "Hide sidebar", + "Show sidebar": "Show sidebar", "More": "More", + "Dialpad": "Dialpad", "Unmute the microphone": "Unmute the microphone", "Mute the microphone": "Mute the microphone", "Hangup": "Hangup", From e1b62ae38b15b503468f212f247dd9470e18c47a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Aug 2021 14:20:31 +0100 Subject: [PATCH 22/27] Increase yOffset by 4px away --- src/components/views/voip/CallView.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 3178566e68..945cc55ed3 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -490,7 +490,7 @@ export default class CallView extends React.Component { onClick={this.onVidMuteClick} title={this.state.vidMuted ? _t("Start the camera") : _t("Stop the camera")} alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} /> ); } @@ -513,7 +513,7 @@ export default class CallView extends React.Component { : _t("Start sharing your screen") } alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} /> ); } @@ -549,7 +549,7 @@ export default class CallView extends React.Component { isExpanded={this.state.showMoreMenu} title={_t("More")} alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} /> ); } @@ -563,7 +563,7 @@ export default class CallView extends React.Component { isExpanded={this.state.showDialpad} title={_t("Dialpad")} alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} /> ); } @@ -610,7 +610,7 @@ export default class CallView extends React.Component { onClick={this.onMicMuteClick} title={this.state.micMuted ? _t("Unmute the microphone") : _t("Mute the microphone")} alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} /> { vidMuteButton }
@@ -623,7 +623,7 @@ export default class CallView extends React.Component { onClick={this.onHangupClick} title={_t("Hangup")} alignment={Alignment.Top} - yOffset={-20} + yOffset={-24} />
); From b860acca8043ea9c8c937380650339566439f775 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Aug 2021 14:43:44 +0100 Subject: [PATCH 23/27] Extract tooltipYOffset to a const --- src/components/views/voip/CallView.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 945cc55ed3..d301a1e43b 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -82,6 +82,8 @@ interface IState { sidebarShown: boolean; } +const tooltipYOffset = -24; + function getFullScreenElement() { return ( document.fullscreenElement || @@ -490,7 +492,7 @@ export default class CallView extends React.Component { onClick={this.onVidMuteClick} title={this.state.vidMuted ? _t("Start the camera") : _t("Stop the camera")} alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} /> ); } @@ -513,7 +515,7 @@ export default class CallView extends React.Component { : _t("Start sharing your screen") } alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} /> ); } @@ -549,7 +551,7 @@ export default class CallView extends React.Component { isExpanded={this.state.showMoreMenu} title={_t("More")} alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} /> ); } @@ -563,7 +565,7 @@ export default class CallView extends React.Component { isExpanded={this.state.showDialpad} title={_t("Dialpad")} alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} /> ); } @@ -610,7 +612,7 @@ export default class CallView extends React.Component { onClick={this.onMicMuteClick} title={this.state.micMuted ? _t("Unmute the microphone") : _t("Mute the microphone")} alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} /> { vidMuteButton }
@@ -623,7 +625,7 @@ export default class CallView extends React.Component { onClick={this.onHangupClick} title={_t("Hangup")} alignment={Alignment.Top} - yOffset={-24} + yOffset={tooltipYOffset} />
); From df888a1886aeb9783091caf506d7b4216495a533 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 5 Aug 2021 16:33:22 +0100 Subject: [PATCH 24/27] Fix in-call context menus when in PiP mode (#6552) Mounting them as children when in PiP mode doesn't work. Condition mounting the context menus as children of the current component based on whether PiP mode is active. --- src/components/views/voip/CallView.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 356e642d65..d5ec2e71d3 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -554,7 +554,11 @@ export default class CallView extends React.Component { ChevronFace.None, CONTEXT_MENU_VPADDING, )} - mountAsChild={true} + // We mount the context menus as a as a child typically in order to include the + // context menus when fullscreening the call content. + // However, this does not work as well when the call is embedded in a + // picture-in-picture frame. Thus, only mount as child when we are *not* in PiP. + mountAsChild={!this.props.pipMode} onFinished={this.closeDialpad} call={this.props.call} />; @@ -568,7 +572,7 @@ export default class CallView extends React.Component { ChevronFace.None, CONTEXT_MENU_VPADDING, )} - mountAsChild={true} + mountAsChild={!this.props.pipMode} onFinished={this.closeContextMenu} call={this.props.call} />; From 81ddaf2efaf0eda2c296b0e2fb43834b7aae5575 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Aug 2021 11:21:22 -0600 Subject: [PATCH 25/27] Properly set style attribute on shared usercontent iframe Fixes https://github.com/vector-im/element-web/issues/18414 --- src/utils/FileDownloader.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/FileDownloader.ts b/src/utils/FileDownloader.ts index a22ff506de..5ec91d71cc 100644 --- a/src/utils/FileDownloader.ts +++ b/src/utils/FileDownloader.ts @@ -43,9 +43,8 @@ function getManagedIframe(): { iframe: HTMLIFrameElement, onLoadPromise: Promise // Dev note: the reassignment warnings are entirely incorrect here. - // @ts-ignore - // noinspection JSConstantReassignment - managedIframe.style = { display: "none" }; + managedIframe.style.display = "none"; + // @ts-ignore // noinspection JSConstantReassignment managedIframe.sandbox = "allow-scripts allow-downloads allow-downloads-without-user-activation"; From 17a3dc5e6dc79ccd9e926c49a9c24f0caae0e0f5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Aug 2021 12:44:12 -0600 Subject: [PATCH 26/27] Stop voice messages that are playing when starting a recording Fixes https://github.com/vector-im/element-web/issues/18410 --- src/components/views/rooms/VoiceRecordComposerTile.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 019e39d415..1b583444a3 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -35,6 +35,7 @@ import NotificationBadge from "./NotificationBadge"; import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState"; import { NotificationColor } from "../../../stores/notifications/NotificationColor"; import InlineSpinner from "../elements/InlineSpinner"; +import { PlaybackManager } from "../../../audio/PlaybackManager"; interface IProps { room: Room; @@ -177,6 +178,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent Date: Thu, 5 Aug 2021 17:56:16 -0400 Subject: [PATCH 27/27] Add comments to isRegionalIndicator Signed-off-by: Robin Townsend --- src/emoji.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/emoji.ts b/src/emoji.ts index e871e0bb58..ee84583fc9 100644 --- a/src/emoji.ts +++ b/src/emoji.ts @@ -35,8 +35,15 @@ export const EMOTICON_TO_EMOJI = new Map(); export const getEmojiFromUnicode = unicode => UNICODE_TO_EMOJI.get(stripVariation(unicode)); -const isRegionalIndicator = (x: string): boolean => - Array.from(x).length === 1 && x >= '\u{1f1e6}' && x <= '\u{1f1ff}'; +const isRegionalIndicator = (x: string): boolean => { + // First verify that the string is a single character. We use Array.from + // to make sure we count by characters, not UTF-8 code units. + return Array.from(x).length === 1 && + // Next verify that the character is within the code point range for + // regional indicators. + // http://unicode.org/charts/PDF/Unicode-6.0/U60-1F100.pdf + x >= '\u{1f1e6}' && x <= '\u{1f1ff}'; +}; const EMOJIBASE_GROUP_ID_TO_CATEGORY = [ "people", // smileys