@netless/fastboard 0.0.4 → 0.0.8

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.
package/dist/index.es.js CHANGED
@@ -17,12 +17,24 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
20
32
  var __publicField = (obj, key, value) => {
21
33
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
34
  return value;
23
35
  };
24
36
  import { WindowManager } from "@netless/window-manager";
25
- import { WhiteWebSdk, DefaultHotKeys, ApplianceNames, ShapeType } from "white-web-sdk";
37
+ import { WhiteWebSdk, DefaultHotKeys, ApplianceNames, ShapeType, PlayerPhase } from "white-web-sdk";
26
38
  import i18next from "i18next";
27
39
  import require$$0, { memo, forwardRef, useContext, useCallback, useState, useEffect, useRef, createContext } from "react";
28
40
  import ReactDOM from "react-dom";
@@ -580,7 +592,7 @@ const Up = (props) => {
580
592
  })
581
593
  });
582
594
  };
583
- const Icons = {
595
+ const Icons$1 = {
584
596
  Clicker: memo(Clicker),
585
597
  Collapse: memo(Collapse),
586
598
  Eraser: memo(Eraser),
@@ -601,7 +613,7 @@ const Icons = {
601
613
  Up: memo(Up),
602
614
  Down: memo(Down)
603
615
  };
604
- const Button = forwardRef((props, ref) => {
616
+ const Button$1 = forwardRef((props, ref) => {
605
617
  const {
606
618
  content,
607
619
  disabled,
@@ -640,7 +652,7 @@ function CutLine() {
640
652
  theme
641
653
  } = useContext(ToolbarContext);
642
654
  return /* @__PURE__ */ jsx("span", {
643
- className: clsx(`${name$3}-cut-line`, theme)
655
+ className: clsx(`${name$4}-cut-line`, theme)
644
656
  });
645
657
  }
646
658
  function useWritable(room) {
@@ -714,14 +726,14 @@ const EmptyToolbarHook = {
714
726
  setStrokeColor: noop
715
727
  };
716
728
  const ShapesMap = {
717
- [ApplianceNames.rectangle]: Icons.Rectangle,
718
- [ApplianceNames.ellipse]: Icons.Circle,
719
- [ApplianceNames.straight]: Icons.Line,
720
- [ApplianceNames.arrow]: Icons.Arrow,
721
- [ShapeType.Pentagram]: Icons.Star,
722
- [ShapeType.Rhombus]: Icons.Diamond,
723
- [ShapeType.Triangle]: Icons.Triangle,
724
- [ShapeType.SpeechBalloon]: Icons.SpeechBalloon
729
+ [ApplianceNames.rectangle]: Icons$1.Rectangle,
730
+ [ApplianceNames.ellipse]: Icons$1.Circle,
731
+ [ApplianceNames.straight]: Icons$1.Line,
732
+ [ApplianceNames.arrow]: Icons$1.Arrow,
733
+ [ShapeType.Pentagram]: Icons$1.Star,
734
+ [ShapeType.Rhombus]: Icons$1.Diamond,
735
+ [ShapeType.Triangle]: Icons$1.Triangle,
736
+ [ShapeType.SpeechBalloon]: Icons$1.SpeechBalloon
725
737
  };
726
738
  const ApplianceShapes = [
727
739
  ApplianceNames.rectangle,
@@ -749,12 +761,12 @@ function UpButton({
749
761
  } = useContext(ToolbarContext);
750
762
  const scrollUp = useCallback(() => scrollTo(-ItemHeight), [scrollTo]);
751
763
  return /* @__PURE__ */ jsxs(Fragment, {
752
- children: [/* @__PURE__ */ jsx(Button, {
764
+ children: [/* @__PURE__ */ jsx(Button$1, {
753
765
  content: "Up",
754
766
  disabled,
755
767
  onClick: scrollUp,
756
768
  children: /* @__PURE__ */ jsx(Icon, {
757
- fallback: /* @__PURE__ */ jsx(Icons.Up, {
769
+ fallback: /* @__PURE__ */ jsx(Icons$1.Up, {
758
770
  theme
759
771
  }),
760
772
  src: disabled ? icons == null ? void 0 : icons.upIconDisable : icons == null ? void 0 : icons.upIcon,
@@ -773,12 +785,12 @@ function DownButton({
773
785
  } = useContext(ToolbarContext);
774
786
  const scrollDown = useCallback(() => scrollTo(ItemHeight), [scrollTo]);
775
787
  return /* @__PURE__ */ jsxs(Fragment, {
776
- children: [/* @__PURE__ */ jsx(CutLine, {}), /* @__PURE__ */ jsx(Button, {
788
+ children: [/* @__PURE__ */ jsx(CutLine, {}), /* @__PURE__ */ jsx(Button$1, {
777
789
  content: "Down",
778
790
  disabled,
779
791
  onClick: scrollDown,
780
792
  children: /* @__PURE__ */ jsx(Icon, {
781
- fallback: /* @__PURE__ */ jsx(Icons.Down, {
793
+ fallback: /* @__PURE__ */ jsx(Icons$1.Down, {
782
794
  theme
783
795
  }),
784
796
  src: disabled ? icons == null ? void 0 : icons.downIconDisable : icons == null ? void 0 : icons.downIcon,
@@ -816,12 +828,12 @@ function ClickerButton() {
816
828
  const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
817
829
  const active = appliance === ApplianceNames.clicker;
818
830
  const disabled = !writable;
819
- return /* @__PURE__ */ jsx(Button, {
831
+ return /* @__PURE__ */ jsx(Button$1, {
820
832
  content: renderToolTip(i18n == null ? void 0 : i18n.t("clicker"), shortcut),
821
833
  onClick: changeAppliance,
822
834
  active,
823
835
  children: /* @__PURE__ */ jsx(Icon, {
824
- fallback: /* @__PURE__ */ jsx(Icons.Clicker, {
836
+ fallback: /* @__PURE__ */ jsx(Icons$1.Clicker, {
825
837
  theme,
826
838
  active
827
839
  }),
@@ -845,12 +857,12 @@ function SelectorButton() {
845
857
  const active = appliance === ApplianceNames.selector;
846
858
  const disabled = !writable;
847
859
  const shortcut = ((app == null ? void 0 : app.config.joinRoom.hotKeys) || defaultHotKeys).changeToSelector;
848
- return /* @__PURE__ */ jsx(Button, {
860
+ return /* @__PURE__ */ jsx(Button$1, {
849
861
  content: renderToolTip(i18n == null ? void 0 : i18n.t("selector"), shortcut),
850
862
  onClick: changeAppliance,
851
863
  active,
852
864
  children: /* @__PURE__ */ jsx(Icon, {
853
- fallback: /* @__PURE__ */ jsx(Icons.Selector, {
865
+ fallback: /* @__PURE__ */ jsx(Icons$1.Selector, {
854
866
  theme,
855
867
  active
856
868
  }),
@@ -874,12 +886,12 @@ function EraserButton() {
874
886
  const active = appliance === ApplianceNames.eraser;
875
887
  const disabled = !writable;
876
888
  const shortcut = ((app == null ? void 0 : app.config.joinRoom.hotKeys) || defaultHotKeys).changeToEraser;
877
- return /* @__PURE__ */ jsx(Button, {
889
+ return /* @__PURE__ */ jsx(Button$1, {
878
890
  content: renderToolTip(i18n == null ? void 0 : i18n.t("eraser"), shortcut),
879
891
  onClick: changeAppliance,
880
892
  active,
881
893
  children: /* @__PURE__ */ jsx(Icon, {
882
- fallback: /* @__PURE__ */ jsx(Icons.Eraser, {
894
+ fallback: /* @__PURE__ */ jsx(Icons$1.Eraser, {
883
895
  theme,
884
896
  active
885
897
  }),
@@ -897,11 +909,11 @@ function CleanButton() {
897
909
  i18n
898
910
  } = useContext(ToolbarContext);
899
911
  const disabled = !writable;
900
- return /* @__PURE__ */ jsx(Button, {
912
+ return /* @__PURE__ */ jsx(Button$1, {
901
913
  content: i18n == null ? void 0 : i18n.t("clean"),
902
914
  onClick: cleanCurrentScene,
903
915
  children: /* @__PURE__ */ jsx(Icon, {
904
- fallback: /* @__PURE__ */ jsx(Icons.Clean, {
916
+ fallback: /* @__PURE__ */ jsx(Icons$1.Clean, {
905
917
  theme
906
918
  }),
907
919
  src: disabled ? icons == null ? void 0 : icons.cleanIconDisable : icons == null ? void 0 : icons.cleanIcon,
@@ -922,11 +934,11 @@ function AppsButton({
922
934
  writable
923
935
  } = useContext(ToolbarContext);
924
936
  const disabled = !writable;
925
- const button = /* @__PURE__ */ jsx(Button, {
937
+ const button = /* @__PURE__ */ jsx(Button$1, {
926
938
  content: "Apps",
927
939
  onClick,
928
940
  children: /* @__PURE__ */ jsx(Icon, {
929
- fallback: /* @__PURE__ */ jsx(Icons.Apps, {
941
+ fallback: /* @__PURE__ */ jsx(Icons$1.Apps, {
930
942
  theme
931
943
  }),
932
944
  src: disabled ? icons == null ? void 0 : icons.appsIconDisable : icons == null ? void 0 : icons.appsIcon,
@@ -986,7 +998,7 @@ function AppIcon({
986
998
  }) {
987
999
  return /* @__PURE__ */ jsxs("span", {
988
1000
  className: "fastboard-toolbar-app-icon",
989
- children: [/* @__PURE__ */ jsx(Button, {
1001
+ children: [/* @__PURE__ */ jsx(Button$1, {
990
1002
  placement: "top",
991
1003
  content: title,
992
1004
  onClick,
@@ -1099,12 +1111,12 @@ function PencilButton() {
1099
1111
  offset: RightOffset,
1100
1112
  arrow: false,
1101
1113
  interactive: true,
1102
- children: /* @__PURE__ */ jsxs(Button, {
1114
+ children: /* @__PURE__ */ jsxs(Button$1, {
1103
1115
  content: renderToolTip(i18n == null ? void 0 : i18n.t("pencil"), shortcut),
1104
1116
  active,
1105
1117
  onClick: changeAppliance,
1106
1118
  children: [/* @__PURE__ */ jsx(Icon, {
1107
- fallback: /* @__PURE__ */ jsx(Icons.Pencil, {
1119
+ fallback: /* @__PURE__ */ jsx(Icons$1.Pencil, {
1108
1120
  theme,
1109
1121
  active
1110
1122
  }),
@@ -1151,12 +1163,12 @@ function TextButton() {
1151
1163
  offset: RightOffset,
1152
1164
  arrow: false,
1153
1165
  interactive: true,
1154
- children: /* @__PURE__ */ jsxs(Button, {
1166
+ children: /* @__PURE__ */ jsxs(Button$1, {
1155
1167
  content: renderToolTip(i18n == null ? void 0 : i18n.t("text"), shortcut),
1156
1168
  active,
1157
1169
  onClick: changeAppliance,
1158
1170
  children: [/* @__PURE__ */ jsx(Icon, {
1159
- fallback: /* @__PURE__ */ jsx(Icons.Text, {
1171
+ fallback: /* @__PURE__ */ jsx(Icons$1.Text, {
1160
1172
  theme,
1161
1173
  active
1162
1174
  }),
@@ -1186,7 +1198,7 @@ function ShapesButton() {
1186
1198
  const shape = memberState == null ? void 0 : memberState.shapeType;
1187
1199
  const key = appliance === ApplianceNames.shape ? shape : appliance;
1188
1200
  const active = ShapeTypes.has(key);
1189
- const CurrentIcon = ShapesMap[key] || Icons.Rectangle;
1201
+ const CurrentIcon = ShapesMap[key] || Icons$1.Rectangle;
1190
1202
  return /* @__PURE__ */ jsx("span", {
1191
1203
  className: "fastboard-toolbar-btn-interactive",
1192
1204
  children: /* @__PURE__ */ jsx(Tippy, {
@@ -1198,7 +1210,7 @@ function ShapesButton() {
1198
1210
  offset: RightOffset,
1199
1211
  arrow: false,
1200
1212
  interactive: true,
1201
- children: /* @__PURE__ */ jsxs(Button, {
1213
+ children: /* @__PURE__ */ jsxs(Button$1, {
1202
1214
  content: i18n == null ? void 0 : i18n.t("shape"),
1203
1215
  active,
1204
1216
  children: [/* @__PURE__ */ jsx(CurrentIcon, {
@@ -1247,7 +1259,7 @@ function ApplianceShapeButton({
1247
1259
  } = useContext(ToolbarContext);
1248
1260
  const current = memberState == null ? void 0 : memberState.currentApplianceName;
1249
1261
  const disabled = !writable;
1250
- return /* @__PURE__ */ jsx(Button, {
1262
+ return /* @__PURE__ */ jsx(Button$1, {
1251
1263
  content,
1252
1264
  disabled,
1253
1265
  placement: "top",
@@ -1272,7 +1284,7 @@ function ShapeShapeButton({
1272
1284
  const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1273
1285
  const current = appliance === ApplianceNames.shape && (memberState == null ? void 0 : memberState.shapeType);
1274
1286
  const disabled = !writable;
1275
- return /* @__PURE__ */ jsx(Button, {
1287
+ return /* @__PURE__ */ jsx(Button$1, {
1276
1288
  content,
1277
1289
  disabled,
1278
1290
  placement: "top",
@@ -1325,7 +1337,7 @@ function Content() {
1325
1337
  disabled: disableScrollUp
1326
1338
  }), /* @__PURE__ */ jsxs("div", {
1327
1339
  ref,
1328
- className: `${name$3}-section`,
1340
+ className: `${name$4}-section`,
1329
1341
  style: {
1330
1342
  height: `${sectionHeight}px`,
1331
1343
  overflow: needScroll ? "hidden" : "visible"
@@ -1343,7 +1355,7 @@ function Content() {
1343
1355
  const ToolbarContext = createContext(__spreadValues({
1344
1356
  theme: "light"
1345
1357
  }, EmptyToolbarHook));
1346
- const name$3 = "fastboard-toolbar";
1358
+ const name$4 = "fastboard-toolbar";
1347
1359
  const Toolbar = ({
1348
1360
  theme = "light",
1349
1361
  icons,
@@ -1362,21 +1374,21 @@ const Toolbar = ({
1362
1374
  i18n
1363
1375
  }),
1364
1376
  children: /* @__PURE__ */ jsxs("div", {
1365
- className: clsx(name$3, theme),
1366
- children: [expanded ? /* @__PURE__ */ jsx(Button, {
1377
+ className: clsx(name$4, theme),
1378
+ children: [expanded ? /* @__PURE__ */ jsx(Button$1, {
1367
1379
  content: i18n == null ? void 0 : i18n.t("collapse"),
1368
1380
  onClick: toggle,
1369
1381
  children: /* @__PURE__ */ jsx(Icon, {
1370
- fallback: /* @__PURE__ */ jsx(Icons.Collapse, {
1382
+ fallback: /* @__PURE__ */ jsx(Icons$1.Collapse, {
1371
1383
  theme
1372
1384
  }),
1373
1385
  src: disabled ? icons == null ? void 0 : icons.collapseIconDisable : icons == null ? void 0 : icons.collapseIcon
1374
1386
  })
1375
- }) : /* @__PURE__ */ jsx(Button, {
1387
+ }) : /* @__PURE__ */ jsx(Button$1, {
1376
1388
  content: i18n == null ? void 0 : i18n.t("expand"),
1377
1389
  onClick: toggle,
1378
1390
  children: /* @__PURE__ */ jsx(Icon, {
1379
- fallback: /* @__PURE__ */ jsx(Icons.Expand, {
1391
+ fallback: /* @__PURE__ */ jsx(Icons$1.Expand, {
1380
1392
  theme
1381
1393
  }),
1382
1394
  src: disabled ? icons == null ? void 0 : icons.expandIconDisable : icons == null ? void 0 : icons.expandIcon
@@ -1431,7 +1443,7 @@ function Redo({
1431
1443
  })
1432
1444
  });
1433
1445
  }
1434
- const name$2 = "fastboard-redo-undo";
1446
+ const name$3 = "fastboard-redo-undo";
1435
1447
  function RedoUndo({
1436
1448
  room,
1437
1449
  theme = "light",
@@ -1461,7 +1473,7 @@ function RedoUndo({
1461
1473
  }, [room]);
1462
1474
  const disabled = !writable;
1463
1475
  return /* @__PURE__ */ jsxs("div", {
1464
- className: clsx(name$2, theme),
1476
+ className: clsx(name$3, theme),
1465
1477
  children: [/* @__PURE__ */ jsx(Tippy, {
1466
1478
  className: "fastboard-tip",
1467
1479
  content: i18n == null ? void 0 : i18n.t("undo"),
@@ -1471,7 +1483,7 @@ function RedoUndo({
1471
1483
  duration: 300,
1472
1484
  offset: TopOffset,
1473
1485
  children: /* @__PURE__ */ jsx("button", {
1474
- className: clsx(`${name$2}-btn`, "undo", theme),
1486
+ className: clsx(`${name$3}-btn`, "undo", theme),
1475
1487
  disabled: disabled || undoSteps === 0,
1476
1488
  onClick: useCallback(() => room && room.undo(), [room]),
1477
1489
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1491,7 +1503,7 @@ function RedoUndo({
1491
1503
  duration: 300,
1492
1504
  offset: TopOffset,
1493
1505
  children: /* @__PURE__ */ jsx("button", {
1494
- className: clsx(`${name$2}-btn`, "redo", theme),
1506
+ className: clsx(`${name$3}-btn`, "redo", theme),
1495
1507
  disabled: disabled || redoSteps === 0,
1496
1508
  onClick: useCallback(() => room && room.redo(), [room]),
1497
1509
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1569,7 +1581,7 @@ function Reset({
1569
1581
  })
1570
1582
  });
1571
1583
  }
1572
- const name$1 = "fastboard-zoom-control";
1584
+ const name$2 = "fastboard-zoom-control";
1573
1585
  const ScalePoints = [0.10737418240000011, 0.13421772800000012, 0.16777216000000014, 0.20971520000000016, 0.26214400000000015, 0.3276800000000002, 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26, 1.5876000000000001, 2.000376, 2.5204737600000002, 3.1757969376000004, 4.001504141376, 5.041895218133761, 6.352787974848539, 8.00451284830916, 10];
1574
1586
  function nextScale(scale, delta) {
1575
1587
  const {
@@ -1697,7 +1709,7 @@ function ZoomControl({
1697
1709
  }, [room, manager]);
1698
1710
  const disabled = !writable;
1699
1711
  return /* @__PURE__ */ jsxs("div", {
1700
- className: clsx(name$1, theme),
1712
+ className: clsx(name$2, theme),
1701
1713
  children: [/* @__PURE__ */ jsx(Tippy, {
1702
1714
  className: "fastboard-tip",
1703
1715
  content: i18n == null ? void 0 : i18n.t("zoomOut"),
@@ -1707,7 +1719,7 @@ function ZoomControl({
1707
1719
  duration: 300,
1708
1720
  offset: TopOffset,
1709
1721
  children: /* @__PURE__ */ jsx("button", {
1710
- className: clsx(`${name$1}-btn`, "minus", theme),
1722
+ className: clsx(`${name$2}-btn`, "minus", theme),
1711
1723
  disabled,
1712
1724
  onClick: zoomOut,
1713
1725
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1719,10 +1731,10 @@ function ZoomControl({
1719
1731
  })
1720
1732
  })
1721
1733
  }), /* @__PURE__ */ jsx("span", {
1722
- className: clsx(`${name$1}-scale`, theme),
1734
+ className: clsx(`${name$2}-scale`, theme),
1723
1735
  children: Math.ceil(scale * 100)
1724
1736
  }), /* @__PURE__ */ jsx("span", {
1725
- className: clsx(`${name$1}-percent`, theme),
1737
+ className: clsx(`${name$2}-percent`, theme),
1726
1738
  children: "%"
1727
1739
  }), /* @__PURE__ */ jsx(Tippy, {
1728
1740
  className: "fastboard-tip",
@@ -1733,7 +1745,7 @@ function ZoomControl({
1733
1745
  duration: 300,
1734
1746
  offset: TopOffset,
1735
1747
  children: /* @__PURE__ */ jsx("button", {
1736
- className: clsx(`${name$1}-btn`, "plus", theme),
1748
+ className: clsx(`${name$2}-btn`, "plus", theme),
1737
1749
  disabled,
1738
1750
  onClick: zoomIn,
1739
1751
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1753,7 +1765,7 @@ function ZoomControl({
1753
1765
  duration: 300,
1754
1766
  offset: TopOffset,
1755
1767
  children: /* @__PURE__ */ jsx("button", {
1756
- className: clsx(`${name$1}-btn`, "reset", theme),
1768
+ className: clsx(`${name$2}-btn`, "reset", theme),
1757
1769
  disabled,
1758
1770
  onClick: resetCamera,
1759
1771
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1815,7 +1827,7 @@ function ChevronRight({
1815
1827
  })
1816
1828
  });
1817
1829
  }
1818
- const name = "fastboard-page-control";
1830
+ const name$1 = "fastboard-page-control";
1819
1831
  function PageControl({
1820
1832
  room,
1821
1833
  manager,
@@ -1835,14 +1847,14 @@ function PageControl({
1835
1847
  if (manager && room) {
1836
1848
  await manager.switchMainViewToWriter();
1837
1849
  const path = room.state.sceneState.contextPath;
1838
- room.putScenes(path, [{}], pageCount);
1839
- await manager.setMainViewSceneIndex(pageIndex);
1850
+ room.putScenes(path, [{}], pageIndex + 1);
1851
+ await manager.setMainViewSceneIndex(pageIndex + 1);
1840
1852
  } else if (!manager && room) {
1841
1853
  const path = room.state.sceneState.contextPath;
1842
- room.putScenes(path, [{}], pageCount);
1843
- room.setSceneIndex(pageIndex);
1854
+ room.putScenes(path, [{}], pageIndex + 1);
1855
+ room.setSceneIndex(pageIndex + 1);
1844
1856
  }
1845
- }, [room, manager, pageCount, pageIndex]);
1857
+ }, [room, manager, pageIndex]);
1846
1858
  const prevPage = useCallback(() => {
1847
1859
  if (room == null ? void 0 : room.isWritable) {
1848
1860
  if (manager) {
@@ -1895,7 +1907,7 @@ function PageControl({
1895
1907
  }, [room, manager]);
1896
1908
  const disabled = !writable;
1897
1909
  return /* @__PURE__ */ jsxs("div", {
1898
- className: clsx(name, theme),
1910
+ className: clsx(name$1, theme),
1899
1911
  children: [/* @__PURE__ */ jsx(Tippy, {
1900
1912
  className: "fastboard-tip",
1901
1913
  content: i18n == null ? void 0 : i18n.t("prevPage"),
@@ -1905,7 +1917,7 @@ function PageControl({
1905
1917
  duration: 300,
1906
1918
  offset: TopOffset,
1907
1919
  children: /* @__PURE__ */ jsx("button", {
1908
- className: clsx(`${name}-btn`, "prev", theme),
1920
+ className: clsx(`${name$1}-btn`, "prev", theme),
1909
1921
  disabled: disabled || pageIndex === 0,
1910
1922
  onClick: prevPage,
1911
1923
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1917,13 +1929,13 @@ function PageControl({
1917
1929
  })
1918
1930
  })
1919
1931
  }), /* @__PURE__ */ jsx("span", {
1920
- className: clsx(`${name}-page`, theme),
1932
+ className: clsx(`${name$1}-page`, theme),
1921
1933
  children: pageCount === 0 ? "\u2026" : pageIndex + 1
1922
1934
  }), /* @__PURE__ */ jsx("span", {
1923
- className: clsx(`${name}-slash`, theme),
1935
+ className: clsx(`${name$1}-slash`, theme),
1924
1936
  children: "/"
1925
1937
  }), /* @__PURE__ */ jsx("span", {
1926
- className: clsx(`${name}-page-count`, theme),
1938
+ className: clsx(`${name$1}-page-count`, theme),
1927
1939
  children: pageCount
1928
1940
  }), /* @__PURE__ */ jsx(Tippy, {
1929
1941
  className: "fastboard-tip",
@@ -1934,7 +1946,7 @@ function PageControl({
1934
1946
  duration: 300,
1935
1947
  offset: TopOffset,
1936
1948
  children: /* @__PURE__ */ jsx("button", {
1937
- className: clsx(`${name}-btn`, "next", theme),
1949
+ className: clsx(`${name$1}-btn`, "next", theme),
1938
1950
  disabled: disabled || pageIndex === pageCount - 1,
1939
1951
  onClick: nextPage,
1940
1952
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1954,7 +1966,7 @@ function PageControl({
1954
1966
  duration: 300,
1955
1967
  offset: TopOffset,
1956
1968
  children: /* @__PURE__ */ jsx("button", {
1957
- className: clsx(`${name}-btn`, "add", theme),
1969
+ className: clsx(`${name$1}-btn`, "add", theme),
1958
1970
  disabled,
1959
1971
  onClick: addPage,
1960
1972
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1973,6 +1985,17 @@ function Root({
1973
1985
  }) {
1974
1986
  const [mux] = useState(() => new Lock());
1975
1987
  const useWhiteboard = useCallback((container) => mux.schedule(container ? () => app.mount(container) : () => app.unmount()), [app, mux]);
1988
+ const {
1989
+ Toolbar: toolbar = true,
1990
+ RedoUndo: redo_undo = true,
1991
+ ZoomControl: zoom_control = true,
1992
+ PageControl: page_control = true
1993
+ } = app.config.layout || {};
1994
+ const props = {
1995
+ room: app.room,
1996
+ manager: app.manager,
1997
+ i18n: app.i18n
1998
+ };
1976
1999
  return /* @__PURE__ */ jsx(Instance.Context.Provider, {
1977
2000
  value: app,
1978
2001
  children: /* @__PURE__ */ jsxs("div", {
@@ -1983,31 +2006,15 @@ function Root({
1983
2006
  }), /* @__PURE__ */ jsx("div", {
1984
2007
  className: "fastboard-view",
1985
2008
  ref: useWhiteboard
1986
- }), /* @__PURE__ */ jsx("div", {
2009
+ }), toolbar && /* @__PURE__ */ jsx("div", {
1987
2010
  className: "fastboard-left",
1988
- children: /* @__PURE__ */ jsx(Toolbar, {
1989
- room: app.room,
1990
- manager: app.manager,
1991
- i18n: app.i18n
1992
- })
1993
- }), /* @__PURE__ */ jsxs("div", {
2011
+ children: /* @__PURE__ */ jsx(Toolbar, __spreadValues({}, props))
2012
+ }), (redo_undo || zoom_control) && /* @__PURE__ */ jsxs("div", {
1994
2013
  className: "fastboard-bottom-left",
1995
- children: [/* @__PURE__ */ jsx(RedoUndo, {
1996
- room: app.room,
1997
- manager: app.manager,
1998
- i18n: app.i18n
1999
- }), /* @__PURE__ */ jsx(ZoomControl, {
2000
- room: app.room,
2001
- manager: app.manager,
2002
- i18n: app.i18n
2003
- })]
2004
- }), /* @__PURE__ */ jsx("div", {
2014
+ children: [redo_undo && /* @__PURE__ */ jsx(RedoUndo, __spreadValues({}, props)), zoom_control && /* @__PURE__ */ jsx(ZoomControl, __spreadValues({}, props))]
2015
+ }), page_control && /* @__PURE__ */ jsx("div", {
2005
2016
  className: "fastboard-bottom-right",
2006
- children: /* @__PURE__ */ jsx(PageControl, {
2007
- room: app.room,
2008
- manager: app.manager,
2009
- i18n: app.i18n
2010
- })
2017
+ children: /* @__PURE__ */ jsx(PageControl, __spreadValues({}, props))
2011
2018
  })]
2012
2019
  })
2013
2020
  });
@@ -2022,8 +2029,9 @@ class Instance {
2022
2029
  __publicField(this, "ready", false);
2023
2030
  __publicField(this, "resolveReady");
2024
2031
  __publicField(this, "readyPromise");
2025
- __publicField(this, "_target", null);
2026
- this.config = config;
2032
+ __publicField(this, "target", null);
2033
+ __publicField(this, "collector", null);
2034
+ this.config = __spreadValues({}, config);
2027
2035
  this.refreshReadyPromise();
2028
2036
  this.initialize();
2029
2037
  }
@@ -2041,14 +2049,16 @@ class Instance {
2041
2049
  this.accept(essentials);
2042
2050
  this.resolveReady();
2043
2051
  }
2044
- get target() {
2045
- return this._target;
2046
- }
2047
- set target(value) {
2048
- if (this._target && value) {
2049
- ReactDOM.unmountComponentAtNode(this._target);
2052
+ bindElement(target, collector) {
2053
+ if (this.target && target) {
2054
+ ReactDOM.unmountComponentAtNode(this.target);
2050
2055
  }
2051
- this._target = value;
2056
+ this.target = target;
2057
+ this.collector = collector;
2058
+ this.forceUpdate();
2059
+ }
2060
+ updateLayout(layout) {
2061
+ this.config.layout = layout;
2052
2062
  this.forceUpdate();
2053
2063
  }
2054
2064
  async forceUpdate() {
@@ -2082,7 +2092,12 @@ class Instance {
2082
2092
  }
2083
2093
  async mount(node) {
2084
2094
  await this.readyPromise;
2085
- if (this.manager) {
2095
+ if (!this.manager) {
2096
+ throw new Error(`[WhiteboardApp] mounted, but not found window manager`);
2097
+ }
2098
+ if (this.collector) {
2099
+ this.manager.bindContainer(node, this.collector);
2100
+ } else {
2086
2101
  this.manager.bindContainer(node);
2087
2102
  }
2088
2103
  }
@@ -2183,12 +2198,45 @@ class WhiteboardApp {
2183
2198
  this.config = config;
2184
2199
  this._instance = new Instance(config);
2185
2200
  }
2186
- bindElement(target) {
2187
- this._instance.target = target || null;
2201
+ get room() {
2202
+ return this._instance.room;
2203
+ }
2204
+ get manager() {
2205
+ return this._instance.manager;
2206
+ }
2207
+ get sdk() {
2208
+ return this._instance.sdk;
2209
+ }
2210
+ get i18n() {
2211
+ return this._instance.i18n;
2212
+ }
2213
+ get target() {
2214
+ return this._instance.target;
2215
+ }
2216
+ get collector() {
2217
+ return this._instance.collector;
2218
+ }
2219
+ bindElement(target, collector) {
2220
+ this._instance.bindElement(target || null, collector || null);
2221
+ }
2222
+ get layout() {
2223
+ return this._instance.config.layout;
2224
+ }
2225
+ updateLayout(layout) {
2226
+ this._instance.updateLayout(layout);
2188
2227
  }
2189
2228
  insertDocs(params) {
2190
2229
  return this._instance.insertDocs(params);
2191
2230
  }
2231
+ insertCodeEditor() {
2232
+ return this._instance.insertCodeEditor();
2233
+ }
2234
+ insertGeoGebra() {
2235
+ return this._instance.insertGeoGebra();
2236
+ }
2237
+ insertCountdown() {
2238
+ return this._instance.insertCountdown();
2239
+ }
2192
2240
  changeLanguage(language) {
2193
2241
  return this._instance.changeLanguage(language);
2194
2242
  }
@@ -2196,10 +2244,268 @@ class WhiteboardApp {
2196
2244
  return this._instance.dispose();
2197
2245
  }
2198
2246
  }
2199
- const version = "0.0.4";
2247
+ const version = "0.0.8";
2248
+ const EMPTY_ARRAY = [];
2249
+ function useForceUpdate() {
2250
+ const [, forceUpdate_] = useState({});
2251
+ return useCallback(() => forceUpdate_({}), EMPTY_ARRAY);
2252
+ }
2253
+ function useLastValue(value) {
2254
+ const ref = useRef(value);
2255
+ useEffect(() => {
2256
+ ref.current = value;
2257
+ }, [value]);
2258
+ return ref.current;
2259
+ }
2260
+ function usePlayer(player) {
2261
+ const togglePlay = useCallback(() => {
2262
+ if (player) {
2263
+ switch (player.phase) {
2264
+ case PlayerPhase.WaitingFirstFrame:
2265
+ case PlayerPhase.Pause:
2266
+ case PlayerPhase.Ended: {
2267
+ player.play();
2268
+ break;
2269
+ }
2270
+ case PlayerPhase.Playing: {
2271
+ player.pause();
2272
+ break;
2273
+ }
2274
+ }
2275
+ }
2276
+ }, [player]);
2277
+ const seekToProgressTime = useCallback((time) => {
2278
+ if (player) {
2279
+ player.seekToProgressTime(time);
2280
+ }
2281
+ }, [player]);
2282
+ const lastPlayer = useLastValue(player);
2283
+ const forceUpdate = useForceUpdate();
2284
+ const setSpeed = useCallback((speed2) => {
2285
+ if (player) {
2286
+ player.playbackSpeed = speed2;
2287
+ forceUpdate();
2288
+ }
2289
+ }, [forceUpdate, player]);
2290
+ useEffect(() => {
2291
+ if (!lastPlayer && player) {
2292
+ forceUpdate();
2293
+ }
2294
+ }, [forceUpdate, lastPlayer, player]);
2295
+ useEffect(() => {
2296
+ if (player) {
2297
+ player.callbacks.on("onPhaseChanged", forceUpdate);
2298
+ player.callbacks.on("onProgressTimeChanged", forceUpdate);
2299
+ return () => {
2300
+ player.callbacks.off("onPhaseChanged", forceUpdate);
2301
+ player.callbacks.off("onProgressTimeChanged", forceUpdate);
2302
+ };
2303
+ }
2304
+ }, [forceUpdate, player]);
2305
+ const phase = player ? player.phase : PlayerPhase.WaitingFirstFrame;
2306
+ const currentTime = player ? player.progressTime : 0;
2307
+ const totalTime = player ? player.timeDuration : 0;
2308
+ const speed = player ? player.playbackSpeed : 1;
2309
+ return {
2310
+ phase,
2311
+ currentTime,
2312
+ totalTime,
2313
+ speed,
2314
+ setSpeed,
2315
+ togglePlay,
2316
+ seekToProgressTime
2317
+ };
2318
+ }
2319
+ const Loading = (props) => {
2320
+ const stroke = getStroke(props);
2321
+ return /* @__PURE__ */ jsx("svg", {
2322
+ viewBox: "0 0 24 24",
2323
+ children: /* @__PURE__ */ jsx("path", {
2324
+ d: "M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z",
2325
+ fill: stroke
2326
+ })
2327
+ });
2328
+ };
2329
+ const Pause = (props) => {
2330
+ const stroke = getStroke(props);
2331
+ return /* @__PURE__ */ jsx("svg", {
2332
+ viewBox: "0 0 24 24",
2333
+ children: /* @__PURE__ */ jsx("path", {
2334
+ d: "M14 19h4V5h-4M6 19h4V5H6v14z",
2335
+ fill: stroke
2336
+ })
2337
+ });
2338
+ };
2339
+ const Play = (props) => {
2340
+ const stroke = getStroke(props);
2341
+ return /* @__PURE__ */ jsx("svg", {
2342
+ viewBox: "0 0 24 24",
2343
+ children: /* @__PURE__ */ jsx("path", {
2344
+ d: "M8 5.14v14l11-7l-11-7z",
2345
+ fill: stroke
2346
+ })
2347
+ });
2348
+ };
2349
+ const Icons = {
2350
+ Play: memo(Play),
2351
+ Pause: memo(Pause),
2352
+ Loading: memo(Loading)
2353
+ };
2354
+ const Button = forwardRef((props, ref) => {
2355
+ const {
2356
+ theme,
2357
+ content,
2358
+ disabled,
2359
+ active,
2360
+ onClick,
2361
+ interactive,
2362
+ placement = "top",
2363
+ children
2364
+ } = props;
2365
+ return /* @__PURE__ */ jsx(Tippy, {
2366
+ className: "fastboard-tip",
2367
+ content,
2368
+ interactive,
2369
+ theme,
2370
+ disabled,
2371
+ placement,
2372
+ offset: TopOffset,
2373
+ duration: 300,
2374
+ children: /* @__PURE__ */ jsx("button", {
2375
+ ref,
2376
+ className: clsx("fastboard-player-control-btn", theme, {
2377
+ active
2378
+ }),
2379
+ onClick,
2380
+ disabled,
2381
+ children
2382
+ })
2383
+ });
2384
+ });
2385
+ const name = "fastboard-player-control";
2386
+ function PlayerControl(_a) {
2387
+ var _b = _a, {
2388
+ autoHide = false,
2389
+ player: player_,
2390
+ theme = "light",
2391
+ i18n
2392
+ } = _b, icons = __objRest(_b, [
2393
+ "autoHide",
2394
+ "player",
2395
+ "theme",
2396
+ "i18n"
2397
+ ]);
2398
+ const [currentTime, setCurrentTime] = useState(0);
2399
+ const player = usePlayer(player_);
2400
+ useEffect(() => {
2401
+ setCurrentTime(player.currentTime);
2402
+ }, [player.currentTime]);
2403
+ useEffect(() => {
2404
+ if (player.currentTime !== currentTime) {
2405
+ player.seekToProgressTime(currentTime);
2406
+ }
2407
+ }, [currentTime]);
2408
+ const isLoading = player.phase === PlayerPhase.WaitingFirstFrame || player.phase === PlayerPhase.Buffering;
2409
+ const isPlaying = player.phase === PlayerPhase.Playing;
2410
+ const {
2411
+ activeColor
2412
+ } = themes[theme];
2413
+ return /* @__PURE__ */ jsxs("div", {
2414
+ className: clsx(name, theme, {
2415
+ "auto-hide": autoHide
2416
+ }),
2417
+ children: [/* @__PURE__ */ jsx("button", {
2418
+ className: clsx(`${name}-btn`, isLoading ? "loading" : isPlaying ? "pause" : "play", theme),
2419
+ disabled: isLoading,
2420
+ onClick: player.togglePlay,
2421
+ children: /* @__PURE__ */ jsx(Icon, {
2422
+ fallback: isLoading ? /* @__PURE__ */ jsx(Icons.Loading, {
2423
+ theme
2424
+ }) : isPlaying ? /* @__PURE__ */ jsx(Icons.Pause, {
2425
+ theme
2426
+ }) : /* @__PURE__ */ jsx(Icons.Play, {
2427
+ theme
2428
+ }),
2429
+ src: isLoading ? icons.loadingIcon : isPlaying ? icons.pauseIcon : icons.playIcon,
2430
+ alt: isLoading ? "[loading]" : isPlaying ? "[pause]" : "[play]"
2431
+ })
2432
+ }), /* @__PURE__ */ jsx("span", {
2433
+ className: clsx(`${name}-slider`, {
2434
+ loading: isLoading
2435
+ }, theme),
2436
+ children: /* @__PURE__ */ jsx(RcSlider, {
2437
+ disabled: isLoading,
2438
+ trackStyle: {
2439
+ background: activeColor
2440
+ },
2441
+ handleStyle: {
2442
+ border: `1px solid ${activeColor}`
2443
+ },
2444
+ value: currentTime,
2445
+ onChange: setCurrentTime,
2446
+ min: 0,
2447
+ max: player.totalTime,
2448
+ step: 100
2449
+ })
2450
+ }), /* @__PURE__ */ jsx("span", {
2451
+ className: clsx(`${name}-current`, theme),
2452
+ children: renderTime(player.currentTime)
2453
+ }), /* @__PURE__ */ jsx("span", {
2454
+ className: clsx(`${name}-slash`, theme),
2455
+ children: "/"
2456
+ }), /* @__PURE__ */ jsx("span", {
2457
+ className: clsx(`${name}-total`, theme),
2458
+ children: renderTime(player.totalTime)
2459
+ }), /* @__PURE__ */ jsx("span", {
2460
+ className: `${name}-btn-interactive`,
2461
+ children: /* @__PURE__ */ jsx(Tippy, {
2462
+ className: "fastboard-tip",
2463
+ content: renderSpeeds(player),
2464
+ theme,
2465
+ placement: "top-end",
2466
+ trigger: "click",
2467
+ offset: TopOffset,
2468
+ arrow: false,
2469
+ interactive: true,
2470
+ children: /* @__PURE__ */ jsx(Button, {
2471
+ content: i18n == null ? void 0 : i18n.t("speed"),
2472
+ theme,
2473
+ disabled: isLoading,
2474
+ children: /* @__PURE__ */ jsxs("span", {
2475
+ className: clsx(`${name}-speed-text`, theme),
2476
+ children: [player.speed, "x"]
2477
+ })
2478
+ })
2479
+ })
2480
+ })]
2481
+ });
2482
+ }
2483
+ function renderTime(ms) {
2484
+ let seconds = ms / 1e3;
2485
+ const minutes = Math.floor(seconds / 60);
2486
+ seconds = Math.floor(seconds) % 60;
2487
+ return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
2488
+ }
2489
+ const Speeds = [2, 1.5, 1.25, 1, 0.75, 0.5];
2490
+ function renderSpeeds({
2491
+ speed: current,
2492
+ setSpeed
2493
+ }) {
2494
+ return /* @__PURE__ */ jsx("div", {
2495
+ className: clsx(`${name}-panel`, "speed"),
2496
+ children: Speeds.map((speed) => /* @__PURE__ */ jsxs("button", {
2497
+ className: clsx(`${name}-btn`, "speed", {
2498
+ active: speed === current
2499
+ }),
2500
+ onClick: () => setSpeed(speed),
2501
+ children: [speed, "x"]
2502
+ }, speed))
2503
+ });
2504
+ }
2200
2505
  function useFastboard(config) {
2201
2506
  const [app, setApp] = useState(null);
2202
2507
  const [currentTarget, ref] = useState(null);
2508
+ const [collector, collectorRef] = useState(null);
2203
2509
  useEffect(() => {
2204
2510
  let isMounted = true;
2205
2511
  const promise = createWhiteboardApp(config).then((app2) => {
@@ -2213,10 +2519,14 @@ function useFastboard(config) {
2213
2519
  }, []);
2214
2520
  useEffect(() => {
2215
2521
  if (app) {
2216
- app.bindElement(currentTarget);
2522
+ app.bindElement(currentTarget, collector);
2217
2523
  }
2218
- }, [app, currentTarget]);
2219
- return Object.assign([app, ref], { app, ref });
2524
+ }, [app, collector, currentTarget]);
2525
+ return Object.assign([app, ref, collectorRef], {
2526
+ app,
2527
+ ref,
2528
+ collectorRef
2529
+ });
2220
2530
  }
2221
2531
  const register = WindowManager.register.bind(WindowManager);
2222
2532
  async function createWhiteboardApp(config) {
@@ -2224,5 +2534,5 @@ async function createWhiteboardApp(config) {
2224
2534
  await app._instance.readyPromise;
2225
2535
  return app;
2226
2536
  }
2227
- export { PageControl, RedoUndo, Toolbar, WhiteboardApp, ZoomControl, createWhiteboardApp, register, useFastboard, version };
2537
+ export { PageControl, PlayerControl, RedoUndo, Toolbar, WhiteboardApp, ZoomControl, createWhiteboardApp, register, useFastboard, version };
2228
2538
  //# sourceMappingURL=index.es.js.map