Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 75f41f0

Browse files
Merge branch 'dev' into fix-for-email-sign-up-env-var-not-applicable
2 parents bc84015 + 852d8ab commit 75f41f0

File tree

12 files changed

+2196
-34
lines changed

12 files changed

+2196
-34
lines changed

‎client/README.md‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66

77
#### Use prebuilt docker image
88

9-
Simply run below command to start a backend server.
9+
Simply run the below command to start a backend server.
1010

1111
```bash
1212
docker run -d --name lowcoder -p 3000:3000 -v "$PWD/stacks:/lowcoder-stacks" lowcoderorg/lowcoder-ce
1313
```
1414

15-
For more information, view our [docs](../docs/self-hosting)
15+
For more information, view our [docs](https://docs.lowcoder.cloud/lowcoder-documentation/setup-and-run/self-hosting)
1616

1717
#### Build Docker image from source
1818

19-
1. Check out source code and change to source dir.
20-
2. Use the command below to build Docker image :
19+
1. Check out the source code and change to source dir.
20+
2. Use the command below to build a Docker image :
2121

2222
```bash
2323
docker build -f ./deploy/docker/Dockerfile -t lowcoder-dev .
@@ -31,11 +31,21 @@ docker run -d --name lowcoder-dev -p 3000:3000 -v "$PWD/stacks:/lowcoder-stacks"
3131

3232
### Start develop
3333

34-
1. Check out source code.
34+
1. Check out the source code.
3535
2. Change to client dir in the repository root via cd client.
36-
3. Run yarn to install dependencies: .
37-
4. Start dev server: `LOWCODER_API_SERVICE_URL=http://localhost:3000 yarn start`.
38-
5. After dev server starts successfully, it will be automatically opened in the default browser.
36+
37+
```bash
38+
cd client
39+
```
40+
41+
4. Run yarn to install dependencies: .
42+
43+
```bash
44+
yarn install
45+
```
46+
47+
5. Start dev server: `LOWCODER_API_SERVICE_URL=http://localhost:3000 yarn start`.
48+
6. After the dev server starts successfully, it will be automatically opened in the default browser.
3949

4050
### Before submitting a pull request
4151

‎client/packages/lowcoder/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@types/react-virtualized": "^9.21.21",
3939
"agora-access-token": "^2.0.4",
4040
"agora-rtc-sdk-ng": "^4.19.0",
41+
"agora-rtm-sdk": "^1.5.1",
4142
"ali-oss": "^6.17.1",
4243
"antd": "5.7.2",
4344
"antd-img-crop": "^4.12.2",

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

Lines changed: 147 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { useUserViewMode } from "util/hooks";
4141
import { isNumeric } from "util/stringUtils";
4242
import { NameConfig, withExposingConfigs } from "../../generators/withExposing";
4343

44+
import axios from "axios";
4445
import AgoraRTC, {
4546
ICameraVideoTrack,
4647
IMicrophoneAudioTrack,
@@ -52,6 +53,7 @@ import AgoraRTC, {
5253

5354
import { JSONValue } from "@lowcoder-ee/index.sdk";
5455
import { getData } from "../listViewComp/listViewUtils";
56+
import AgoraRTM, { RtmChannel, RtmClient, RtmMessage } from "agora-rtm-sdk";
5557

5658
const EventOptions = [closeEvent] as const;
5759

@@ -105,6 +107,17 @@ let audioTrack: IMicrophoneAudioTrack;
105107
let videoTrack: ICameraVideoTrack;
106108
let screenShareStream: ILocalVideoTrack;
107109
let userId: UID | null | undefined;
110+
let rtmChannelResponse: RtmChannel;
111+
let rtmClient: RtmClient;
112+
113+
const generateToken = async (
114+
appId: any,
115+
certificate: any,
116+
channelName: any
117+
) => {
118+
const agoraTokenUrl = `https://api.agora.io/v1/token?channelName=test&uid=${userId}&appID=${appId}&appCertificate=${certificate}`;
119+
await axios.post(agoraTokenUrl);
120+
};
108121

109122
const turnOnCamera = async (flag?: boolean) => {
110123
if (videoTrack) {
@@ -119,8 +132,6 @@ const turnOnMicrophone = async (flag?: boolean) => {
119132
return audioTrack.setEnabled(flag!);
120133
}
121134
audioTrack = await AgoraRTC.createMicrophoneAudioTrack();
122-
// audioTrack.play();
123-
124135
if (!flag) {
125136
await client.unpublish(audioTrack);
126137
} else {
@@ -141,7 +152,7 @@ const shareScreen = async (sharing: boolean) => {
141152
"disable"
142153
);
143154
await client.unpublish(videoTrack);
144-
screenShareStream.play(userId+"");
155+
screenShareStream.play("share-screen");
145156
await client.publish(screenShareStream);
146157
}
147158
} catch (error) {
@@ -158,15 +169,29 @@ const leaveChannel = async () => {
158169
await turnOnMicrophone(false);
159170
}
160171
await client.leave();
172+
await rtmChannelResponse.leave();
161173
};
162174

163175
const hostChanged = (users: any) => {};
164176

165-
const publishVideo = async (appId: any, channel: any, height: any) => {
177+
const publishVideo = async (
178+
appId: string,
179+
channel: any,
180+
height: any,
181+
certifiCateKey: string
182+
) => {
183+
// console.log(
184+
// "generateToken",
185+
// await generateToken(appId, certifiCateKey, channel)
186+
// );
187+
188+
// return;
166189
await turnOnCamera(true);
167190
await client.join(appId, channel, null, userId);
168191
await client.publish(videoTrack);
169192

193+
await rtmInit(appId, userId, channel);
194+
170195
const mediaStreamTrack = videoTrack.getMediaStreamTrack();
171196
if (mediaStreamTrack) {
172197
const videoSettings = mediaStreamTrack.getSettings();
@@ -177,6 +202,57 @@ const publishVideo = async (appId: any, channel: any, height: any) => {
177202
}
178203
};
179204

205+
const sendMessageRtm = (message: any) => {
206+
rtmChannelResponse
207+
.sendMessage({ text: JSON.stringify(message) })
208+
.then(() => {
209+
console.log("message sent " + JSON.stringify(message));
210+
})
211+
.catch((e: any) => {
212+
console.log("error", e);
213+
});
214+
};
215+
216+
const sendPeerMessageRtm = (message: any, toId: string) => {
217+
rtmClient
218+
.sendMessageToPeer({ text: JSON.stringify(message) }, toId)
219+
.then(() => {
220+
console.log("message sent " + JSON.stringify(message));
221+
})
222+
.catch((e: any) => {
223+
console.log("error", e);
224+
});
225+
};
226+
227+
const rtmInit = async (appId: any, uid: any, channel: any) => {
228+
rtmClient = AgoraRTM.createInstance(appId);
229+
let options = {
230+
uid: String(uid),
231+
};
232+
await rtmClient.login(options);
233+
234+
rtmClient.on("ConnectionStateChanged", function (state, reason) {
235+
console.log("State changed To: " + state + " Reason: " + reason);
236+
});
237+
238+
rtmChannelResponse = rtmClient.createChannel(channel);
239+
240+
await rtmChannelResponse.join().then(async () => {
241+
console.log(
242+
"You have successfully joined channel " + rtmChannelResponse.channelId
243+
);
244+
});
245+
246+
// Display channel member stats
247+
rtmChannelResponse.on("MemberJoined", function (memberId) {
248+
console.log(memberId + " joined the channel");
249+
});
250+
// Display channel member stats
251+
rtmChannelResponse.on("MemberLeft", function (memberId) {
252+
console.log(memberId + " left the channel");
253+
});
254+
};
255+
180256
export const meetingControllerChildren = {
181257
visible: booleanExposingStateControl("visible"),
182258
onEvent: eventHandlerControl(EventOptions),
@@ -199,6 +275,8 @@ export const meetingControllerChildren = {
199275
usersScreenShared: stateComp<JSONValue>([]),
200276
localUser: jsonObjectExposingStateControl(""),
201277
meetingName: stringExposingStateControl("meetingName"),
278+
certifiCateKey: stringExposingStateControl(""),
279+
messages: stateComp<JSONValue>([]),
202280
};
203281
let MTComp = (function () {
204282
return new ContainerCompBuilder(
@@ -222,6 +300,7 @@ let MTComp = (function () {
222300
[dispatch, isTopBom]
223301
);
224302
const [userIds, setUserIds] = useState<any>([]);
303+
const [rtmMessages, setRtmMessages] = useState<any>([]);
225304

226305
useEffect(() => {
227306
dispatch(
@@ -238,6 +317,32 @@ let MTComp = (function () {
238317
}
239318
}, [props.endCall.value]);
240319

320+
useEffect(() => {
321+
if (rtmMessages) {
322+
dispatch(
323+
changeChildAction("messages", getData(rtmMessages).data, false)
324+
);
325+
}
326+
}, [rtmMessages]);
327+
328+
useEffect(() => {
329+
if (rtmChannelResponse) {
330+
rtmClient.on("MessageFromPeer", function (message, peerId) {
331+
console.log(
332+
"Message from: " + peerId + " Message: " + message.text
333+
);
334+
setRtmMessages(message.text);
335+
});
336+
rtmChannelResponse.on("ChannelMessage", function (message, memberId) {
337+
console.log("Message received from: " + memberId, message.text);
338+
setRtmMessages(message.text);
339+
dispatch(
340+
changeChildAction("messages", getData(rtmMessages).data, false)
341+
);
342+
});
343+
}
344+
}, [rtmChannelResponse]);
345+
241346
useEffect(() => {
242347
client.on("user-joined", (user: IAgoraRTCRemoteUser) => {
243348
let userData = {
@@ -331,6 +436,10 @@ let MTComp = (function () {
331436
<>
332437
<Section name={sectionNames.basic}>
333438
{children.appId.propertyView({ label: trans("meeting.appid") })}
439+
{children.certifiCateKey.propertyView({
440+
label: trans("meeting.certifiCateKey"),
441+
})}
442+
334443
{children.meetingName.propertyView({
335444
label: trans("meeting.meetingName"),
336445
})}
@@ -429,7 +538,6 @@ MTComp = withMethodExposing(MTComp, [
429538
} else {
430539
await turnOnCamera(value);
431540
}
432-
433541
comp.children.videoControl.change(value);
434542
},
435543
},
@@ -450,10 +558,42 @@ MTComp = withMethodExposing(MTComp, [
450558
comp.children.meetingName.getView().value == ""
451559
? "_meetingId"
452560
: comp.children.meetingName.getView().value,
453-
comp.children
561+
comp.children,
562+
comp.children.certifiCateKey.getView().value
454563
);
455564
},
456565
},
566+
{
567+
method: {
568+
name: "broadCast",
569+
description: trans("meeting.broadCast"),
570+
params: [],
571+
},
572+
execute: async (comp, values) => {
573+
let otherData =
574+
values != undefined && values[1] !== undefined ? values[1] : "";
575+
let toUsers: any =
576+
values != undefined && values[0] !== undefined ? values[0] : "";
577+
578+
let message: any = {
579+
time: Date.now(),
580+
from: userId,
581+
};
582+
message["data"] = otherData;
583+
584+
console.log(toUsers);
585+
586+
if (toUsers.length > 0 && toUsers[0] !== undefined) {
587+
let peers = toUsers?.map((u: any) => u.user);
588+
console.log("peers", peers);
589+
peers.forEach((p: any) => {
590+
sendPeerMessageRtm(message, String(p));
591+
});
592+
} else {
593+
sendMessageRtm(message);
594+
}
595+
},
596+
},
457597
{
458598
method: {
459599
name: "endMeeting",
@@ -484,8 +624,5 @@ export const VideoMeetingControllerComp = withExposingConfigs(MTComp, [
484624
new NameConfig("localUser", trans("meeting.host")),
485625
new NameConfig("participants", trans("meeting.participants")),
486626
new NameConfig("meetingName", trans("meeting.meetingName")),
627+
new NameConfig("messages", trans("meeting.meetingName")),
487628
]);
488-
489-
export function agoraClient() {
490-
return client;
491-
}

‎client/packages/lowcoder/src/comps/comps/meetingComp/videoMeetingStreamComp.tsx‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ import { RefControl } from "comps/controls/refControl";
2828
import { useEffect, useRef, useState } from "react";
2929

3030
import { AutoHeightControl } from "comps/controls/autoHeightControl";
31-
import {
32-
client,
33-
} from "./videoMeetingControllerComp";
31+
import { client } from "./videoMeetingControllerComp";
3432

3533
import { IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng";
3634

@@ -60,7 +58,7 @@ const Container = styled.div<{ $style: any }>`
6058
display: flex;
6159
align-items: center;
6260
justify-content: center;
63-
`;
61+
`;
6462
const VideoContainer = styled.video<{ $style: any }>`
6563
height: 100%;
6664
width: 100%;
@@ -154,6 +152,7 @@ const typeOptions = [
154152

155153
export const meetingStreamChildren = {
156154
autoHeight: withDefault(AutoHeightControl, "fixed"),
155+
shareScreen: withDefault(BoolCodeControl, false),
157156
type: dropdownControl(typeOptions, ""),
158157
onEvent: MeetingEventHandlerControl,
159158
disabled: BoolCodeControl,
@@ -246,8 +245,6 @@ let VideoCompBuilder = (function (props) {
246245
}
247246
}, [props.userId.value]);
248247

249-
250-
251248
return (
252249
<EditorContext.Consumer>
253250
{(editorState) => (
@@ -257,7 +254,7 @@ let VideoCompBuilder = (function (props) {
257254
onClick={() => props.onEvent("videoClicked")}
258255
ref={videoRef}
259256
$style={props.style}
260-
id={userId}
257+
id={props.shareScreen ? "share-screen" : userId}
261258
></VideoContainer>
262259
</Container>
263260
</ReactResizeDetector>
@@ -270,6 +267,9 @@ let VideoCompBuilder = (function (props) {
270267
<Section name={sectionNames.basic}>
271268
{children.userId.propertyView({ label: trans("meeting.videoId") })}
272269
{children.autoHeight.getPropertyView()}
270+
{children.shareScreen.propertyView({
271+
label: trans("meeting.shareScreen"),
272+
})}
273273
</Section>
274274
<Section name={sectionNames.interaction}>
275275
{children.onEvent.getPropertyView()}

‎client/packages/lowcoder/src/i18n/locales/en.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ export const en = {
14481448
top: "Top",
14491449
host: "Host",
14501450
participants: "Participants",
1451+
shareScreen: "Share Screen",
14511452
appid: "Application Id",
14521453
meetingName: "Meeting Name",
14531454
right: "Right",
@@ -1462,6 +1463,8 @@ export const en = {
14621463
width: "Drawer width",
14631464
height: "Drawer height",
14641465
actionBtnDesc: "Action Button",
1466+
broadCast: "BroadCast Messages",
1467+
certifiCateKey: "certifiCate Key",
14651468
title: "Meeting title",
14661469
meetingCompName: "Meeting Controller",
14671470
videoCompName: "Video Stream",

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /