Display info dialogs if unable to start voice broadcasts (#9453)
parent
3c3df11d32
commit
bb0c175b7e
|
@ -113,7 +113,6 @@ import { isLocalRoom } from '../../utils/localRoom/isLocalRoom';
|
||||||
import { ShowThreadPayload } from "../../dispatcher/payloads/ShowThreadPayload";
|
import { ShowThreadPayload } from "../../dispatcher/payloads/ShowThreadPayload";
|
||||||
import { RoomStatusBarUnsentMessages } from './RoomStatusBarUnsentMessages';
|
import { RoomStatusBarUnsentMessages } from './RoomStatusBarUnsentMessages';
|
||||||
import { LargeLoader } from './LargeLoader';
|
import { LargeLoader } from './LargeLoader';
|
||||||
import { VoiceBroadcastInfoEventType } from '../../voice-broadcast';
|
|
||||||
import { isVideoRoom } from '../../utils/video-rooms';
|
import { isVideoRoom } from '../../utils/video-rooms';
|
||||||
import { SDKContext } from '../../contexts/SDKContext';
|
import { SDKContext } from '../../contexts/SDKContext';
|
||||||
import { CallStore, CallStoreEvent } from "../../stores/CallStore";
|
import { CallStore, CallStoreEvent } from "../../stores/CallStore";
|
||||||
|
@ -199,7 +198,6 @@ export interface IRoomState {
|
||||||
upgradeRecommendation?: IRecommendedVersion;
|
upgradeRecommendation?: IRecommendedVersion;
|
||||||
canReact: boolean;
|
canReact: boolean;
|
||||||
canSendMessages: boolean;
|
canSendMessages: boolean;
|
||||||
canSendVoiceBroadcasts: boolean;
|
|
||||||
tombstone?: MatrixEvent;
|
tombstone?: MatrixEvent;
|
||||||
resizing: boolean;
|
resizing: boolean;
|
||||||
layout: Layout;
|
layout: Layout;
|
||||||
|
@ -404,7 +402,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
statusBarVisible: false,
|
statusBarVisible: false,
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
resizing: false,
|
resizing: false,
|
||||||
layout: SettingsStore.getValue("layout"),
|
layout: SettingsStore.getValue("layout"),
|
||||||
lowBandwidth: SettingsStore.getValue("lowBandwidth"),
|
lowBandwidth: SettingsStore.getValue("lowBandwidth"),
|
||||||
|
@ -1377,12 +1374,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
);
|
);
|
||||||
const canSendMessages = room.maySendMessage();
|
const canSendMessages = room.maySendMessage();
|
||||||
const canSelfRedact = room.currentState.maySendEvent(EventType.RoomRedaction, me);
|
const canSelfRedact = room.currentState.maySendEvent(EventType.RoomRedaction, me);
|
||||||
const canSendVoiceBroadcasts = room.currentState.maySendEvent(VoiceBroadcastInfoEventType, me);
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
canReact,
|
canReact,
|
||||||
canSendMessages,
|
canSendMessages,
|
||||||
canSendVoiceBroadcasts,
|
|
||||||
canSelfRedact,
|
canSelfRedact,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2253,7 +2248,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
replyToEvent={this.state.replyToEvent}
|
replyToEvent={this.state.replyToEvent}
|
||||||
permalinkCreator={this.permalinkCreator}
|
permalinkCreator={this.permalinkCreator}
|
||||||
showVoiceBroadcastButton={this.state.canSendVoiceBroadcasts}
|
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@ interface IProps {
|
||||||
relation?: IEventRelation;
|
relation?: IEventRelation;
|
||||||
e2eStatus?: E2EStatus;
|
e2eStatus?: E2EStatus;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
showVoiceBroadcastButton?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -384,10 +383,6 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
return this.state.showStickersButton && !isLocalRoom(this.props.room);
|
return this.state.showStickersButton && !isLocalRoom(this.props.room);
|
||||||
}
|
}
|
||||||
|
|
||||||
private get showVoiceBroadcastButton(): boolean {
|
|
||||||
return this.props.showVoiceBroadcastButton && this.state.showVoiceBroadcastButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const isWysiwygComposerEnabled = SettingsStore.getValue("feature_wysiwyg_composer");
|
const isWysiwygComposerEnabled = SettingsStore.getValue("feature_wysiwyg_composer");
|
||||||
const controls = [
|
const controls = [
|
||||||
|
@ -532,10 +527,10 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
showPollsButton={this.state.showPollsButton}
|
showPollsButton={this.state.showPollsButton}
|
||||||
showStickersButton={this.showStickersButton}
|
showStickersButton={this.showStickersButton}
|
||||||
toggleButtonMenu={this.toggleButtonMenu}
|
toggleButtonMenu={this.toggleButtonMenu}
|
||||||
showVoiceBroadcastButton={this.showVoiceBroadcastButton}
|
showVoiceBroadcastButton={this.state.showVoiceBroadcastButton}
|
||||||
onStartVoiceBroadcastClick={() => {
|
onStartVoiceBroadcastClick={() => {
|
||||||
startNewVoiceBroadcastRecording(
|
startNewVoiceBroadcastRecording(
|
||||||
this.props.room.roomId,
|
this.props.room,
|
||||||
MatrixClientPeg.get(),
|
MatrixClientPeg.get(),
|
||||||
VoiceBroadcastRecordingsStore.instance(),
|
VoiceBroadcastRecordingsStore.instance(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -45,7 +45,6 @@ const RoomContext = createContext<IRoomState>({
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSelfRedact: false,
|
canSelfRedact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
resizing: false,
|
resizing: false,
|
||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
lowBandwidth: false,
|
lowBandwidth: false,
|
||||||
|
|
|
@ -637,6 +637,10 @@
|
||||||
"Send <b>%(msgtype)s</b> messages as you in your active room": "Send <b>%(msgtype)s</b> messages as you in your active room",
|
"Send <b>%(msgtype)s</b> messages as you in your active room": "Send <b>%(msgtype)s</b> messages as you in your active room",
|
||||||
"See <b>%(msgtype)s</b> messages posted to this room": "See <b>%(msgtype)s</b> messages posted to this room",
|
"See <b>%(msgtype)s</b> messages posted to this room": "See <b>%(msgtype)s</b> messages posted to this room",
|
||||||
"See <b>%(msgtype)s</b> messages posted to your active room": "See <b>%(msgtype)s</b> messages posted to your active room",
|
"See <b>%(msgtype)s</b> messages posted to your active room": "See <b>%(msgtype)s</b> messages posted to your active room",
|
||||||
|
"Can't start a new voice broadcast": "Can't start a new voice broadcast",
|
||||||
|
"You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.": "You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.",
|
||||||
|
"You don't have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.": "You don't have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.",
|
||||||
|
"Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.": "Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.",
|
||||||
"Stop live broadcasting?": "Stop live broadcasting?",
|
"Stop live broadcasting?": "Stop live broadcasting?",
|
||||||
"Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.": "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.",
|
"Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.": "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.",
|
||||||
"Yes, stop broadcast": "Yes, stop broadcast",
|
"Yes, stop broadcast": "Yes, stop broadcast",
|
||||||
|
|
|
@ -35,6 +35,7 @@ export * from "./components/molecules/VoiceBroadcastRecordingPip";
|
||||||
export * from "./hooks/useVoiceBroadcastRecording";
|
export * from "./hooks/useVoiceBroadcastRecording";
|
||||||
export * from "./stores/VoiceBroadcastPlaybacksStore";
|
export * from "./stores/VoiceBroadcastPlaybacksStore";
|
||||||
export * from "./stores/VoiceBroadcastRecordingsStore";
|
export * from "./stores/VoiceBroadcastRecordingsStore";
|
||||||
|
export * from "./utils/hasRoomLiveVoiceBroadcast";
|
||||||
export * from "./utils/shouldDisplayAsVoiceBroadcastRecordingTile";
|
export * from "./utils/shouldDisplayAsVoiceBroadcastRecordingTile";
|
||||||
export * from "./utils/shouldDisplayAsVoiceBroadcastTile";
|
export * from "./utils/shouldDisplayAsVoiceBroadcastTile";
|
||||||
export * from "./utils/startNewVoiceBroadcastRecording";
|
export * from "./utils/startNewVoiceBroadcastRecording";
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
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 { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
|
import { VoiceBroadcastInfoEventType, VoiceBroadcastInfoState } from "..";
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
hasBroadcast: boolean;
|
||||||
|
startedByUser: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds out whether there is a live broadcast in a room.
|
||||||
|
* Also returns if the user started the broadcast (if any).
|
||||||
|
*/
|
||||||
|
export const hasRoomLiveVoiceBroadcast = (room: Room, userId: string): Result => {
|
||||||
|
let hasBroadcast = false;
|
||||||
|
let startedByUser = false;
|
||||||
|
|
||||||
|
const stateEvents = room.currentState.getStateEvents(VoiceBroadcastInfoEventType);
|
||||||
|
stateEvents.forEach((event: MatrixEvent) => {
|
||||||
|
const state = event.getContent()?.state;
|
||||||
|
|
||||||
|
if (state && state !== VoiceBroadcastInfoState.Stopped) {
|
||||||
|
hasBroadcast = true;
|
||||||
|
|
||||||
|
// state key = sender's MXID
|
||||||
|
if (event.getStateKey() === userId) {
|
||||||
|
startedByUser = true;
|
||||||
|
// break here, because more than true / true is not possible
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasBroadcast,
|
||||||
|
startedByUser,
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
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 { ISendEventResponse, MatrixClient, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
|
||||||
import { defer } from "matrix-js-sdk/src/utils";
|
|
||||||
|
|
||||||
import {
|
|
||||||
VoiceBroadcastInfoEventContent,
|
|
||||||
VoiceBroadcastInfoEventType,
|
|
||||||
VoiceBroadcastInfoState,
|
|
||||||
VoiceBroadcastRecordingsStore,
|
|
||||||
VoiceBroadcastRecording,
|
|
||||||
} from "..";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a new Voice Broadcast Recording.
|
|
||||||
* Sends a voice_broadcast_info state event and waits for the event to actually appear in the room state.
|
|
||||||
*/
|
|
||||||
export const startNewVoiceBroadcastRecording = async (
|
|
||||||
roomId: string,
|
|
||||||
client: MatrixClient,
|
|
||||||
recordingsStore: VoiceBroadcastRecordingsStore,
|
|
||||||
): Promise<VoiceBroadcastRecording> => {
|
|
||||||
const room = client.getRoom(roomId);
|
|
||||||
const { promise, resolve } = defer<VoiceBroadcastRecording>();
|
|
||||||
let result: ISendEventResponse = null;
|
|
||||||
|
|
||||||
const onRoomStateEvents = () => {
|
|
||||||
if (!result) return;
|
|
||||||
|
|
||||||
const voiceBroadcastEvent = room.currentState.getStateEvents(
|
|
||||||
VoiceBroadcastInfoEventType,
|
|
||||||
client.getUserId(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (voiceBroadcastEvent?.getId() === result.event_id) {
|
|
||||||
room.off(RoomStateEvent.Events, onRoomStateEvents);
|
|
||||||
const recording = new VoiceBroadcastRecording(
|
|
||||||
voiceBroadcastEvent,
|
|
||||||
client,
|
|
||||||
);
|
|
||||||
recordingsStore.setCurrent(recording);
|
|
||||||
recording.start();
|
|
||||||
resolve(recording);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
room.on(RoomStateEvent.Events, onRoomStateEvents);
|
|
||||||
|
|
||||||
// XXX Michael W: refactor to live event
|
|
||||||
result = await client.sendStateEvent(
|
|
||||||
roomId,
|
|
||||||
VoiceBroadcastInfoEventType,
|
|
||||||
{
|
|
||||||
device_id: client.getDeviceId(),
|
|
||||||
state: VoiceBroadcastInfoState.Started,
|
|
||||||
chunk_length: 300,
|
|
||||||
} as VoiceBroadcastInfoEventContent,
|
|
||||||
client.getUserId(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
};
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
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 { ISendEventResponse, MatrixClient, Room, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
||||||
|
import { defer } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
|
import { _t } from "../../languageHandler";
|
||||||
|
import InfoDialog from "../../components/views/dialogs/InfoDialog";
|
||||||
|
import Modal from "../../Modal";
|
||||||
|
import {
|
||||||
|
VoiceBroadcastInfoEventContent,
|
||||||
|
VoiceBroadcastInfoEventType,
|
||||||
|
VoiceBroadcastInfoState,
|
||||||
|
VoiceBroadcastRecordingsStore,
|
||||||
|
VoiceBroadcastRecording,
|
||||||
|
hasRoomLiveVoiceBroadcast,
|
||||||
|
} from "..";
|
||||||
|
|
||||||
|
const startBroadcast = async (
|
||||||
|
room: Room,
|
||||||
|
client: MatrixClient,
|
||||||
|
recordingsStore: VoiceBroadcastRecordingsStore,
|
||||||
|
): Promise<VoiceBroadcastRecording> => {
|
||||||
|
const { promise, resolve } = defer<VoiceBroadcastRecording>();
|
||||||
|
let result: ISendEventResponse = null;
|
||||||
|
|
||||||
|
const onRoomStateEvents = () => {
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
const voiceBroadcastEvent = room.currentState.getStateEvents(
|
||||||
|
VoiceBroadcastInfoEventType,
|
||||||
|
client.getUserId(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (voiceBroadcastEvent?.getId() === result.event_id) {
|
||||||
|
room.off(RoomStateEvent.Events, onRoomStateEvents);
|
||||||
|
const recording = new VoiceBroadcastRecording(
|
||||||
|
voiceBroadcastEvent,
|
||||||
|
client,
|
||||||
|
);
|
||||||
|
recordingsStore.setCurrent(recording);
|
||||||
|
recording.start();
|
||||||
|
resolve(recording);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
room.on(RoomStateEvent.Events, onRoomStateEvents);
|
||||||
|
|
||||||
|
// XXX Michael W: refactor to live event
|
||||||
|
result = await client.sendStateEvent(
|
||||||
|
room.roomId,
|
||||||
|
VoiceBroadcastInfoEventType,
|
||||||
|
{
|
||||||
|
device_id: client.getDeviceId(),
|
||||||
|
state: VoiceBroadcastInfoState.Started,
|
||||||
|
chunk_length: 300,
|
||||||
|
} as VoiceBroadcastInfoEventContent,
|
||||||
|
client.getUserId(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
const showAlreadyRecordingDialog = () => {
|
||||||
|
Modal.createDialog(InfoDialog, {
|
||||||
|
title: _t("Can't start a new voice broadcast"),
|
||||||
|
description: <p>{ _t("You are already recording a voice broadcast. "
|
||||||
|
+ "Please end your current voice broadcast to start a new one.") }</p>,
|
||||||
|
hasCloseButton: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const showInsufficientPermissionsDialog = () => {
|
||||||
|
Modal.createDialog(InfoDialog, {
|
||||||
|
title: _t("Can't start a new voice broadcast"),
|
||||||
|
description: <p>{ _t("You don't have the required permissions to start a voice broadcast in this room. "
|
||||||
|
+ "Contact a room administrator to upgrade your permissions.") }</p>,
|
||||||
|
hasCloseButton: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const showOthersAlreadyRecordingDialog = () => {
|
||||||
|
Modal.createDialog(InfoDialog, {
|
||||||
|
title: _t("Can't start a new voice broadcast"),
|
||||||
|
description: <p>{ _t("Someone else is already recording a voice broadcast. "
|
||||||
|
+ "Wait for their voice broadcast to end to start a new one.") }</p>,
|
||||||
|
hasCloseButton: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new Voice Broadcast Recording, if
|
||||||
|
* - the user has the permissions to do so in the room
|
||||||
|
* - there is no other broadcast being recorded in the room, yet
|
||||||
|
* Sends a voice_broadcast_info state event and waits for the event to actually appear in the room state.
|
||||||
|
*/
|
||||||
|
export const startNewVoiceBroadcastRecording = async (
|
||||||
|
room: Room,
|
||||||
|
client: MatrixClient,
|
||||||
|
recordingsStore: VoiceBroadcastRecordingsStore,
|
||||||
|
): Promise<VoiceBroadcastRecording | null> => {
|
||||||
|
const currentUserId = client.getUserId();
|
||||||
|
|
||||||
|
if (!room.currentState.maySendStateEvent(VoiceBroadcastInfoEventType, currentUserId)) {
|
||||||
|
showInsufficientPermissionsDialog();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { hasBroadcast, startedByUser } = hasRoomLiveVoiceBroadcast(room, currentUserId);
|
||||||
|
|
||||||
|
if (hasBroadcast && startedByUser) {
|
||||||
|
showAlreadyRecordingDialog();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasBroadcast) {
|
||||||
|
showOthersAlreadyRecordingDialog();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return startBroadcast(room, client, recordingsStore);
|
||||||
|
};
|
|
@ -147,7 +147,7 @@ describe("MessageComposer", () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
SettingsStore.setValue(setting, null, SettingLevel.DEVICE, value);
|
SettingsStore.setValue(setting, null, SettingLevel.DEVICE, value);
|
||||||
wrapper = wrapAndRender({ room, showVoiceBroadcastButton: true });
|
wrapper = wrapAndRender({ room });
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should pass the prop ${prop} = ${value}`, () => {
|
it(`should pass the prop ${prop} = ${value}`, () => {
|
||||||
|
@ -174,17 +174,6 @@ describe("MessageComposer", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
[false, undefined].forEach((value) => {
|
|
||||||
it(`should pass showVoiceBroadcastButton = false if the MessageComposer prop is ${value}`, () => {
|
|
||||||
SettingsStore.setValue(Features.VoiceBroadcast, null, SettingLevel.DEVICE, true);
|
|
||||||
const wrapper = wrapAndRender({
|
|
||||||
room,
|
|
||||||
showVoiceBroadcastButton: value,
|
|
||||||
});
|
|
||||||
expect(wrapper.find(MessageComposerButtons).props().showVoiceBroadcastButton).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not render the send button", () => {
|
it("should not render the send button", () => {
|
||||||
const wrapper = wrapAndRender({ room });
|
const wrapper = wrapAndRender({ room });
|
||||||
expect(wrapper.find("SendButton")).toHaveLength(0);
|
expect(wrapper.find("SendButton")).toHaveLength(0);
|
||||||
|
|
|
@ -250,7 +250,6 @@ function createRoomState(room: Room, narrow: boolean): IRoomState {
|
||||||
statusBarVisible: false,
|
statusBarVisible: false,
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
lowBandwidth: false,
|
lowBandwidth: false,
|
||||||
alwaysShowTimestamps: false,
|
alwaysShowTimestamps: false,
|
||||||
|
|
|
@ -72,7 +72,6 @@ describe('<SendMessageComposer/>', () => {
|
||||||
statusBarVisible: false,
|
statusBarVisible: false,
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
lowBandwidth: false,
|
lowBandwidth: false,
|
||||||
alwaysShowTimestamps: false,
|
alwaysShowTimestamps: false,
|
||||||
|
|
|
@ -91,7 +91,6 @@ describe('WysiwygComposer', () => {
|
||||||
statusBarVisible: false,
|
statusBarVisible: false,
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
lowBandwidth: false,
|
lowBandwidth: false,
|
||||||
alwaysShowTimestamps: false,
|
alwaysShowTimestamps: false,
|
||||||
|
|
|
@ -123,7 +123,6 @@ describe('message', () => {
|
||||||
statusBarVisible: false,
|
statusBarVisible: false,
|
||||||
canReact: false,
|
canReact: false,
|
||||||
canSendMessages: false,
|
canSendMessages: false,
|
||||||
canSendVoiceBroadcasts: false,
|
|
||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
lowBandwidth: false,
|
lowBandwidth: false,
|
||||||
alwaysShowTimestamps: false,
|
alwaysShowTimestamps: false,
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`startNewVoiceBroadcastRecording when the current user is allowed to send voice broadcast info state events when there already is a live broadcast of another user should show an info dialog 1`] = `
|
||||||
|
[MockFunction] {
|
||||||
|
"calls": Array [
|
||||||
|
Array [
|
||||||
|
[Function],
|
||||||
|
Object {
|
||||||
|
"description": <p>
|
||||||
|
Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.
|
||||||
|
</p>,
|
||||||
|
"hasCloseButton": true,
|
||||||
|
"title": "Can't start a new voice broadcast",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"results": Array [
|
||||||
|
Object {
|
||||||
|
"type": "return",
|
||||||
|
"value": undefined,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`startNewVoiceBroadcastRecording when the current user is allowed to send voice broadcast info state events when there already is a live broadcast of the current user should show an info dialog 1`] = `
|
||||||
|
[MockFunction] {
|
||||||
|
"calls": Array [
|
||||||
|
Array [
|
||||||
|
[Function],
|
||||||
|
Object {
|
||||||
|
"description": <p>
|
||||||
|
You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.
|
||||||
|
</p>,
|
||||||
|
"hasCloseButton": true,
|
||||||
|
"title": "Can't start a new voice broadcast",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"results": Array [
|
||||||
|
Object {
|
||||||
|
"type": "return",
|
||||||
|
"value": undefined,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`startNewVoiceBroadcastRecording when the current user is not allowed to send voice broadcast info state events should show an info dialog 1`] = `
|
||||||
|
[MockFunction] {
|
||||||
|
"calls": Array [
|
||||||
|
Array [
|
||||||
|
[Function],
|
||||||
|
Object {
|
||||||
|
"description": <p>
|
||||||
|
You don't have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.
|
||||||
|
</p>,
|
||||||
|
"hasCloseButton": true,
|
||||||
|
"title": "Can't start a new voice broadcast",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"results": Array [
|
||||||
|
Object {
|
||||||
|
"type": "return",
|
||||||
|
"value": undefined,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
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 { MatrixClient, Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
|
import {
|
||||||
|
hasRoomLiveVoiceBroadcast,
|
||||||
|
VoiceBroadcastInfoEventType,
|
||||||
|
VoiceBroadcastInfoState,
|
||||||
|
} from "../../../src/voice-broadcast";
|
||||||
|
import { mkEvent, stubClient } from "../../test-utils";
|
||||||
|
import { mkVoiceBroadcastInfoStateEvent } from "./test-utils";
|
||||||
|
|
||||||
|
describe("hasRoomLiveVoiceBroadcast", () => {
|
||||||
|
const otherUserId = "@other:example.com";
|
||||||
|
const roomId = "!room:example.com";
|
||||||
|
let client: MatrixClient;
|
||||||
|
let room: Room;
|
||||||
|
|
||||||
|
const addVoiceBroadcastInfoEvent = (
|
||||||
|
state: VoiceBroadcastInfoState,
|
||||||
|
sender: string,
|
||||||
|
) => {
|
||||||
|
room.currentState.setStateEvents([
|
||||||
|
mkVoiceBroadcastInfoStateEvent(room.roomId, state, sender),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const itShouldReturnTrueTrue = () => {
|
||||||
|
it("should return true/true", () => {
|
||||||
|
expect(hasRoomLiveVoiceBroadcast(room, client.getUserId())).toEqual({
|
||||||
|
hasBroadcast: true,
|
||||||
|
startedByUser: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const itShouldReturnTrueFalse = () => {
|
||||||
|
it("should return true/false", () => {
|
||||||
|
expect(hasRoomLiveVoiceBroadcast(room, client.getUserId())).toEqual({
|
||||||
|
hasBroadcast: true,
|
||||||
|
startedByUser: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const itShouldReturnFalseFalse = () => {
|
||||||
|
it("should return false/false", () => {
|
||||||
|
expect(hasRoomLiveVoiceBroadcast(room, client.getUserId())).toEqual({
|
||||||
|
hasBroadcast: false,
|
||||||
|
startedByUser: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
client = stubClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
room = new Room(roomId, client, client.getUserId());
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there is no voice broadcast info at all", () => {
|
||||||
|
itShouldReturnFalseFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when the »state« prop is missing", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
room.currentState.setStateEvents([
|
||||||
|
mkEvent({
|
||||||
|
event: true,
|
||||||
|
room: room.roomId,
|
||||||
|
user: client.getUserId(),
|
||||||
|
type: VoiceBroadcastInfoEventType,
|
||||||
|
skey: client.getUserId(),
|
||||||
|
content: {},
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
itShouldReturnFalseFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there is a live broadcast from the current and another user", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Started, client.getUserId());
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Started, otherUserId);
|
||||||
|
});
|
||||||
|
|
||||||
|
itShouldReturnTrueTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there are only stopped info events", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Stopped, client.getUserId());
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Stopped, otherUserId);
|
||||||
|
});
|
||||||
|
|
||||||
|
itShouldReturnFalseFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.each([
|
||||||
|
// all there are kind of live states
|
||||||
|
VoiceBroadcastInfoState.Started,
|
||||||
|
VoiceBroadcastInfoState.Paused,
|
||||||
|
VoiceBroadcastInfoState.Running,
|
||||||
|
])("when there is a live broadcast (%s) from the current user", (state: VoiceBroadcastInfoState) => {
|
||||||
|
beforeEach(() => {
|
||||||
|
addVoiceBroadcastInfoEvent(state, client.getUserId());
|
||||||
|
});
|
||||||
|
|
||||||
|
itShouldReturnTrueTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there was a live broadcast, that has been stopped", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Running, client.getUserId());
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Stopped, client.getUserId());
|
||||||
|
});
|
||||||
|
|
||||||
|
itShouldReturnFalseFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there is a live broadcast from another user", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
addVoiceBroadcastInfoEvent(VoiceBroadcastInfoState.Running, otherUserId);
|
||||||
|
});
|
||||||
|
|
||||||
|
itShouldReturnTrueFalse();
|
||||||
|
});
|
||||||
|
});
|
|
@ -15,8 +15,9 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mocked } from "jest-mock";
|
import { mocked } from "jest-mock";
|
||||||
import { EventType, MatrixClient, MatrixEvent, Room, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
import { EventType, MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
|
import Modal from "../../../src/Modal";
|
||||||
import {
|
import {
|
||||||
startNewVoiceBroadcastRecording,
|
startNewVoiceBroadcastRecording,
|
||||||
VoiceBroadcastInfoEventType,
|
VoiceBroadcastInfoEventType,
|
||||||
|
@ -25,46 +26,29 @@ import {
|
||||||
VoiceBroadcastRecording,
|
VoiceBroadcastRecording,
|
||||||
} from "../../../src/voice-broadcast";
|
} from "../../../src/voice-broadcast";
|
||||||
import { mkEvent, stubClient } from "../../test-utils";
|
import { mkEvent, stubClient } from "../../test-utils";
|
||||||
|
import { mkVoiceBroadcastInfoStateEvent } from "./test-utils";
|
||||||
|
|
||||||
jest.mock("../../../src/voice-broadcast/models/VoiceBroadcastRecording", () => ({
|
jest.mock("../../../src/voice-broadcast/models/VoiceBroadcastRecording", () => ({
|
||||||
VoiceBroadcastRecording: jest.fn(),
|
VoiceBroadcastRecording: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock("../../../src/Modal");
|
||||||
|
|
||||||
describe("startNewVoiceBroadcastRecording", () => {
|
describe("startNewVoiceBroadcastRecording", () => {
|
||||||
const roomId = "!room:example.com";
|
const roomId = "!room:example.com";
|
||||||
|
const otherUserId = "@other:example.com";
|
||||||
let client: MatrixClient;
|
let client: MatrixClient;
|
||||||
let recordingsStore: VoiceBroadcastRecordingsStore;
|
let recordingsStore: VoiceBroadcastRecordingsStore;
|
||||||
let room: Room;
|
let room: Room;
|
||||||
let roomOnStateEventsCallbackRegistered: Promise<void>;
|
|
||||||
let roomOnStateEventsCallbackRegisteredResolver: Function;
|
|
||||||
let roomOnStateEventsCallback: () => void;
|
|
||||||
let infoEvent: MatrixEvent;
|
let infoEvent: MatrixEvent;
|
||||||
let otherEvent: MatrixEvent;
|
let otherEvent: MatrixEvent;
|
||||||
let stateEvent: MatrixEvent;
|
let result: VoiceBroadcastRecording | null;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
roomOnStateEventsCallbackRegistered = new Promise((resolve) => {
|
|
||||||
roomOnStateEventsCallbackRegisteredResolver = resolve;
|
|
||||||
});
|
|
||||||
|
|
||||||
room = {
|
|
||||||
currentState: {
|
|
||||||
getStateEvents: jest.fn().mockImplementation((type, userId) => {
|
|
||||||
if (type === VoiceBroadcastInfoEventType && userId === client.getUserId()) {
|
|
||||||
return stateEvent;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
on: jest.fn().mockImplementation((eventType, callback) => {
|
|
||||||
if (eventType === RoomStateEvent.Events) {
|
|
||||||
roomOnStateEventsCallback = callback;
|
|
||||||
roomOnStateEventsCallbackRegisteredResolver();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
off: jest.fn(),
|
|
||||||
} as unknown as Room;
|
|
||||||
|
|
||||||
client = stubClient();
|
client = stubClient();
|
||||||
|
room = new Room(roomId, client, client.getUserId());
|
||||||
|
jest.spyOn(room.currentState, "maySendStateEvent");
|
||||||
|
|
||||||
mocked(client.getRoom).mockImplementation((getRoomId: string) => {
|
mocked(client.getRoom).mockImplementation((getRoomId: string) => {
|
||||||
if (getRoomId === roomId) {
|
if (getRoomId === roomId) {
|
||||||
return room;
|
return room;
|
||||||
|
@ -85,22 +69,14 @@ describe("startNewVoiceBroadcastRecording", () => {
|
||||||
setCurrent: jest.fn(),
|
setCurrent: jest.fn(),
|
||||||
} as unknown as VoiceBroadcastRecordingsStore;
|
} as unknown as VoiceBroadcastRecordingsStore;
|
||||||
|
|
||||||
infoEvent = mkEvent({
|
infoEvent = mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Started, client.getUserId());
|
||||||
event: true,
|
|
||||||
type: VoiceBroadcastInfoEventType,
|
|
||||||
content: {
|
|
||||||
device_id: client.getDeviceId(),
|
|
||||||
state: VoiceBroadcastInfoState.Started,
|
|
||||||
},
|
|
||||||
user: client.getUserId(),
|
|
||||||
room: roomId,
|
|
||||||
});
|
|
||||||
otherEvent = mkEvent({
|
otherEvent = mkEvent({
|
||||||
event: true,
|
event: true,
|
||||||
type: EventType.RoomMember,
|
type: EventType.RoomMember,
|
||||||
content: {},
|
content: {},
|
||||||
user: client.getUserId(),
|
user: client.getUserId(),
|
||||||
room: roomId,
|
room: roomId,
|
||||||
|
skey: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
mocked(VoiceBroadcastRecording).mockImplementation((
|
mocked(VoiceBroadcastRecording).mockImplementation((
|
||||||
|
@ -115,29 +91,96 @@ describe("startNewVoiceBroadcastRecording", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create a new Voice Broadcast", (done) => {
|
afterEach(() => {
|
||||||
let ok = false;
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
startNewVoiceBroadcastRecording(roomId, client, recordingsStore).then((recording) => {
|
describe("when the current user is allowed to send voice broadcast info state events", () => {
|
||||||
expect(ok).toBe(true);
|
beforeEach(() => {
|
||||||
expect(mocked(room.off)).toHaveBeenCalledWith(RoomStateEvent.Events, roomOnStateEventsCallback);
|
mocked(room.currentState.maySendStateEvent).mockReturnValue(true);
|
||||||
expect(recording.infoEvent).toBe(infoEvent);
|
|
||||||
expect(recording.start).toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
roomOnStateEventsCallbackRegistered.then(() => {
|
describe("when there currently is no other broadcast", () => {
|
||||||
// no state event, yet
|
it("should create a new Voice Broadcast", async () => {
|
||||||
roomOnStateEventsCallback();
|
mocked(client.sendStateEvent).mockImplementation(async (
|
||||||
|
_roomId: string,
|
||||||
|
_eventType: string,
|
||||||
|
_content: any,
|
||||||
|
_stateKey = "",
|
||||||
|
) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
// emit state events after resolving the promise
|
||||||
|
room.currentState.setStateEvents([otherEvent]);
|
||||||
|
room.currentState.setStateEvents([infoEvent]);
|
||||||
|
}, 0);
|
||||||
|
return { event_id: infoEvent.getId() };
|
||||||
|
});
|
||||||
|
const recording = await startNewVoiceBroadcastRecording(room, client, recordingsStore);
|
||||||
|
|
||||||
// other state event
|
expect(client.sendStateEvent).toHaveBeenCalledWith(
|
||||||
stateEvent = otherEvent;
|
roomId,
|
||||||
roomOnStateEventsCallback();
|
VoiceBroadcastInfoEventType,
|
||||||
|
{
|
||||||
|
chunk_length: 300,
|
||||||
|
device_id: client.getDeviceId(),
|
||||||
|
state: VoiceBroadcastInfoState.Started,
|
||||||
|
},
|
||||||
|
client.getUserId(),
|
||||||
|
);
|
||||||
|
expect(recording.infoEvent).toBe(infoEvent);
|
||||||
|
expect(recording.start).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// the expected Voice Broadcast Info event
|
describe("when there already is a live broadcast of the current user", () => {
|
||||||
stateEvent = infoEvent;
|
beforeEach(async () => {
|
||||||
ok = true;
|
room.currentState.setStateEvents([
|
||||||
roomOnStateEventsCallback();
|
mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Running, client.getUserId()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
result = await startNewVoiceBroadcastRecording(room, client, recordingsStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not start a voice broadcast", () => {
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show an info dialog", () => {
|
||||||
|
expect(Modal.createDialog).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when there already is a live broadcast of another user", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
room.currentState.setStateEvents([
|
||||||
|
mkVoiceBroadcastInfoStateEvent(roomId, VoiceBroadcastInfoState.Running, otherUserId),
|
||||||
|
]);
|
||||||
|
|
||||||
|
result = await startNewVoiceBroadcastRecording(room, client, recordingsStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not start a voice broadcast", () => {
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show an info dialog", () => {
|
||||||
|
expect(Modal.createDialog).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when the current user is not allowed to send voice broadcast info state events", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mocked(room.currentState.maySendStateEvent).mockReturnValue(false);
|
||||||
|
result = await startNewVoiceBroadcastRecording(room, client, recordingsStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not start a voice broadcast", () => {
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show an info dialog", () => {
|
||||||
|
expect(Modal.createDialog).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
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 { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
|
import { VoiceBroadcastInfoEventType, VoiceBroadcastInfoState } from "../../../src/voice-broadcast";
|
||||||
|
import { mkEvent } from "../../test-utils";
|
||||||
|
|
||||||
|
export const mkVoiceBroadcastInfoStateEvent = (
|
||||||
|
roomId: string,
|
||||||
|
state: VoiceBroadcastInfoState,
|
||||||
|
sender: string,
|
||||||
|
): MatrixEvent => {
|
||||||
|
return mkEvent({
|
||||||
|
event: true,
|
||||||
|
room: roomId,
|
||||||
|
user: sender,
|
||||||
|
type: VoiceBroadcastInfoEventType,
|
||||||
|
skey: sender,
|
||||||
|
content: {
|
||||||
|
state,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue