@netless/fastboard 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +11 -1
  2. package/dist/index.cjs.js +4 -4
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +527 -365
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/svelte.cjs.js +1 -1
  7. package/dist/svelte.cjs.js.map +1 -1
  8. package/dist/svelte.es.js +1 -0
  9. package/dist/svelte.es.js.map +1 -1
  10. package/dist/vue.cjs.js +1 -1
  11. package/dist/vue.cjs.js.map +1 -1
  12. package/dist/vue.es.js +1 -0
  13. package/dist/vue.es.js.map +1 -1
  14. package/package.json +3 -2
  15. package/src/components/{PageControl.scss → PageControl/PageControl.scss} +0 -0
  16. package/src/components/PageControl/PageControl.tsx +110 -0
  17. package/src/components/PageControl/hooks.ts +70 -0
  18. package/src/components/PageControl/index.ts +2 -0
  19. package/src/components/PlayerControl/PlayerControl.tsx +7 -8
  20. package/src/components/PlayerControl/hooks.ts +1 -1
  21. package/src/components/PlayerControl/index.ts +1 -0
  22. package/src/components/{RedoUndo.scss → RedoUndo/RedoUndo.scss} +0 -0
  23. package/src/components/{RedoUndo.tsx → RedoUndo/RedoUndo.tsx} +13 -29
  24. package/src/components/RedoUndo/hooks.ts +50 -0
  25. package/src/components/RedoUndo/index.ts +2 -0
  26. package/src/components/Root.tsx +10 -6
  27. package/src/components/Toolbar/Content.tsx +4 -3
  28. package/src/components/Toolbar/Toolbar.scss +35 -1
  29. package/src/components/Toolbar/Toolbar.tsx +78 -28
  30. package/src/components/Toolbar/components/Mask.tsx +44 -0
  31. package/src/components/Toolbar/components/assets/collapsed.png +0 -0
  32. package/src/components/Toolbar/components/assets/expanded.png +0 -0
  33. package/src/components/Toolbar/hooks.ts +28 -29
  34. package/src/components/Toolbar/index.ts +1 -0
  35. package/src/components/{ZoomControl.scss → ZoomControl/ZoomControl.scss} +0 -0
  36. package/src/components/ZoomControl/ZoomControl.tsx +109 -0
  37. package/src/components/ZoomControl/hooks.ts +111 -0
  38. package/src/components/ZoomControl/index.ts +2 -0
  39. package/src/components/hooks.ts +80 -0
  40. package/src/index.ts +19 -4
  41. package/src/style.scss +3 -3
  42. package/src/components/PageControl.tsx +0 -181
  43. package/src/components/ZoomControl.tsx +0 -221
@@ -1,181 +0,0 @@
1
- import type { RoomState, ViewVisionMode } from "white-web-sdk";
2
- import type { CommonProps, GenericIcon } from "../types";
3
-
4
- import clsx from "clsx";
5
- import React, { useCallback, useEffect, useState } from "react";
6
- import Tippy from "@tippyjs/react";
7
-
8
- import { TopOffset } from "../theme";
9
- import { Icon } from "../icons";
10
- import { FilePlus } from "../icons/FilePlus";
11
- import { ChevronLeft } from "../icons/ChevronLeft";
12
- import { ChevronRight } from "../icons/ChevronRight";
13
-
14
- export const name = "fastboard-page-control";
15
-
16
- export type PageControlProps = CommonProps &
17
- GenericIcon<"add" | "prev" | "next">;
18
-
19
- export function PageControl({
20
- room,
21
- manager,
22
- theme = "light",
23
- addIcon,
24
- addIconDisable,
25
- prevIcon,
26
- prevIconDisable,
27
- nextIcon,
28
- nextIconDisable,
29
- i18n,
30
- }: PageControlProps) {
31
- const [writable, setWritable] = useState(false);
32
- const [pageIndex, setPageIndex] = useState(0);
33
- const [pageCount, setPageCount] = useState(0);
34
-
35
- const addPage = useCallback(async () => {
36
- if (manager && room) {
37
- await manager.switchMainViewToWriter();
38
- const path = room.state.sceneState.contextPath;
39
- room.putScenes(path, [{}], pageIndex + 1);
40
- await manager.setMainViewSceneIndex(pageIndex + 1);
41
- } else if (!manager && room) {
42
- const path = room.state.sceneState.contextPath;
43
- room.putScenes(path, [{}], pageIndex + 1);
44
- room.setSceneIndex(pageIndex + 1);
45
- }
46
- }, [room, manager, pageIndex]);
47
-
48
- const prevPage = useCallback(() => {
49
- if (room?.isWritable) {
50
- if (manager) {
51
- manager.setMainViewSceneIndex(pageIndex - 1);
52
- } else {
53
- room.pptPreviousStep();
54
- }
55
- }
56
- }, [room, manager, pageIndex]);
57
-
58
- const nextPage = useCallback(() => {
59
- if (room?.isWritable) {
60
- if (manager) {
61
- manager.setMainViewSceneIndex(pageIndex + 1);
62
- } else {
63
- room.pptNextStep();
64
- }
65
- }
66
- }, [room, manager, pageIndex]);
67
-
68
- useEffect(() => {
69
- if (room) {
70
- setWritable(room.isWritable);
71
- setPageIndex(room.state.sceneState.index);
72
- setPageCount(room.state.sceneState.scenes.length);
73
- }
74
-
75
- const onRoomStateChanged = (modifyState: Partial<RoomState>) => {
76
- if (modifyState.sceneState) {
77
- setPageIndex(modifyState.sceneState.index);
78
- setPageCount(modifyState.sceneState.scenes.length);
79
- }
80
- };
81
-
82
- const onMainViewModeChanged = (mode: number) => {
83
- if (room && mode === (0 as ViewVisionMode.Writable)) {
84
- setPageIndex(room.state.sceneState.index);
85
- setPageCount(room.state.sceneState.scenes.length);
86
- }
87
- };
88
-
89
- const updateWritable = () => setWritable(room?.isWritable || false);
90
-
91
- if (room) {
92
- room.callbacks.on("onEnableWriteNowChanged", updateWritable);
93
- room.callbacks.on("onRoomStateChanged", onRoomStateChanged);
94
- manager?.callbacks.on("mainViewModeChange", onMainViewModeChanged);
95
- }
96
-
97
- return () => {
98
- if (room) {
99
- room.callbacks.off("onEnableWriteNowChanged", updateWritable);
100
- room.callbacks.off("onRoomStateChanged", onRoomStateChanged);
101
- manager?.callbacks.off("mainViewModeChange", onMainViewModeChanged);
102
- }
103
- };
104
- }, [room, manager]);
105
-
106
- const disabled = !writable;
107
-
108
- return (
109
- <div className={clsx(name, theme)}>
110
- {/* <span className={clsx(`${name}-cut-line`, theme)} />{" "} */}
111
- <Tippy
112
- className="fastboard-tip"
113
- content={i18n?.t("prevPage")}
114
- theme={theme}
115
- disabled={disabled}
116
- placement="top"
117
- duration={300}
118
- offset={TopOffset}
119
- >
120
- <button
121
- className={clsx(`${name}-btn`, "prev", theme)}
122
- disabled={disabled || pageIndex === 0}
123
- onClick={prevPage}
124
- >
125
- <Icon
126
- fallback={<ChevronLeft theme={theme} />}
127
- src={disabled ? prevIconDisable : prevIcon}
128
- alt="[prev]"
129
- />
130
- </button>
131
- </Tippy>
132
- <span className={clsx(`${name}-page`, theme)}>
133
- {pageCount === 0 ? "\u2026" : pageIndex + 1}
134
- </span>
135
- <span className={clsx(`${name}-slash`, theme)}>/</span>
136
- <span className={clsx(`${name}-page-count`, theme)}>{pageCount}</span>
137
- <Tippy
138
- className="fastboard-tip"
139
- content={i18n?.t("nextPage")}
140
- theme={theme}
141
- disabled={disabled}
142
- placement="top"
143
- duration={300}
144
- offset={TopOffset}
145
- >
146
- <button
147
- className={clsx(`${name}-btn`, "next", theme)}
148
- disabled={disabled || pageIndex === pageCount - 1}
149
- onClick={nextPage}
150
- >
151
- <Icon
152
- fallback={<ChevronRight theme={theme} />}
153
- src={disabled ? nextIconDisable : nextIcon}
154
- alt="[next]"
155
- />
156
- </button>
157
- </Tippy>
158
- <Tippy
159
- className="fastboard-tip"
160
- content={i18n?.t("addPage")}
161
- theme={theme}
162
- disabled={disabled}
163
- placement="top"
164
- duration={300}
165
- offset={TopOffset}
166
- >
167
- <button
168
- className={clsx(`${name}-btn`, "add", theme)}
169
- disabled={disabled}
170
- onClick={addPage}
171
- >
172
- <Icon
173
- fallback={<FilePlus theme={theme} />}
174
- src={disabled ? addIconDisable : addIcon}
175
- alt="[add]"
176
- />
177
- </button>
178
- </Tippy>
179
- </div>
180
- );
181
- }
@@ -1,221 +0,0 @@
1
- import type { RoomState } from "white-web-sdk";
2
- import type { CommonProps, GenericIcon } from "../types";
3
-
4
- import clsx from "clsx";
5
- import React, { useCallback, useEffect, useState } from "react";
6
- import Tippy from "@tippyjs/react";
7
-
8
- import { clamp } from "../internal";
9
- import { TopOffset } from "../theme";
10
- import { Icon } from "../icons";
11
- import { Minus } from "../icons/Minus";
12
- import { Plus } from "../icons/Plus";
13
- import { Reset } from "../icons/Reset";
14
-
15
- export const name = "fastboard-zoom-control";
16
-
17
- export const ScalePoints: readonly number[] = [
18
- 0.10737418240000011, 0.13421772800000012, 0.16777216000000014,
19
- 0.20971520000000016, 0.26214400000000015, 0.3276800000000002,
20
- 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26,
21
- 1.5876000000000001, 2.000376, 2.5204737600000002, 3.1757969376000004,
22
- 4.001504141376, 5.041895218133761, 6.352787974848539, 8.00451284830916, 10,
23
- ];
24
-
25
- function nextScale(scale: number, delta: 1 | -1) {
26
- const { length } = ScalePoints;
27
- const last = length - 1;
28
- if (scale < ScalePoints[0]) return ScalePoints[0];
29
- if (scale > ScalePoints[last]) return ScalePoints[last];
30
- for (let i = 0; i < length; ++i) {
31
- const curr = ScalePoints[i];
32
- const prev = i === 0 ? -Infinity : (ScalePoints[i - 1] + curr) / 2;
33
- const next = i === last ? Infinity : (ScalePoints[i + 1] + curr) / 2;
34
- if (prev <= scale && scale <= next)
35
- return ScalePoints[clamp(i + delta, 0, last)];
36
- }
37
- return 1;
38
- }
39
-
40
- export type ZoomControlProps = CommonProps &
41
- GenericIcon<"reset" | "minus" | "plus">;
42
-
43
- export function ZoomControl({
44
- room,
45
- manager,
46
- theme = "light",
47
- resetIcon,
48
- resetIconDisable,
49
- minusIcon,
50
- minusIconDisable,
51
- plusIcon,
52
- plusIconDisable,
53
- i18n,
54
- }: ZoomControlProps) {
55
- const [writable, setWritable] = useState(false);
56
- const [scale, setScale] = useState(1);
57
-
58
- const resetCamera = useCallback(() => {
59
- if (room?.isWritable) {
60
- if (manager) {
61
- manager.mainView.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
62
- } else {
63
- const { scenes, index } = room.state.sceneState;
64
- if (scenes[index].ppt) {
65
- room.scalePptToFit();
66
- } else {
67
- room.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
68
- }
69
- }
70
- }
71
- }, [room, manager]);
72
-
73
- const zoomIn = useCallback(() => {
74
- if (room?.isWritable) {
75
- if (manager) {
76
- manager.mainView.moveCamera({
77
- scale: nextScale(scale, 1),
78
- centerX: 0,
79
- centerY: 0,
80
- });
81
- } else {
82
- room.moveCamera({
83
- scale: nextScale(scale, 1),
84
- centerX: 0,
85
- centerY: 0,
86
- });
87
- }
88
- }
89
- }, [room, manager, scale]);
90
-
91
- const zoomOut = useCallback(() => {
92
- if (room?.isWritable) {
93
- if (manager) {
94
- manager.mainView.moveCamera({
95
- scale: nextScale(scale, -1),
96
- centerX: 0,
97
- centerY: 0,
98
- });
99
- } else {
100
- room.moveCamera({
101
- scale: nextScale(scale, -1),
102
- centerX: 0,
103
- centerY: 0,
104
- });
105
- }
106
- }
107
- }, [room, manager, scale]);
108
-
109
- useEffect(() => {
110
- if (room) {
111
- setWritable(room.isWritable);
112
- setScale(room.state.cameraState.scale);
113
- }
114
-
115
- if (manager) {
116
- setScale(manager.mainView.camera.scale);
117
- }
118
-
119
- const onRoomStateChanged = (modifyState: Partial<RoomState>) => {
120
- if (modifyState.cameraState) {
121
- setScale(modifyState.cameraState.scale);
122
- }
123
- };
124
-
125
- const onCameraUpdated = ({ scale }: { scale: number }) => setScale(scale);
126
-
127
- const updateWritable = () => setWritable(room?.isWritable || false);
128
-
129
- if (room) {
130
- room.callbacks.on("onEnableWriteNowChanged", updateWritable);
131
- if (manager) {
132
- manager.mainView.callbacks.on("onCameraUpdated", onCameraUpdated);
133
- } else {
134
- room.callbacks.on("onRoomStateChanged", onRoomStateChanged);
135
- }
136
- }
137
-
138
- return () => {
139
- if (room) {
140
- room.callbacks.off("onEnableWriteNowChanged", updateWritable);
141
- room.callbacks.off("onRoomStateChanged", onRoomStateChanged);
142
- manager?.mainView.callbacks.off("onCameraUpdated", onCameraUpdated);
143
- }
144
- };
145
- }, [room, manager]);
146
-
147
- const disabled = !writable;
148
-
149
- return (
150
- <div className={clsx(name, theme)}>
151
- {/* <span className={clsx(`${name}-cut-line`, theme)} /> */}
152
- <Tippy
153
- className="fastboard-tip"
154
- content={i18n?.t("zoomOut")}
155
- theme={theme}
156
- disabled={disabled}
157
- placement="top"
158
- duration={300}
159
- offset={TopOffset}
160
- >
161
- <button
162
- className={clsx(`${name}-btn`, "minus", theme)}
163
- disabled={disabled}
164
- onClick={zoomOut}
165
- >
166
- <Icon
167
- fallback={<Minus theme={theme} />}
168
- src={disabled ? minusIconDisable : minusIcon}
169
- alt="[minus]"
170
- />
171
- </button>
172
- </Tippy>
173
- <span className={clsx(`${name}-scale`, theme)}>
174
- {Math.ceil(scale * 100)}
175
- </span>
176
- <span className={clsx(`${name}-percent`, theme)}>%</span>
177
- <Tippy
178
- className="fastboard-tip"
179
- content={i18n?.t("zoomIn")}
180
- theme={theme}
181
- disabled={disabled}
182
- placement="top"
183
- duration={300}
184
- offset={TopOffset}
185
- >
186
- <button
187
- className={clsx(`${name}-btn`, "plus", theme)}
188
- disabled={disabled}
189
- onClick={zoomIn}
190
- >
191
- <Icon
192
- fallback={<Plus theme={theme} />}
193
- src={disabled ? plusIconDisable : plusIcon}
194
- alt="[plus]"
195
- />
196
- </button>
197
- </Tippy>
198
- <Tippy
199
- className="fastboard-tip"
200
- content={i18n?.t("reset")}
201
- theme={theme}
202
- disabled={disabled}
203
- placement="top"
204
- duration={300}
205
- offset={TopOffset}
206
- >
207
- <button
208
- className={clsx(`${name}-btn`, "reset", theme)}
209
- disabled={disabled}
210
- onClick={resetCamera}
211
- >
212
- <Icon
213
- fallback={<Reset theme={theme} />}
214
- src={disabled ? resetIconDisable : resetIcon}
215
- alt="[reset]"
216
- />
217
- </button>
218
- </Tippy>
219
- </div>
220
- );
221
- }