aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MainView.tsx1220
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.tsx41
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx1300
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx55
4 files changed, 1306 insertions, 1310 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 8e9be1eeb..7ee9f5b70 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -68,310 +68,342 @@ const _global = (window /* browser */ || global /* node */) as any;
@observer
export class MainView extends React.Component {
- public static Instance: MainView;
- public static Live: boolean = false;
- private _docBtnRef = React.createRef<HTMLDivElement>();
- @observable public LastButton: Opt<Doc>;
- @observable private _windowWidth: number = 0;
- @observable private _windowHeight: number = 0;
- @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row)
- @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons
- @observable private _panelContent: string = "none";
- @observable private _sidebarContent: any = this.userDoc?.sidebar;
- @observable private _leftMenuFlyoutWidth: number = 0;
-
- @computed private get dashboardTabHeight() { return 27; } // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
- @computed private get topOfDashUI() { return Number(DASHBOARD_SELECTOR_HEIGHT.replace("px", "")); }
- @computed private get topOfMainDoc() { return this.topOfDashUI + this.topMenuHeight(); }
- @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
- @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
- @computed private get userDoc() { return Doc.UserDoc(); }
- @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
- @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
- @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
-
- topMenuHeight = () => 35;
- topMenuWidth = returnZero; // value is ignored ...
- leftMenuWidth = () => Number(LEFT_MENU_WIDTH.replace("px", ""));
- leftMenuHeight = () => this._dashUIHeight;
- leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
- leftMenuFlyoutHeight = () => this._dashUIHeight;
- propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
- propertiesHeight = () => this._dashUIHeight;
- mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
- mainDocViewHeight = () => this._dashUIHeight;
-
- componentDidMount() {
- document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
- const ele = document.getElementById("loader");
- const prog = document.getElementById("dash-progress");
- if (ele && prog) {
- // remove from DOM
- setTimeout(() => {
- clearTimeout();
- prog.style.transition = "1s";
- prog.style.width = "100%";
- }, 0);
- setTimeout(() => ele.outerHTML = '', 1000);
- }
- this._sidebarContent.proto = undefined;
- if (!MainView.Live) {
- DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
- "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
- "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
- }
- DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
-
- const tag = document.createElement('script');
- tag.src = "https://www.youtube.com/iframe_api";
- const firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
- window.removeEventListener("keydown", KeyManager.Instance.handle);
- window.addEventListener("keydown", KeyManager.Instance.handle);
- window.removeEventListener("keyup", KeyManager.Instance.unhandle);
- window.addEventListener("keyup", KeyManager.Instance.unhandle);
- window.addEventListener("paste", KeyManager.Instance.paste as any);
- document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on
- const id = FormattedTextBox.GetDocFromUrl(e.detail);
- DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined) : (null));
- });
- document.addEventListener("linkAnnotationToDash", Hypothesis.linkListener);
- this.initEventListeners();
- }
-
- componentWillUnMount() {
- window.removeEventListener("keyup", KeyManager.Instance.unhandle);
- window.removeEventListener("keydown", KeyManager.Instance.handle);
- window.removeEventListener("pointerdown", this.globalPointerDown);
- window.removeEventListener("paste", KeyManager.Instance.paste as any);
- document.removeEventListener("linkAnnotationToDash", Hypothesis.linkListener);
- }
-
- constructor(props: Readonly<{}>) {
- super(props);
- MainView.Instance = this;
- CurrentUserUtils._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
-
- // causes errors to be generated when modifying an observable outside of an action
- configure({ enforceActions: "observed" });
-
- if (window.location.pathname !== "/home") {
- const pathname = window.location.pathname.substr(1).split("/");
- if (pathname.length > 1 && pathname[0] === "doc") {
- CurrentUserUtils.MainDocId = pathname[1];
- !this.userDoc && DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
+ public static Instance: MainView;
+ public static Live: boolean = false;
+ private _docBtnRef = React.createRef<HTMLDivElement>();
+ @observable public LastButton: Opt<Doc>;
+ @observable private _windowWidth: number = 0;
+ @observable private _windowHeight: number = 0;
+ @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row)
+ @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons
+ @observable private _panelContent: string = "none";
+ @observable private _sidebarContent: any = this.userDoc?.sidebar;
+ @observable private _leftMenuFlyoutWidth: number = 0;
+
+ @computed private get dashboardTabHeight() { return 27; } // 27 comes form lm.config.defaultConfig.dimensions.headerHeight in goldenlayout.js
+ @computed private get topOfDashUI() { return Number(DASHBOARD_SELECTOR_HEIGHT.replace("px", "")); }
+ @computed private get topOfMainDoc() { return this.topOfDashUI + this.topMenuHeight(); }
+ @computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
+ @computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
+ @computed private get userDoc() { return Doc.UserDoc(); }
+ @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
+ @computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
+ @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
+
+ topMenuHeight = () => 35;
+ topMenuWidth = returnZero; // value is ignored ...
+ leftMenuWidth = () => Number(LEFT_MENU_WIDTH.replace("px", ""));
+ leftMenuHeight = () => this._dashUIHeight;
+ leftMenuFlyoutWidth = () => this._leftMenuFlyoutWidth;
+ leftMenuFlyoutHeight = () => this._dashUIHeight;
+ propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
+ propertiesHeight = () => this._dashUIHeight;
+ mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
+ mainDocViewHeight = () => this._dashUIHeight;
+
+ componentDidMount() {
+ document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
+ const ele = document.getElementById("loader");
+ const prog = document.getElementById("dash-progress");
+ if (ele && prog) {
+ // remove from DOM
+ setTimeout(() => {
+ clearTimeout();
+ prog.style.transition = "1s";
+ prog.style.width = "100%";
+ }, 0);
+ setTimeout(() => ele.outerHTML = '', 1000);
}
- }
-
- library.add(...[fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar,
- fa.faSquare, far.faSquare as any, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock,
- fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard,
- fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight,
- fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow,
- fa.faSearch, fa.faFileDownload, fa.faFileUpload, fa.faStop, fa.faCalculator, fa.faWindowMaximize, fa.faAddressCard, fa.faQuestionCircle, fa.faArrowLeft,
- fa.faArrowRight, fa.faArrowDown, fa.faArrowUp, fa.faBolt, fa.faBullseye, fa.faCaretUp, fa.faCat, fa.faCheck, fa.faChevronRight, fa.faChevronLeft, fa.faChevronDown, fa.faChevronUp,
- fa.faClone, fa.faCloudUploadAlt, fa.faCommentAlt, fa.faCompressArrowsAlt, fa.faCut, fa.faEllipsisV, fa.faEraser, fa.faExclamation, fa.faFileAlt,
- fa.faFileAudio, fa.faFileVideo, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer,
- fa.faMusic, fa.faObjectGroup, fa.faPause, fa.faPen, fa.faPenNib, fa.faPhone, fa.faPlay, fa.faPortrait, fa.faRedoAlt, fa.faStamp, fa.faStickyNote, fa.faArrowsAltV,
- fa.faTimesCircle, fa.faThumbtack, fa.faTree, fa.faTv, fa.faUndoAlt, fa.faVideo, fa.faAsterisk, fa.faBrain, fa.faImage, fa.faPaintBrush, fa.faTimes,
- fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
- fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faClipboard, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
- fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper as any,
- fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, far.faCircle as any,
- fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer as any, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp,
- fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl,
- fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo,
- fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical,
- fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll,
- fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines,
- fa.faSave, fa.faBookmark, fa.faList, fa.faListOl, fa.faFolderPlus, fa.faLightbulb, fa.faBookOpen, fa.faMapMarkerAlt, fa.faSearchPlus, fa.faVolumeUp, fa.faVolumeDown]);
- this.initAuthenticationRouters();
- }
-
- globalPointerDown = action((e: PointerEvent) => {
- AudioBox.Enabled = true;
- const targets = document.elementsFromPoint(e.x, e.y);
- if (targets.length) {
- const targClass = targets[0].className.toString();
- !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
- !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
- }
- });
-
- initEventListeners = () => {
- window.addEventListener("drop", e => e.preventDefault(), false); // prevent default behavior of navigating to a new web page
- window.addEventListener("dragover", e => e.preventDefault(), false);
- // document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
- document.addEventListener("pointerdown", this.globalPointerDown);
- document.addEventListener("click", (e: MouseEvent) => {
- if (!e.cancelBubble) {
- const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
- if (pathstr?.includes("libraryFlyout")) {
- SelectionManager.DeselectAll();
- }
+ this._sidebarContent.proto = undefined;
+ if (!MainView.Live) {
+ DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
+ "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
+ "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
}
- }, false);
- document.oncontextmenu = () => false;
- }
-
- initAuthenticationRouters = async () => {
- // Load the user's active dashboard, or create a new one if initial session after signup
- const received = CurrentUserUtils.MainDocId;
- if (received && !this.userDoc) {
- reaction(() => CurrentUserUtils.GuestTarget, target => target && CurrentUserUtils.createNewDashboard(Doc.UserDoc()), { fireImmediately: true });
- } else {
- if (received && CurrentUserUtils._urlState.sharing) {
- reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
- initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
- if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
- CollectionDockingView.AddSplit(docField, "right");
+ DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
+
+ const tag = document.createElement('script');
+ tag.src = "https://www.youtube.com/iframe_api";
+ const firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
+ window.removeEventListener("keydown", KeyManager.Instance.handle);
+ window.addEventListener("keydown", KeyManager.Instance.handle);
+ window.removeEventListener("keyup", KeyManager.Instance.unhandle);
+ window.addEventListener("keyup", KeyManager.Instance.unhandle);
+ window.addEventListener("paste", KeyManager.Instance.paste as any);
+ document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on
+ const id = FormattedTextBox.GetDocFromUrl(e.detail);
+ DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined) : (null));
+ });
+ document.addEventListener("linkAnnotationToDash", Hypothesis.linkListener);
+ this.initEventListeners();
+ }
+
+ componentWillUnMount() {
+ window.removeEventListener("keyup", KeyManager.Instance.unhandle);
+ window.removeEventListener("keydown", KeyManager.Instance.handle);
+ window.removeEventListener("pointerdown", this.globalPointerDown);
+ window.removeEventListener("paste", KeyManager.Instance.paste as any);
+ document.removeEventListener("linkAnnotationToDash", Hypothesis.linkListener);
+ }
+
+ constructor(props: Readonly<{}>) {
+ super(props);
+ MainView.Instance = this;
+ CurrentUserUtils._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
+
+ // causes errors to be generated when modifying an observable outside of an action
+ configure({ enforceActions: "observed" });
+
+ if (window.location.pathname !== "/home") {
+ const pathname = window.location.pathname.substr(1).split("/");
+ if (pathname.length > 1 && pathname[0] === "doc") {
+ CurrentUserUtils.MainDocId = pathname[1];
+ !this.userDoc && DocServer.GetRefField(pathname[1]).then(action(field => field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
+ }
+ }
+
+ library.add(...[fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar, fa.faVideoSlash, fa.faVideo,
+ fa.faSquare, far.faSquare as any, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock,
+ fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard,
+ fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight,
+ fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow,
+ fa.faSearch, fa.faFileDownload, fa.faFileUpload, fa.faStop, fa.faCalculator, fa.faWindowMaximize, fa.faAddressCard, fa.faQuestionCircle, fa.faArrowLeft,
+ fa.faArrowRight, fa.faArrowDown, fa.faArrowUp, fa.faBolt, fa.faBullseye, fa.faCaretUp, fa.faCat, fa.faCheck, fa.faChevronRight, fa.faChevronLeft, fa.faChevronDown, fa.faChevronUp,
+ fa.faClone, fa.faCloudUploadAlt, fa.faCommentAlt, fa.faCompressArrowsAlt, fa.faCut, fa.faEllipsisV, fa.faEraser, fa.faExclamation, fa.faFileAlt,
+ fa.faFileAudio, fa.faFileVideo, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer,
+ fa.faMusic, fa.faObjectGroup, fa.faPause, fa.faPen, fa.faPenNib, fa.faPhone, fa.faPlay, fa.faPortrait, fa.faRedoAlt, fa.faStamp, fa.faStickyNote, fa.faArrowsAltV,
+ fa.faTimesCircle, fa.faThumbtack, fa.faTree, fa.faTv, fa.faUndoAlt, fa.faVideo, fa.faAsterisk, fa.faBrain, fa.faImage, fa.faPaintBrush, fa.faTimes,
+ fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
+ fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faClipboard, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
+ fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper as any,
+ fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, far.faCircle as any,
+ fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer as any, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp,
+ fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl,
+ fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo,
+ fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical,
+ fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll,
+ fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines,
+ fa.faSave, fa.faBookmark, fa.faList, fa.faListOl, fa.faFolderPlus, fa.faLightbulb, fa.faBookOpen, fa.faMapMarkerAlt, fa.faSearchPlus, fa.faVolumeUp, fa.faVolumeDown]);
+ this.initAuthenticationRouters();
+ }
+
+ globalPointerDown = action((e: PointerEvent) => {
+ AudioBox.Enabled = true;
+ const targets = document.elementsFromPoint(e.x, e.y);
+ if (targets.length) {
+ const targClass = targets[0].className.toString();
+ !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
+ !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
+ }
+ });
+
+ initEventListeners = () => {
+ window.addEventListener("drop", e => e.preventDefault(), false); // prevent default behavior of navigating to a new web page
+ window.addEventListener("dragover", e => e.preventDefault(), false);
+ // document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
+ document.addEventListener("pointerdown", this.globalPointerDown);
+ document.addEventListener("click", (e: MouseEvent) => {
+ if (!e.cancelBubble) {
+ const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
+ if (pathstr?.includes("libraryFlyout")) {
+ SelectionManager.DeselectAll();
}
- }),
- );
+ }
+ }, false);
+ document.oncontextmenu = () => false;
+ }
+
+ initAuthenticationRouters = async () => {
+ // Load the user's active dashboard, or create a new one if initial session after signup
+ const received = CurrentUserUtils.MainDocId;
+ if (received && !this.userDoc) {
+ reaction(() => CurrentUserUtils.GuestTarget, target => target && CurrentUserUtils.createNewDashboard(Doc.UserDoc()), { fireImmediately: true });
+ } else {
+ if (received && CurrentUserUtils._urlState.sharing) {
+ reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
+ initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
+ if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
+ CollectionDockingView.AddSplit(docField, "right");
+ }
+ }),
+ );
+ }
+ const activeDash = PromiseValue(this.userDoc.activeDashboard);
+ activeDash.then(dash => {
+ if (dash instanceof Doc) CurrentUserUtils.openDashboard(this.userDoc, dash);
+ else CurrentUserUtils.createNewDashboard(this.userDoc);
+ });
}
- const activeDash = PromiseValue(this.userDoc.activeDashboard);
- activeDash.then(dash => {
- if (dash instanceof Doc) CurrentUserUtils.openDashboard(this.userDoc, dash);
- else CurrentUserUtils.createNewDashboard(this.userDoc);
- });
- }
- }
-
- @action
- createNewPresentation = async () => {
- if (!await this.userDoc.myTrails) {
- this.userDoc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
- }));
- }
- const pres = Docs.Create.PresDocument(new List<Doc>(),
- { title: "Untitled Trail", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
- CollectionDockingView.AddSplit(pres, "right");
- this.userDoc.activePresentation = pres;
- Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
- }
-
- @action
- createNewFolder = async () => {
- if (!await this.userDoc.myFilesystem) {
- this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
- const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!;
- const newFolderButton: Doc = Docs.Create.FontIconDocument({
- onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder",
- btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true
- });
- this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], {
- title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
- treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
- explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
- }));
- }
- const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
- Doc.AddDocToList(this.userDoc.myFilesystem as Doc, "data", folder);
- }
-
- @computed get mainDocView() {
- return <DocumentView key="main"
- Document={this.mainContainer!}
- DataDoc={undefined}
- addDocument={undefined}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- docViewPath={returnEmptyDoclist}
- layerProvider={undefined}
- styleProvider={undefined}
- rootSelected={returnTrue}
- isContentActive={returnTrue}
- removeDocument={undefined}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.mainDocViewWidth}
- PanelHeight={this.mainDocViewHeight}
- focus={DocUtils.DefaultFocus}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- suppressSetHeight={true}
- renderDepth={-1}
- />;
- }
-
- @computed get dockingContent() {
- return <div key="docking" className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? "-flyout" : ""}`} onDrop={e => { e.stopPropagation(); e.preventDefault(); }}
- style={{
- minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
- transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined,
- }}>
- {!this.mainContainer ? (null) : this.mainDocView}
- </div>;
- }
-
- @action
- onPropertiesPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- action(e => (CurrentUserUtils.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false),
- action(() => CurrentUserUtils.propertiesWidth < 5 && (CurrentUserUtils.propertiesWidth = 0)),
- action(() => CurrentUserUtils.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0), false);
- }
-
- @action
- onFlyoutPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- action(e => (this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false),
- () => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
- this.closeFlyout);
- }
-
- sidebarScreenToLocal = () => new Transform(0, -this.topOfMainDoc, 1);
- mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
- addDocTabFunc = (doc: Doc, location: string): boolean => {
- const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
- const locationParams = locationFields.length > 1 ? locationFields[1] : "";
- if (doc.dockingConfig) return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
- switch (locationFields[0]) {
- case "dashboard": return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
- case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
- case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
- case "lightbox": return LightboxView.AddDocTab(doc, location);
- case "toggle": return CollectionDockingView.ToggleSplit(doc, locationParams);
- case "inPlace":
- case "add":
- default:
- return CollectionDockingView.AddSplit(doc, locationParams);
- }
- }
-
-
- @computed get flyout() {
- return !this._leftMenuFlyoutWidth ? <div key="flyout" className={`mainView-libraryFlyout-out`}>
- {this.docButtons}
- </div> :
- <div key="libFlyout" className="mainView-libraryFlyout" style={{ minWidth: this._leftMenuFlyoutWidth, width: this._leftMenuFlyoutWidth }} >
- <div className="mainView-contentArea" >
- <DocumentView
- Document={this._sidebarContent.proto || this._sidebarContent}
+ }
+
+ @action
+ createNewPresentation = async () => {
+ if (!await this.userDoc.myTrails) {
+ this.userDoc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
+ title: "TRAILS", childDontRegisterViews: true, _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true
+ }));
+ }
+ const pres = Docs.Create.PresDocument(new List<Doc>(),
+ { title: "Untitled Trail", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
+ CollectionDockingView.AddSplit(pres, "right");
+ this.userDoc.activePresentation = pres;
+ Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
+ }
+
+ @action
+ createNewFolder = async () => {
+ if (!await this.userDoc.myFilesystem) {
+ this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
+ const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!;
+ const newFolderButton: Doc = Docs.Create.FontIconDocument({
+ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder",
+ btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true
+ });
+ this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], {
+ title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
+ treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
+ treeViewTruncateTitleWidth: 150, ignoreClick: true,
+ isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
+ explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
+ }));
+ }
+ const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
+ Doc.AddDocToList(this.userDoc.myFilesystem as Doc, "data", folder);
+ }
+
+ @computed get mainDocView() {
+ return <DocumentView key="main"
+ Document={this.mainContainer!}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ layerProvider={undefined}
+ styleProvider={undefined}
+ rootSelected={returnTrue}
+ isContentActive={returnTrue}
+ removeDocument={undefined}
+ ScreenToLocalTransform={Transform.Identity}
+ PanelWidth={this.mainDocViewWidth}
+ PanelHeight={this.mainDocViewHeight}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ suppressSetHeight={true}
+ renderDepth={-1}
+ />;
+ }
+
+ @computed get dockingContent() {
+ return <div key="docking" className={`mainView-dockingContent${this._leftMenuFlyoutWidth ? "-flyout" : ""}`} onDrop={e => { e.stopPropagation(); e.preventDefault(); }}
+ style={{
+ minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`,
+ transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined,
+ }}>
+ {!this.mainContainer ? (null) : this.mainDocView}
+ </div>;
+ }
+
+ @action
+ onPropertiesPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ action(e => (CurrentUserUtils.propertiesWidth = Math.max(0, this._dashUIWidth - e.clientX)) ? false : false),
+ action(() => CurrentUserUtils.propertiesWidth < 5 && (CurrentUserUtils.propertiesWidth = 0)),
+ action(() => CurrentUserUtils.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._dashUIWidth - 50, 250) : 0), false);
+ }
+
+ @action
+ onFlyoutPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ action(e => (this._leftMenuFlyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false),
+ () => this._leftMenuFlyoutWidth < 5 && this.closeFlyout(),
+ this.closeFlyout);
+ }
+
+ sidebarScreenToLocal = () => new Transform(0, -this.topOfMainDoc, 1);
+ mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0);
+ addDocTabFunc = (doc: Doc, location: string): boolean => {
+ const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
+ const locationParams = locationFields.length > 1 ? locationFields[1] : "";
+ if (doc.dockingConfig) return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
+ switch (locationFields[0]) {
+ case "dashboard": return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
+ case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
+ case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
+ case "lightbox": return LightboxView.AddDocTab(doc, location);
+ case "toggle": return CollectionDockingView.ToggleSplit(doc, locationParams);
+ case "inPlace":
+ case "add":
+ default:
+ return CollectionDockingView.AddSplit(doc, locationParams);
+ }
+ }
+
+
+ @computed get flyout() {
+ return !this._leftMenuFlyoutWidth ? <div key="flyout" className={`mainView-libraryFlyout-out`}>
+ {this.docButtons}
+ </div> :
+ <div key="libFlyout" className="mainView-libraryFlyout" style={{ minWidth: this._leftMenuFlyoutWidth, width: this._leftMenuFlyoutWidth }} >
+ <div className="mainView-contentArea" >
+ <DocumentView
+ Document={this._sidebarContent.proto || this._sidebarContent}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ layerProvider={undefined}
+ styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards || this._sidebarContent.proto === Doc.UserDoc().myFilesystem ? DashboardStyleProvider : DefaultStyleProvider}
+ rootSelected={returnTrue}
+ removeDocument={returnFalse}
+ ScreenToLocalTransform={this.mainContainerXf}
+ PanelWidth={this.leftMenuFlyoutWidth}
+ PanelHeight={this.leftMenuFlyoutHeight}
+ renderDepth={0}
+ isContentActive={returnTrue}
+ scriptContext={CollectionDockingView.Instance?.props.Document}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ />
+ </div>
+ {this.docButtons}
+ </div>;
+ }
+
+ @computed get leftMenuPanel() {
+ return <div key="menu" className="mainView-leftMenuPanel">
+ <DocumentView
+ Document={Doc.UserDoc().menuStack as Doc}
DataDoc={undefined}
addDocument={undefined}
addDocTab={this.addDocTabFunc}
pinToPres={emptyFunction}
- docViewPath={returnEmptyDoclist}
- layerProvider={undefined}
- styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards || this._sidebarContent.proto === Doc.UserDoc().myFilesystem ? DashboardStyleProvider : DefaultStyleProvider}
rootSelected={returnTrue}
removeDocument={returnFalse}
- ScreenToLocalTransform={this.mainContainerXf}
- PanelWidth={this.leftMenuFlyoutWidth}
- PanelHeight={this.leftMenuFlyoutHeight}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
+ PanelWidth={this.leftMenuWidth}
+ PanelHeight={this.leftMenuHeight}
renderDepth={0}
- isContentActive={returnTrue}
- scriptContext={CollectionDockingView.Instance?.props.Document}
+ docViewPath={returnEmptyDoclist}
focus={DocUtils.DefaultFocus}
+ styleProvider={DefaultStyleProvider}
+ layerProvider={undefined}
+ isContentActive={returnTrue}
whenChildContentsActiveChanged={emptyFunction}
bringToFront={emptyFunction}
docFilters={returnEmptyFilter}
@@ -379,333 +411,301 @@ export class MainView extends React.Component {
searchFilterDocs={returnEmptyDoclist}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
- />
- </div>
- {this.docButtons}
+ scriptContext={this}
+ />
</div>;
- }
-
- @computed get leftMenuPanel() {
- return <div key="menu" className="mainView-leftMenuPanel">
- <DocumentView
- Document={Doc.UserDoc().menuStack as Doc}
- DataDoc={undefined}
- addDocument={undefined}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- rootSelected={returnTrue}
- removeDocument={returnFalse}
- ScreenToLocalTransform={this.sidebarScreenToLocal}
- PanelWidth={this.leftMenuWidth}
- PanelHeight={this.leftMenuHeight}
- renderDepth={0}
- docViewPath={returnEmptyDoclist}
- focus={DocUtils.DefaultFocus}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
- isContentActive={returnTrue}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- scriptContext={this}
- />
- </div>;
- }
-
- @action
- selectMenu = (button: Doc) => {
- const title = StrCast(Doc.GetProto(button).title);
- const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title;
- this.closeFlyout();
- if (willOpen) {
- switch (this._panelContent = title) {
- case "Settings":
- SettingsManager.Instance.open();
- break;
- case "Help":
- break;
- default:
- this.expandFlyout(button);
+ }
+
+ @action
+ selectMenu = (button: Doc) => {
+ const title = StrCast(Doc.GetProto(button).title);
+ const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title;
+ this.closeFlyout();
+ if (willOpen) {
+ switch (this._panelContent = title) {
+ case "Settings":
+ SettingsManager.Instance.open();
+ break;
+ case "Help":
+ break;
+ default:
+ this.expandFlyout(button);
+ }
}
- }
- return true;
- }
-
- @computed get mainInnerContent() {
- const leftMenuFlyoutWidth = this._leftMenuFlyoutWidth + this.leftMenuWidth();
- const width = this.propertiesWidth() + leftMenuFlyoutWidth;
- return <>
- {this.leftMenuPanel}
- <div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
- {this.flyout}
- <div className="mainView-libraryHandle" style={{ left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
- <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
- </div>
- <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
-
- {this.dockingContent}
-
- <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
- <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
- </div>
- <div className="properties-container" style={{ width: this.propertiesWidth() }}>
- {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={this.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />}
- </div>
- </div>
- </div>
- </>;
- }
-
- @computed get mainDashboardArea() {
- return !this.userDoc ? (null) :
- <div className="mainView-dashboardArea" ref={r => {
- r && new _global.ResizeObserver(action(() => {
- this._dashUIWidth = r.getBoundingClientRect().width;
- this._dashUIHeight = r.getBoundingClientRect().height;
- })).observe(r);
- }} style={{
- color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
- height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
- width: "100%",
- }} >
- {this.mainInnerContent}
- </div>;
- }
-
-
- expandFlyout = action((button: Doc) => {
- // bcz: What's going on here!?
- // Chrome(not firefox) seems to have a bug when the flyout expands and there's a zoomed freeform tab. All of the div below the CollectionFreeFormView's main div
- // generate the wrong value from getClientRectangle() -- specifically they return an 'x' that is the flyout's width greater than it should be.
- // interactively adjusting the flyout fixes the problem. So does programmatically changing the value after a timeout to something *fractionally* different (ie, 1.5, not 1);)
- this._leftMenuFlyoutWidth = (this._leftMenuFlyoutWidth || 250);
- setTimeout(action(() => this._leftMenuFlyoutWidth += 0.5), 0);
-
- this._sidebarContent.proto = button.target as any;
- this.LastButton = button;
- });
-
- closeFlyout = action(() => {
- this.LastButton = undefined;
- this._panelContent = "none";
- this._sidebarContent.proto = undefined;
- this._leftMenuFlyoutWidth = 0;
- });
-
- remButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.RemoveDocFromList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
- moveButtonDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
- addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
-
- buttonBarXf = () => {
- if (!this._docBtnRef.current) return Transform.Identity();
- const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
- return new Transform(-translateX, -translateY, 1 / scale);
- }
-
- @computed get docButtons() {
- return !(this.userDoc.dockedBtns instanceof Doc) ? (null) :
- <div className="mainView-docButtons" ref={this._docBtnRef} style={{ height: !this.userDoc.dockedBtns.linearViewIsExpanded ? "42px" : undefined }} >
- <CollectionLinearView
- Document={this.userDoc.dockedBtns}
- DataDoc={undefined}
- fieldKey={"data"}
- dropAction={"alias"}
- setHeight={returnFalse}
- styleProvider={DefaultStyleProvider}
- layerProvider={undefined}
- rootSelected={returnTrue}
- bringToFront={emptyFunction}
- select={emptyFunction}
- isAnyChildContentActive={returnFalse}
- isContentActive={emptyFunction}
- isSelected={returnFalse}
- docViewPath={returnEmptyDoclist}
- moveDocument={this.moveButtonDoc}
- CollectionView={undefined}
- addDocument={this.addButtonDoc}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- removeDocument={this.remButtonDoc}
- ScreenToLocalTransform={this.buttonBarXf}
- PanelWidth={this.leftMenuFlyoutWidth}
- PanelHeight={this.leftMenuFlyoutHeight}
- renderDepth={0}
- focus={DocUtils.DefaultFocus}
- whenChildContentsActiveChanged={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />
- {['watching', 'recording'].includes(String(this.userDoc?.presentationMode) ?? '') ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{this.userDoc?.presentationMode}</div>: <></>}
+ return true;
+ }
+
+ @computed get mainInnerContent() {
+ const leftMenuFlyoutWidth = this._leftMenuFlyoutWidth + this.leftMenuWidth();
+ const width = this.propertiesWidth() + leftMenuFlyoutWidth;
+ return <>
+ {this.leftMenuPanel}
+ <div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
+ {this.flyout}
+ <div className="mainView-libraryHandle" style={{ left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
+ <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
+ </div>
+ <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
+
+ {this.dockingContent}
+
+ <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
+ <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
+ </div>
+ <div className="properties-container" style={{ width: this.propertiesWidth() }}>
+ {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} addDocTab={this.addDocTabFunc} width={this.propertiesWidth()} height={this.propertiesHeight()} />}
+ </div>
+ </div>
+ </div>
+ </>;
+ }
+
+ @computed get mainDashboardArea() {
+ return !this.userDoc ? (null) :
+ <div className="mainView-dashboardArea" ref={r => {
+ r && new _global.ResizeObserver(action(() => {
+ this._dashUIWidth = r.getBoundingClientRect().width;
+ this._dashUIHeight = r.getBoundingClientRect().height;
+ })).observe(r);
+ }} style={{
+ color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
+ height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
+ width: "100%",
+ }} >
+ {this.mainInnerContent}
+ </div>;
+ }
+
+
+ expandFlyout = action((button: Doc) => {
+ // bcz: What's going on here!?
+ // Chrome(not firefox) seems to have a bug when the flyout expands and there's a zoomed freeform tab. All of the div below the CollectionFreeFormView's main div
+ // generate the wrong value from getClientRectangle() -- specifically they return an 'x' that is the flyout's width greater than it should be.
+ // interactively adjusting the flyout fixes the problem. So does programmatically changing the value after a timeout to something *fractionally* different (ie, 1.5, not 1);)
+ this._leftMenuFlyoutWidth = (this._leftMenuFlyoutWidth || 250);
+ setTimeout(action(() => this._leftMenuFlyoutWidth += 0.5), 0);
+
+ this._sidebarContent.proto = button.target as any;
+ this.LastButton = button;
+ });
+
+ closeFlyout = action(() => {
+ this.LastButton = undefined;
+ this._panelContent = "none";
+ this._sidebarContent.proto = undefined;
+ this._leftMenuFlyoutWidth = 0;
+ });
+
+ remButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.RemoveDocFromList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
+ moveButtonDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
+ addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
+
+ buttonBarXf = () => {
+ if (!this._docBtnRef.current) return Transform.Identity();
+ const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ return new Transform(-translateX, -translateY, 1 / scale);
+ }
+
+ @computed get docButtons() {
+ return !(this.userDoc.dockedBtns instanceof Doc) ? (null) :
+ <div className="mainView-docButtons" ref={this._docBtnRef} style={{ height: !this.userDoc.dockedBtns.linearViewIsExpanded ? "42px" : undefined }} >
+ <CollectionLinearView
+ Document={this.userDoc.dockedBtns}
+ DataDoc={undefined}
+ fieldKey={"data"}
+ dropAction={"alias"}
+ setHeight={returnFalse}
+ styleProvider={DefaultStyleProvider}
+ layerProvider={undefined}
+ rootSelected={returnTrue}
+ bringToFront={emptyFunction}
+ select={emptyFunction}
+ isAnyChildContentActive={returnFalse}
+ isContentActive={emptyFunction}
+ isSelected={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ moveDocument={this.moveButtonDoc}
+ CollectionView={undefined}
+ addDocument={this.addButtonDoc}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ removeDocument={this.remButtonDoc}
+ ScreenToLocalTransform={this.buttonBarXf}
+ PanelWidth={this.leftMenuFlyoutWidth}
+ PanelHeight={this.leftMenuFlyoutHeight}
+ renderDepth={0}
+ focus={DocUtils.DefaultFocus}
+ whenChildContentsActiveChanged={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined} />
+ {['watching', 'recording'].includes(String(this.userDoc?.presentationMode) ?? '') ? <div style={{ border: '.5rem solid green', padding: '5px' }}>{this.userDoc?.presentationMode}</div> : <></>}
+ </div>;
+ }
+ @computed get snapLines() {
+ return !this.userDoc.showSnapLines ? (null) : <div className="mainView-snapLines">
+ <svg style={{ width: "100%", height: "100%" }}>
+ {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+ {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+ </svg>
</div>;
- }
- @computed get snapLines() {
- return !this.userDoc.showSnapLines ? (null) : <div className="mainView-snapLines">
- <svg style={{ width: "100%", height: "100%" }}>
- {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
- {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
- </svg>
- </div>;
- }
-
- @computed get inkResources() {
- return <svg width={0} height={0}>
- <defs>
- <filter id="inkSelectionHalo">
- <feColorMatrix type="matrix"
- result="color"
- values="1 0 0 0 0
+ }
+
+ @computed get inkResources() {
+ return <svg width={0} height={0}>
+ <defs>
+ <filter id="inkSelectionHalo">
+ <feColorMatrix type="matrix"
+ result="color"
+ values="1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0">
- </feColorMatrix>
- <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
- <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
- <feMerge>
- <feMergeNode in="bg"></feMergeNode>
- <feMergeNode in="offset"></feMergeNode>
- <feMergeNode in="SourceGraphic"></feMergeNode>
- </feMerge>
- </filter>
- </defs>
- </svg>;
- }
-
- @computed get topbar() {
- TraceMobx();
- return <div className="mainView-topbar">
- <TopBar />
- </div>;
- }
-
- @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
- return !DocumentLinksButton.invisibleWebDoc ? null :
- <div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
- <WebBox
- fieldKey={"data"}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- Document={DocumentLinksButton.invisibleWebDoc}
- dropAction={"move"}
- layerProvider={undefined}
- styleProvider={undefined}
- isSelected={returnFalse}
- select={returnFalse}
- setHeight={returnFalse}
- rootSelected={returnFalse}
- renderDepth={0}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- bringToFront={returnFalse}
- isContentActive={emptyFunction}
- whenChildContentsActiveChanged={returnFalse}
- focus={returnFalse}
- docViewPath={returnEmptyDoclist}
- PanelWidth={() => 500}
- PanelHeight={() => 800}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
+ </feColorMatrix>
+ <feGaussianBlur in="color" stdDeviation="4" result="blur"></feGaussianBlur>
+ <feOffset in="blur" dx="0" dy="0" result="offset"></feOffset>
+ <feMerge>
+ <feMergeNode in="bg"></feMergeNode>
+ <feMergeNode in="offset"></feMergeNode>
+ <feMergeNode in="SourceGraphic"></feMergeNode>
+ </feMerge>
+ </filter>
+ </defs>
+ </svg>;
+ }
+
+ @computed get topbar() {
+ TraceMobx();
+ return <div className="mainView-topbar">
+ <TopBar />
</div>;
- }
-
- render() {
- return (<div className={`mainView-container${this.colorScheme}`}
- onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
- ref={r => {
- r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
- }}>
- {this.inkResources}
- <DictationOverlay />
- <SharingManager />
- <SettingsManager />
- <CaptureManager />
- <GroupManager />
- <GoogleAuthenticationManager />
- <DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
- <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
- {this.topbar}
- {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
- {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
- {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
- <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
- <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
- </div>
- <GestureOverlay >
- {this.mainDashboardArea}
- </GestureOverlay>
- <PreviewCursor />
- <TaskCompletionBox />
- <ContextMenu />
- <RadialMenu />
- <AnchorMenu />
- <MarqueeOptionsMenu />
- <OverlayView />
- <TimelineMenu />
- <RichTextMenu />
- {this.snapLines}
- <div className="mainView-webRef" ref={this.makeWebRef} />
- <LightboxView PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
- </div >);
- }
-
- makeWebRef = (ele: HTMLDivElement) => {
- reaction(() => DocumentLinksButton.invisibleWebDoc,
- invisibleDoc => {
- ReactDOM.unmountComponentAtNode(ele);
- invisibleDoc && ReactDOM.render(<span title="Drag as document" className="invisible-webbox" >
- <div className="mainView-webRef" ref={DocumentLinksButton.invisibleWebRef}>
+ }
+
+ @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
+ return !DocumentLinksButton.invisibleWebDoc ? null :
+ <div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
<WebBox
- fieldKey={"data"}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- Document={invisibleDoc}
- dropAction={"move"}
- isSelected={returnFalse}
- docViewPath={returnEmptyDoclist}
- select={returnFalse}
- rootSelected={returnFalse}
- renderDepth={0}
- setHeight={returnFalse}
- layerProvider={undefined}
- styleProvider={undefined}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- bringToFront={returnFalse}
- isContentActive={emptyFunction}
- whenChildContentsActiveChanged={returnFalse}
- focus={returnFalse}
- PanelWidth={() => 500}
- PanelHeight={() => 800}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
+ fieldKey={"data"}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ Document={DocumentLinksButton.invisibleWebDoc}
+ dropAction={"move"}
+ layerProvider={undefined}
+ styleProvider={undefined}
+ isSelected={returnFalse}
+ select={returnFalse}
+ setHeight={returnFalse}
+ rootSelected={returnFalse}
+ renderDepth={0}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ bringToFront={returnFalse}
+ isContentActive={emptyFunction}
+ whenChildContentsActiveChanged={returnFalse}
+ focus={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ PanelWidth={() => 500}
+ PanelHeight={() => 800}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
/>
- </div>;
- </span>, ele);
-
- let success = false;
- const onSuccess = () => {
- success = true;
- clearTimeout(interval);
- document.removeEventListener("editSuccess", onSuccess);
- };
-
- // For some reason, Hypothes.is annotations don't load until a click is registered on the page,
- // so we keep simulating clicks until annotations have loaded and editing is successful
- const interval = setInterval(() => !success && simulateMouseClick(ele, 50, 50, 50, 50), 500);
- setTimeout(() => !success && clearInterval(interval), 10000); // give up if no success after 10s
- document.addEventListener("editSuccess", onSuccess);
- });
- }
+ </div>;
+ }
+
+ render() {
+ return (<div className={`mainView-container${this.colorScheme}`}
+ onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
+ ref={r => {
+ r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
+ }}>
+ {this.inkResources}
+ <DictationOverlay />
+ <SharingManager />
+ <SettingsManager />
+ <CaptureManager />
+ <GroupManager />
+ <GoogleAuthenticationManager />
+ <DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
+ <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
+ {this.topbar}
+ {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
+ {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)}
+ {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
+ <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
+ <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
+ </div>
+ <GestureOverlay >
+ {this.mainDashboardArea}
+ </GestureOverlay>
+ <PreviewCursor />
+ <TaskCompletionBox />
+ <ContextMenu />
+ <RadialMenu />
+ <AnchorMenu />
+ <MarqueeOptionsMenu />
+ <OverlayView />
+ <TimelineMenu />
+ <RichTextMenu />
+ {this.snapLines}
+ <div className="mainView-webRef" ref={this.makeWebRef} />
+ <LightboxView PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
+ </div >);
+ }
+
+ makeWebRef = (ele: HTMLDivElement) => {
+ reaction(() => DocumentLinksButton.invisibleWebDoc,
+ invisibleDoc => {
+ ReactDOM.unmountComponentAtNode(ele);
+ invisibleDoc && ReactDOM.render(<span title="Drag as document" className="invisible-webbox" >
+ <div className="mainView-webRef" ref={DocumentLinksButton.invisibleWebRef}>
+ <WebBox
+ fieldKey={"data"}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ Document={invisibleDoc}
+ dropAction={"move"}
+ isSelected={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ select={returnFalse}
+ rootSelected={returnFalse}
+ renderDepth={0}
+ setHeight={returnFalse}
+ layerProvider={undefined}
+ styleProvider={undefined}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ bringToFront={returnFalse}
+ isContentActive={emptyFunction}
+ whenChildContentsActiveChanged={returnFalse}
+ focus={returnFalse}
+ PanelWidth={() => 500}
+ PanelHeight={() => 800}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ />
+ </div>;
+ </span>, ele);
+
+ let success = false;
+ const onSuccess = () => {
+ success = true;
+ clearTimeout(interval);
+ document.removeEventListener("editSuccess", onSuccess);
+ };
+
+ // For some reason, Hypothes.is annotations don't load until a click is registered on the page,
+ // so we keep simulating clicks until annotations have loaded and editing is successful
+ const interval = setInterval(() => !success && simulateMouseClick(ele, 50, 50, 50, 50), 500);
+ setTimeout(() => !success && clearInterval(interval), 10000); // give up if no success after 10s
+ document.addEventListener("editSuccess", onSuccess);
+ });
+ }
}
ScriptingGlobals.add(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); }); \ No newline at end of file
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 6aed07c60..a2a08f5b8 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -67,23 +67,13 @@ export function RecordingView(props: IRecordingViewProps) {
if (finished) {
props.setDuration(recordingTimer * 100)
let allVideoChunks: any = []
- console.log(videos)
videos.forEach((vid) => {
console.log(vid.videoChunks)
allVideoChunks = allVideoChunks.concat(vid.videoChunks)
})
- console.log(allVideoChunks)
const videoFile = new File(allVideoChunks, "video.mkv", { type: allVideoChunks[0].type, lastModified: Date.now() });
- // const uploadVideo = async () => {
- // const [{ result }] = await Networking.UploadFilesToServer(videoFile);
- // console.log("upload result", result);
- // if (!(result instanceof Error)) {
- // setResult(result)
- // }
- // }
-
Networking.UploadFilesToServer(videoFile)
.then((data) => {
const result = data[0].result
@@ -93,13 +83,9 @@ export function RecordingView(props: IRecordingViewProps) {
alert("video conversion failed");
}
})
- // uploadVideo()
// this.dataDoc[this.fieldKey + "-duration"] = (new Date().getTime() - this.recordingStart!) / 1000;
-
-
- // change to one recording box
}
@@ -190,7 +176,6 @@ export function RecordingView(props: IRecordingViewProps) {
// recording paused
videoRecorder.current.onpause = (event: any) => {
// append the current portion to the video pieces
- console.log(videoChunks)
setVideos(videos => [...videos, { videoChunks: videoChunks, endTime: recordingTimerRef.current }])
// reset the temporary chunks
@@ -199,7 +184,6 @@ export function RecordingView(props: IRecordingViewProps) {
}
videoRecorder.current.onresume = async (event: any) => {
- console.log(event)
await startShowingStream();
setRecording(true);
}
@@ -226,7 +210,6 @@ export function RecordingView(props: IRecordingViewProps) {
}
const startOrResume = () => {
- console.log('[RecordingView.tsx] startOrResume')
if (!videoRecorder.current || videoRecorder.current.state === "inactive") {
record();
} else if (videoRecorder.current.state === "paused") {
@@ -234,22 +217,6 @@ export function RecordingView(props: IRecordingViewProps) {
}
}
- // const playSegment = (idx: number) => {
- // console.log(idx)
- // let currentChunks = videos[idx].chunks
- // console.log(currentChunks)
-
- // const blob = new Blob(currentChunks, {
- // type: 'video/webm'
- // })
- // const blobUrl = URL.createObjectURL(blob)
- // console.log(blobUrl)
-
- // videoElementRef.current!.srcObject = null
- // videoElementRef.current!.src = blobUrl
- // videoElementRef.current!.muted = false
- // }
-
const clearPrevious = () => {
const numVideos = videos.length
setRecordingTimer(numVideos == 1 ? 0 : videos[numVideos - 2].endTime)
@@ -284,14 +251,6 @@ export function RecordingView(props: IRecordingViewProps) {
return toTwoDigit(minutes) + " : " + toTwoDigit(seconds);
}
-
-
-
- useEffect(() => {
- console.log(videos.map((elt) => elt.endTime / MAXTIME * 100))
- console.log(videos)
- }, [videos])
-
return (
<div className="recording-container">
<div className="video-wrapper">
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index ca13590de..71b165618 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -30,540 +30,540 @@ import { WebBox } from '../WebBox';
import { FontIconBadge } from './FontIconBadge';
import './FontIconBox.scss';
const FontIconSchema = createSchema({
- icon: "string",
+ icon: "string",
});
export enum ButtonType {
- TextButton = "textBtn",
- MenuButton = "menuBtn",
- DropdownList = "drpdownList",
- DropdownButton = "drpdownBtn",
- ClickButton = "clickBtn",
- DoubleButton = "dblBtn",
- ToggleButton = "tglBtn",
- ColorButton = "colorBtn",
- ToolButton = "toolBtn",
- NumberButton = "numBtn",
- EditableText = "editableText"
+ TextButton = "textBtn",
+ MenuButton = "menuBtn",
+ DropdownList = "drpdownList",
+ DropdownButton = "drpdownBtn",
+ ClickButton = "clickBtn",
+ DoubleButton = "dblBtn",
+ ToggleButton = "tglBtn",
+ ColorButton = "colorBtn",
+ ToolButton = "toolBtn",
+ NumberButton = "numBtn",
+ EditableText = "editableText"
}
export enum NumButtonType {
- Slider = "slider",
- DropdownOptions = "list",
- Inline = "inline"
+ Slider = "slider",
+ DropdownOptions = "list",
+ Inline = "inline"
}
export interface ButtonProps extends FieldViewProps {
- type?: ButtonType;
+ type?: ButtonType;
}
@observer
export class FontIconBox extends DocComponent<ButtonProps>() {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
- showTemplate = (): void => {
- const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
- dragFactory && this.props.addDocTab(dragFactory, "add:right");
- }
- dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
- useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };
-
- specificContextMenu = (): void => {
- if (!Doc.UserDoc().noviceMode) {
- const cm = ContextMenu.Instance;
- cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
- cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
- cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
- }
- }
-
- // Determining UI Specs
- @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
- @observable private icon = StrCast(this.dataDoc.icon, "user") as any;
- @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen);
- @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList);
- @observable private type = StrCast(this.rootDoc.btnType);
-
- /**
- * Types of buttons in dash:
- * - Main menu button (LHS)
- * - Tool button
- * - Expandable button (CollectionLinearView)
- * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
- * - Action button
- * - Dropdown button
- * - Color button
- * - Dropdown list
- * - Number button
- **/
-
- _batch: UndoManager.Batch | undefined = undefined;
- /**
- * Number button
- */
- @computed get numberButton() {
- const numBtnType: string = StrCast(this.rootDoc.numBtnType);
- const numScript = ScriptCast(this.rootDoc.script);
- const setValue = (value: number) => numScript?.script.run({ value, _readOnly_: false });
-
- // Script for checking the outcome of the toggle
- const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0;
-
- if (numBtnType === NumButtonType.Slider) {
- const dropdown =
- <div
- className="menuButton-dropdownBox"
- onPointerDown={e => e.stopPropagation()}
- >
- <input type="range" step="1" min={NumCast(this.rootDoc.numBtnMin, 0)} max={NumCast(this.rootDoc.numBtnMax, 100)} value={checkResult}
- className={"menu-slider"} id="slider"
- onPointerDown={() => this._batch = UndoManager.StartBatch("presDuration")}
- onPointerUp={() => this._batch?.end()}
- onChange={e => { e.stopPropagation(); setValue(Number(e.target.value)); }}
- />
- </div>;
- return (
- <div
- className={`menuButton ${this.type} ${numBtnType}`}
- onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
- >
- {checkResult}
- {this.rootDoc.dropDownOpen ? dropdown : null}
- </div>
- );
- } else if (numBtnType === NumButtonType.DropdownOptions) {
- const items: number[] = [];
- for (let i = 0; i < 100; i++) {
- if (i % 2 === 0) {
- items.push(i);
- }
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
+ showTemplate = (): void => {
+ const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
+ dragFactory && this.props.addDocTab(dragFactory, "add:right");
+ }
+ dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
+ useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };
+
+ specificContextMenu = (): void => {
+ if (!Doc.UserDoc().noviceMode) {
+ const cm = ContextMenu.Instance;
+ cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
}
- const list = items.map((value) => {
- return <div className="list-item" key={`${value}`}
- style={{
- backgroundColor: value === checkResult ? Colors.LIGHT_BLUE : undefined
- }}
- onClick={() => setValue(value)}>
- {value}
- </div>;
- });
- return (
- <div
- className={`menuButton ${this.type} ${numBtnType}`}
- >
- <div className={`button`} onClick={action((e) => setValue(Number(checkResult) - 1))}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
- </div>
- <div
- className={`button ${'number'}`}
- onPointerDown={(e) => {
- e.stopPropagation();
- e.preventDefault();
- }}
- onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
- >
- <input
- style={{ width: 30 }}
- className="button-input"
- type="number"
- value={checkResult}
- onChange={action((e) => setValue(Number(e.target.value)))}
- />
- </div>
- <div className={`button`} onClick={action((e) => setValue(Number(checkResult) + 1))}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
- </div>
-
- {this.rootDoc.dropDownOpen ?
+ }
+
+ // Determining UI Specs
+ @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
+ @observable private icon = StrCast(this.dataDoc.icon, "user") as any;
+ @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen);
+ @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList);
+ @observable private type = StrCast(this.rootDoc.btnType);
+
+ /**
+ * Types of buttons in dash:
+ * - Main menu button (LHS)
+ * - Tool button
+ * - Expandable button (CollectionLinearView)
+ * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
+ * - Action button
+ * - Dropdown button
+ * - Color button
+ * - Dropdown list
+ * - Number button
+ **/
+
+ _batch: UndoManager.Batch | undefined = undefined;
+ /**
+ * Number button
+ */
+ @computed get numberButton() {
+ const numBtnType: string = StrCast(this.rootDoc.numBtnType);
+ const numScript = ScriptCast(this.rootDoc.script);
+ const setValue = (value: number) => numScript?.script.run({ value, _readOnly_: false });
+
+ // Script for checking the outcome of the toggle
+ const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0;
+
+ if (numBtnType === NumButtonType.Slider) {
+ const dropdown =
+ <div
+ className="menuButton-dropdownBox"
+ onPointerDown={e => e.stopPropagation()}
+ >
+ <input type="range" step="1" min={NumCast(this.rootDoc.numBtnMin, 0)} max={NumCast(this.rootDoc.numBtnMax, 100)} value={checkResult}
+ className={"menu-slider"} id="slider"
+ onPointerDown={() => this._batch = UndoManager.StartBatch("presDuration")}
+ onPointerUp={() => this._batch?.end()}
+ onChange={e => { e.stopPropagation(); setValue(Number(e.target.value)); }}
+ />
+ </div>;
+ return (
+ <div
+ className={`menuButton ${this.type} ${numBtnType}`}
+ onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
+ >
+ {checkResult}
+ {this.rootDoc.dropDownOpen ? dropdown : null}
+ </div>
+ );
+ } else if (numBtnType === NumButtonType.DropdownOptions) {
+ const items: number[] = [];
+ for (let i = 0; i < 100; i++) {
+ if (i % 2 === 0) {
+ items.push(i);
+ }
+ }
+ const list = items.map((value) => {
+ return <div className="list-item" key={`${value}`}
+ style={{
+ backgroundColor: value === checkResult ? Colors.LIGHT_BLUE : undefined
+ }}
+ onClick={() => setValue(value)}>
+ {value}
+ </div>;
+ });
+ return (
+ <div
+ className={`menuButton ${this.type} ${numBtnType}`}
+ >
+ <div className={`button`} onClick={action((e) => setValue(Number(checkResult) - 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
+ </div>
+ <div
+ className={`button ${'number'}`}
+ onPointerDown={(e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ }}
+ onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
+ >
+ <input
+ style={{ width: 30 }}
+ className="button-input"
+ type="number"
+ value={checkResult}
+ onChange={action((e) => setValue(Number(e.target.value)))}
+ />
+ </div>
+ <div className={`button`} onClick={action((e) => setValue(Number(checkResult) + 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
+ </div>
+
+ {this.rootDoc.dropDownOpen ?
+ <div>
+ <div className="menuButton-dropdownList"
+ style={{ left: "25%" }}>
+ {list}
+ </div>
+ <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
+ </div> : null}
+
+ </div>
+ );
+ } else {
+ return (
<div>
- <div className="menuButton-dropdownList"
- style={{ left: "25%" }}>
- {list}
- </div>
- <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
- </div> : null}
-
- </div>
- );
- } else {
- return (
- <div>
- </div>
- );
- }
-
-
- }
-
- /**
- * Dropdown button
- */
- @computed get dropdownButton() {
- const active: string = StrCast(this.rootDoc.dropDownOpen);
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- return (
- <div className={`menuButton ${this.type} ${active}`}
- style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
- onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
- <div
- className="menuButton-dropdown"
- style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
- <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
- </div>
- {this.rootDoc.dropDownOpen ?
- <div className="menuButton-dropdownBox">
- {/* DROPDOWN BOX CONTENTS */}
- </div> : null}
- </div>
- );
- }
-
- /**
- * Dropdown list
- */
- @computed get dropdownListButton() {
- const active: string = StrCast(this.rootDoc.dropDownOpen);
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-
- const script = ScriptCast(this.rootDoc.script);
-
- let noviceList: string[] = [];
- let text: string | undefined;
- let dropdown = true;
- let icon: IconProp = "caret-down";
- try {
- if (script.script.originalScript.startsWith('setView')) {
- const selected = SelectionManager.Docs().lastElement();
- if (selected) {
- if (StrCast(selected.type) === DocumentType.COL) {
- text = StrCast(selected._viewType);
- } else {
- dropdown = false;
- text = selected.type === DocumentType.RTF ? "Text" : StrCast(selected.type);
- icon = Doc.toIcon(selected);
- }
- } else {
- dropdown = false;
- icon = "globe-asia";
- text = "User Default";
- }
- noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
- } else if (script.script.originalScript.startsWith('setFont')) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
- noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
- "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
- }
- } catch (e) {
- console.log(e);
- }
-
- // Get items to place into the list
- const list = this.buttonList.map((value) => {
- if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) {
- return;
+ </div>
+ );
}
- return <div className="list-item" key={`${value}`}
- style={{
- fontFamily: script.script.originalScript.startsWith('setFont') ? value : undefined,
- backgroundColor: value === text ? Colors.LIGHT_BLUE : undefined
- }}
- onClick={() => script.script.run({ value }).result}>
- {value[0].toUpperCase() + value.slice(1)}
- </div>;
- });
- const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
- {this.label}
- </div>;
- return (
- <div className={`menuButton ${this.type} ${active}`}
- style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
- onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
- {dropdown ? (null) : <FontAwesomeIcon style={{ marginLeft: 5 }} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
- <div className="menuButton-dropdown-header">
- {text && text[0].toUpperCase() + text.slice(1)}
- </div>
- {label}
- {!dropdown ? (null) : <div className="menuButton-dropDown">
- <FontAwesomeIcon icon={icon} color={color} size="sm" />
- </div>}
- {this.rootDoc.dropDownOpen ?
- <div>
- <div className="menuButton-dropdownList"
- style={{ left: 0 }}>
- {list}
- </div>
- <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
- </div>
- : null}
- </div>
- );
- }
-
- @observable colorPickerClosed: boolean = true;
- @computed get colorScript() { return ScriptCast(this.rootDoc.script); }
-
- colorPicker = (curColor: string) => {
- const change = (value: ColorState) => {
- const s = this.colorScript;
- s && undoBatch(() => s.script.run({ value: Utils.colorString(value), _readOnly_: false }).result)();
- };
- const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
- '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
- '#FFFFFF', '#f1efeb', "transparent"];
- return <SketchPicker
- onChange={change}
- color={curColor}
- presetColors={presets} />;
- }
- /**
- * Color button
- */
- @computed get colorButton() {
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const curColor = this.colorScript?.script.run({ value: undefined, _readOnly_: true }).result ?? "transparent";
-
- const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
- {this.label}
- </div>;
+ }
- const dropdownCaret = <div
- className="menuButton-dropDown"
- style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
- <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
- </div>;
- setTimeout(() => this.colorPicker(curColor)); // cause an update to the color picker rendered in MainView
- return (
- <div className={`menuButton ${this.type} ${this.colorPickerClosed}`}
- style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
- onClick={action(() => this.colorPickerClosed = !this.colorPickerClosed)}
- onPointerDown={e => e.stopPropagation()}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- <div className="colorButton-color" style={{ backgroundColor: curColor }} />
- {label}
- {/* {dropdownCaret} */}
- {this.colorPickerClosed ? (null) :
- <div>
- <div className="menuButton-dropdownBox"
- onPointerDown={e => e.stopPropagation()}
- onClick={e => e.stopPropagation()}>
- {this.colorPicker(curColor)}
+ /**
+ * Dropdown button
+ */
+ @computed get dropdownButton() {
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ return (
+ <div className={`menuButton ${this.type} ${active}`}
+ style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
+ onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
+ <div
+ className="menuButton-dropdown"
+ style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
+ <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
</div>
- <div className="dropbox-background" onClick={action((e) => {
- e.stopPropagation(); this.colorPickerClosed = true;
- })} />
- </div>}
- </div>
- );
- }
-
- @computed get toggleButton() {
- // Determine the type of toggle button
- const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
- const buttonText: string = StrCast(this.rootDoc.buttonText);
- // Colors
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-
- // Button label
- const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
- {this.label}
- </div>;
+ {this.rootDoc.dropDownOpen ?
+ <div className="menuButton-dropdownBox">
+ {/* DROPDOWN BOX CONTENTS */}
+ </div> : null}
+ </div>
+ );
+ }
+
+ /**
+ * Dropdown list
+ */
+ @computed get dropdownListButton() {
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+ const script = ScriptCast(this.rootDoc.script);
+
+ let noviceList: string[] = [];
+ let text: string | undefined;
+ let dropdown = true;
+ let icon: IconProp = "caret-down";
+ try {
+ if (script.script.originalScript.startsWith('setView')) {
+ const selected = SelectionManager.Docs().lastElement();
+ if (selected) {
+ if (StrCast(selected.type) === DocumentType.COL) {
+ text = StrCast(selected._viewType);
+ } else {
+ dropdown = false;
+ text = selected.type === DocumentType.RTF ? "Text" : StrCast(selected.type);
+ icon = Doc.toIcon(selected);
+ }
+ } else {
+ dropdown = false;
+ icon = "globe-asia";
+ text = "User Default";
+ }
+ noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
+ } else if (script.script.originalScript.startsWith('setFont')) {
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
+ "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
+ }
+ } catch (e) {
+ console.log(e);
+ }
+
+ // Get items to place into the list
+ const list = this.buttonList.map((value) => {
+ if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) {
+ return;
+ }
+ return <div className="list-item" key={`${value}`}
+ style={{
+ fontFamily: script.script.originalScript.startsWith('setFont') ? value : undefined,
+ backgroundColor: value === text ? Colors.LIGHT_BLUE : undefined
+ }}
+ onClick={() => script.script.run({ value }).result}>
+ {value[0].toUpperCase() + value.slice(1)}
+ </div>;
+ });
+
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
- if (switchToggle) {
return (
- <div className={`menuButton ${this.type} ${'switch'}`}>
- {buttonText ? buttonText : null}
- <label className="switch">
- <input type="checkbox"
- checked={backgroundColor === Colors.MEDIUM_BLUE}
- />
- <span className="slider round"></span>
- </label>
- </div>
+ <div className={`menuButton ${this.type} ${active}`}
+ style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
+ onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
+ {dropdown ? (null) : <FontAwesomeIcon style={{ marginLeft: 5 }} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
+ <div className="menuButton-dropdown-header">
+ {text && text[0].toUpperCase() + text.slice(1)}
+ </div>
+ {label}
+ {!dropdown ? (null) : <div className="menuButton-dropDown">
+ <FontAwesomeIcon icon={icon} color={color} size="sm" />
+ </div>}
+ {this.rootDoc.dropDownOpen ?
+ <div>
+ <div className="menuButton-dropdownList"
+ style={{ left: 0 }}>
+ {list}
+ </div>
+ <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
+ </div>
+ : null}
+ </div>
);
- } else {
+ }
+
+ @observable colorPickerClosed: boolean = true;
+ @computed get colorScript() { return ScriptCast(this.rootDoc.script); }
+
+ colorPicker = (curColor: string) => {
+ const change = (value: ColorState) => {
+ const s = this.colorScript;
+ s && undoBatch(() => s.script.run({ value: Utils.colorString(value), _readOnly_: false }).result)();
+ };
+ const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+ '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+ '#FFFFFF', '#f1efeb', "transparent"];
+ return <SketchPicker
+ onChange={change}
+ color={curColor}
+ presetColors={presets} />;
+ }
+ /**
+ * Color button
+ */
+ @computed get colorButton() {
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ const curColor = this.colorScript?.script.run({ value: undefined, _readOnly_: true }).result ?? "transparent";
+
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ const dropdownCaret = <div
+ className="menuButton-dropDown"
+ style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
+ <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
+ </div>;
+ setTimeout(() => this.colorPicker(curColor)); // cause an update to the color picker rendered in MainView
return (
- <div className={`menuButton ${this.type}`}
- style={{ opacity: 1, backgroundColor, color }}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- {label}
- </div>
+ <div className={`menuButton ${this.type} ${this.colorPickerClosed}`}
+ style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
+ onClick={action(() => this.colorPickerClosed = !this.colorPickerClosed)}
+ onPointerDown={e => e.stopPropagation()}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ <div className="colorButton-color" style={{ backgroundColor: curColor }} />
+ {label}
+ {/* {dropdownCaret} */}
+ {this.colorPickerClosed ? (null) :
+ <div>
+ <div className="menuButton-dropdownBox"
+ onPointerDown={e => e.stopPropagation()}
+ onClick={e => e.stopPropagation()}>
+ {this.colorPicker(curColor)}
+ </div>
+ <div className="dropbox-background" onClick={action((e) => {
+ e.stopPropagation(); this.colorPickerClosed = true;
+ })} />
+ </div>}
+ </div>
);
- }
- }
-
-
-
- /**
- * Default
- */
- @computed get defaultButton() {
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const active: string = StrCast(this.rootDoc.dropDownOpen);
- return (
- <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu}
- style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
- <div className="menuButton-wrap">
- <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} />
- {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
- </div>
- </div>
- );
- }
-
- @computed get editableText() {
- // Script for running the toggle
- const script = ScriptCast(this.rootDoc.script);
- // Function to run the script
- const checkResult = script?.script.run({ value: "", _readOnly_: true }).result;
-
- const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
- return (
- <div className="menuButton editableText">
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"lock"} />
- <div style={{ width: "calc(100% - .875em)", paddingLeft: "4px" }}>
- <EditableView GetValue={() => script?.script.run({ value: "", _readOnly_: true }).result} SetValue={setValue} contents={checkResult} />
- </div>
- </div>
- );
- }
-
- render() {
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
- {this.label}
- </div>;
+ }
+
+ @computed get toggleButton() {
+ // Determine the type of toggle button
+ const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
+ const buttonText: string = StrCast(this.rootDoc.buttonText);
+ // Colors
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+ // Button label
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ if (switchToggle) {
+ return (
+ <div className={`menuButton ${this.type} ${'switch'}`}>
+ {buttonText ? buttonText : null}
+ <label className="switch">
+ <input type="checkbox"
+ checked={backgroundColor === Colors.MEDIUM_BLUE}
+ />
+ <span className="slider round"></span>
+ </label>
+ </div>
+ );
+ } else {
+ return (
+ <div className={`menuButton ${this.type}`}
+ style={{ opacity: 1, backgroundColor, color }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {label}
+ </div>
+ );
+ }
+ }
- const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
- <div className="fontIconBox-label" style={{ color, backgroundColor: "transparent" }}>
- {this.label}
- </div>;
- const buttonText = StrCast(this.rootDoc.buttonText);
- // TODO:glr Add label of button type
- let button = this.defaultButton;
+ /**
+ * Default
+ */
+ @computed get defaultButton() {
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ return (
+ <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu}
+ style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
+ <div className="menuButton-wrap">
+ <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} />
+ {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
+ </div>
+ </div>
+ );
+ }
- switch (this.type) {
- case ButtonType.TextButton:
- button = (
- <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- {buttonText ?
- <div className="button-text">
- {buttonText}
- </div>
- : null}
- {label}
- </div>
- );
- // button = <TextButton {...buttonProps}></TextButton>
- break;
- case ButtonType.EditableText:
- button = this.editableText;
- break;
- case ButtonType.NumberButton:
- button = this.numberButton;
- break;
- case ButtonType.DropdownButton:
- button = this.dropdownButton;
- break;
- case ButtonType.DropdownList:
- button = this.dropdownListButton;
- break;
- case ButtonType.ColorButton:
- button = this.colorButton;
- break;
- case ButtonType.ToolButton:
- button = (
- <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor, color }}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- {label}
- </div>
- );
- break;
- case ButtonType.ToggleButton:
- button = this.toggleButton;
- // button = <ToggleButton {...buttonProps}></ToggleButton>
- break;
- case ButtonType.ClickButton:
- button = (
- <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1 }}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- {label}
- </div>
- );
- break;
- case ButtonType.MenuButton:
- const trailsIcon = <img src={`/assets/${"presTrails.png"}`}
- style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
- button = (
- <div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}>
- {this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />}
- {menuLabel}
- <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
- </div >
- );
- break;
- default:
- break;
- }
-
- return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button :
- <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
- {button}
- </Tooltip>;
- }
+ @computed get editableText() {
+ // Script for running the toggle
+ const script = ScriptCast(this.rootDoc.script);
+ // Function to run the script
+ const checkResult = script?.script.run({ value: "", _readOnly_: true }).result;
+
+ const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
+ return (
+ <div className="menuButton editableText">
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"lock"} />
+ <div style={{ width: "calc(100% - .875em)", paddingLeft: "4px" }}>
+ <EditableView GetValue={() => script?.script.run({ value: "", _readOnly_: true }).result} SetValue={setValue} contents={checkResult} />
+ </div>
+ </div>
+ );
+ }
+
+ render() {
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color, backgroundColor: "transparent" }}>
+ {this.label}
+ </div>;
+
+ const buttonText = StrCast(this.rootDoc.buttonText);
+
+ // TODO:glr Add label of button type
+ let button = this.defaultButton;
+
+ switch (this.type) {
+ case ButtonType.TextButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {buttonText ?
+ <div className="button-text">
+ {buttonText}
+ </div>
+ : null}
+ {label}
+ </div>
+ );
+ // button = <TextButton {...buttonProps}></TextButton>
+ break;
+ case ButtonType.EditableText:
+ button = this.editableText;
+ break;
+ case ButtonType.NumberButton:
+ button = this.numberButton;
+ break;
+ case ButtonType.DropdownButton:
+ button = this.dropdownButton;
+ break;
+ case ButtonType.DropdownList:
+ button = this.dropdownListButton;
+ break;
+ case ButtonType.ColorButton:
+ button = this.colorButton;
+ break;
+ case ButtonType.ToolButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor, color }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {label}
+ </div>
+ );
+ break;
+ case ButtonType.ToggleButton:
+ button = this.toggleButton;
+ // button = <ToggleButton {...buttonProps}></ToggleButton>
+ break;
+ case ButtonType.ClickButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1 }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {label}
+ </div>
+ );
+ break;
+ case ButtonType.MenuButton:
+ const trailsIcon = <img src={`/assets/${"presTrails.png"}`}
+ style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}>
+ {this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />}
+ {menuLabel}
+ <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
+ </div >
+ );
+ break;
+ default:
+ break;
+ }
+
+ return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button :
+ <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
+ {button}
+ </Tooltip>;
+ }
}
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setView(view: string) {
- const selected = SelectionManager.Docs().lastElement();
- selected ? selected._viewType = view : console.log("[FontIconBox.tsx] changeView failed");
+ const selected = SelectionManager.Docs().lastElement();
+ selected ? selected._viewType = view : console.log("[FontIconBox.tsx] changeView failed");
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) {
- const selected = SelectionManager.Docs().lastElement();
- if (checkResult) {
- return selected?._backgroundColor ?? "transparent";
- }
- if (selected) selected._backgroundColor = color;
+ const selected = SelectionManager.Docs().lastElement();
+ if (checkResult) {
+ return selected?._backgroundColor ?? "transparent";
+ }
+ if (selected) selected._backgroundColor = color;
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boolean) {
- if (checkResult) {
- return Doc.SharingDoc().userColor;
- }
- Doc.SharingDoc().userColor = undefined;
- Doc.GetProto(Doc.SharingDoc()).userColor = color;
- Doc.UserDoc().showTitle = color === "transparent" ? undefined : StrCast(Doc.UserDoc().showTitle, "creationDate");
+ if (checkResult) {
+ return Doc.SharingDoc().userColor;
+ }
+ Doc.SharingDoc().userColor = undefined;
+ Doc.GetProto(Doc.SharingDoc()).userColor = color;
+ Doc.UserDoc().showTitle = color === "transparent" ? undefined : StrCast(Doc.UserDoc().showTitle, "creationDate");
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
- const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
- if (checkResult && selected) {
- if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
- return "transparent";
- }
- selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ if (checkResult && selected) {
+ if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
+ return "transparent";
+ }
+ selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
});
/** TEXT
@@ -580,115 +580,115 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setFont(font: string, checkResult?: boolean) {
- SelectionManager.Docs().map(doc => doc._fontFamily = font);
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (checkResult) {
- return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
- }
- if (editorView) RichTextMenu.Instance.setFontFamily(font);
- else Doc.UserDoc().fontFamily = font;
+ SelectionManager.Docs().map(doc => doc._fontFamily = font);
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
+ if (checkResult) {
+ return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ }
+ if (editorView) RichTextMenu.Instance.setFontFamily(font);
+ else Doc.UserDoc().fontFamily = font;
});
ScriptingGlobals.add(function getActiveTextInfo(info: "family" | "size" | "color" | "highlight") {
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- const style = editorView?.state && RichTextMenu.Instance.getActiveFontStylesOnSelection();
- switch (info) {
- case "family": return style?.activeFamilies[0];
- case "size": return style?.activeSizes[0];
- case "color": return style?.activeColors[0];
- case "highlight": return style?.activeHighlights[0];
- }
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
+ const style = editorView?.state && RichTextMenu.Instance.getActiveFontStylesOnSelection();
+ switch (info) {
+ case "family": return style?.activeFamilies[0];
+ case "size": return style?.activeSizes[0];
+ case "color": return style?.activeColors[0];
+ case "highlight": return style?.activeHighlights[0];
+ }
});
ScriptingGlobals.add(function setAlignment(align: "left" | "right" | "center", checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return (editorView ? RichTextMenu.Instance.textAlign : Doc.UserDoc().textAlign) === align ? Colors.MEDIUM_BLUE : "transparent";
- }
- if (editorView?.state) RichTextMenu.Instance.align(editorView, editorView.dispatch, align);
- else Doc.UserDoc().textAlign = align;
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ return (editorView ? RichTextMenu.Instance.textAlign : Doc.UserDoc().textAlign) === align ? Colors.MEDIUM_BLUE : "transparent";
+ }
+ if (editorView?.state) RichTextMenu.Instance.align(editorView, editorView.dispatch, align);
+ else Doc.UserDoc().textAlign = align;
});
ScriptingGlobals.add(function setBulletList(mapStyle: "bullet" | "decimal", checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
- if (active === mapStyle) return Colors.MEDIUM_BLUE;
- return "transparent";
- }
- if (editorView) {
- const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
- editorView?.state && RichTextMenu.Instance.changeListType(
- editorView.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? "" : mapStyle }));
- }
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
+ if (active === mapStyle) return Colors.MEDIUM_BLUE;
+ return "transparent";
+ }
+ if (editorView) {
+ const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
+ editorView?.state && RichTextMenu.Instance.changeListType(
+ editorView.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? "" : mapStyle }));
+ }
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setFontColor(color?: string, checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return editorView ? RichTextMenu.Instance.fontColor : Doc.UserDoc().fontColor;
- }
+ if (checkResult) {
+ return editorView ? RichTextMenu.Instance.fontColor : Doc.UserDoc().fontColor;
+ }
- if (editorView) color && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
- else Doc.UserDoc().fontColor = color;
+ if (editorView) color && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
+ else Doc.UserDoc().fontColor = color;
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setFontHighlight(color?: string, checkResult?: boolean) {
- const selected = SelectionManager.Docs().lastElement();
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
-
- if (checkResult) {
- return (selected ?? Doc.UserDoc())._fontHighlight;
- }
- if (selected) {
- selected._fontColor = color;
- if (color) {
- editorView?.state && RichTextMenu.Instance.setHighlight(color, editorView, editorView?.dispatch);
- }
- }
- Doc.UserDoc()._fontHighlight = color;
+ const selected = SelectionManager.Docs().lastElement();
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
+
+ if (checkResult) {
+ return (selected ?? Doc.UserDoc())._fontHighlight;
+ }
+ if (selected) {
+ selected._fontColor = color;
+ if (color) {
+ editorView?.state && RichTextMenu.Instance.setHighlight(color, editorView, editorView?.dispatch);
+ }
+ }
+ Doc.UserDoc()._fontHighlight = color;
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setFontSize(size: string | number, checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", "");
- }
- if (typeof size === "number") size = size.toString();
- if (size && Number(size).toString() === size) size += "px";
- if (editorView) RichTextMenu.Instance.setFontSize(size);
- else Doc.UserDoc()._fontSize = size;
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", "");
+ }
+ if (typeof size === "number") size = size.toString();
+ if (size && Number(size).toString() === size) size += "px";
+ if (editorView) RichTextMenu.Instance.setFontSize(size);
+ else Doc.UserDoc()._fontSize = size;
});
ScriptingGlobals.add(function toggleBold(checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return (editorView ? RichTextMenu.Instance.bold : Doc.UserDoc().fontWeight === "bold") ? Colors.MEDIUM_BLUE : "transparent";
- }
- if (editorView) RichTextMenu.Instance?.toggleBold();
- else Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === "bold" ? undefined : "bold";
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ return (editorView ? RichTextMenu.Instance.bold : Doc.UserDoc().fontWeight === "bold") ? Colors.MEDIUM_BLUE : "transparent";
+ }
+ if (editorView) RichTextMenu.Instance?.toggleBold();
+ else Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === "bold" ? undefined : "bold";
});
ScriptingGlobals.add(function toggleUnderline(checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return (editorView ? RichTextMenu.Instance.underline : Doc.UserDoc().textDecoration === "underline") ? Colors.MEDIUM_BLUE : "transparent";
- }
- if (editorView) RichTextMenu.Instance?.toggleUnderline();
- else Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === "underline" ? undefined : "underline";
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ return (editorView ? RichTextMenu.Instance.underline : Doc.UserDoc().textDecoration === "underline") ? Colors.MEDIUM_BLUE : "transparent";
+ }
+ if (editorView) RichTextMenu.Instance?.toggleUnderline();
+ else Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === "underline" ? undefined : "underline";
});
ScriptingGlobals.add(function toggleItalic(checkResult?: boolean) {
- const editorView = RichTextMenu.Instance?.TextView?.EditorView;
- if (checkResult) {
- return (editorView ? RichTextMenu.Instance.italics : Doc.UserDoc().fontStyle === "italics") ? Colors.MEDIUM_BLUE : "transparent";
- }
- if (editorView) RichTextMenu.Instance?.toggleItalics();
- else Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === "italics" ? undefined : "italics";
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ if (checkResult) {
+ return (editorView ? RichTextMenu.Instance.italics : Doc.UserDoc().fontStyle === "italics") ? Colors.MEDIUM_BLUE : "transparent";
+ }
+ if (editorView) RichTextMenu.Instance?.toggleItalics();
+ else Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === "italics" ? undefined : "italics";
});
@@ -701,66 +701,66 @@ ScriptingGlobals.add(function toggleItalic(checkResult?: boolean) {
**/
ScriptingGlobals.add(function setActiveInkTool(tool: string, checkResult?: boolean) {
- if (checkResult) {
- return ((Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool) ?
- Colors.MEDIUM_BLUE : "transparent";
- }
- if (["circle", "square", "line"].includes(tool)) {
- if (GestureOverlay.Instance.InkShape === tool) {
- Doc.UserDoc().activeInkTool = InkTool.None;
- GestureOverlay.Instance.InkShape = InkTool.None;
- } else {
- Doc.UserDoc().activeInkTool = InkTool.Pen;
- GestureOverlay.Instance.InkShape = tool;
- }
- } else if (tool) { // pen or eraser
- if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) {
+ if (checkResult) {
+ return ((Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool) ?
+ Colors.MEDIUM_BLUE : "transparent";
+ }
+ if (["circle", "square", "line"].includes(tool)) {
+ if (GestureOverlay.Instance.InkShape === tool) {
+ Doc.UserDoc().activeInkTool = InkTool.None;
+ GestureOverlay.Instance.InkShape = InkTool.None;
+ } else {
+ Doc.UserDoc().activeInkTool = InkTool.Pen;
+ GestureOverlay.Instance.InkShape = tool;
+ }
+ } else if (tool) { // pen or eraser
+ if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) {
+ Doc.UserDoc().activeInkTool = InkTool.None;
+ } else {
+ Doc.UserDoc().activeInkTool = tool;
+ GestureOverlay.Instance.InkShape = "";
+ }
+ } else {
Doc.UserDoc().activeInkTool = InkTool.None;
- } else {
- Doc.UserDoc().activeInkTool = tool;
- GestureOverlay.Instance.InkShape = "";
- }
- } else {
- Doc.UserDoc().activeInkTool = InkTool.None;
- }
+ }
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setFillColor(color?: string, checkResult?: boolean) {
- const selected = SelectionManager.Docs().lastElement();
- if (checkResult) {
- if (selected?.type === DocumentType.INK) {
- return StrCast(selected.fillColor);
- }
- return ActiveFillColor();
- }
- SetActiveFillColor(StrCast(color));
- SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.fillColor = color);
+ const selected = SelectionManager.Docs().lastElement();
+ if (checkResult) {
+ if (selected?.type === DocumentType.INK) {
+ return StrCast(selected.fillColor);
+ }
+ return ActiveFillColor();
+ }
+ SetActiveFillColor(StrCast(color));
+ SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.fillColor = color);
});
ScriptingGlobals.add(function setStrokeWidth(width: number, checkResult?: boolean) {
- if (checkResult) {
- const selected = SelectionManager.Docs().lastElement();
- if (selected?.type === DocumentType.INK) {
- return NumCast(selected.strokeWidth);
- }
- return ActiveInkWidth();
- }
- SetActiveInkWidth(width.toString());
- SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.strokeWidth = Number(width));
+ if (checkResult) {
+ const selected = SelectionManager.Docs().lastElement();
+ if (selected?.type === DocumentType.INK) {
+ return NumCast(selected.strokeWidth);
+ }
+ return ActiveInkWidth();
+ }
+ SetActiveInkWidth(width.toString());
+ SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.strokeWidth = Number(width));
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setStrokeColor(color?: string, checkResult?: boolean) {
- if (checkResult) {
- const selected = SelectionManager.Docs().lastElement();
- if (selected?.type === DocumentType.INK) {
- return StrCast(selected.color);
- }
- return ActiveInkColor();
- }
- SetActiveInkColor(StrCast(color));
- SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.color = String(color));
+ if (checkResult) {
+ const selected = SelectionManager.Docs().lastElement();
+ if (selected?.type === DocumentType.INK) {
+ return StrCast(selected.color);
+ }
+ return ActiveInkColor();
+ }
+ SetActiveInkColor(StrCast(color));
+ SelectionManager.Docs().filter(doc => doc.type === DocumentType.INK).map(doc => doc.color = String(color));
});
@@ -768,28 +768,28 @@ ScriptingGlobals.add(function setStrokeColor(color?: string, checkResult?: boole
* webSetURL
**/
ScriptingGlobals.add(function webSetURL(url: string, checkResult?: boolean) {
- const selected = SelectionManager.Views().lastElement();
- if (selected?.rootDoc.type === DocumentType.WEB) {
- if (checkResult) {
- return StrCast(selected.rootDoc.data, Cast(selected.rootDoc.data, WebField, null)?.url?.href);
- }
- (selected.ComponentView as WebBox).submitURL(url);
- //selected.rootDoc.data = new WebField(url);
- }
+ const selected = SelectionManager.Views().lastElement();
+ if (selected?.rootDoc.type === DocumentType.WEB) {
+ if (checkResult) {
+ return StrCast(selected.rootDoc.data, Cast(selected.rootDoc.data, WebField, null)?.url?.href);
+ }
+ (selected.ComponentView as WebBox).submitURL(url);
+ //selected.rootDoc.data = new WebField(url);
+ }
});
ScriptingGlobals.add(function webForward(checkResult?: boolean) {
- const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
- if (checkResult) {
- return selected?.forward(checkResult) ? undefined : "lightGray";
- }
- selected?.forward();
+ const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
+ if (checkResult) {
+ return selected?.forward(checkResult) ? undefined : "lightGray";
+ }
+ selected?.forward();
});
ScriptingGlobals.add(function webBack(checkResult?: boolean) {
- const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
- if (checkResult) {
- return selected?.back(checkResult) ? undefined : "lightGray";
- }
- selected?.back();
+ const selected = (SelectionManager.Views().lastElement()?.ComponentView as WebBox);
+ if (checkResult) {
+ return selected?.back(checkResult) ? undefined : "lightGray";
+ }
+ selected?.back();
});
@@ -797,30 +797,30 @@ ScriptingGlobals.add(function webBack(checkResult?: boolean) {
* toggleSchemaPreview
**/
ScriptingGlobals.add(function toggleSchemaPreview(checkResult?: boolean) {
- const selected = SelectionManager.Docs().lastElement();
- if (checkResult && selected) {
- const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
- if (result) return Colors.MEDIUM_BLUE;
- else return "transparent";
- }
- else if (selected) {
- if (NumCast(selected.schemaPreviewWidth) > 0) {
- selected.schemaPreviewWidth = 200;
- } else {
- selected.schemaPreviewWidth = 0;
- }
- }
+ const selected = SelectionManager.Docs().lastElement();
+ if (checkResult && selected) {
+ const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
+ if (result) return Colors.MEDIUM_BLUE;
+ else return "transparent";
+ }
+ else if (selected) {
+ if (NumCast(selected.schemaPreviewWidth) > 0) {
+ selected.schemaPreviewWidth = 200;
+ } else {
+ selected.schemaPreviewWidth = 0;
+ }
+ }
});
/** STACK
* groupBy
*/
ScriptingGlobals.add(function setGroupBy(key: string, checkResult?: boolean) {
- SelectionManager.Docs().map(doc => doc._fontFamily = key);
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (checkResult) {
- return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
- }
- if (editorView) RichTextMenu.Instance.setFontFamily(key);
- else Doc.UserDoc().fontFamily = key;
+ SelectionManager.Docs().map(doc => doc._fontFamily = key);
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
+ if (checkResult) {
+ return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ }
+ if (editorView) RichTextMenu.Instance.setFontFamily(key);
+ else Doc.UserDoc().fontFamily = key;
}); \ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index f4f33482e..bc1cea505 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -43,6 +43,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); }
@computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
+
@observable isShowingVideo = false;
@action setIsShowingVideo(shown: boolean) {
this.isShowingVideo = shown
@@ -271,10 +272,31 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
+ @computed get recordingIsInOverlay() {
+ let isInOverlay = false
+ DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => {
+ if (doc.slides === this.rootDoc) {
+ isInOverlay = true
+ return
+ }
+ })
+ return isInOverlay
+ }
+
@undoBatch
@action
- startRecording = (targetDoc: Doc, activeItem: Doc) => {
+ hideRecording = (targetDoc: Doc, activeItem: Doc) => {
+ console.log("hide recording")
+ DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => {
+ if (doc.slides === activeItem) {
+ Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
+ }
+ })
+ }
+ @undoBatch
+ @action
+ startRecording = (targetDoc: Doc, activeItem: Doc) => {
// Remove every recording that already exists in overlay view
DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => {
if (doc.slides !== null) {
@@ -284,21 +306,24 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (activeItem.recording) {
// if we already have an existing recording
+ console.log("recording exists")
Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, Cast(activeItem.recording, Doc, null));
} else {
+ console.log("creating new recording")
// if we dont have any recording
const recording = Docs.Create.WebCamDocument("", { _width: 400, _height: 200, title: "recording", system: true, cloneFieldFilter: new List<string>(["system"]) });
+
// attach the recording to the slide, and attach the slide to the recording
recording.slides = activeItem
activeItem.recording = recording
+
// TODO: Figure out exactly where we want the video to appear
const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
recording.x = pt[0];
recording.y = pt[1];
Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, recording);
}
-
}
@computed
@@ -375,13 +400,25 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
onClick={() => this.updateView(targetDoc, activeItem)}
style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V</div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Start recording"}</div></>}>
- <div className="slideButton"
- onClick={() => this.startRecording(targetDoc, activeItem)}
- style={{ fontWeight: 700 }}>
- <FontAwesomeIcon icon={"video"} onPointerDown={e => e.stopPropagation()} />
- </div>
- </Tooltip>
+
+ {this.recordingIsInOverlay ?
+ <Tooltip title={<><div className="dash-tooltip">{"Hide Recording"}</div></>}>
+ <div className="slideButton"
+ onClick={() => this.hideRecording(targetDoc, activeItem)}
+ style={{ fontWeight: 700 }}>
+ <FontAwesomeIcon icon={"video-slash"} onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip> :
+ <Tooltip title={<><div className="dash-tooltip">{"Start recording"}</div></>}>
+ <div className="slideButton"
+ onClick={() => this.startRecording(targetDoc, activeItem)}
+ style={{ fontWeight: 700 }}>
+ <FontAwesomeIcon icon={"video"} onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip>
+ }
+
+
{this.indexInPres === 0 ? (null) : <Tooltip title={<><div className="dash-tooltip">{activeItem.groupWithUp ? "Ungroup" : "Group with up"}</div></>}>
<div className="slideButton"
onClick={() => activeItem.groupWithUp = !activeItem.groupWithUp}