Skip to content

Commit c78a54c

Browse files
added video stream controller events
1 parent 34a001e commit c78a54c

File tree

4 files changed

+321
-215
lines changed

4 files changed

+321
-215
lines changed

client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingControllerComp.tsx

Lines changed: 141 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ import AgoraRTC, {
4949
UID,
5050
ILocalVideoTrack,
5151
} from "agora-rtc-sdk-ng";
52+
5253
import { JSONValue } from "@lowcoder-ee/index.sdk";
5354
import { getData } from "../listViewComp/listViewUtils";
55+
import { meetingStreamChildren } from "./videoMeetingStreamComp";
5456

5557
const EventOptions = [closeEvent] as const;
5658

@@ -104,6 +106,7 @@ let audioTrack: IMicrophoneAudioTrack;
104106
let videoTrack: ICameraVideoTrack;
105107
let screenShareStream: ILocalVideoTrack;
106108
let userId: UID | null | undefined;
109+
107110
const turnOnCamera = async (flag?: boolean) => {
108111
if (videoTrack) {
109112
return videoTrack.setEnabled(flag!);
@@ -172,6 +175,9 @@ const joinChannel = async (appId: any, channel: any, token: any) => {
172175

173176
isJoined = true;
174177
};
178+
const hostChanged = (users: any) => {};
179+
180+
175181

176182
const publishVideo = async (appId: any, channel: any, height: any) => {
177183
await turnOnCamera(true);
@@ -193,127 +199,145 @@ const publishVideo = async (appId: any, channel: any, height: any) => {
193199
}
194200
};
195201

202+
export const meetingControllerChildren = {
203+
visible: booleanExposingStateControl("visible"),
204+
onEvent: eventHandlerControl(EventOptions),
205+
width: StringControl,
206+
height: StringControl,
207+
autoHeight: AutoHeightControl,
208+
style: styleControl(DrawerStyle),
209+
placement: PositionControl,
210+
maskClosable: withDefault(BoolControl, true),
211+
showMask: withDefault(BoolControl, true),
212+
audioControl: booleanExposingStateControl("false"),
213+
videoControl: booleanExposingStateControl("true"),
214+
endCall: booleanExposingStateControl("false"),
215+
sharingScreen: booleanExposingStateControl("false"),
216+
videoSettings: jsonObjectExposingStateControl(""),
217+
videoWidth: numberExposingStateControl("videoWidth", 200),
218+
videoHeight: numberExposingStateControl("videoHeight", 200),
219+
appId: withDefault(StringControl, trans("meeting.appid")),
220+
participants: stateComp<JSONValue>([]),
221+
host: stringExposingStateControl("host"),
222+
meetingName: stringExposingStateControl("meetingName"),
223+
};
196224
let MTComp = (function () {
197-
const childrenMap = {
198-
visible: booleanExposingStateControl("visible"),
199-
onEvent: eventHandlerControl(EventOptions),
200-
width: StringControl,
201-
height: StringControl,
202-
autoHeight: AutoHeightControl,
203-
style: styleControl(DrawerStyle),
204-
placement: PositionControl,
205-
maskClosable: withDefault(BoolControl, true),
206-
showMask: withDefault(BoolControl, true),
207-
audioControl: booleanExposingStateControl("false"),
208-
videoControl: booleanExposingStateControl("true"),
209-
endCall: booleanExposingStateControl("false"),
210-
sharingScreen: booleanExposingStateControl("false"),
211-
videoSettings: jsonObjectExposingStateControl(""),
212-
videoWidth: numberExposingStateControl("videoWidth", 200),
213-
videoHeight: numberExposingStateControl("videoHeight", 200),
214-
appId: withDefault(StringControl, trans("meeting.appid")),
215-
participants: stateComp<JSONValue>([]),
216-
host: stringExposingStateControl("host"),
217-
meetingName: stringExposingStateControl("meetingName"),
218-
};
219-
return new ContainerCompBuilder(childrenMap, (props, dispatch) => {
220-
const isTopBom = ["top", "bottom"].includes(props.placement);
221-
const { items, ...otherContainerProps } = props.container;
222-
const userViewMode = useUserViewMode();
223-
const resizable = !userViewMode && (!isTopBom || !props.autoHeight);
224-
const onResizeStop = useCallback(
225-
(
226-
e: React.SyntheticEvent,
227-
node: HTMLElement,
228-
size: { width: number; height: number },
229-
handle: ResizeHandle
230-
) => {
231-
isTopBom
232-
? dispatch(changeChildAction("height", size.height, true))
233-
: dispatch(changeChildAction("width", size.width, true));
234-
},
235-
[dispatch, isTopBom]
236-
);
237-
const [userIds, setUserIds] = useState<any>([]);
238-
239-
useEffect(() => {
240-
dispatch(changeChildAction("participants", getData(userIds).data, false));
241-
}, [userIds]);
242-
243-
useEffect(() => {
244-
client.on("user-joined", (user: IAgoraRTCRemoteUser) => {
245-
setUserIds((userIds: any) => [...userIds, { user: user.uid }]);
246-
});
247-
client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => {
248-
setUserIds((userIds: any) =>
249-
userIds.filter((item: any) => item.user !== user.uid)
225+
return new ContainerCompBuilder(
226+
meetingControllerChildren,
227+
(props, dispatch) => {
228+
const isTopBom = ["top", "bottom"].includes(props.placement);
229+
const { items, ...otherContainerProps } = props.container;
230+
const userViewMode = useUserViewMode();
231+
const resizable = !userViewMode && (!isTopBom || !props.autoHeight);
232+
const onResizeStop = useCallback(
233+
(
234+
e: React.SyntheticEvent,
235+
node: HTMLElement,
236+
size: { width: number; height: number },
237+
handle: ResizeHandle
238+
) => {
239+
isTopBom
240+
? dispatch(changeChildAction("height", size.height, true))
241+
: dispatch(changeChildAction("width", size.width, true));
242+
},
243+
[dispatch, isTopBom]
244+
);
245+
const [userIds, setUserIds] = useState<any>([]);
246+
247+
useEffect(() => {
248+
dispatch(
249+
changeChildAction("participants", getData(userIds).data, false)
250250
);
251-
});
252-
}, [client]);
253-
254-
return (
255-
<BackgroundColorContext.Provider value={props.style.background}>
256-
<DrawerWrapper>
257-
<Drawer
258-
resizable={resizable}
259-
onResizeStop={onResizeStop}
260-
rootStyle={
261-
props.visible.value
262-
? { overflow: "auto", pointerEvents: "auto" }
263-
: {}
264-
}
265-
contentWrapperStyle={{ maxHeight: "100%", maxWidth: "100%" }}
266-
bodyStyle={{
267-
padding: 0,
268-
backgroundColor: props.style.background,
269-
}}
270-
closable={false}
271-
placement={props.placement}
272-
open={props.visible.value}
273-
getContainer={() =>
274-
document.querySelector(`#${CanvasContainerID}`) || document.body
275-
}
276-
footer={null}
277-
width={transToPxSize(props.width || DEFAULT_SIZE)}
278-
height={
279-
!props.autoHeight
280-
? transToPxSize(props.height || DEFAULT_SIZE)
281-
: ""
282-
}
283-
onClose={(e) => {
284-
props.visible.onChange(false);
285-
}}
286-
afterOpenChange={(visible) => {
287-
if (!visible) {
288-
props.onEvent("close");
251+
}, [userIds]);
252+
253+
useEffect(() => {
254+
client.on("user-joined", (user: IAgoraRTCRemoteUser) => {
255+
console.log("userData", user);
256+
let userData = { user: user.uid, host: false };
257+
if (userIds.length == 0) {
258+
userData.host = true;
259+
} else {
260+
userData.host = false;
261+
}
262+
console.log("userData", userData);
263+
264+
setUserIds((userIds: any) => [...userIds, userData]);
265+
});
266+
client.on("user-left", (user: IAgoraRTCRemoteUser, reason: any) => {
267+
let newUsers = userIds.filter((item: any) => item.user !== user.uid);
268+
let hostExists = newUsers.filter((f: any) => f.host === true);
269+
if (hostExists.length == 0 && newUsers.length > 0) {
270+
newUsers[0].host = true;
271+
hostChanged(newUsers);
272+
}
273+
setUserIds(newUsers);
274+
});
275+
}, [client]);
276+
277+
return (
278+
<BackgroundColorContext.Provider value={props.style.background}>
279+
<DrawerWrapper>
280+
<Drawer
281+
resizable={resizable}
282+
onResizeStop={onResizeStop}
283+
rootStyle={
284+
props.visible.value
285+
? { overflow: "auto", pointerEvents: "auto" }
286+
: {}
287+
}
288+
contentWrapperStyle={{ maxHeight: "100%", maxWidth: "100%" }}
289+
bodyStyle={{
290+
padding: 0,
291+
backgroundColor: props.style.background,
292+
}}
293+
closable={false}
294+
placement={props.placement}
295+
open={props.visible.value}
296+
getContainer={() =>
297+
document.querySelector(`#${CanvasContainerID}`) || document.body
289298
}
290-
}}
291-
zIndex={Layers.drawer}
292-
maskClosable={props.maskClosable}
293-
mask={props.showMask}
294-
>
295-
<ButtonStyle
296-
onClick={() => {
299+
footer={null}
300+
width={transToPxSize(props.width || DEFAULT_SIZE)}
301+
height={
302+
!props.autoHeight
303+
? transToPxSize(props.height || DEFAULT_SIZE)
304+
: ""
305+
}
306+
onClose={(e) => {
297307
props.visible.onChange(false);
298308
}}
309+
afterOpenChange={(visible) => {
310+
if (!visible) {
311+
props.onEvent("close");
312+
}
313+
}}
314+
zIndex={Layers.drawer}
315+
maskClosable={props.maskClosable}
316+
mask={props.showMask}
299317
>
300-
<CloseOutlined />
301-
</ButtonStyle>
302-
<InnerGrid
303-
{...otherContainerProps}
304-
items={gridItemCompToGridItems(items)}
305-
autoHeight={props.autoHeight}
306-
minHeight={isTopBom ? DEFAULT_SIZE + "px" : "100%"}
307-
style={{ height: "100%" }}
308-
containerPadding={[DEFAULT_PADDING, DEFAULT_PADDING]}
309-
hintPlaceholder={HintPlaceHolder}
310-
bgColor={props.style.background}
311-
/>
312-
</Drawer>
313-
</DrawerWrapper>
314-
</BackgroundColorContext.Provider>
315-
);
316-
})
318+
<ButtonStyle
319+
onClick={() => {
320+
props.visible.onChange(false);
321+
}}
322+
>
323+
<CloseOutlined />
324+
</ButtonStyle>
325+
<InnerGrid
326+
{...otherContainerProps}
327+
items={gridItemCompToGridItems(items)}
328+
autoHeight={props.autoHeight}
329+
minHeight={isTopBom ? DEFAULT_SIZE + "px" : "100%"}
330+
style={{ height: "100%" }}
331+
containerPadding={[DEFAULT_PADDING, DEFAULT_PADDING]}
332+
hintPlaceholder={HintPlaceHolder}
333+
bgColor={props.style.background}
334+
/>
335+
</Drawer>
336+
</DrawerWrapper>
337+
</BackgroundColorContext.Provider>
338+
);
339+
}
340+
)
317341
.setPropertyViewFn((children) => (
318342
<>
319343
<Section name={sectionNames.basic}>
@@ -422,15 +446,15 @@ MTComp = withMethodExposing(MTComp, [
422446
await publishVideo(
423447
comp.children.appId.getView(),
424448
comp.children.meetingName.getView().value == ""
425-
? userId + "_meetingId"
449+
? "_meetingId"
426450
: comp.children.meetingName.getView().value,
427451
comp.children
428452
);
429453
},
430454
},
431455
{
432456
method: {
433-
name: "endCall",
457+
name: "endMeeting",
434458
description: trans("meeting.actionBtnDesc"),
435459
params: [],
436460
},

0 commit comments

Comments
 (0)