Skip to content

Commit 30cc4dd

Browse files
authored
feat(whiteboard): use fastboard (#1356)
* feat(whiteboard): use the fastboard * refactor(classroom): remove AppStoreButton components * refactor(classroom): change destroy methods * chore(library): add the fastboard and remove unused package
1 parent 02d74a6 commit 30cc4dd

File tree

18 files changed

+387
-681
lines changed

18 files changed

+387
-681
lines changed

cspell.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ module.exports = {
5050
// whiteboard
5151
"unban",
5252
"convertcdn",
53+
"fastboard",
5354

5455
// date-fns
5556
"Weekiii",

desktop/renderer-app/package.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@
1111
"@netless/app-monaco": "^0.1.12",
1212
"@netless/app-slide": "0.0.56",
1313
"@netless/combine-player": "^1.1.4",
14-
"@netless/cursor-tool": "^0.1.0",
14+
"@netless/fastboard": "^0.2.4",
15+
"@netless/fastboard-react": "^0.2.4",
1516
"@netless/fetch-middleware": "^1.0.7",
1617
"@netless/player-controller": "^0.0.9",
17-
"@netless/redo-undo": "^0.1.9",
18-
"@netless/tool-box": "^0.1.6",
1918
"@netless/video-js-plugin": "^0.3.6",
20-
"@netless/window-manager": "0.4.0-canary.31",
19+
"@netless/window-manager": "0.4.0-canary.33",
2120
"@videojs/vhs-utils": "^2.3.0",
2221
"agora-rtm-sdk": "^1.4.3",
2322
"antd": "^4.15.4",

desktop/renderer-app/src/components/Whiteboard.less

+33-56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
.whiteboard-container {
22
width: 100%;
33
height: 100%;
4+
background: #f3f6f9;
5+
6+
.telebox-collector {
7+
position: absolute;
8+
left: 220px;
9+
bottom: 8px;
10+
width: 40px;
11+
height: 34px;
12+
border-radius: 4px;
13+
border: 1px solid rgba(0, 0, 0, 0.15);
14+
transition: ease-out 0.2s;
15+
}
16+
17+
.fastboard-toolbar-btn {
18+
outline: 0;
19+
}
20+
21+
.fastboard-bottom-left {
22+
bottom: 0;
23+
}
24+
25+
.fastboard-bottom-right {
26+
bottom: 0px;
27+
}
428

529
&.is-readonly {
630
.zoom-controller-box {
@@ -10,39 +34,16 @@
1034
.whiteboard-writable-area {
1135
display: none;
1236
}
13-
}
14-
}
15-
16-
.tool-box-out {
17-
height: 100%;
18-
width: 0;
19-
display: flex;
20-
flex-direction: column;
21-
justify-content: center;
22-
position: absolute;
23-
z-index: 3;
24-
left: 8px;
25-
}
26-
27-
.redo-undo-box {
28-
position: absolute;
29-
z-index: 3;
30-
bottom: 8px;
31-
left: 8px;
32-
33-
&.is-disabled {
34-
display: none;
35-
}
36-
}
37-
38-
.page-controller-box {
39-
position: absolute;
40-
z-index: 3;
41-
bottom: 8px;
42-
right: 8px;
4337

44-
&.is-disabled {
45-
display: none;
38+
.telebox-collector {
39+
position: absolute;
40+
left: 8px;
41+
width: 40px;
42+
height: 32px;
43+
border-radius: 4px;
44+
border: 1px solid rgba(0, 0, 0, 0.15);
45+
transition: ease-out 0.2s;
46+
}
4647
}
4748
}
4849

@@ -57,30 +58,6 @@
5758
background: #fff;
5859
}
5960

60-
.collector-container {
61-
> .telebox-collector {
62-
position: absolute;
63-
left: 80px;
64-
width: 40px;
65-
height: 32px;
66-
border-radius: 4px;
67-
border: 1px solid rgba(0, 0, 0, 0.15);
68-
transition: ease-out 0.2s;
69-
}
70-
}
71-
72-
.collector-container-not-writable {
73-
> .telebox-collector {
74-
position: absolute;
75-
left: 8px;
76-
width: 40px;
77-
height: 32px;
78-
border-radius: 4px;
79-
border: 1px solid rgba(0, 0, 0, 0.15);
80-
transition: ease-out 0.2s;
81-
}
82-
}
83-
8461
.raise-hand-container {
8562
position: absolute;
8663
width: 48px;

desktop/renderer-app/src/components/Whiteboard.tsx

+13-94
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import "@netless/window-manager/dist/style.css";
22
import "./Whiteboard.less";
33

4-
import RedoUndo from "@netless/redo-undo";
5-
import ToolBox from "@netless/tool-box";
6-
import { WindowManager } from "@netless/window-manager";
4+
import { Fastboard, Language } from "@netless/fastboard-react";
75
import classNames from "classnames";
8-
import { RaiseHand, ScenesController } from "flat-components";
6+
import { RaiseHand } from "flat-components";
97
import { observer } from "mobx-react-lite";
108
import React, { useCallback, useEffect, useState } from "react";
119
import { message } from "antd";
@@ -32,7 +30,7 @@ export const Whiteboard = observer<WhiteboardProps>(function Whiteboard({
3230
disableHandRaising,
3331
}) {
3432
const { i18n, t } = useTranslation();
35-
const { room, phase } = whiteboardStore;
33+
const { room, phase, fastboardAPP } = whiteboardStore;
3634

3735
const [whiteboardEl, setWhiteboardEl] = useState<HTMLElement | null>(null);
3836
const [collectorEl, setCollectorEl] = useState<HTMLElement | null>(null);
@@ -44,40 +42,10 @@ export const Whiteboard = observer<WhiteboardProps>(function Whiteboard({
4442
}, [isReconnecting, t]);
4543

4644
useEffect(() => {
47-
const mountWindowManager = async (): Promise<void> => {
48-
if (whiteboardEl && collectorEl && room) {
49-
const windowManager = await WindowManager.mount({
50-
room,
51-
container: whiteboardEl,
52-
collectorContainer: collectorEl,
53-
cursor: true,
54-
/* the containerSizeRatio config limit width and height ratio of windowManager
55-
for make sure windowManager sync in whiteboard. */
56-
containerSizeRatio: whiteboardStore.getWhiteboardRatio(),
57-
collectorStyles: {
58-
position: "absolute",
59-
bottom: "8px",
60-
},
61-
chessboard: false,
62-
});
63-
64-
whiteboardStore.updateWindowManager(windowManager);
65-
whiteboardStore.onMainViewSceneChange();
66-
whiteboardStore.onMainViewSceneLengthChange();
67-
whiteboardStore.onMainViewRedoUndoStepsChange();
68-
whiteboardStore.onWindowManagerBoxStateChange(
69-
whiteboardStore.windowManager?.boxState,
70-
);
71-
}
72-
};
73-
74-
void mountWindowManager();
75-
76-
return () => {
77-
whiteboardStore.destroyWindowManager();
78-
};
79-
// eslint-disable-next-line react-hooks/exhaustive-deps
80-
}, [whiteboardEl, collectorEl, room]);
45+
if (fastboardAPP && collectorEl) {
46+
fastboardAPP.bindCollector(collectorEl);
47+
}
48+
}, [collectorEl, fastboardAPP]);
8149

8250
const whiteboardOnResize = useCallback(() => {
8351
if (whiteboardEl) {
@@ -200,54 +168,6 @@ export const Whiteboard = observer<WhiteboardProps>(function Whiteboard({
200168
onDragOver={onDragOver}
201169
onDrop={onDrop}
202170
>
203-
<div className="whiteboard-writable-area">
204-
<div className="tool-box-out">
205-
<ToolBox
206-
hotkeys={{
207-
arrow: "A",
208-
clear: "",
209-
clicker: "",
210-
ellipse: "C",
211-
eraser: "E",
212-
hand: "H",
213-
laserPointer: "Z",
214-
pencil: "P",
215-
rectangle: "R",
216-
selector: "S",
217-
shape: "",
218-
straight: "L",
219-
text: "T",
220-
}}
221-
i18nLanguage={i18n.language}
222-
room={room}
223-
/>
224-
</div>
225-
<div
226-
className={classNames("redo-undo-box", {
227-
"is-disabled": whiteboardStore.isWindowMaximization,
228-
})}
229-
>
230-
<RedoUndo
231-
redoSteps={whiteboardStore.redoSteps}
232-
room={room}
233-
undoSteps={whiteboardStore.undoSteps}
234-
/>
235-
</div>
236-
<div
237-
className={classNames("page-controller-box", {
238-
"is-disabled": whiteboardStore.isWindowMaximization,
239-
})}
240-
>
241-
<ScenesController
242-
addScene={whiteboardStore.addMainViewScene}
243-
currentSceneIndex={whiteboardStore.currentSceneIndex}
244-
disabled={false}
245-
nextScene={whiteboardStore.nextMainViewScene}
246-
preScene={whiteboardStore.preMainViewScene}
247-
scenesCount={whiteboardStore.scenesCount}
248-
/>
249-
</div>
250-
</div>
251171
{!whiteboardStore.isCreator && !whiteboardStore.isWritable && (
252172
<div className="raise-hand-container">
253173
<RaiseHand
@@ -257,14 +177,13 @@ export const Whiteboard = observer<WhiteboardProps>(function Whiteboard({
257177
/>
258178
</div>
259179
)}
260-
<div
261-
ref={bindCollector}
262-
className={classNames("collector-container", {
263-
"collector-container-not-writable": !whiteboardStore.isWritable,
264-
})}
180+
<div ref={bindCollector} />
181+
<Fastboard
182+
ref={bindWhiteboard}
183+
app={fastboardAPP}
184+
language={i18n.language as Language}
185+
theme="light"
265186
/>
266-
267-
<div ref={bindWhiteboard} className="whiteboard-box" />
268187
</div>
269188
)
270189
);

desktop/renderer-app/src/pages/BigClassPage/index.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import { BigClassAvatar } from "./BigClassAvatar";
4040
import { runtime } from "../../utils/runtime";
4141
import { ShareScreen, ShareScreenPicker } from "../../components/ShareScreen";
4242
import { generateAvatar } from "../../utils/generate-avatar";
43-
import { AppStoreButton } from "../../components/AppStoreButton";
4443
import shareScreenActiveSVG from "../../assets/image/share-screen-active.svg";
4544
import shareScreenSVG from "../../assets/image/share-screen.svg";
4645
import exitSVG from "../../assets/image/exit.svg";
@@ -248,8 +247,6 @@ export const BigClassPage = observer<BigClassPageProps>(function BigClassPage()
248247
function renderTopBarRight(): React.ReactNode {
249248
return (
250249
<>
251-
{whiteboardStore.isWritable && <AppStoreButton addApp={whiteboardStore.addApp} />}
252-
253250
{whiteboardStore.isWritable && !shareScreenStore.existOtherShareScreen && (
254251
<TopBarRightBtn
255252
icon={

desktop/renderer-app/src/pages/OneToOnePage/index.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import { runtime } from "../../utils/runtime";
4040
import { useTranslation } from "react-i18next";
4141
import { ShareScreen, ShareScreenPicker } from "../../components/ShareScreen";
4242
import { generateAvatar } from "../../utils/generate-avatar";
43-
import { AppStoreButton } from "../../components/AppStoreButton";
4443
import shareScreenActiveSVG from "../../assets/image/share-screen-active.svg";
4544
import shareScreenSVG from "../../assets/image/share-screen.svg";
4645
import exitSVG from "../../assets/image/exit.svg";
@@ -206,8 +205,6 @@ export const OneToOnePage = observer<OneToOnePageProps>(function OneToOnePage()
206205
function renderTopBarRight(): React.ReactNode {
207206
return (
208207
<>
209-
{whiteboardStore.isWritable && <AppStoreButton addApp={whiteboardStore.addApp} />}
210-
211208
{whiteboardStore.isWritable && !shareScreenStore.existOtherShareScreen && (
212209
<TopBarRightBtn
213210
icon={

desktop/renderer-app/src/pages/SmallClassPage/index.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ import { CloudStorageButton } from "../../components/CloudStorageButton";
4444
import { runtime } from "../../utils/runtime";
4545
import { ShareScreen, ShareScreenPicker } from "../../components/ShareScreen";
4646
import { generateAvatar } from "../../utils/generate-avatar";
47-
import { AppStoreButton } from "../../components/AppStoreButton";
4847

4948
import shareScreenActiveSVG from "../../assets/image/share-screen-active.svg";
5049
import shareScreenSVG from "../../assets/image/share-screen.svg";
@@ -277,8 +276,6 @@ export const SmallClassPage = observer<SmallClassPageProps>(function SmallClassP
277276
function renderTopBarRight(): React.ReactNode {
278277
return (
279278
<>
280-
{whiteboardStore.isWritable && <AppStoreButton addApp={whiteboardStore.addApp} />}
281-
282279
{whiteboardStore.isWritable && !shareScreenStore.existOtherShareScreen && (
283280
<TopBarRightBtn
284281
icon={

desktop/renderer-app/src/stores/class-room-store.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,9 @@ export class ClassRoomStore {
596596

597597
promises.push(this.shareScreenStore.destroy());
598598

599-
this.leaveRTC();
599+
promises.push(this.whiteboardStore.destroy());
600600

601-
this.whiteboardStore.destroy();
601+
this.leaveRTC();
602602

603603
this.offRTCEvents();
604604
this.rtc.destroy();

0 commit comments

Comments
 (0)