Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit fcc49d0

Browse files
[Backport staging] Update Voice Broadcast buffering style (#9660)
Co-authored-by: Michael Weimann <[email protected]>
1 parent f4b6719 commit fcc49d0

File tree

8 files changed

+164
-61
lines changed

8 files changed

+164
-61
lines changed

res/css/voice-broadcast/atoms/_VoiceBroadcastHeader.pcss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ limitations under the License.
4040
display: flex;
4141
gap: $spacing-4;
4242

43-
i {
44-
flex-shrink: 0;
43+
.mx_Spinner {
44+
flex: 0 0 14px;
45+
padding: 1px;
4546
}
4647

4748
span {

src/i18n/strings/en_EN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@
657657
"Change input device": "Change input device",
658658
"Live": "Live",
659659
"Voice broadcast": "Voice broadcast",
660+
"Buffering…": "Buffering…",
660661
"Cannot reach homeserver": "Cannot reach homeserver",
661662
"Ensure you have a stable internet connection, or get in touch with the server admin": "Ensure you have a stable internet connection, or get in touch with the server admin",
662663
"Your %(brand)s is misconfigured": "Your %(brand)s is misconfigured",

src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import AccessibleButton from "../../../components/views/elements/AccessibleButto
2525
import { Icon as XIcon } from "../../../../res/img/element-icons/cancel-rounded.svg";
2626
import Clock from "../../../components/views/audio_messages/Clock";
2727
import { formatTimeLeft } from "../../../DateUtils";
28+
import Spinner from "../../../components/views/elements/Spinner";
2829

2930
interface VoiceBroadcastHeaderProps {
3031
live?: VoiceBroadcastLiveness;
@@ -33,6 +34,7 @@ interface VoiceBroadcastHeaderProps {
3334
room: Room;
3435
microphoneLabel?: string;
3536
showBroadcast?: boolean;
37+
showBuffering?: boolean;
3638
timeLeft?: number;
3739
showClose?: boolean;
3840
}
@@ -44,47 +46,55 @@ export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
4446
room,
4547
microphoneLabel,
4648
showBroadcast = false,
49+
showBuffering = false,
4750
showClose = false,
4851
timeLeft,
4952
}) => {
50-
const broadcast = showBroadcast
51-
? <div className="mx_VoiceBroadcastHeader_line">
53+
const broadcast = showBroadcast && (
54+
<div className="mx_VoiceBroadcastHeader_line">
5255
<LiveIcon className="mx_Icon mx_Icon_16" />
5356
{ _t("Voice broadcast") }
5457
</div>
55-
: null;
58+
);
5659

57-
const liveBadge = live === "not-live"
58-
? null
59-
: <LiveBadge grey={live === "grey"} />;
60+
const liveBadge = live !== "not-live" && (
61+
<LiveBadge grey={live === "grey"} />
62+
);
6063

61-
const closeButton = showClose
62-
? <AccessibleButton onClick={onCloseClick}>
64+
const closeButton = showClose && (
65+
<AccessibleButton onClick={onCloseClick}>
6366
<XIcon className="mx_Icon mx_Icon_16" />
6467
</AccessibleButton>
65-
: null;
68+
);
6669

67-
const timeLeftLine = timeLeft
68-
? <div className="mx_VoiceBroadcastHeader_line">
70+
const timeLeftLine = timeLeft && (
71+
<div className="mx_VoiceBroadcastHeader_line">
6972
<TimerIcon className="mx_Icon mx_Icon_16" />
7073
<Clock formatFn={formatTimeLeft} seconds={timeLeft} />
7174
</div>
72-
: null;
75+
);
76+
77+
const buffering = showBuffering && (
78+
<div className="mx_VoiceBroadcastHeader_line">
79+
<Spinner w={14} h={14} />
80+
{ _t("Buffering…") }
81+
</div>
82+
);
7383

7484
const microphoneLineClasses = classNames({
7585
mx_VoiceBroadcastHeader_line: true,
7686
["mx_VoiceBroadcastHeader_mic--clickable"]: onMicrophoneLineClick,
7787
});
7888

79-
const microphoneLine = microphoneLabel
80-
? <div
89+
const microphoneLine = microphoneLabel && (
90+
<div
8191
className={microphoneLineClasses}
8292
onClick={onMicrophoneLineClick}
8393
>
8494
<MicrophoneIcon className="mx_Icon mx_Icon_16" />
8595
<span>{ microphoneLabel }</span>
8696
</div>
87-
: null;
97+
);
8898

8999
return <div className="mx_VoiceBroadcastHeader">
90100
<RoomAvatar room={room} width={32} height={32} />
@@ -95,6 +105,7 @@ export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
95105
{ microphoneLine }
96106
{ timeLeftLine }
97107
{ broadcast }
108+
{ buffering }
98109
</div>
99110
{ liveBadge }
100111
{ closeButton }

src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
VoiceBroadcastPlayback,
2424
VoiceBroadcastPlaybackState,
2525
} from "../..";
26-
import Spinner from "../../../components/views/elements/Spinner";
2726
import { useVoiceBroadcastPlayback } from "../../hooks/useVoiceBroadcastPlayback";
2827
import { Icon as PlayIcon } from "../../../../res/img/element-icons/play.svg";
2928
import { Icon as PauseIcon } from "../../../../res/img/element-icons/pause.svg";
@@ -55,40 +54,35 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
5554
toggle,
5655
} = useVoiceBroadcastPlayback(playback);
5756

58-
let control: React.ReactNode;
59-
60-
if (playbackState === VoiceBroadcastPlaybackState.Buffering) {
61-
control = <Spinner />;
62-
} else {
63-
let controlIcon: React.FC<React.SVGProps<SVGSVGElement>>;
64-
let controlLabel: string;
65-
let className = "";
66-
67-
switch (playbackState) {
68-
case VoiceBroadcastPlaybackState.Stopped:
69-
controlIcon = PlayIcon;
70-
className = "mx_VoiceBroadcastControl-play";
71-
controlLabel = _t("play voice broadcast");
72-
break;
73-
case VoiceBroadcastPlaybackState.Paused:
74-
controlIcon = PlayIcon;
75-
className = "mx_VoiceBroadcastControl-play";
76-
controlLabel = _t("resume voice broadcast");
77-
break;
78-
case VoiceBroadcastPlaybackState.Playing:
79-
controlIcon = PauseIcon;
80-
controlLabel = _t("pause voice broadcast");
81-
break;
82-
}
83-
84-
control = <VoiceBroadcastControl
85-
className={className}
86-
label={controlLabel}
87-
icon={controlIcon}
88-
onClick={toggle}
89-
/>;
57+
let controlIcon: React.FC<React.SVGProps<SVGSVGElement>>;
58+
let controlLabel: string;
59+
let className = "";
60+
61+
switch (playbackState) {
62+
case VoiceBroadcastPlaybackState.Stopped:
63+
controlIcon = PlayIcon;
64+
className = "mx_VoiceBroadcastControl-play";
65+
controlLabel = _t("play voice broadcast");
66+
break;
67+
case VoiceBroadcastPlaybackState.Paused:
68+
controlIcon = PlayIcon;
69+
className = "mx_VoiceBroadcastControl-play";
70+
controlLabel = _t("resume voice broadcast");
71+
break;
72+
case VoiceBroadcastPlaybackState.Buffering:
73+
case VoiceBroadcastPlaybackState.Playing:
74+
controlIcon = PauseIcon;
75+
controlLabel = _t("pause voice broadcast");
76+
break;
9077
}
9178

79+
const control = <VoiceBroadcastControl
80+
className={className}
81+
label={controlLabel}
82+
icon={controlIcon}
83+
onClick={toggle}
84+
/>;
85+
9286
let seekBackwardButton: ReactElement | null = null;
9387
let seekForwardButton: ReactElement | null = null;
9488

@@ -125,7 +119,8 @@ export const VoiceBroadcastPlaybackBody: React.FC<VoiceBroadcastPlaybackBodyProp
125119
live={liveness}
126120
microphoneLabel={sender?.name}
127121
room={room}
128-
showBroadcast={true}
122+
showBroadcast={playbackState !== VoiceBroadcastPlaybackState.Buffering}
123+
showBuffering={playbackState === VoiceBroadcastPlaybackState.Buffering}
129124
/>
130125
<div className="mx_VoiceBroadcastBody_controls">
131126
{ seekBackwardButton }

src/voice-broadcast/hooks/useVoiceBroadcastPlayback.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ import {
2727
export const useVoiceBroadcastPlayback = (playback: VoiceBroadcastPlayback) => {
2828
const client = MatrixClientPeg.get();
2929
const room = client.getRoom(playback.infoEvent.getRoomId());
30+
31+
if (!room) {
32+
throw new Error(
33+
`Voice Broadcast room not found (event ${playback.infoEvent.getId()})`,
34+
);
35+
}
36+
3037
const playbackToggle = () => {
3138
playback.toggle();
3239
};

test/voice-broadcast/components/atoms/VoiceBroadcastHeader-test.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ describe("VoiceBroadcastHeader", () => {
3535
const sender = new RoomMember(roomId, userId);
3636
let container: Container;
3737

38-
const renderHeader = (live: VoiceBroadcastLiveness, showBroadcast: boolean = undefined): RenderResult => {
38+
const renderHeader = (
39+
live: VoiceBroadcastLiveness,
40+
showBroadcast?: boolean,
41+
buffering?: boolean,
42+
): RenderResult => {
3943
return render(<VoiceBroadcastHeader
4044
live={live}
4145
microphoneLabel={sender.name}
4246
room={room}
4347
showBroadcast={showBroadcast}
48+
showBuffering={buffering}
4449
/>);
4550
};
4651

@@ -51,6 +56,16 @@ describe("VoiceBroadcastHeader", () => {
5156
});
5257

5358
describe("when rendering a live broadcast header with broadcast info", () => {
59+
beforeEach(() => {
60+
container = renderHeader("live", true, true).container;
61+
});
62+
63+
it("should render the header with a red live badge", () => {
64+
expect(container).toMatchSnapshot();
65+
});
66+
});
67+
68+
describe("when rendering a buffering live broadcast header with broadcast info", () => {
5469
beforeEach(() => {
5570
container = renderHeader("live", true).container;
5671
});

test/voice-broadcast/components/atoms/__snapshots__/VoiceBroadcastHeader-test.tsx.snap

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`VoiceBroadcastHeader when rendering a buffering live broadcast header with broadcast info should render the header with a red live badge 1`] = `
4+
<div>
5+
<div
6+
class="mx_VoiceBroadcastHeader"
7+
>
8+
<div
9+
data-testid="room-avatar"
10+
>
11+
room avatar:
12+
!room:example.com
13+
</div>
14+
<div
15+
class="mx_VoiceBroadcastHeader_content"
16+
>
17+
<div
18+
class="mx_VoiceBroadcastHeader_room"
19+
>
20+
!room:example.com
21+
</div>
22+
<div
23+
class="mx_VoiceBroadcastHeader_line"
24+
>
25+
<div
26+
class="mx_Icon mx_Icon_16"
27+
/>
28+
<span>
29+
test user
30+
</span>
31+
</div>
32+
<div
33+
class="mx_VoiceBroadcastHeader_line"
34+
>
35+
<div
36+
class="mx_Icon mx_Icon_16"
37+
/>
38+
Voice broadcast
39+
</div>
40+
</div>
41+
<div
42+
class="mx_LiveBadge"
43+
>
44+
<div
45+
class="mx_Icon mx_Icon_16"
46+
/>
47+
Live
48+
</div>
49+
</div>
50+
</div>
51+
`;
52+
353
exports[`VoiceBroadcastHeader when rendering a live (grey) broadcast header with broadcast info should render the header with a grey live badge 1`] = `
454
<div>
555
<div
@@ -87,6 +137,22 @@ exports[`VoiceBroadcastHeader when rendering a live broadcast header with broadc
87137
/>
88138
Voice broadcast
89139
</div>
140+
<div
141+
class="mx_VoiceBroadcastHeader_line"
142+
>
143+
<div
144+
class="mx_Spinner"
145+
>
146+
<div
147+
aria-label="Loading..."
148+
class="mx_Spinner_icon"
149+
data-testid="spinner"
150+
role="progressbar"
151+
style="width: 14px; height: 14px;"
152+
/>
153+
</div>
154+
Buffering…
155+
</div>
90156
</div>
91157
<div
92158
class="mx_LiveBadge"

test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastPlaybackBody-test.tsx.snap

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,17 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
242242
class="mx_VoiceBroadcastHeader_line"
243243
>
244244
<div
245-
class="mx_Icon mx_Icon_16"
246-
/>
247-
Voice broadcast
245+
class="mx_Spinner"
246+
>
247+
<div
248+
aria-label="Loading..."
249+
class="mx_Spinner_icon"
250+
data-testid="spinner"
251+
role="progressbar"
252+
style="width: 14px; height: 14px;"
253+
/>
254+
</div>
255+
Buffering…
248256
</div>
249257
</div>
250258
<div
@@ -270,14 +278,13 @@ exports[`VoiceBroadcastPlaybackBody when rendering a buffering voice broadcast s
270278
/>
271279
</div>
272280
<div
273-
class="mx_Spinner"
281+
aria-label="pause voice broadcast"
282+
class="mx_AccessibleButton mx_VoiceBroadcastControl"
283+
role="button"
284+
tabindex="0"
274285
>
275286
<div
276-
aria-label="Loading..."
277-
class="mx_Spinner_icon"
278-
data-testid="spinner"
279-
role="progressbar"
280-
style="width: 32px; height: 32px;"
287+
class="mx_Icon mx_Icon_16"
281288
/>
282289
</div>
283290
<div

0 commit comments

Comments
 (0)