mirror of
https://github.com/element-hq/element-web
synced 2024-11-25 18:55:58 +03:00
Add voice broadcast seek 30s forward/backward buttons (#9592)
This commit is contained in:
parent
caac059479
commit
d699f5607b
13 changed files with 316 additions and 11 deletions
|
@ -36,3 +36,9 @@ limitations under the License.
|
|||
flex: 0 0 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mx_Icon_24 {
|
||||
height: 24px;
|
||||
flex: 0 0 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,10 @@ limitations under the License.
|
|||
color: $accent;
|
||||
}
|
||||
|
||||
&.mx_AccessibleButton_kind_secondary_content {
|
||||
color: $secondary-content;
|
||||
}
|
||||
|
||||
&.mx_AccessibleButton_kind_danger {
|
||||
color: $button-danger-fg-color;
|
||||
background-color: $alert;
|
||||
|
|
|
@ -22,7 +22,6 @@ limitations under the License.
|
|||
display: flex;
|
||||
height: 32px;
|
||||
justify-content: center;
|
||||
margin-bottom: $spacing-8;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,11 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_VoiceBroadcastBody_controls {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
gap: $spacing-32;
|
||||
justify-content: center;
|
||||
margin-bottom: $spacing-8;
|
||||
}
|
||||
|
||||
.mx_VoiceBroadcastBody_timerow {
|
||||
|
|
1
res/img/element-icons/Back30s.svg
Normal file
1
res/img/element-icons/Back30s.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="19.977" height="22.975" fill="none"><path fill="currentColor" d="M9.976 22.975c-2.648 0-4.922-.88-6.82-2.64C1.258 18.577.206 16.4.003 13.808a.728.728 0 0 1 .208-.583.786.786 0 0 1 .598-.25c.222 0 .412.078.57.236.157.157.254.356.29.597.205 2.13 1.093 3.913 2.668 5.348 1.574 1.435 3.454 2.153 5.64 2.153 2.314 0 4.282-.81 5.903-2.43 1.62-1.621 2.43-3.59 2.43-5.904 0-2.315-.786-4.283-2.36-5.904-1.575-1.62-3.52-2.43-5.835-2.43h-.611l1.445 1.444a.8.8 0 0 1 .25.583.8.8 0 0 1-.25.584.8.8 0 0 1-.584.25.8.8 0 0 1-.583-.25L6.865 4.334a.846.846 0 0 1-.195-.278.816.816 0 0 1-.055-.306c0-.11.018-.213.055-.305a.846.846 0 0 1 .195-.278L9.81.222A.754.754 0 0 1 10.365 0a.85.85 0 0 1 .584.222.85.85 0 0 1 .222.584.754.754 0 0 1-.222.555L9.337 2.973h.64c1.388 0 2.69.259 3.903.777a10.021 10.021 0 0 1 3.18 2.14 10.02 10.02 0 0 1 2.14 3.18 9.824 9.824 0 0 1 .777 3.904c0 1.389-.259 2.69-.777 3.903a10.02 10.02 0 0 1-2.14 3.18 10.02 10.02 0 0 1-3.18 2.14 9.824 9.824 0 0 1-3.904.778z"/><path fill="currentColor" d="M7.017 16.914c-.46 0-.87-.078-1.227-.236a2.052 2.052 0 0 1-.844-.658 1.707 1.707 0 0 1-.33-.975h1.202c.011.177.07.331.176.463.107.13.248.231.425.304.177.072.375.108.595.108.234 0 .442-.04.623-.12.181-.084.323-.2.425-.346a.85.85 0 0 0 .15-.508.882.882 0 0 0-.153-.524 1.026 1.026 0 0 0-.454-.355 1.775 1.775 0 0 0-.71-.128h-.578v-.914h.579c.227 0 .427-.04.597-.118a.967.967 0 0 0 .406-.333.856.856 0 0 0 .144-.502.872.872 0 0 0-.125-.482.841.841 0 0 0-.354-.323 1.166 1.166 0 0 0-.534-.115c-.2 0-.386.036-.556.109-.17.072-.308.175-.413.31a.786.786 0 0 0-.166.473h-1.14a1.66 1.66 0 0 1 .316-.965 2.04 2.04 0 0 1 .818-.652c.34-.158.723-.237 1.147-.237.437 0 .816.082 1.138.246.324.162.574.38.751.655.177.275.265.579.265.911.002.369-.106.678-.326.927a1.53 1.53 0 0 1-.856.489v.051c.46.064.813.235 1.058.511.247.275.37.617.367 1.026 0 .367-.104.695-.313.985a2.076 2.076 0 0 1-.857.677 2.991 2.991 0 0 1-1.246.246zm5.498.036c-.526 0-.978-.134-1.355-.4-.375-.268-.664-.655-.866-1.16-.2-.507-.3-1.118-.3-1.831.002-.714.103-1.321.303-1.822.202-.503.491-.886.866-1.15.377-.265.828-.397 1.352-.397.524 0 .975.132 1.352.396.377.265.666.648.866 1.15.203.504.304 1.111.304 1.823 0 .716-.101 1.327-.304 1.834-.2.505-.489.89-.866 1.157-.375.266-.826.4-1.352.4zm0-1c.41 0 .732-.202.968-.605.24-.405.358-1 .358-1.786 0-.52-.054-.957-.163-1.31-.108-.354-.262-.62-.46-.8a1.008 1.008 0 0 0-.703-.271c-.407 0-.729.202-.965.607-.237.403-.356.994-.358 1.774-.002.522.05.96.157 1.316.108.356.262.625.46.806.198.179.433.268.706.268z"/></svg>
|
After Width: | Height: | Size: 2.5 KiB |
1
res/img/element-icons/Forward30s.svg
Normal file
1
res/img/element-icons/Forward30s.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="19.977" height="22.975" fill="none"><path fill="currentColor" d="M10.001 22.975c2.649 0 4.922-.88 6.82-2.64 1.899-1.759 2.95-3.935 3.153-6.528a.728.728 0 0 0-.208-.583.786.786 0 0 0-.597-.25.776.776 0 0 0-.57.236 1.044 1.044 0 0 0-.291.597c-.204 2.13-1.093 3.913-2.667 5.348-1.575 1.435-3.454 2.153-5.64 2.153-2.315 0-4.283-.81-5.903-2.43-1.62-1.621-2.431-3.59-2.431-5.904 0-2.315.787-4.283 2.361-5.904 1.574-1.62 3.52-2.43 5.834-2.43h.611L9.03 6.083a.8.8 0 0 0-.25.583.8.8 0 0 0 .25.584.8.8 0 0 0 .583.25.8.8 0 0 0 .584-.25l2.917-2.917a.846.846 0 0 0 .194-.278.817.817 0 0 0 .056-.306.817.817 0 0 0-.056-.305.846.846 0 0 0-.194-.278L10.168.222A.754.754 0 0 0 9.612 0a.85.85 0 0 0-.583.222.85.85 0 0 0-.222.584c0 .222.074.407.222.555l1.611 1.612h-.639c-1.389 0-2.69.259-3.903.777a10.021 10.021 0 0 0-3.181 2.14 10.022 10.022 0 0 0-2.14 3.18A9.824 9.824 0 0 0 0 12.974c0 1.389.26 2.69.778 3.903a10.021 10.021 0 0 0 2.139 3.18 10.02 10.02 0 0 0 3.18 2.14 9.824 9.824 0 0 0 3.904.778z"/><path fill="currentColor" d="M7.017 16.914c-.46 0-.87-.078-1.227-.236a2.052 2.052 0 0 1-.844-.658 1.707 1.707 0 0 1-.33-.975h1.202c.011.177.07.331.176.463.107.13.248.231.425.304.177.072.375.108.595.108.234 0 .442-.04.623-.12.181-.084.323-.2.425-.346a.85.85 0 0 0 .15-.508.882.882 0 0 0-.153-.524 1.026 1.026 0 0 0-.454-.355 1.775 1.775 0 0 0-.71-.128h-.578v-.914h.578c.228 0 .428-.04.598-.118a.967.967 0 0 0 .406-.333.856.856 0 0 0 .144-.502.872.872 0 0 0-.125-.482.841.841 0 0 0-.355-.323 1.166 1.166 0 0 0-.533-.115c-.2 0-.386.036-.556.109-.17.072-.308.175-.413.31a.786.786 0 0 0-.166.473h-1.14a1.66 1.66 0 0 1 .315-.965 2.04 2.04 0 0 1 .819-.652c.34-.158.723-.237 1.147-.237.437 0 .816.082 1.138.246.324.162.574.38.75.655.178.275.266.579.266.911.002.369-.106.678-.326.927a1.53 1.53 0 0 1-.856.489v.051c.46.064.812.235 1.057.511.248.275.37.617.368 1.026 0 .367-.104.695-.313.985a2.076 2.076 0 0 1-.857.677 2.991 2.991 0 0 1-1.246.246zm5.498.036c-.526 0-.978-.134-1.355-.4-.375-.268-.664-.655-.866-1.16-.2-.507-.3-1.118-.3-1.831.001-.714.103-1.321.303-1.822.202-.503.491-.886.866-1.15.377-.265.828-.397 1.352-.397.524 0 .975.132 1.352.396.377.265.666.648.866 1.15.202.504.304 1.111.304 1.823 0 .716-.102 1.327-.304 1.834-.2.505-.489.89-.866 1.157-.375.266-.826.4-1.352.4zm0-1c.409 0 .732-.202.968-.605.239-.405.358-1 .358-1.786 0-.52-.054-.957-.163-1.31-.108-.354-.262-.62-.46-.8a1.008 1.008 0 0 0-.703-.271c-.407 0-.729.202-.965.607-.237.403-.356.994-.358 1.774-.002.522.05.96.156 1.316.109.356.262.625.46.806.199.179.434.268.707.268z"/></svg>
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -26,6 +26,7 @@ type AccessibleButtonKind = | 'primary'
|
|||
| 'primary_outline'
|
||||
| 'primary_sm'
|
||||
| 'secondary'
|
||||
| 'secondary_content'
|
||||
| 'content_inline'
|
||||
| 'danger'
|
||||
| 'danger_outline'
|
||||
|
|
|
@ -651,6 +651,8 @@
|
|||
"play voice broadcast": "play voice broadcast",
|
||||
"resume voice broadcast": "resume voice broadcast",
|
||||
"pause voice broadcast": "pause voice broadcast",
|
||||
"30s backward": "30s backward",
|
||||
"30s forward": "30s forward",
|
||||
"Go live": "Go live",
|
||||
"Live": "Live",
|
||||
"Voice broadcast": "Voice broadcast",
|
||||
|
|
39
src/voice-broadcast/components/atoms/SeekButton.tsx
Normal file
39
src/voice-broadcast/components/atoms/SeekButton.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import AccessibleButton from "../../../components/views/elements/AccessibleButton";
|
||||
|
||||
interface Props {
|
||||
icon: React.FC<React.SVGProps<SVGSVGElement>>;
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export const SeekButton: React.FC<Props> = ({
|
||||
onClick,
|
||||
icon: Icon,
|
||||
label,
|
||||
}) => {
|
||||
return <AccessibleButton
|
||||
kind="secondary_content"
|
||||
onClick={onClick}
|
||||
aria-label={label}
|
||||
>
|
||||
<Icon className="mx_Icon mx_Icon_24" />
|
||||
</AccessibleButton>;
|
||||
};
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ReactElement } from "react";
|
||||
|
||||
import {
|
||||
VoiceBroadcastControl,
|
||||
|
@ -26,9 +26,14 @@ import Spinner from "../../../components/views/elements/Spinner";
|
|||
import { useVoiceBroadcastPlayback } from "../../hooks/useVoiceBroadcastPlayback";
|
||||
import { Icon as PlayIcon } from "../../../../res/img/element-icons/play.svg";
|
||||
import { Icon as PauseIcon } from "../../../../res/img/element-icons/pause.svg";
|
||||
import { Icon as Back30sIcon } from "../../../../res/img/element-icons/Back30s.svg";
|
||||
import { Icon as Forward30sIcon } from "../../../../res/img/element-icons/Forward30s.svg";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Clock from "../../../components/views/audio_messages/Clock";
|
||||
import SeekBar from "../../../components/views/audio_messages/SeekBar";
|
||||
import { SeekButton } from "../atoms/SeekButton";
|
||||
|
||||
const SEEK_TIME = 30;
|
||||
|
||||
interface VoiceBroadcastPlaybackBodyProps {
|
||||
playback: VoiceBroadcastPlayback;
|
||||
|
@ -40,10 +45,11 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
|
|||
const {
|
||||
duration,
|
||||
liveness,
|
||||
playbackState,
|
||||
position,
|
||||
room,
|
||||
sender,
|
||||
toggle,
|
||||
playbackState,
|
||||
} = useVoiceBroadcastPlayback(playback);
|
||||
|
||||
let control: React.ReactNode;
|
||||
|
@ -76,6 +82,31 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
|
|||
/>;
|
||||
}
|
||||
|
||||
let seekBackwardButton: ReactElement | null = null;
|
||||
let seekForwardButton: ReactElement | null = null;
|
||||
|
||||
if (playbackState !== VoiceBroadcastPlaybackState.Stopped) {
|
||||
const onSeekBackwardButtonClick = () => {
|
||||
playback.skipTo(Math.max(0, position - SEEK_TIME));
|
||||
};
|
||||
|
||||
seekBackwardButton = <SeekButton
|
||||
icon={Back30sIcon}
|
||||
label={_t("30s backward")}
|
||||
onClick={onSeekBackwardButtonClick}
|
||||
/>;
|
||||
|
||||
const onSeekForwardButtonClick = () => {
|
||||
playback.skipTo(Math.min(duration, position + SEEK_TIME));
|
||||
};
|
||||
|
||||
seekForwardButton = <SeekButton
|
||||
icon={Forward30sIcon}
|
||||
label={_t("30s forward")}
|
||||
onClick={onSeekForwardButtonClick}
|
||||
/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_VoiceBroadcastBody">
|
||||
<VoiceBroadcastHeader
|
||||
|
@ -85,7 +116,9 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
|
|||
showBroadcast={true}
|
||||
/>
|
||||
<div className="mx_VoiceBroadcastBody_controls">
|
||||
{ seekBackwardButton }
|
||||
{ control }
|
||||
{ seekForwardButton }
|
||||
</div>
|
||||
<div className="mx_VoiceBroadcastBody_timerow">
|
||||
<SeekBar playback={playback} />
|
||||
|
|
|
@ -47,6 +47,13 @@ export const useVoiceBroadcastPlayback = (playback: VoiceBroadcastPlayback) => {
|
|||
d => setDuration(d / 1000),
|
||||
);
|
||||
|
||||
const [position, setPosition] = useState(playback.timeSeconds);
|
||||
useTypedEventEmitter(
|
||||
playback,
|
||||
VoiceBroadcastPlaybackEvent.PositionChanged,
|
||||
p => setPosition(p / 1000),
|
||||
);
|
||||
|
||||
const [liveness, setLiveness] = useState(playback.getLiveness());
|
||||
useTypedEventEmitter(
|
||||
playback,
|
||||
|
@ -57,9 +64,10 @@ export const useVoiceBroadcastPlayback = (playback: VoiceBroadcastPlayback) => {
|
|||
return {
|
||||
duration,
|
||||
liveness: liveness,
|
||||
playbackState,
|
||||
position,
|
||||
room: room,
|
||||
sender: playback.infoEvent.sender,
|
||||
toggle: playbackToggle,
|
||||
playbackState,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { act, render, RenderResult } from "@testing-library/react";
|
||||
import { act, render, RenderResult, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
|
@ -54,7 +54,7 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
|
||||
infoEvent = mkVoiceBroadcastInfoStateEvent(
|
||||
roomId,
|
||||
VoiceBroadcastInfoState.Started,
|
||||
VoiceBroadcastInfoState.Stopped,
|
||||
userId,
|
||||
client.getDeviceId(),
|
||||
);
|
||||
|
@ -65,6 +65,7 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
jest.spyOn(playback, "toggle").mockImplementation(() => Promise.resolve());
|
||||
jest.spyOn(playback, "getLiveness");
|
||||
jest.spyOn(playback, "getState");
|
||||
jest.spyOn(playback, "skipTo");
|
||||
jest.spyOn(playback, "durationSeconds", "get").mockReturnValue(23 * 60 + 42); // 23:42
|
||||
});
|
||||
|
||||
|
@ -80,6 +81,50 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("when rendering a playing broadcast", () => {
|
||||
beforeEach(() => {
|
||||
mocked(playback.getState).mockReturnValue(VoiceBroadcastPlaybackState.Playing);
|
||||
mocked(playback.getLiveness).mockReturnValue("not-live");
|
||||
renderResult = render(<VoiceBroadcastPlaybackBody playback={playback} />);
|
||||
});
|
||||
|
||||
it("should render as expected", () => {
|
||||
expect(renderResult.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe("and being in the middle of the playback", () => {
|
||||
beforeEach(() => {
|
||||
act(() => {
|
||||
playback.emit(VoiceBroadcastPlaybackEvent.PositionChanged, 10 * 60 * 1000); // 10:00
|
||||
});
|
||||
});
|
||||
|
||||
describe("and clicking 30s backward", () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
await userEvent.click(screen.getByLabelText("30s backward"));
|
||||
});
|
||||
});
|
||||
|
||||
it("should seek 30s backward", () => {
|
||||
expect(playback.skipTo).toHaveBeenCalledWith(9 * 60 + 30);
|
||||
});
|
||||
});
|
||||
|
||||
describe("and clicking 30s forward", () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
await userEvent.click(screen.getByLabelText("30s forward"));
|
||||
});
|
||||
});
|
||||
|
||||
it("should seek 30s forward", () => {
|
||||
expect(playback.skipTo).toHaveBeenCalledWith(10 * 60 + 30);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(`when rendering a stopped broadcast`, () => {
|
||||
beforeEach(() => {
|
||||
mocked(playback.getState).mockReturnValue(VoiceBroadcastPlaybackState.Stopped);
|
||||
|
@ -87,6 +132,10 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
renderResult = render(<VoiceBroadcastPlaybackBody playback={playback} />);
|
||||
});
|
||||
|
||||
it("should render as expected", () => {
|
||||
expect(renderResult.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe("and clicking the play button", () => {
|
||||
beforeEach(async () => {
|
||||
await userEvent.click(renderResult.getByLabelText("play voice broadcast"));
|
||||
|
@ -104,8 +153,8 @@ describe("VoiceBroadcastPlaybackBody", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("should render as expected", () => {
|
||||
expect(renderResult.container).toMatchSnapshot();
|
||||
it("should render the new length", async () => {
|
||||
expect(await screen.findByText("00:42")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -45,6 +45,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a 0/not-live broadcast should
|
|||
<div
|
||||
class="mx_VoiceBroadcastBody_controls"
|
||||
>
|
||||
<div
|
||||
aria-label="30s backward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="resume voice broadcast"
|
||||
class="mx_AccessibleButton mx_VoiceBroadcastControl"
|
||||
|
@ -55,6 +65,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a 0/not-live broadcast should
|
|||
class="mx_Icon mx_Icon_16"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="30s forward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody_timerow"
|
||||
|
@ -132,6 +152,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a 1/live broadcast should ren
|
|||
<div
|
||||
class="mx_VoiceBroadcastBody_controls"
|
||||
>
|
||||
<div
|
||||
aria-label="30s backward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="pause voice broadcast"
|
||||
class="mx_AccessibleButton mx_VoiceBroadcastControl"
|
||||
|
@ -142,6 +172,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a 1/live broadcast should ren
|
|||
class="mx_Icon mx_Icon_16"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="30s forward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody_timerow"
|
||||
|
@ -219,6 +259,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
|
|||
<div
|
||||
class="mx_VoiceBroadcastBody_controls"
|
||||
>
|
||||
<div
|
||||
aria-label="30s backward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Spinner"
|
||||
>
|
||||
|
@ -230,6 +280,16 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
|
|||
style="width: 32px; height: 32px;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="30s forward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody_timerow"
|
||||
|
@ -254,7 +314,106 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`VoiceBroadcastPlaybackBody when rendering a stopped broadcast and the length updated should render as expected 1`] = `
|
||||
exports[`VoiceBroadcastPlaybackBody when rendering a playing broadcast should render as expected 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody"
|
||||
>
|
||||
<div
|
||||
class="mx_VoiceBroadcastHeader"
|
||||
>
|
||||
<div
|
||||
data-testid="room-avatar"
|
||||
>
|
||||
room avatar:
|
||||
My room
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastHeader_content"
|
||||
>
|
||||
<div
|
||||
class="mx_VoiceBroadcastHeader_room"
|
||||
>
|
||||
My room
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastHeader_line"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_16"
|
||||
/>
|
||||
<span>
|
||||
@user:example.com
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastHeader_line"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_16"
|
||||
/>
|
||||
Voice broadcast
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody_controls"
|
||||
>
|
||||
<div
|
||||
aria-label="30s backward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="pause voice broadcast"
|
||||
class="mx_AccessibleButton mx_VoiceBroadcastControl"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_16"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="30s forward"
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_secondary_content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Icon mx_Icon_24"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody_timerow"
|
||||
>
|
||||
<input
|
||||
class="mx_SeekBar"
|
||||
max="1"
|
||||
min="0"
|
||||
step="0.001"
|
||||
style="--fillTo: 0;"
|
||||
tabindex="0"
|
||||
type="range"
|
||||
value="0"
|
||||
/>
|
||||
<span
|
||||
class="mx_Clock"
|
||||
>
|
||||
23:42
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`VoiceBroadcastPlaybackBody when rendering a stopped broadcast should render as expected 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mx_VoiceBroadcastBody"
|
||||
|
@ -326,7 +485,7 @@ exports[`VoiceBroadcastPlaybackBody when rendering a stopped broadcast and the l
|
|||
<span
|
||||
class="mx_Clock"
|
||||
>
|
||||
00:42
|
||||
23:42
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue