@netless/fastboard 0.0.11 → 0.1.0

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 (118) hide show
  1. package/LICENSE.txt +1 -1
  2. package/dist/index.js +426 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +393 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +16 -80
  7. package/src/base.ts +55 -0
  8. package/src/core.ts +307 -0
  9. package/src/emitter.ts +21 -0
  10. package/src/index.ts +73 -42
  11. package/src/{behaviors/register-apps.ts → register-apps.ts} +6 -14
  12. package/src/utils.ts +74 -0
  13. package/src/value.ts +74 -0
  14. package/README.md +0 -136
  15. package/dist/index.cjs.js +0 -14
  16. package/dist/index.cjs.js.map +0 -1
  17. package/dist/index.es.js +0 -2804
  18. package/dist/index.es.js.map +0 -1
  19. package/dist/svelte.cjs.js +0 -2
  20. package/dist/svelte.cjs.js.map +0 -1
  21. package/dist/svelte.es.js +0 -32
  22. package/dist/svelte.es.js.map +0 -1
  23. package/dist/vue.cjs.js +0 -2
  24. package/dist/vue.cjs.js.map +0 -1
  25. package/dist/vue.es.js +0 -43
  26. package/dist/vue.es.js.map +0 -1
  27. package/src/WhiteboardApp.ts +0 -146
  28. package/src/behaviors/style.ts +0 -17
  29. package/src/components/PageControl/PageControl.scss +0 -80
  30. package/src/components/PageControl/PageControl.tsx +0 -110
  31. package/src/components/PageControl/hooks.ts +0 -70
  32. package/src/components/PageControl/index.ts +0 -2
  33. package/src/components/PlayerControl/PlayerControl.scss +0 -145
  34. package/src/components/PlayerControl/PlayerControl.tsx +0 -157
  35. package/src/components/PlayerControl/components/Button.tsx +0 -55
  36. package/src/components/PlayerControl/hooks.ts +0 -88
  37. package/src/components/PlayerControl/icons/Loading.tsx +0 -13
  38. package/src/components/PlayerControl/icons/Pause.tsx +0 -13
  39. package/src/components/PlayerControl/icons/Play.tsx +0 -13
  40. package/src/components/PlayerControl/icons/index.ts +0 -10
  41. package/src/components/PlayerControl/index.ts +0 -2
  42. package/src/components/RedoUndo/RedoUndo.scss +0 -56
  43. package/src/components/RedoUndo/RedoUndo.tsx +0 -79
  44. package/src/components/RedoUndo/hooks.ts +0 -50
  45. package/src/components/RedoUndo/index.ts +0 -2
  46. package/src/components/Root.scss +0 -55
  47. package/src/components/Root.tsx +0 -65
  48. package/src/components/Toolbar/Content.tsx +0 -94
  49. package/src/components/Toolbar/Toolbar.scss +0 -281
  50. package/src/components/Toolbar/Toolbar.tsx +0 -132
  51. package/src/components/Toolbar/components/ApplianceButtons.tsx +0 -132
  52. package/src/components/Toolbar/components/AppsButton.tsx +0 -106
  53. package/src/components/Toolbar/components/Button.tsx +0 -54
  54. package/src/components/Toolbar/components/ColorBox.tsx +0 -56
  55. package/src/components/Toolbar/components/CutLine.tsx +0 -8
  56. package/src/components/Toolbar/components/Mask.tsx +0 -44
  57. package/src/components/Toolbar/components/PencilButton.tsx +0 -70
  58. package/src/components/Toolbar/components/ShapesButton.tsx +0 -143
  59. package/src/components/Toolbar/components/Slider.tsx +0 -27
  60. package/src/components/Toolbar/components/TextButton.tsx +0 -66
  61. package/src/components/Toolbar/components/UpDownButtons.tsx +0 -49
  62. package/src/components/Toolbar/components/assets/cocos.png +0 -0
  63. package/src/components/Toolbar/components/assets/collapsed.png +0 -0
  64. package/src/components/Toolbar/components/assets/countdown.png +0 -0
  65. package/src/components/Toolbar/components/assets/expanded.png +0 -0
  66. package/src/components/Toolbar/components/assets/geogebra.png +0 -0
  67. package/src/components/Toolbar/components/assets/vscode.png +0 -0
  68. package/src/components/Toolbar/const.ts +0 -32
  69. package/src/components/Toolbar/hooks.ts +0 -112
  70. package/src/components/Toolbar/icons/Apps.tsx +0 -16
  71. package/src/components/Toolbar/icons/Arrow.tsx +0 -16
  72. package/src/components/Toolbar/icons/Circle.tsx +0 -21
  73. package/src/components/Toolbar/icons/Clean.tsx +0 -16
  74. package/src/components/Toolbar/icons/Clicker.tsx +0 -19
  75. package/src/components/Toolbar/icons/Collapse.tsx +0 -17
  76. package/src/components/Toolbar/icons/Diamond.tsx +0 -17
  77. package/src/components/Toolbar/icons/Down.tsx +0 -17
  78. package/src/components/Toolbar/icons/Eraser.tsx +0 -16
  79. package/src/components/Toolbar/icons/Expand.tsx +0 -17
  80. package/src/components/Toolbar/icons/Line.tsx +0 -13
  81. package/src/components/Toolbar/icons/Pencil.tsx +0 -16
  82. package/src/components/Toolbar/icons/Rectangle.tsx +0 -13
  83. package/src/components/Toolbar/icons/Selector.tsx +0 -16
  84. package/src/components/Toolbar/icons/SpeechBalloon.tsx +0 -17
  85. package/src/components/Toolbar/icons/Star.tsx +0 -17
  86. package/src/components/Toolbar/icons/Text.tsx +0 -16
  87. package/src/components/Toolbar/icons/Triangle.tsx +0 -17
  88. package/src/components/Toolbar/icons/Up.tsx +0 -17
  89. package/src/components/Toolbar/icons/index.ts +0 -42
  90. package/src/components/Toolbar/index.ts +0 -2
  91. package/src/components/ZoomControl/ZoomControl.scss +0 -80
  92. package/src/components/ZoomControl/ZoomControl.tsx +0 -109
  93. package/src/components/ZoomControl/hooks.ts +0 -111
  94. package/src/components/ZoomControl/index.ts +0 -2
  95. package/src/components/hooks.ts +0 -80
  96. package/src/i18n/en.json +0 -31
  97. package/src/i18n/index.ts +0 -22
  98. package/src/i18n/zh-CN.json +0 -32
  99. package/src/icons/ChevronLeft.tsx +0 -21
  100. package/src/icons/ChevronRight.tsx +0 -21
  101. package/src/icons/FilePlus.tsx +0 -18
  102. package/src/icons/Minus.tsx +0 -21
  103. package/src/icons/Plus.tsx +0 -21
  104. package/src/icons/Redo.tsx +0 -24
  105. package/src/icons/Reset.tsx +0 -23
  106. package/src/icons/Undo.tsx +0 -24
  107. package/src/icons/index.tsx +0 -11
  108. package/src/internal/Instance.tsx +0 -275
  109. package/src/internal/helpers.ts +0 -86
  110. package/src/internal/hooks.ts +0 -9
  111. package/src/internal/index.ts +0 -3
  112. package/src/internal/mount-whiteboard.ts +0 -90
  113. package/src/react.tsx +0 -52
  114. package/src/style.scss +0 -35
  115. package/src/svelte.ts +0 -45
  116. package/src/theme/index.ts +0 -36
  117. package/src/types/index.ts +0 -22
  118. package/src/vue.ts +0 -74
@@ -1,157 +0,0 @@
1
- import type { CommonProps, GenericIcon } from "../../types";
2
- import Tippy from "@tippyjs/react";
3
- import clsx from "clsx";
4
- import RcSlider from "rc-slider";
5
- import React, { useEffect, useState } from "react";
6
- import { PlayerPhase, type Player } from "white-web-sdk";
7
-
8
- import { Icon } from "../../icons";
9
- import { themes, TopOffset } from "../../theme";
10
- import { Button } from "./components/Button";
11
- import { Icons } from "./icons";
12
- import { usePlayerControl } from "./hooks";
13
-
14
- export type PlayerControlProps = {
15
- autoHide?: boolean;
16
- player?: Player;
17
- } & Omit<CommonProps, "room"> &
18
- GenericIcon<"play" | "pause" | "loading">;
19
-
20
- export const name = "fastboard-player-control";
21
-
22
- export function PlayerControl({
23
- autoHide = false,
24
- player: player_,
25
- theme = "light",
26
- i18n,
27
- ...icons
28
- }: PlayerControlProps) {
29
- const [currentTime, setCurrentTime] = useState(0);
30
- const player = usePlayerControl(player_);
31
-
32
- useEffect(() => {
33
- setCurrentTime(player.currentTime);
34
- }, [player.currentTime]);
35
-
36
- useEffect(() => {
37
- if (player.currentTime !== currentTime) {
38
- player.seekToProgressTime(currentTime);
39
- }
40
- // eslint-disable-next-line react-hooks/exhaustive-deps
41
- }, [currentTime]);
42
-
43
- const isLoading =
44
- player.phase === PlayerPhase.WaitingFirstFrame ||
45
- player.phase === PlayerPhase.Buffering;
46
- const isPlaying = player.phase === PlayerPhase.Playing;
47
-
48
- const { activeColor } = themes[theme];
49
-
50
- return (
51
- <div className={clsx(name, theme, { "auto-hide": autoHide })}>
52
- <button
53
- className={clsx(
54
- `${name}-btn`,
55
- isLoading ? "loading" : isPlaying ? "pause" : "play",
56
- theme
57
- )}
58
- disabled={isLoading}
59
- onClick={player.togglePlay}
60
- >
61
- <Icon
62
- fallback={
63
- isLoading ? (
64
- <Icons.Loading theme={theme} />
65
- ) : isPlaying ? (
66
- <Icons.Pause theme={theme} />
67
- ) : (
68
- <Icons.Play theme={theme} />
69
- )
70
- }
71
- src={
72
- isLoading
73
- ? icons.loadingIcon
74
- : isPlaying
75
- ? icons.pauseIcon
76
- : icons.playIcon
77
- }
78
- alt={isLoading ? "[loading]" : isPlaying ? "[pause]" : "[play]"}
79
- />
80
- </button>
81
- <span className={clsx(`${name}-slider`, { loading: isLoading }, theme)}>
82
- <RcSlider
83
- disabled={isLoading}
84
- trackStyle={{ background: activeColor }}
85
- handleStyle={{ border: `1px solid ${activeColor}` }}
86
- value={currentTime}
87
- onChange={setCurrentTime}
88
- min={0}
89
- max={player.totalTime}
90
- step={100}
91
- />
92
- </span>
93
- <span className={clsx(`${name}-current`, theme)}>
94
- {renderTime(player.currentTime)}
95
- </span>
96
- <span className={clsx(`${name}-slash`, theme)}>/</span>
97
- <span className={clsx(`${name}-total`, theme)}>
98
- {renderTime(player.totalTime)}
99
- </span>
100
- <span className={`${name}-btn-interactive`}>
101
- <Tippy
102
- className="fastboard-tip"
103
- content={renderSpeeds(player)}
104
- theme={theme}
105
- placement="top-end"
106
- trigger="click"
107
- offset={TopOffset}
108
- arrow={false}
109
- interactive
110
- >
111
- <Button content={i18n?.t("speed")} theme={theme} disabled={isLoading}>
112
- <span className={clsx(`${name}-speed-text`, theme)}>
113
- {player.speed}x
114
- </span>
115
- </Button>
116
- </Tippy>
117
- </span>
118
- </div>
119
- );
120
- }
121
-
122
- function renderTime(ms: number) {
123
- let seconds = ms / 1000;
124
- const minutes = Math.floor(seconds / 60);
125
- seconds = Math.floor(seconds) % 60;
126
-
127
- return (
128
- `${String(minutes).padStart(2, "0")}` +
129
- `:${String(seconds).padStart(2, "0")}`
130
- );
131
- }
132
-
133
- const Speeds = [2.0, 1.5, 1.25, 1.0, 0.75, 0.5];
134
-
135
- function renderSpeeds({
136
- speed: current,
137
- setSpeed,
138
- }: {
139
- speed: number;
140
- setSpeed: (speed: number) => void;
141
- }) {
142
- return (
143
- <div className={clsx(`${name}-panel`, "speed")}>
144
- {Speeds.map(speed => (
145
- <button
146
- className={clsx(`${name}-btn`, "speed", {
147
- active: speed === current,
148
- })}
149
- key={speed}
150
- onClick={() => setSpeed(speed)}
151
- >
152
- {speed}x
153
- </button>
154
- ))}
155
- </div>
156
- );
157
- }
@@ -1,55 +0,0 @@
1
- import type { Placement } from "tippy.js";
2
- import type { Theme } from "../../../types";
3
-
4
- import clsx from "clsx";
5
- import React, { forwardRef, type PropsWithChildren } from "react";
6
- import Tippy from "@tippyjs/react";
7
-
8
- import { TopOffset } from "../../../theme";
9
-
10
- type ButtonProps = PropsWithChildren<{
11
- theme: Theme;
12
- content: React.ReactNode;
13
- disabled?: boolean;
14
- active?: boolean;
15
- onClick?: () => void;
16
- interactive?: boolean;
17
- placement?: Placement;
18
- }>;
19
-
20
- export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
21
- (props, ref) => {
22
- const {
23
- theme,
24
- content,
25
- disabled,
26
- active,
27
- onClick,
28
- interactive,
29
- placement = "top",
30
- children,
31
- } = props;
32
-
33
- return (
34
- <Tippy
35
- className="fastboard-tip"
36
- content={content}
37
- interactive={interactive}
38
- theme={theme}
39
- disabled={disabled}
40
- placement={placement}
41
- offset={TopOffset}
42
- duration={300}
43
- >
44
- <button
45
- ref={ref}
46
- className={clsx("fastboard-player-control-btn", theme, { active })}
47
- onClick={onClick}
48
- disabled={disabled}
49
- >
50
- {children}
51
- </button>
52
- </Tippy>
53
- );
54
- }
55
- );
@@ -1,88 +0,0 @@
1
- import type { DependencyList } from "react";
2
- import type { Player } from "white-web-sdk";
3
-
4
- import { useCallback, useEffect, useState } from "react";
5
- import { PlayerPhase } from "white-web-sdk";
6
- import { useLastValue } from "../../internal/hooks";
7
-
8
- const EMPTY_ARRAY: DependencyList = [];
9
-
10
- function useForceUpdate() {
11
- const [, forceUpdate_] = useState({});
12
- // eslint-disable-next-line react-hooks/exhaustive-deps
13
- return useCallback(() => forceUpdate_({}), EMPTY_ARRAY);
14
- }
15
-
16
- export function usePlayerControl(player?: Player | null) {
17
- const togglePlay = useCallback(() => {
18
- if (player) {
19
- switch (player.phase) {
20
- case PlayerPhase.WaitingFirstFrame:
21
- case PlayerPhase.Pause:
22
- case PlayerPhase.Ended: {
23
- player.play();
24
- break;
25
- }
26
- case PlayerPhase.Playing: {
27
- player.pause();
28
- break;
29
- }
30
- }
31
- }
32
- }, [player]);
33
-
34
- const seekToProgressTime = useCallback(
35
- (time: number) => {
36
- if (player) {
37
- player.seekToProgressTime(time);
38
- }
39
- },
40
- [player]
41
- );
42
-
43
- const lastPlayer = useLastValue(player);
44
-
45
- const forceUpdate = useForceUpdate();
46
-
47
- const setSpeed = useCallback(
48
- (speed: number) => {
49
- if (player) {
50
- player.playbackSpeed = speed;
51
- forceUpdate();
52
- }
53
- },
54
- [forceUpdate, player]
55
- );
56
-
57
- useEffect(() => {
58
- if (!lastPlayer && player) {
59
- forceUpdate();
60
- }
61
- }, [forceUpdate, lastPlayer, player]);
62
-
63
- useEffect(() => {
64
- if (player) {
65
- player.callbacks.on("onPhaseChanged", forceUpdate);
66
- player.callbacks.on("onProgressTimeChanged", forceUpdate);
67
- return () => {
68
- player.callbacks.off("onPhaseChanged", forceUpdate);
69
- player.callbacks.off("onProgressTimeChanged", forceUpdate);
70
- };
71
- }
72
- }, [forceUpdate, player]);
73
-
74
- const phase = player ? player.phase : PlayerPhase.WaitingFirstFrame;
75
- const currentTime = player ? player.progressTime : 0;
76
- const totalTime = player ? player.timeDuration : 0;
77
- const speed = player ? player.playbackSpeed : 1;
78
-
79
- return {
80
- phase,
81
- currentTime,
82
- totalTime,
83
- speed,
84
- setSpeed,
85
- togglePlay,
86
- seekToProgressTime,
87
- };
88
- }
@@ -1,13 +0,0 @@
1
- import type { IconProps } from "../../../types";
2
-
3
- import React from "react";
4
- import { getStroke } from "../../../theme";
5
-
6
- export const Loading = (props: IconProps) => {
7
- const stroke = getStroke(props);
8
- return (
9
- <svg viewBox="0 0 24 24">
10
- <path d="M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z" fill={stroke}></path>
11
- </svg>
12
- );
13
- };
@@ -1,13 +0,0 @@
1
- import type { IconProps } from "../../../types";
2
-
3
- import React from "react";
4
- import { getStroke } from "../../../theme";
5
-
6
- export const Pause = (props: IconProps) => {
7
- const stroke = getStroke(props);
8
- return (
9
- <svg viewBox="0 0 24 24">
10
- <path d="M14 19h4V5h-4M6 19h4V5H6v14z" fill={stroke}></path>
11
- </svg>
12
- );
13
- };
@@ -1,13 +0,0 @@
1
- import type { IconProps } from "../../../types";
2
-
3
- import React from "react";
4
- import { getStroke } from "../../../theme";
5
-
6
- export const Play = (props: IconProps) => {
7
- const stroke = getStroke(props);
8
- return (
9
- <svg viewBox="0 0 24 24">
10
- <path d="M8 5.14v14l11-7l-11-7z" fill={stroke}></path>
11
- </svg>
12
- );
13
- };
@@ -1,10 +0,0 @@
1
- import { memo } from "react";
2
- import { Loading } from "./Loading";
3
- import { Pause } from "./Pause";
4
- import { Play } from "./Play";
5
-
6
- export const Icons = {
7
- Play: memo(Play),
8
- Pause: memo(Pause),
9
- Loading: memo(Loading),
10
- };
@@ -1,2 +0,0 @@
1
- export * from "./hooks";
2
- export { PlayerControl, name, type PlayerControlProps } from "./PlayerControl";
@@ -1,56 +0,0 @@
1
- $name: "fastboard-redo-undo";
2
-
3
- .#{$name} {
4
- display: inline-flex;
5
- align-items: center;
6
- gap: 4px;
7
- padding: 4px;
8
- border-radius: 4px;
9
- backdrop-filter: blur(2px);
10
- -webkit-backdrop-filter: blur(2px);
11
-
12
- &.light {
13
- color: #333;
14
- background-color: rgba($color: #fff, $alpha: 0.85);
15
- border: 1px solid rgba(0, 0, 0, 0.15);
16
- }
17
-
18
- &.dark {
19
- color: #ddd;
20
- background-color: rgba($color: #333, $alpha: 0.85);
21
- border: 1px solid rgba(0, 0, 0, 0.45);
22
- }
23
- }
24
-
25
- .#{$name}-btn {
26
- appearance: none;
27
- cursor: pointer;
28
- margin: 0;
29
- border: 0;
30
- padding: 0;
31
- width: 24px;
32
- height: 24px;
33
- background-color: transparent;
34
- border-radius: 4px;
35
- font-size: 24px;
36
- line-height: 1;
37
-
38
- svg,
39
- img {
40
- width: 1em;
41
- height: 1em;
42
- }
43
-
44
- &:disabled {
45
- opacity: 0.5;
46
- cursor: not-allowed;
47
- }
48
-
49
- &.light:not(:disabled):hover {
50
- background-color: rgba(51, 129, 255, 0.1);
51
- }
52
-
53
- &.dark:not(:disabled):hover {
54
- background-color: rgba(51, 129, 255, 0.25);
55
- }
56
- }
@@ -1,79 +0,0 @@
1
- import type { CommonProps, GenericIcon } from "../../types";
2
-
3
- import clsx from "clsx";
4
- import React from "react";
5
- import Tippy from "@tippyjs/react";
6
-
7
- import { Icon } from "../../icons";
8
- import { Undo } from "../../icons/Undo";
9
- import { Redo } from "../../icons/Redo";
10
- import { TopOffset } from "../../theme";
11
- import { useWritable } from "../hooks";
12
- import { useRedoUndo } from "./hooks";
13
-
14
- export const name = "fastboard-redo-undo";
15
-
16
- export type RedoUndoProps = CommonProps & GenericIcon<"undo" | "redo">;
17
-
18
- export function RedoUndo({
19
- room,
20
- manager,
21
- theme = "light",
22
- undoIcon,
23
- undoIconDisable,
24
- redoIcon,
25
- redoIconDisable,
26
- i18n,
27
- }: RedoUndoProps) {
28
- const writable = useWritable(room);
29
- const { redoSteps, undoSteps, redo, undo } = useRedoUndo(room, manager);
30
-
31
- const disabled = !writable;
32
-
33
- return (
34
- <div className={clsx(name, theme)}>
35
- <Tippy
36
- className="fastboard-tip"
37
- content={i18n?.t("undo")}
38
- theme={theme}
39
- disabled={disabled}
40
- placement="top"
41
- duration={300}
42
- offset={TopOffset}
43
- >
44
- <button
45
- className={clsx(`${name}-btn`, "undo", theme)}
46
- disabled={disabled || undoSteps === 0}
47
- onClick={undo}
48
- >
49
- <Icon
50
- fallback={<Undo theme={theme} />}
51
- src={undoSteps === 0 ? undoIconDisable : undoIcon}
52
- alt="[undo]"
53
- />
54
- </button>
55
- </Tippy>
56
- <Tippy
57
- className="fastboard-tip"
58
- content={i18n?.t("redo")}
59
- theme={theme}
60
- disabled={disabled}
61
- placement="top"
62
- duration={300}
63
- offset={TopOffset}
64
- >
65
- <button
66
- className={clsx(`${name}-btn`, "redo", theme)}
67
- disabled={disabled || redoSteps === 0}
68
- onClick={redo}
69
- >
70
- <Icon
71
- fallback={<Redo theme={theme} />}
72
- src={redoSteps === 0 ? redoIconDisable : redoIcon}
73
- alt="[redo]"
74
- />
75
- </button>
76
- </Tippy>
77
- </div>
78
- );
79
- }
@@ -1,50 +0,0 @@
1
- import type { WindowManager, Room } from "@netless/window-manager";
2
- import { useCallback, useEffect, useState } from "react";
3
-
4
- export function useRedoUndo(
5
- room?: Room | null,
6
- manager?: WindowManager | null
7
- ) {
8
- const [undoSteps, setUndoSteps] = useState(0);
9
- const [redoSteps, setRedoSteps] = useState(0);
10
-
11
- useEffect(() => {
12
- if (manager) {
13
- manager.mainView.callbacks.on("onCanUndoStepsUpdate", setUndoSteps);
14
- manager.mainView.callbacks.on("onCanRedoStepsUpdate", setRedoSteps);
15
-
16
- return () => {
17
- manager.mainView.callbacks.off("onCanUndoStepsUpdate", setUndoSteps);
18
- manager.mainView.callbacks.off("onCanRedoStepsUpdate", setRedoSteps);
19
- };
20
- }
21
-
22
- if (room) {
23
- room.callbacks.on("onCanUndoStepsUpdate", setUndoSteps);
24
- room.callbacks.on("onCanRedoStepsUpdate", setRedoSteps);
25
-
26
- return () => {
27
- room.callbacks.off("onCanUndoStepsUpdate", setUndoSteps);
28
- room.callbacks.off("onCanRedoStepsUpdate", setRedoSteps);
29
- };
30
- }
31
- }, [room, manager]);
32
-
33
- const undo = useCallback(() => {
34
- if (manager) {
35
- manager.mainView.undo();
36
- } else if (room) {
37
- room.undo();
38
- }
39
- }, [manager, room]);
40
-
41
- const redo = useCallback(() => {
42
- if (manager) {
43
- manager.mainView.redo();
44
- } else if (room) {
45
- room.redo();
46
- }
47
- }, [manager, room]);
48
-
49
- return { redoSteps, undoSteps, redo, undo };
50
- }
@@ -1,2 +0,0 @@
1
- export * from "./hooks";
2
- export { name, RedoUndo, type RedoUndoProps } from "./RedoUndo";
@@ -1,55 +0,0 @@
1
- .fastboard-root {
2
- position: relative;
3
- width: 100%;
4
- height: 100%;
5
- overflow: hidden;
6
- }
7
-
8
- .fastboard-loading {
9
- position: absolute;
10
- top: 0;
11
- left: 0;
12
- width: 100%;
13
- height: 100%;
14
- display: flex;
15
- align-items: center;
16
- justify-content: center;
17
- opacity: 0.6;
18
- }
19
-
20
- .fastboard-view {
21
- position: absolute;
22
- top: 0;
23
- left: 0;
24
- width: 100%;
25
- height: 100%;
26
- }
27
-
28
- $unit: 8px;
29
-
30
- .fastboard-left {
31
- position: absolute;
32
- top: 0;
33
- left: 0;
34
- height: calc(100% - 48px);
35
- padding: $unit * 2;
36
- z-index: 201;
37
- display: flex;
38
- align-items: center;
39
- }
40
-
41
- .fastboard-bottom-left {
42
- display: flex;
43
- gap: 10px;
44
- position: absolute;
45
- bottom: $unit;
46
- left: $unit;
47
- padding: $unit;
48
- z-index: 200;
49
- }
50
-
51
- .fastboard-bottom-right {
52
- @extend .fastboard-bottom-left;
53
- left: initial;
54
- right: $unit;
55
- }
@@ -1,65 +0,0 @@
1
- import React, { useCallback, useState } from "react";
2
-
3
- import { Lock, Instance } from "../internal";
4
- import { Toolbar } from "./Toolbar";
5
- import { RedoUndo } from "./RedoUndo";
6
- import { ZoomControl } from "./ZoomControl";
7
- import { PageControl } from "./PageControl";
8
- import { useHideControls } from "./hooks";
9
-
10
- export interface RootProps {
11
- instance: Instance;
12
- }
13
-
14
- export function Root({ instance: app }: RootProps) {
15
- const [mux] = useState(() => new Lock());
16
-
17
- const useWhiteboard = useCallback(
18
- (container: HTMLDivElement | null) =>
19
- mux.schedule(
20
- container ? () => app.mount(container) : () => app.unmount()
21
- ),
22
- [app, mux]
23
- );
24
-
25
- const hideControls = useHideControls(app.manager);
26
- const showControls = !hideControls;
27
-
28
- const props = {
29
- room: app.room,
30
- manager: app.manager,
31
- i18n: app.i18n,
32
- };
33
-
34
- const {
35
- Toolbar: toolbar = showControls || hideControls === "toolbar-only",
36
- RedoUndo: redo_undo = showControls,
37
- ZoomControl: zoom_control = showControls,
38
- PageControl: page_control = showControls,
39
- } = app.config.layout || {};
40
-
41
- return (
42
- <Instance.Context.Provider value={app}>
43
- <div className="fastboard-root">
44
- {!app.room && <div className="fastboard-loading">Loading&hellip;</div>}
45
- <div className="fastboard-view" ref={useWhiteboard} />
46
- {toolbar && (
47
- <div className="fastboard-left">
48
- <Toolbar {...props} />
49
- </div>
50
- )}
51
- {(redo_undo || zoom_control) && (
52
- <div className="fastboard-bottom-left">
53
- {redo_undo && <RedoUndo {...props} />}
54
- {zoom_control && <ZoomControl {...props} />}
55
- </div>
56
- )}
57
- {page_control && (
58
- <div className="fastboard-bottom-right">
59
- <PageControl {...props} />
60
- </div>
61
- )}
62
- </div>
63
- </Instance.Context.Provider>
64
- );
65
- }