From 3c8cb517c811f94dce1e3d8430e07af316642365 Mon Sep 17 00:00:00 2001 From: sotech117 Date: Thu, 13 Apr 2023 05:39:21 -0400 Subject: Compile and make compatible all the scattered code I had for empowering trails for dash meeting. Still much to do with ui, but basic functionaltiy is there. Two key things, 1) navigation for branching trails, and 2) ability to runSubroutines on tested trails. --- src/client/util/BranchingTrailManager.tsx | 113 ++++++++++++++++++++++++++++++ src/client/util/DocumentManager.ts | 1 + 2 files changed, 114 insertions(+) create mode 100644 src/client/util/BranchingTrailManager.tsx (limited to 'src/client/util') diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx new file mode 100644 index 000000000..5a9dd7743 --- /dev/null +++ b/src/client/util/BranchingTrailManager.tsx @@ -0,0 +1,113 @@ +import * as React from 'react'; +import { action, observable, computed } from 'mobx'; +import { observer } from 'mobx-react'; +import { Doc } from '../../fields/Doc'; +import { PresBox } from '../views/nodes/trails'; +import { Id } from '../../fields/FieldSymbols'; +import { DocumentManager } from './DocumentManager'; +import { OverlayView } from '../views/OverlayView'; +import { compute } from 'googleapis/build/src/apis/compute'; + +@observer +export class BranchingTrailManager extends React.Component { + public static Instance: BranchingTrailManager; + + constructor(props: any) { + super(props); + if (!BranchingTrailManager.Instance) { + BranchingTrailManager.Instance = this; + } + } + + setupUi = () => { + OverlayView.Instance.addWindow(, { x: 100, y: 150, width: 1000, title: 'Branching Trail' }); + }; + + // stack of the history + @observable private slideHistoryStack: String[] = []; + @action setSlideHistoryStack = action((newArr: String[]) => { + this.slideHistoryStack = newArr; + }); + + @observable private containsSet: Set = new Set(); + + // prev pres to copmare with + @observable private prevPresId: String | null = null; + @action setPrevPres = action((newId: String | null) => { + this.prevPresId = newId; + }); + + // docId to Doc map + @observable private docIdToDocMap: Map = new Map(); + + observeDocumentChange = (targetDoc: Doc, pres: PresBox) => { + const presId = pres.props.Document[Id]; + if (this.prevPresId === presId) { + return; + } + + const targetDocId = targetDoc[Id]; + this.docIdToDocMap.set(targetDocId, targetDoc); + + if (this.prevPresId === null) { + this.setupUi(); + } + + if (this.prevPresId === null || this.prevPresId !== presId) { + this.setPrevPres(presId); + // REVERT THE SET + const stringified = [presId, targetDocId].toString(); + if (this.containsSet.has([presId, targetDocId].toString())) { + // remove all the elements after the targetDocId + const newStack = this.slideHistoryStack.slice(0, this.slideHistoryStack.indexOf(stringified)); + const removed = this.slideHistoryStack.slice(this.slideHistoryStack.indexOf(stringified)); + this.setSlideHistoryStack(newStack); + + removed.forEach(info => this.containsSet.delete(info.toString())); + } else { + this.setSlideHistoryStack([...this.slideHistoryStack, stringified]); + this.containsSet.add(stringified); + } + } + }; + + clickHandler = (e: React.PointerEventHandler, targetDocId: string, removeIndex: number) => { + const targetDoc = this.docIdToDocMap.get(targetDocId); + if (!targetDoc) { + return; + } + const newStack = this.slideHistoryStack.slice(0, removeIndex); + const removed = this.slideHistoryStack.slice(removeIndex); + this.setSlideHistoryStack(newStack); + + removed.forEach(info => this.containsSet.delete(info.toString())); + DocumentManager.Instance.showDocument(targetDoc, { willZoomCentered: true }); + //PresBox.NavigateToTarget(targetDoc, targetDoc); + }; + + @computed get trailBreadcrumbs() { + return ( +
+ {this.slideHistoryStack.map((info, index) => { + const [presId, targetDocId] = info.split(','); + const doc = this.docIdToDocMap.get(targetDocId); + if (!doc) { + return <>; + } + return ( + + + -{'>'} + + ); + })} +
+ ); + } + + render() { + return
{BranchingTrailManager.Instance.trailBreadcrumbs}
; + } +} diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ccf370662..9cf584bba 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -19,6 +19,7 @@ import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox'; import { PresBox } from '../views/nodes/trails'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; +import { BranchingTrailManager } from './BranchingTrailManager'; const { Howl } = require('howler'); export class DocumentManager { -- cgit v1.2.3-70-g09d2 From 2bc89733ce522527c2f27203b537d99395c9479b Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 17 Apr 2023 15:39:41 -0400 Subject: minor cleanup --- src/client/util/BranchingTrailManager.tsx | 11 +++++------ src/client/util/DocumentManager.ts | 1 - src/client/views/MainView.tsx | 5 ++--- src/client/views/collections/TreeView.scss | 3 +-- 4 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx index 5a9dd7743..44cec6922 100644 --- a/src/client/util/BranchingTrailManager.tsx +++ b/src/client/util/BranchingTrailManager.tsx @@ -1,12 +1,11 @@ -import * as React from 'react'; -import { action, observable, computed } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import { Doc } from '../../fields/Doc'; -import { PresBox } from '../views/nodes/trails'; import { Id } from '../../fields/FieldSymbols'; -import { DocumentManager } from './DocumentManager'; +import { PresBox } from '../views/nodes/trails'; import { OverlayView } from '../views/OverlayView'; -import { compute } from 'googleapis/build/src/apis/compute'; +import { DocumentManager } from './DocumentManager'; @observer export class BranchingTrailManager extends React.Component { @@ -71,7 +70,7 @@ export class BranchingTrailManager extends React.Component { } }; - clickHandler = (e: React.PointerEventHandler, targetDocId: string, removeIndex: number) => { + clickHandler = (e: React.PointerEvent, targetDocId: string, removeIndex: number) => { const targetDoc = this.docIdToDocMap.get(targetDocId); if (!targetDoc) { return; diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 8263e1ba7..e01457b4f 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -15,7 +15,6 @@ import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox'; import { PresBox } from '../views/nodes/trails'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; -import { BranchingTrailManager } from './BranchingTrailManager'; const { Howl } = require('howler'); export class DocumentManager { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index f0f744886..f625d44fe 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -14,7 +14,7 @@ import { StrCast } from '../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../Utils'; import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; -import { Docs, DocUtils } from '../documents/Documents'; +import { Docs } from '../documents/Documents'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { CaptureManager } from '../util/CaptureManager'; import { DocumentManager } from '../util/DocumentManager'; @@ -40,7 +40,7 @@ import { DashboardView } from './DashboardView'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; import { GestureOverlay } from './GestureOverlay'; -import { TOPBAR_HEIGHT, LEFT_MENU_WIDTH } from './global/globalCssVariables.scss'; +import { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } from './global/globalCssVariables.scss'; import { Colors } from './global/globalEnums'; import { KeyManager } from './GlobalKeyHandler'; import { InkTranscription } from './InkTranscription'; @@ -63,7 +63,6 @@ import { PreviewCursor } from './PreviewCursor'; import { PropertiesView } from './PropertiesView'; import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider'; import { TopBar } from './topbar/TopBar'; -import { BranchingTrailManager } from '../util/BranchingTrailManager'; const _global = (window /* browser */ || global) /* node */ as any; @observer diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index cb6432687..185bed74c 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -25,10 +25,9 @@ width: 100%; height: 100%; position: absolute; - left: 10px; .treeView-expandIcon { - // display: none; + display: none; left: -8px; position: absolute; } -- cgit v1.2.3-70-g09d2 From bdabb0eb1aeac9ea9d4f1fa40889b8d30937c1f0 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Sat, 19 Aug 2023 03:22:16 -0400 Subject: Toggling icon for mic and added webcapturedoc to dropdown --- src/client/util/CurrentUserUtils.ts | 8 +++- src/client/views/UndoStack.tsx | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 47 ++++++++++++++++++++-- .../views/nodes/RecordingBox/RecordingView.tsx | 3 +- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 6 files changed, 56 insertions(+), 12 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 25c8f511b..54828867e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,7 +714,9 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: "microphone", toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}, funcs: { }} + { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, + { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, + { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, ]; } @@ -737,6 +739,8 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; + Doc.UserDoc().workspaceRecordings = new List; + Doc.UserDoc().isRecording = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -999,4 +1003,4 @@ ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index a551e5332..813cdd050 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -37,7 +37,7 @@ export class UndoStack extends React.Component { }}> {UndoManager.undoStackNames.map((name, i) => (
-
{name.replace(/[^\.]*\./, '')}
+
{StrCast(name).replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) @@ -45,7 +45,7 @@ export class UndoStack extends React.Component { .map((name, i) => (
- {name.replace(/[^\.]*\./, '')} + {StrCast(name).replace(/[^\.]*\./, '')}
))} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 5ff5f7bfa..41ad90155 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -242,7 +242,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value.charAt(0).toUpperCase() + value.slice(1), + text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 8fa2861b6..3237ce6cd 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -15,6 +15,8 @@ import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; +import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -82,27 +84,64 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { + console.log(_readOnly_) + console.log(RecordingBox.screengrabber) if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { + //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening + console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 100; + RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 RecordingBox.screengrabber!.rootDoc.overlayY = 100; + console.log(RecordingBox.screengrabber?.rootDoc) RecordingBox.screengrabber = undefined; }, 100); + Doc.UserDoc().isRecording = false; + // console.log(RecordingBox.screengrabber.dataDoc); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); + Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); + // console.log(RecordingBox.screengrabber.rootDoc) + // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); } else { + //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { _width: 384, _height: 216, }); - screengrabber.overlayX = -400; - screengrabber.overlayY = 0; + // Doc.UserDoc().currentScreenGrab = screengrabber; + screengrabber.overlayX = 100; //was -400 + screengrabber.overlayY = 100; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); + Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); + Doc.UserDoc().isRecording = true; + } }, 'toggle recording'); +ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { + console.log(value) + const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); + + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); + +}); + +ScriptingGlobals.add(function getCurrRecording() { + console.log(RecordingBox.screengrabber); +}); +ScriptingGlobals.add(function getWorkspaceRecordings() { + return Doc.UserDoc().workspaceRecordings +}); +ScriptingGlobals.add(function getIsRecording() { + return Doc.UserDoc().isRecording; +}) + + + diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 0e386b093..8c0f5efef 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -163,8 +163,9 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active + console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - + console.log("this it") // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index aa514be3b..5de51dbe9 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -365,7 +365,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording -- cgit v1.2.3-70-g09d2 From 2466587655888d5894159b942f09661ab73ebe66 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:33:14 -0400 Subject: Revert "Toggling icon for mic and added webcapturedoc to dropdown" This reverts commit bdabb0eb1aeac9ea9d4f1fa40889b8d30937c1f0. --- src/client/util/CurrentUserUtils.ts | 8 +--- src/client/views/UndoStack.tsx | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 47 ++-------------------- .../views/nodes/RecordingBox/RecordingView.tsx | 3 +- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 6 files changed, 12 insertions(+), 56 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 54828867e..25c8f511b 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,9 +714,7 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, - { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, - { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, + { title: "Audio", icon: "microphone", toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}, funcs: { }} ]; } @@ -739,8 +737,6 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; - Doc.UserDoc().workspaceRecordings = new List; - Doc.UserDoc().isRecording = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -1003,4 +999,4 @@ ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index 813cdd050..a551e5332 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -37,7 +37,7 @@ export class UndoStack extends React.Component { }}> {UndoManager.undoStackNames.map((name, i) => (
-
{StrCast(name).replace(/[^\.]*\./, '')}
+
{name.replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) @@ -45,7 +45,7 @@ export class UndoStack extends React.Component { .map((name, i) => (
- {StrCast(name).replace(/[^\.]*\./, '')} + {name.replace(/[^\.]*\./, '')}
))} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 41ad90155..5ff5f7bfa 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -242,7 +242,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), + text: value.charAt(0).toUpperCase() + value.slice(1), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 3237ce6cd..8fa2861b6 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -15,8 +15,6 @@ import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; -import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -84,64 +82,27 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { - console.log(_readOnly_) - console.log(RecordingBox.screengrabber) if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { - //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening - console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 + RecordingBox.screengrabber!.rootDoc.overlayX = 100; RecordingBox.screengrabber!.rootDoc.overlayY = 100; - console.log(RecordingBox.screengrabber?.rootDoc) RecordingBox.screengrabber = undefined; }, 100); - Doc.UserDoc().isRecording = false; - // console.log(RecordingBox.screengrabber.dataDoc); - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); - Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); - // console.log(RecordingBox.screengrabber.rootDoc) - // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); } else { - //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { _width: 384, _height: 216, }); - // Doc.UserDoc().currentScreenGrab = screengrabber; - screengrabber.overlayX = 100; //was -400 - screengrabber.overlayY = 100; //was 0 + screengrabber.overlayX = -400; + screengrabber.overlayY = 0; screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay + Doc.AddToMyOverlay(screengrabber); DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); - Doc.UserDoc().isRecording = true; - } }, 'toggle recording'); -ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { - console.log(value) - const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); - - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); - -}); - -ScriptingGlobals.add(function getCurrRecording() { - console.log(RecordingBox.screengrabber); -}); -ScriptingGlobals.add(function getWorkspaceRecordings() { - return Doc.UserDoc().workspaceRecordings -}); -ScriptingGlobals.add(function getIsRecording() { - return Doc.UserDoc().isRecording; -}) - - - diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 8c0f5efef..0e386b093 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -163,9 +163,8 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active - console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - console.log("this it") + // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 5de51dbe9..aa514be3b 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -365,7 +365,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording -- cgit v1.2.3-70-g09d2 From 5e8cc0a6a7f8dfc0c33fbdfa8879de88f057233e Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:39:45 -0400 Subject: Revert "Revert "Toggling icon for mic and added webcapturedoc to dropdown"" This reverts commit 2466587655888d5894159b942f09661ab73ebe66. --- src/client/util/CurrentUserUtils.ts | 8 +++- src/client/views/UndoStack.tsx | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 47 ++++++++++++++++++++-- .../views/nodes/RecordingBox/RecordingView.tsx | 3 +- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 6 files changed, 56 insertions(+), 12 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 25c8f511b..54828867e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,7 +714,9 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: "microphone", toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}, funcs: { }} + { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, + { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, + { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, ]; } @@ -737,6 +739,8 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; + Doc.UserDoc().workspaceRecordings = new List; + Doc.UserDoc().isRecording = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -999,4 +1003,4 @@ ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index a551e5332..813cdd050 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -37,7 +37,7 @@ export class UndoStack extends React.Component { }}> {UndoManager.undoStackNames.map((name, i) => (
-
{name.replace(/[^\.]*\./, '')}
+
{StrCast(name).replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) @@ -45,7 +45,7 @@ export class UndoStack extends React.Component { .map((name, i) => (
- {name.replace(/[^\.]*\./, '')} + {StrCast(name).replace(/[^\.]*\./, '')}
))} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 5ff5f7bfa..41ad90155 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -242,7 +242,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value.charAt(0).toUpperCase() + value.slice(1), + text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 8fa2861b6..3237ce6cd 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -15,6 +15,8 @@ import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; +import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -82,27 +84,64 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { + console.log(_readOnly_) + console.log(RecordingBox.screengrabber) if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { + //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening + console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 100; + RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 RecordingBox.screengrabber!.rootDoc.overlayY = 100; + console.log(RecordingBox.screengrabber?.rootDoc) RecordingBox.screengrabber = undefined; }, 100); + Doc.UserDoc().isRecording = false; + // console.log(RecordingBox.screengrabber.dataDoc); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); + Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); + // console.log(RecordingBox.screengrabber.rootDoc) + // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); } else { + //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { _width: 384, _height: 216, }); - screengrabber.overlayX = -400; - screengrabber.overlayY = 0; + // Doc.UserDoc().currentScreenGrab = screengrabber; + screengrabber.overlayX = 100; //was -400 + screengrabber.overlayY = 100; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); + Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); + Doc.UserDoc().isRecording = true; + } }, 'toggle recording'); +ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { + console.log(value) + const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); + + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); + +}); + +ScriptingGlobals.add(function getCurrRecording() { + console.log(RecordingBox.screengrabber); +}); +ScriptingGlobals.add(function getWorkspaceRecordings() { + return Doc.UserDoc().workspaceRecordings +}); +ScriptingGlobals.add(function getIsRecording() { + return Doc.UserDoc().isRecording; +}) + + + diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 0e386b093..8c0f5efef 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -163,8 +163,9 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active + console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - + console.log("this it") // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index aa514be3b..5de51dbe9 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -365,7 +365,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording -- cgit v1.2.3-70-g09d2 From 40a39db25646b513c25554a2abdf35ef977500a8 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:52:33 -0400 Subject: Revert "Revert "Revert "Toggling icon for mic and added webcapturedoc to dropdown""" This reverts commit 5e8cc0a6a7f8dfc0c33fbdfa8879de88f057233e. --- src/client/util/CurrentUserUtils.ts | 8 +--- src/client/views/UndoStack.tsx | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 47 ++-------------------- .../views/nodes/RecordingBox/RecordingView.tsx | 3 +- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 6 files changed, 12 insertions(+), 56 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 54828867e..25c8f511b 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,9 +714,7 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, - { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, - { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, + { title: "Audio", icon: "microphone", toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}, funcs: { }} ]; } @@ -739,8 +737,6 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; - Doc.UserDoc().workspaceRecordings = new List; - Doc.UserDoc().isRecording = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -1003,4 +999,4 @@ ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index 813cdd050..a551e5332 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -37,7 +37,7 @@ export class UndoStack extends React.Component { }}> {UndoManager.undoStackNames.map((name, i) => (
-
{StrCast(name).replace(/[^\.]*\./, '')}
+
{name.replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) @@ -45,7 +45,7 @@ export class UndoStack extends React.Component { .map((name, i) => (
- {StrCast(name).replace(/[^\.]*\./, '')} + {name.replace(/[^\.]*\./, '')}
))} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 41ad90155..5ff5f7bfa 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -242,7 +242,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), + text: value.charAt(0).toUpperCase() + value.slice(1), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 3237ce6cd..8fa2861b6 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -15,8 +15,6 @@ import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; -import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -84,64 +82,27 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { - console.log(_readOnly_) - console.log(RecordingBox.screengrabber) if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { - //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening - console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 + RecordingBox.screengrabber!.rootDoc.overlayX = 100; RecordingBox.screengrabber!.rootDoc.overlayY = 100; - console.log(RecordingBox.screengrabber?.rootDoc) RecordingBox.screengrabber = undefined; }, 100); - Doc.UserDoc().isRecording = false; - // console.log(RecordingBox.screengrabber.dataDoc); - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); - Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); - // console.log(RecordingBox.screengrabber.rootDoc) - // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); } else { - //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { _width: 384, _height: 216, }); - // Doc.UserDoc().currentScreenGrab = screengrabber; - screengrabber.overlayX = 100; //was -400 - screengrabber.overlayY = 100; //was 0 + screengrabber.overlayX = -400; + screengrabber.overlayY = 0; screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay + Doc.AddToMyOverlay(screengrabber); DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); - Doc.UserDoc().isRecording = true; - } }, 'toggle recording'); -ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { - console.log(value) - const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); - - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); - -}); - -ScriptingGlobals.add(function getCurrRecording() { - console.log(RecordingBox.screengrabber); -}); -ScriptingGlobals.add(function getWorkspaceRecordings() { - return Doc.UserDoc().workspaceRecordings -}); -ScriptingGlobals.add(function getIsRecording() { - return Doc.UserDoc().isRecording; -}) - - - diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 8c0f5efef..0e386b093 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -163,9 +163,8 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active - console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - console.log("this it") + // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 5de51dbe9..aa514be3b 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -365,7 +365,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording -- cgit v1.2.3-70-g09d2 From ec6a5f5d5684ca66cd21bb8fef91c86852dd126f Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Sat, 19 Aug 2023 08:53:11 -0400 Subject: Revert "Revert "Revert "Revert "Toggling icon for mic and added webcapturedoc to dropdown"""" This reverts commit 40a39db25646b513c25554a2abdf35ef977500a8. --- src/client/util/CurrentUserUtils.ts | 8 +++- src/client/views/UndoStack.tsx | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 4 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 47 ++++++++++++++++++++-- .../views/nodes/RecordingBox/RecordingView.tsx | 3 +- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 6 files changed, 56 insertions(+), 12 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 25c8f511b..54828867e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,7 +714,9 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: "microphone", toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}, funcs: { }} + { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, + { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, + { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, ]; } @@ -737,6 +739,8 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; + Doc.UserDoc().workspaceRecordings = new List; + Doc.UserDoc().isRecording = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -999,4 +1003,4 @@ ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); \ No newline at end of file +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; }); diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index a551e5332..813cdd050 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -37,7 +37,7 @@ export class UndoStack extends React.Component { }}> {UndoManager.undoStackNames.map((name, i) => (
-
{name.replace(/[^\.]*\./, '')}
+
{StrCast(name).replace(/[^\.]*\./, '')}
))} {Array.from(UndoManager.redoStackNames) @@ -45,7 +45,7 @@ export class UndoStack extends React.Component { .map((name, i) => (
- {name.replace(/[^\.]*\./, '')} + {StrCast(name).replace(/[^\.]*\./, '')}
))} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 5ff5f7bfa..41ad90155 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -242,7 +242,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value.charAt(0).toUpperCase() + value.slice(1), + text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 8fa2861b6..3237ce6cd 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -15,6 +15,8 @@ import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; +import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -82,27 +84,64 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { + console.log(_readOnly_) + console.log(RecordingBox.screengrabber) if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { + //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening + console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 100; + RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 RecordingBox.screengrabber!.rootDoc.overlayY = 100; + console.log(RecordingBox.screengrabber?.rootDoc) RecordingBox.screengrabber = undefined; }, 100); + Doc.UserDoc().isRecording = false; + // console.log(RecordingBox.screengrabber.dataDoc); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); + Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); + // console.log(RecordingBox.screengrabber.rootDoc) + // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); } else { + //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { _width: 384, _height: 216, }); - screengrabber.overlayX = -400; - screengrabber.overlayY = 0; + // Doc.UserDoc().currentScreenGrab = screengrabber; + screengrabber.overlayX = 100; //was -400 + screengrabber.overlayY = 100; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); + Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); + Doc.UserDoc().isRecording = true; + } }, 'toggle recording'); +ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { + console.log(value) + const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); + + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); + +}); + +ScriptingGlobals.add(function getCurrRecording() { + console.log(RecordingBox.screengrabber); +}); +ScriptingGlobals.add(function getWorkspaceRecordings() { + return Doc.UserDoc().workspaceRecordings +}); +ScriptingGlobals.add(function getIsRecording() { + return Doc.UserDoc().isRecording; +}) + + + diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 0e386b093..8c0f5efef 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -163,8 +163,9 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active + console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - + console.log("this it") // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index aa514be3b..5de51dbe9 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -365,7 +365,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording -- cgit v1.2.3-70-g09d2 From 7a2f4ea7d58b816e84949c58d66310ac6a18edd6 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Tue, 22 Aug 2023 15:42:55 -0400 Subject: uptodate --- package-lock.json | 39 ++++++++++++ src/client/util/CurrentUserUtils.ts | 12 +++- .../views/nodes/RecordingBox/RecordingBox.tsx | 69 +++++++++++++++++----- 3 files changed, 103 insertions(+), 17 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index 870974738..e6985cf65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10391,6 +10391,16 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "d3": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", @@ -11771,6 +11781,28 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", @@ -11782,6 +11814,7 @@ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "requires": { + "d": "^1.0.1", "ext": "^1.1.2" } }, @@ -27540,6 +27573,12 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 54828867e..053f416ce 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -714,9 +714,13 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, - { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, - { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}, }, + { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, + { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, + { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, + { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, + { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, + { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, + { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `console.log("heya")`}}, ]; } @@ -741,6 +745,8 @@ export class CurrentUserUtils { const subMenu = params.subMenu; Doc.UserDoc().workspaceRecordings = new List; Doc.UserDoc().isRecording = false; + Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().currentRecording = undefined; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 3237ce6cd..5502a1e08 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -9,7 +9,7 @@ import { VideoBox } from '../VideoBox'; import { RecordingView } from './RecordingView'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Presentation } from '../../../util/TrackMovements'; -import { Doc } from '../../../../fields/Doc'; +import { Doc, DocListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { BoolCast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; @@ -17,6 +17,11 @@ import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; +import { DocumentView } from '../DocumentView'; +import { SettingsManager } from '../../../util/SettingsManager'; +import { PropertiesView } from '../../PropertiesView'; +import { PropertiesSection } from '../../PropertiesSection'; +import { PropertiesDocContextSelector } from '../../PropertiesDocContextSelector'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -91,19 +96,29 @@ ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening console.log('grabbing screen!') RecordingBox.screengrabber.Pause?.(); + const remDoc = RecordingBox.screengrabber.rootDoc; setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 RecordingBox.screengrabber!.rootDoc.overlayY = 100; - console.log(RecordingBox.screengrabber?.rootDoc) + // DocListCast(Doc.MyOverlayDocs.data) + // .filter(doc => doc.slides === RecordingBox.screengrabber!.rootDoc) + // .forEach(Doc.RemFromMyOverlay); + console.log(RecordingBox.screengrabber) RecordingBox.screengrabber = undefined; }, 100); + //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this + setTimeout(() => { + Doc.RemFromMyOverlay(remDoc); + + }, 1000) Doc.UserDoc().isRecording = false; - // console.log(RecordingBox.screengrabber.dataDoc); + // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); - // console.log(RecordingBox.screengrabber.rootDoc) - // console.log(RecordingBox.screengrabber.dataDoc.data?.valueOf); + + // let recView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + // console.log(recView) } else { //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { @@ -125,23 +140,49 @@ ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { } }, 'toggle recording'); ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { + let docval = undefined; + Doc.UserDoc().isRecPlayback = true; + Doc.UserDoc().currentRecording = value; console.log(value) - const screenvid = Docs.Create.VideoDocument('', {_width: 384, _height: 216}); - - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); - + value.overlayX = 100; + value.overlayY = 100; + Doc.AddToMyOverlay(value); + DocumentManager.Instance.AddViewRenderedCb(value, docView => { + docval = + Doc.UserDoc().currentRecording = docView.ComponentView as VideoBox; + // docval.Play(); + }) + // let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); }); +ScriptingGlobals.add(function addRectoWorkspace() { + console.log("adding rec to doc"); + +}) +ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { + value.Play(); +}) +ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { + value.Pause(); +}) +ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { + value.Pause(); + Doc.RemFromMyOverlay(value.rootDoc); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; +}) -ScriptingGlobals.add(function getCurrRecording() { - console.log(RecordingBox.screengrabber); -}); ScriptingGlobals.add(function getWorkspaceRecordings() { return Doc.UserDoc().workspaceRecordings }); ScriptingGlobals.add(function getIsRecording() { return Doc.UserDoc().isRecording; }) - +ScriptingGlobals.add(function getIsRecPlayback() { + return Doc.UserDoc().isRecPlayback; +}) +ScriptingGlobals.add(function getCurrentRecording() { + return Doc.UserDoc().currentRecording; +}) -- cgit v1.2.3-70-g09d2 From f710353318543a43349944f9c0a96ce3f3388270 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:30:17 -0400 Subject: topbar Audio progress Logically works, need to consider how to add to doc --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/DragManager.ts | 55 +++++++++++++++++++++- .../views/nodes/RecordingBox/RecordingBox.tsx | 25 +++++++--- 3 files changed, 73 insertions(+), 9 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 1d63e90f0..99a8ee571 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -720,7 +720,7 @@ export class CurrentUserUtils { { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, - { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `console.log("heya")`}}, + { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `addRectoWorkspace(getCurrentRecording())`}}, ]; } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index f4ff38515..f06d4a0e7 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -4,7 +4,7 @@ import { Doc, Field, Opt, StrListCast } from '../../fields/Doc'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; import { ScriptField } from '../../fields/ScriptField'; -import { BoolCast, ScriptCast, StrCast } from '../../fields/Types'; +import { BoolCast, Cast, ScriptCast, StrCast } from '../../fields/Types'; import { emptyFunction, Utils } from '../../Utils'; import { Docs, DocUtils } from '../documents/Documents'; import * as globalCssVariables from '../views/global/globalCssVariables.scss'; @@ -14,6 +14,7 @@ import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; +import { listSpec } from '../../fields/Schema'; export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove @@ -241,6 +242,58 @@ export namespace DragManager { return true; } + export function StartDropdownDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, recordingIndex: number, options?: DragOptions, dropEvent?: () => any,) { + + const addAudioTag = (dropDoc: any) => { + dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField()); + dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); + return dropDoc; + }; + const finishDrag = async (e: DragCompleteEvent) => { + Doc.UserDoc().isAddRecToDocMode = false; + Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; + Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); + const docDragData = e.docDragData; + dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails + if (docDragData && !docDragData.droppedDocuments.length) { + docDragData.dropAction = dragData.userDropAction || dragData.dropAction; + docDragData.droppedDocuments = ( + await Promise.all( + dragData.draggedDocuments.map(async d => + !dragData.isDocDecorationMove && !dragData.userDropAction && ScriptCast(d.onDragStart) + ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) + : docDragData.dropAction === 'embed' + ? Doc.BestEmbedding(d) + : docDragData.dropAction === 'add' + ? d + : docDragData.dropAction === 'proto' + ? Doc.GetProto(d) + : docDragData.dropAction === 'copy' + ? ( + await Doc.MakeClone(d) + ).clone + : d + ) + ) + ).filter(d => d); + !['same', 'proto'].includes(docDragData.dropAction as any) && + docDragData.droppedDocuments + // .filter(drop => !drop.dragOnlyWithinContainer || ['embed', 'copy'].includes(docDragData.dropAction as any)) + .forEach((drop: Doc, i: number) => { + const dragProps = StrListCast(dragData.draggedDocuments[i].dropPropertiesToRemove); + const remProps = (dragData?.dropPropertiesToRemove || []).concat(Array.from(dragProps)); + [...remProps, 'dropPropertiesToRemove'].map(prop => (drop[prop] = undefined)); + }); + } + return e; + }; + dragData.draggedDocuments.map(d => d.dragFactory); // does this help? trying to make sure the dragFactory Doc is loaded + StartDrag(eles, dragData, downX, downY, options, finishDrag); + return true; + } + // drag a button template and drop a new button export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { const finishDrag = (e: DragCompleteEvent) => { diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 5502a1e08..d6e4bd304 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -11,7 +11,7 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { Presentation } from '../../../util/TrackMovements'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; -import { BoolCast, DocCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast } from '../../../../fields/Types'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { DocumentManager } from '../../../util/DocumentManager'; import { Docs } from '../../../documents/Documents'; @@ -22,6 +22,8 @@ import { SettingsManager } from '../../../util/SettingsManager'; import { PropertiesView } from '../../PropertiesView'; import { PropertiesSection } from '../../PropertiesSection'; import { PropertiesDocContextSelector } from '../../PropertiesDocContextSelector'; +import { listSpec } from '../../../../fields/Schema'; +import { DragManager } from '../../../util/DragManager'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -146,17 +148,26 @@ ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { console.log(value) value.overlayX = 100; value.overlayY = 100; + if (!Doc.UserDoc().isAddRecToDocMode) { Doc.AddToMyOverlay(value); - DocumentManager.Instance.AddViewRenderedCb(value, docView => { - docval = - Doc.UserDoc().currentRecording = docView.ComponentView as VideoBox; - // docval.Play(); - }) + DocumentManager.Instance.AddViewRenderedCb(value, docView => { + docval = + Doc.UserDoc().currentRecording = docView.ComponentView as VideoBox; + // docval.Play(); + })} else { + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); + DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); + + } + // let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); }); -ScriptingGlobals.add(function addRectoWorkspace() { +ScriptingGlobals.add(function addRectoWorkspace(value: VideoBox) { console.log("adding rec to doc"); + console.log(value.rootDoc); + Doc.UserDoc().isAddRecToDocMode = true; + }) ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { -- cgit v1.2.3-70-g09d2 From aab4148a23a6505f103564fff305ac4c97b64479 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:15:31 -0400 Subject: Basic implementation of micahels branching trail on master --- src/client/util/BranchingTrailManager.tsx | 29 ++++++++++++++++++++-- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/Main.tsx | 2 +- src/client/views/OverlayView.tsx | 1 + .../collectionLinear/CollectionLinearView.tsx | 2 ++ .../views/nodes/RecordingBox/RecordingBox.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 9 ++++++- src/client/views/nodes/trails/PresElementBox.tsx | 2 ++ 8 files changed, 43 insertions(+), 5 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx index 44cec6922..a224b84f4 100644 --- a/src/client/util/BranchingTrailManager.tsx +++ b/src/client/util/BranchingTrailManager.tsx @@ -6,6 +6,8 @@ import { Id } from '../../fields/FieldSymbols'; import { PresBox } from '../views/nodes/trails'; import { OverlayView } from '../views/OverlayView'; import { DocumentManager } from './DocumentManager'; +import { Docs } from '../documents/Documents'; +import { nullAudio } from '../../fields/URLField'; @observer export class BranchingTrailManager extends React.Component { @@ -19,8 +21,20 @@ export class BranchingTrailManager extends React.Component { } setupUi = () => { - OverlayView.Instance.addWindow(, { x: 100, y: 150, width: 1000, title: 'Branching Trail' }); + OverlayView.Instance.addWindow(, { x: 100, y: 150, width: 1000, title: 'Branching Trail'}); + // OverlayView.Instance.forceUpdate(); + console.log(OverlayView.Instance); + // let hi = Docs.Create.TextDocument("beee", { + // x: 100, + // y: 100, + // }) + // hi.overlayX = 100; + // hi.overlayY = 100; + + // Doc.AddToMyOverlay(hi); + console.log(DocumentManager._overlayViews); }; + // stack of the history @observable private slideHistoryStack: String[] = []; @@ -53,7 +67,9 @@ export class BranchingTrailManager extends React.Component { } if (this.prevPresId === null || this.prevPresId !== presId) { + Doc.UserDoc().isBranchingMode = true; this.setPrevPres(presId); + // REVERT THE SET const stringified = [presId, targetDocId].toString(); if (this.containsSet.has([presId, targetDocId].toString())) { @@ -68,6 +84,10 @@ export class BranchingTrailManager extends React.Component { this.containsSet.add(stringified); } } + console.log(this.slideHistoryStack.length); + if (this.slideHistoryStack.length === 0) { + Doc.UserDoc().isBranchingMode = false; + } }; clickHandler = (e: React.PointerEvent, targetDocId: string, removeIndex: number) => { @@ -75,18 +95,23 @@ export class BranchingTrailManager extends React.Component { if (!targetDoc) { return; } + const newStack = this.slideHistoryStack.slice(0, removeIndex); const removed = this.slideHistoryStack.slice(removeIndex); + this.setSlideHistoryStack(newStack); removed.forEach(info => this.containsSet.delete(info.toString())); DocumentManager.Instance.showDocument(targetDoc, { willZoomCentered: true }); + if (this.slideHistoryStack.length === 0) { + Doc.UserDoc().isBranchingMode = false; + } //PresBox.NavigateToTarget(targetDoc, targetDoc); }; @computed get trailBreadcrumbs() { return ( -
+
{this.slideHistoryStack.map((info, index) => { const [presId, targetDocId] = info.split(','); const doc = this.docIdToDocMap.get(targetDocId); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 99a8ee571..0c2b235cb 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -609,6 +609,7 @@ export class CurrentUserUtils { { scripts: { }, opts: { title: "undoStack", layout: "", toolTip: "Undo/Redo Stack"}}, // note: layout fields are hacks -- they don't actually run through the JSX parser (yet) { scripts: { }, opts: { title: "linker", layout: "", toolTip: "link started"}}, { scripts: { }, opts: { title: "currently playing", layout: "", toolTip: "currently playing media"}}, + { scripts: { }, opts: { title: "Branching", layout: "", toolTip: "Branch, baby!"}} ]; const btns = btnDescs.map(desc => dockBtn({_width: 30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts)); const dockBtnsReqdOpts:DocumentOptions = { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 730a926a2..8f0c00cc3 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -51,7 +51,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; document.cookie = `loadtime=${loading};${expires};path=/`; new TrackMovements(); new ReplayMovements(); - new BranchingTrailManager(); + new BranchingTrailManager({}); new PingManager(); root.render(); }, 0); diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 339507f65..e838473d2 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -146,6 +146,7 @@ export class OverlayView extends React.Component { @action addWindow(contents: JSX.Element, options: OverlayElementOptions): OverlayDisposer { + console.log("adding window"); const remove = action(() => { const index = this._elements.indexOf(contents); if (index !== -1) this._elements.splice(index, 1); diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 2254b2e5f..707986ec3 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -22,6 +22,7 @@ import { CollectionSubView } from '../CollectionSubView'; import './CollectionLinearView.scss'; import { Button, Toggle, ToggleType, Type } from 'browndash-components'; import { Colors } from '../../global/globalEnums'; +import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; /** * CollectionLinearView is the class for rendering the horizontal collection @@ -145,6 +146,7 @@ export class CollectionLinearView extends CollectionSubView() { case '': return this.getLinkUI(); case '': return this.getCurrentlyPlayingUI(); case '': return ; + case '': return Doc.UserDoc().isBranchingMode ? : null; } const nested = doc._type_collection === CollectionViewType.Linear; diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index d6e4bd304..fdb00c552 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -155,7 +155,7 @@ ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { Doc.UserDoc().currentRecording = docView.ComponentView as VideoBox; // docval.Play(); })} else { - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(Doc); DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index b02e7ecbd..ee85287ed 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -38,6 +38,7 @@ import './PresBox.scss'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; import { TreeView } from '../../collections/TreeView'; +import { OverlayView } from '../../OverlayView'; const { Howl } = require('howler'); export interface pinDataTypes { @@ -378,6 +379,7 @@ export class PresBox extends ViewBoxBaseComponent() { //it'll also execute the necessary actions if presentation is playing. @undoBatch public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => { + console.log("going to document"); Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; @@ -1101,13 +1103,18 @@ export class PresBox extends ViewBoxBaseComponent() { //Regular click @action selectElement = (doc: Doc, noNav = false) => { + BranchingTrailManager.Instance.observeDocumentChange(doc, this); CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => clip?.ComponentView?.Pause?.()); if (noNav) { const index = this.childDocs.indexOf(doc); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; } - } else this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); + console.log("no nav") + } else { + this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); + console.log('e bitch') + } this.updateCurrentPresentation(DocCast(doc.embedContainer)); }; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 6bc1e95ac..711c9cab9 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -26,6 +26,7 @@ import './PresElementBox.scss'; import { PresMovement } from './PresEnums'; import React = require('react'); import { TreeView } from '../../collections/TreeView'; +import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -431,6 +432,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { const hasChildren: boolean = Cast(this.rootDoc?.hasChildren, 'boolean') || false; const items: JSX.Element[] = []; + items.push( Update captured doc layout
}>
Date: Thu, 24 Aug 2023 00:21:42 -0400 Subject: Current Implementation topbar video --- src/client/util/CurrentUserUtils.ts | 7 +-- src/client/util/DragManager.ts | 3 ++ .../views/nodes/RecordingBox/RecordingBox.tsx | 53 ++++++++++++++++++---- src/client/views/nodes/VideoBox.tsx | 5 +- src/client/views/nodes/trails/PresBox.tsx | 9 ++++ src/client/views/nodes/trails/PresElementBox.tsx | 48 +++++++++++++++++--- 6 files changed, 106 insertions(+), 19 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 0c2b235cb..6cdc2956c 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -715,11 +715,11 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'},}, + { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, - { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, - { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, + { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, + { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPaused()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `addRectoWorkspace(getCurrentRecording())`}}, ]; @@ -748,6 +748,7 @@ export class CurrentUserUtils { Doc.UserDoc().isRecording = false; Doc.UserDoc().isRecPlayback = false; Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isPlaybackPlaying = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index f06d4a0e7..306092ee4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -254,6 +254,9 @@ export namespace DragManager { Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; + Doc.UserDoc().isAddRecToDocMode = false; Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); const docDragData = e.docDragData; dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index fdb00c552..ade8d0d45 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -24,6 +24,8 @@ import { PropertiesSection } from '../../PropertiesSection'; import { PropertiesDocContextSelector } from '../../PropertiesDocContextSelector'; import { listSpec } from '../../../../fields/Schema'; import { DragManager } from '../../../util/DragManager'; +import { SelectionManager } from '../../../util/SelectionManager'; +import { AudioBox } from '../AudioBox'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -143,44 +145,71 @@ ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { }, 'toggle recording'); ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { let docval = undefined; - Doc.UserDoc().isRecPlayback = true; Doc.UserDoc().currentRecording = value; console.log(value) value.overlayX = 100; value.overlayY = 100; if (!Doc.UserDoc().isAddRecToDocMode) { - Doc.AddToMyOverlay(value); + Doc.UserDoc().isRecPlayback = true; + Doc.UserDoc().isWorkspaceRecPlaying = true; + Doc.AddToMyOverlay(value); DocumentManager.Instance.AddViewRenderedCb(value, docView => { - docval = - Doc.UserDoc().currentRecording = docView.ComponentView as VideoBox; + // docval = + Doc.UserDoc().currentRecording = docView.ComponentView as RecordingBox; + SelectionManager.SelectSchemaViewDoc(value); + // docval.Play(); + })} else { - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(Doc); + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); - } // let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); }); -ScriptingGlobals.add(function addRectoWorkspace(value: VideoBox) { +ScriptingGlobals.add(function addRectoWorkspace(value: RecordingBox) { console.log("adding rec to doc"); - console.log(value.rootDoc); - Doc.UserDoc().isAddRecToDocMode = true; + console.log(value); + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.rootDoc); + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); + console.log(recordingIndex); + Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); + Doc.UserDoc().isAddRecToDocMode = false; + Doc.RemFromMyOverlay(value.rootDoc); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isAddRecToDocMode = false; + // Doc.UserDoc().isAddRecToDocMode = true; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; + // let audiodoc: Doc = Docs.Create.AudioDocument(value.dataDoc.data, { + // x: 100, + // y: 100 + // }); + // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(audiodoc); + }) ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { value.Play(); + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = true; }) ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { value.Pause(); + Doc.UserDoc().isWorkspaceRecPlaying = true; + Doc.UserDoc().isWorkspaceRecPaused = false; }) ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { value.Pause(); Doc.RemFromMyOverlay(value.rootDoc); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; }) ScriptingGlobals.add(function getWorkspaceRecordings() { @@ -195,5 +224,11 @@ ScriptingGlobals.add(function getIsRecPlayback() { ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }) +ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { + return Doc.UserDoc().isWorkspaceRecPlaying; +}) +ScriptingGlobals.add(function getIsWorkspaceRecPaused() { + return Doc.UserDoc().isWorkspaceRecPaused; +}) diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 2177adeff..1bd98a3eb 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -192,7 +192,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { pinDoc.config_viewBounds = new List([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]); } } + + @action + static reversePin(pinDoc: Doc, targetDoc: Doc) { + // const fkey = Doc.LayoutFieldKey(targetDoc); + pinDoc.config_data = targetDoc.data; + + console.log(pinDoc.presData); + } + /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 711c9cab9..ee4498e53 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -27,6 +27,7 @@ import { PresMovement } from './PresEnums'; import React = require('react'); import { TreeView } from '../../collections/TreeView'; import { BranchingTrailManager } from '../../../util/BranchingTrailManager'; +import { MultiToggle, Type } from 'browndash-components'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -303,8 +304,28 @@ export class PresElementBox extends ViewBoxBaseComponent() { activeItem.config_rotation = NumCast(targetDoc.rotation); activeItem.config_width = NumCast(targetDoc.width); activeItem.config_height = NumCast(targetDoc.height); - activeItem.config_pinLayout = true; + activeItem.config_pinLayout = !activeItem.config_pinLayout; + // activeItem.config_pinLayout = true; }; + + //wait i dont think i have to do anything here since by default it'll revert to the previously saved if I don't save + //so basically, don't have an onClick for this, just let it do nada for now + @undoBatch + @action + revertToPreviouslySaved = (presTargetDoc: Doc, activeItem: Doc) => { + console.log('reverting'); + // console.log("reverting to previosly saved\n"); + // console.log(this.prevTarget); + console.log("Content continuously updating"); + const target = DocCast(activeItem.annotationOn) ?? activeItem; + console.log(presTargetDoc.pinData) + PresBox.reversePin(activeItem, target); + // console.log("new target\n"); + // console.log(target); + // PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(this.prevTarget) }, this.prevTarget ? this.prevTarget : target); + //figure out how to make it go back to the previously saved one + } + /** * Method called for updating the view of the currently selected document * @@ -443,16 +464,31 @@ export class PresElementBox extends ViewBoxBaseComponent() {
); + // items.push( + // Update captured doc content
}> + //
setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))} + // style={{ opacity: activeItem.config_pinData || activeItem.config_pinView ? 1 : 0.5, fontWeight: 700, display: 'flex' }}> + // C + //
+ // + // ); items.push( Update captured doc content}>
setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))} - style={{ opacity: activeItem.config_pinData || activeItem.config_pinView ? 1 : 0.5, fontWeight: 700, display: 'flex' }}> - C + className="slideButton" + style={{fontWeight: 700, display: 'flex'}} + > + , tooltip: "Save data to presentation", val: 'floppy', + onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))}, + {icon: , tooltip: "Continously update content", val: "revert", + onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.revertToPreviouslySaved(targetDoc, activeItem))}, + ]} />
- ); + ) items.push( {this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}}>
(this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> -- cgit v1.2.3-70-g09d2 From 0686d497275e6deae983fcfd821495d0d126204f Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Thu, 24 Aug 2023 08:06:46 -0400 Subject: overlay ui changes --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/nodes/RecordingBox/RecordingBox.tsx | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 6cdc2956c..919c56fe2 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -715,7 +715,7 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'microphone', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, + { title: "Audio", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index ade8d0d45..1908b74b5 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -103,8 +103,8 @@ ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { const remDoc = RecordingBox.screengrabber.rootDoc; setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 400; //was 100 - RecordingBox.screengrabber!.rootDoc.overlayY = 100; + RecordingBox.screengrabber!.rootDoc.overlayX = 360; //was 100 + RecordingBox.screengrabber!.rootDoc.overlayY = 740; // DocListCast(Doc.MyOverlayDocs.data) // .filter(doc => doc.slides === RecordingBox.screengrabber!.rootDoc) // .forEach(Doc.RemFromMyOverlay); @@ -126,12 +126,12 @@ ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { } else { //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { - _width: 384, - _height: 216, + _width: 192, + _height: 108, }); // Doc.UserDoc().currentScreenGrab = screengrabber; - screengrabber.overlayX = 100; //was -400 - screengrabber.overlayY = 100; //was 0 + screengrabber.overlayX = 360; //was -400 + screengrabber.overlayY = 740; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { @@ -147,8 +147,8 @@ ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { let docval = undefined; Doc.UserDoc().currentRecording = value; console.log(value) - value.overlayX = 100; - value.overlayY = 100; + value.overlayX =70; + value.overlayY = 690; if (!Doc.UserDoc().isAddRecToDocMode) { Doc.UserDoc().isRecPlayback = true; Doc.UserDoc().isWorkspaceRecPlaying = true; -- cgit v1.2.3-70-g09d2 From 6297cd58741f39ce7f6510e0a4cc634d62d4778e Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:34:16 -0400 Subject: before meeting with Andy --- src/client/util/CurrentUserUtils.ts | 3 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 295 +++++++++++---------- .../views/nodes/RecordingBox/RecordingView.tsx | 1 + src/client/views/nodes/trails/PresBox.tsx | 1 + src/client/views/nodes/trails/PresElementBox.tsx | 4 +- 5 files changed, 163 insertions(+), 141 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 919c56fe2..7b11e59eb 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -715,13 +715,14 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Audio", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, + { title: "Video", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPaused()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `addRectoWorkspace(getCurrentRecording())`}}, + { title: "Delete Rec", icon: "trash", toolTip: "delete selected recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `removeWorkspaceRec(getCurrentRecording())`}} ]; } diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 429fc60c2..c73082f78 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { VideoField } from '../../../../fields/URLField'; @@ -26,6 +26,7 @@ import { listSpec } from '../../../../fields/Schema'; import { DragManager } from '../../../util/DragManager'; import { SelectionManager } from '../../../util/SelectionManager'; import { AudioBox } from '../AudioBox'; +import { UndoManager, undoBatch } from '../../../util/UndoManager'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -66,6 +67,146 @@ export class RecordingBox extends ViewBoxBaseComponent() { } }; + /** + * This method toggles whether or not we are currently using the RecordingBox to record with the topbar button + * @param _readOnly_ + * @returns + */ + @undoBatch + @action + public static toggleWorkspaceRecording(_readOnly_: boolean) { + if (_readOnly_) return RecordingBox.screengrabber ? true : false; + if (RecordingBox.screengrabber) { + //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening + console.log('grabbing screen!') + RecordingBox.screengrabber.Pause?.(); + const remDoc = RecordingBox.screengrabber.rootDoc; + setTimeout(() => { + RecordingBox.screengrabber?.Finish?.(); + RecordingBox.screengrabber!.rootDoc.overlayX = 70; //was 100 + RecordingBox.screengrabber!.rootDoc.overlayY = 590; + console.log(RecordingBox.screengrabber) + RecordingBox.screengrabber = undefined; + }, 100); + //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this + setTimeout(() => { + Doc.RemFromMyOverlay(remDoc); + + }, 1000) + Doc.UserDoc().isRecording = false; + Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); + } else { + //when we first press mic + const screengrabber = Docs.Create.WebCamDocument('', { + _width: 205, + _height: 115, + }); + screengrabber.overlayX = 70; //was -400 + screengrabber.overlayY = 590; //was 0 + screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; + Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay + DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { + RecordingBox.screengrabber = docView.ComponentView as RecordingBox; + RecordingBox.screengrabber.Record?.(); + }); + Doc.UserDoc().isRecording = true; + } + } + + /** + * This method changes the menu depending on whether or not we are in playback mode + * @param value RecordingBox rootdoc + */ + @undoBatch + @action + public static toggleWorkspaceRecPlayback(value: Doc) { + let docval = undefined; + Doc.UserDoc().currentRecording = value; + console.log(value) + value.overlayX =70; + value.overlayY = 590; + if (!Doc.UserDoc().isAddRecToDocMode) { + Doc.UserDoc().isRecPlayback = true; + Doc.UserDoc().isWorkspaceRecPlaying = true; + Doc.AddToMyOverlay(value); + DocumentManager.Instance.AddViewRenderedCb(value, docView => { + Doc.UserDoc().currentRecording = docView.ComponentView as RecordingBox; + SelectionManager.SelectSchemaViewDoc(value); + })} else { + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); + DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); + } + } + + /** + * Adds the recording box to the canvas + * @param value current recordingbox + */ + @undoBatch + @action + public static addRecToWorkspace(value: RecordingBox) { + console.log("adding rec to doc"); + console.log(value); + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.rootDoc); + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); + console.log(recordingIndex); + Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); + Doc.UserDoc().isAddRecToDocMode = false; + Doc.RemFromMyOverlay(value.rootDoc); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isAddRecToDocMode = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; + } + + @undoBatch + @action + public static playWorkspaceRec(value: VideoBox) { + value.Play(); + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = true; + } + + @undoBatch + @action + public static pauseWorkspaceRec(value: VideoBox) { + value.Pause(); + Doc.UserDoc().isWorkspaceRecPlaying = true; + Doc.UserDoc().isWorkspaceRecPaused = false; + } + + @undoBatch + @action + public static closeWorkspaceRec(value: VideoBox) { + value.Pause(); + Doc.RemFromMyOverlay(value.rootDoc); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; + Doc.RemFromMyOverlay(value.rootDoc); + + } + + @undoBatch + @action + public static removeWorkspaceRec(value: VideoBox) { + let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); + Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); + Doc.UserDoc().isAddRecToDocMode = false; + Doc.RemFromMyOverlay(value.rootDoc); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().isAddRecToDocMode = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; + + } + + + Record: undefined | (() => void); Pause: undefined | (() => void); Finish: undefined | (() => void); @@ -92,143 +233,21 @@ export class RecordingBox extends ViewBoxBaseComponent() { } static screengrabber: RecordingBox | undefined; } -ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { - console.log(_readOnly_) - console.log(RecordingBox.screengrabber) - if (_readOnly_) return RecordingBox.screengrabber ? true : false; - if (RecordingBox.screengrabber) { - //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening - console.log('grabbing screen!') - RecordingBox.screengrabber.Pause?.(); - const remDoc = RecordingBox.screengrabber.rootDoc; - setTimeout(() => { - RecordingBox.screengrabber?.Finish?.(); - RecordingBox.screengrabber!.rootDoc.overlayX = 70; //was 100 - RecordingBox.screengrabber!.rootDoc.overlayY = 610; - // DocListCast(Doc.MyOverlayDocs.data) - // .filter(doc => doc.slides === RecordingBox.screengrabber!.rootDoc) - // .forEach(Doc.RemFromMyOverlay); - console.log(RecordingBox.screengrabber) - RecordingBox.screengrabber = undefined; - }, 100); - //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this - setTimeout(() => { - Doc.RemFromMyOverlay(remDoc); - - }, 1000) - Doc.UserDoc().isRecording = false; - - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.dataDoc); - Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); - - // let recView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - // console.log(recView) - } else { - //when we first press mic - const screengrabber = Docs.Create.WebCamDocument('', { - _width: 205, - _height: 115, - }); - // Doc.UserDoc().currentScreenGrab = screengrabber; - screengrabber.overlayX = 70; //was -400 - screengrabber.overlayY = 610; //was 0 - screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay - DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { - RecordingBox.screengrabber = docView.ComponentView as RecordingBox; - RecordingBox.screengrabber.Record?.(); - }); - // Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", screengrabber); - Doc.UserDoc().isRecording = true; - - } -}, 'toggle recording'); -ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { - let docval = undefined; - Doc.UserDoc().currentRecording = value; - console.log(value) - value.overlayX =70; - value.overlayY = 610; - if (!Doc.UserDoc().isAddRecToDocMode) { - Doc.UserDoc().isRecPlayback = true; - Doc.UserDoc().isWorkspaceRecPlaying = true; - Doc.AddToMyOverlay(value); - DocumentManager.Instance.AddViewRenderedCb(value, docView => { - // docval = - Doc.UserDoc().currentRecording = docView.ComponentView as RecordingBox; - SelectionManager.SelectSchemaViewDoc(value); - - // docval.Play(); - - })} else { - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); - DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); - } - - // let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value); -}); -ScriptingGlobals.add(function addRectoWorkspace(value: RecordingBox) { - console.log("adding rec to doc"); - console.log(value); - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); - (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.rootDoc); - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); - console.log(recordingIndex); - Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); - Doc.UserDoc().isAddRecToDocMode = false; - Doc.RemFromMyOverlay(value.rootDoc); - Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().isRecPlayback = false; - Doc.UserDoc().isAddRecToDocMode = false; - // Doc.UserDoc().isAddRecToDocMode = true; - Doc.UserDoc().isWorkspaceRecPlaying = false; - Doc.UserDoc().isWorkspaceRecPaused = false; - // let audiodoc: Doc = Docs.Create.AudioDocument(value.dataDoc.data, { - // x: 100, - // y: 100 - // }); - - // (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(audiodoc); - -}) -ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { - value.Play(); - Doc.UserDoc().isWorkspaceRecPlaying = false; - Doc.UserDoc().isWorkspaceRecPaused = true; -}) -ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { - value.Pause(); - Doc.UserDoc().isWorkspaceRecPlaying = true; - Doc.UserDoc().isWorkspaceRecPaused = false; -}) -ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { - value.Pause(); - Doc.RemFromMyOverlay(value.rootDoc); - Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().isRecPlayback = false; - Doc.UserDoc().isWorkspaceRecPlaying = false; - Doc.UserDoc().isWorkspaceRecPaused = false; -}) - -ScriptingGlobals.add(function getWorkspaceRecordings() { - return Doc.UserDoc().workspaceRecordings -}); -ScriptingGlobals.add(function getIsRecording() { - return Doc.UserDoc().isRecording; -}) -ScriptingGlobals.add(function getIsRecPlayback() { - return Doc.UserDoc().isRecPlayback; -}) -ScriptingGlobals.add(function getCurrentRecording() { - return Doc.UserDoc().currentRecording; -}) -ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { - return Doc.UserDoc().isWorkspaceRecPlaying; -}) -ScriptingGlobals.add(function getIsWorkspaceRecPaused() { - return Doc.UserDoc().isWorkspaceRecPaused; -}) +ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { RecordingBox.toggleWorkspaceRecording(_readOnly_); }); +ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { RecordingBox.toggleWorkspaceRecPlayback(value); }); +ScriptingGlobals.add(function addRectoWorkspace(value: RecordingBox) { RecordingBox.addRecToWorkspace(value); }); + +ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { RecordingBox.playWorkspaceRec(value); }); +ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { RecordingBox.pauseWorkspaceRec(value); }); +ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { RecordingBox.closeWorkspaceRec(value); }); +ScriptingGlobals.add(function removeWorkspaceRec(value: VideoBox) { RecordingBox.removeWorkspaceRec(value) }); + +ScriptingGlobals.add(function getWorkspaceRecordings() { return Doc.UserDoc().workspaceRecordings }); +ScriptingGlobals.add(function getIsRecording() { return Doc.UserDoc().isRecording; }) +ScriptingGlobals.add(function getIsRecPlayback() { return Doc.UserDoc().isRecPlayback; }) +ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }) +ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { return Doc.UserDoc().isWorkspaceRecPlaying; }) +ScriptingGlobals.add(function getIsWorkspaceRecPaused() { return Doc.UserDoc().isWorkspaceRecPaused; }) diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 8c0f5efef..755f1adc0 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -9,6 +9,7 @@ import { Networking } from '../../../Network'; import { Presentation, TrackMovements } from '../../../util/TrackMovements'; import { ProgressBar } from './ProgressBar'; import './RecordingView.scss'; +import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; export interface MediaSegment { videoChunks: any[]; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index b9585b132..dd91660ec 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -298,6 +298,7 @@ export class PresBox extends ViewBoxBaseComponent() { // Called when the user activates 'next' - to move to the next part of the pres. trail @action next = () => { + console.log("next"); const progressiveReveal = (first: boolean) => { const presIndexed = Cast(this.activeItem?.presentation_indexed, 'number', null); if (presIndexed !== undefined) { diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index ee4498e53..d90f96249 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -481,9 +481,9 @@ export class PresElementBox extends ViewBoxBaseComponent() { style={{fontWeight: 700, display: 'flex'}} > , tooltip: "Save data to presentation", val: 'floppy', + {icon: , tooltip: "Save data to presentation", val: 'revert', onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))}, - {icon: , tooltip: "Continously update content", val: "revert", + {icon: , tooltip: "Continously update content", val: "floppy-disk", onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.revertToPreviouslySaved(targetDoc, activeItem))}, ]} />
-- cgit v1.2.3-70-g09d2 From 06363e4bfa55d10075f72d39221c6ba7b92f9f6c Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Mon, 28 Aug 2023 13:07:16 -0400 Subject: Fixed reload bug --- package-lock.json | 497 ++++++++++++++---------------- src/client/util/CurrentUserUtils.ts | 8 +- src/client/views/nodes/trails/PresBox.tsx | 11 +- 3 files changed, 248 insertions(+), 268 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index 31a29409b..af5bddbf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,24 +142,24 @@ "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==" }, "@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", + "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.10", "@babel/generator": "^7.22.10", "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", + "@babel/helpers": "^7.22.11", + "@babel/parser": "^7.22.11", "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "dependencies": { @@ -194,14 +194,14 @@ } }, "@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==" + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", + "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==" }, "@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", + "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", "requires": { "@babel/code-frame": "^7.22.10", "@babel/generator": "^7.22.10", @@ -209,16 +209,16 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.22.11", + "@babel/types": "^7.22.11", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -278,9 +278,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -322,9 +322,9 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz", - "integrity": "sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", + "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", @@ -557,9 +557,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -569,13 +569,13 @@ } }, "@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", + "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", "requires": { "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11" }, "dependencies": { "@babel/code-frame": { @@ -609,14 +609,14 @@ } }, "@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==" + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", + "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==" }, "@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", + "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", "requires": { "@babel/code-frame": "^7.22.10", "@babel/generator": "^7.22.10", @@ -624,16 +624,16 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.22.11", + "@babel/types": "^7.22.11", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -941,9 +941,9 @@ } }, "@babel/plugin-transform-async-generator-functions": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz", - "integrity": "sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.11.tgz", + "integrity": "sha512-0pAlmeRJn6wU84zzZsEOx1JV1Jf8fqO9ok7wofIJwUnplYo247dcd24P+cMJht7ts9xkzdtB0EPHmOb7F+KzXw==", "requires": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -1022,11 +1022,11 @@ } }, "@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -1132,9 +1132,9 @@ } }, "@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1164,9 +1164,9 @@ } }, "@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1212,9 +1212,9 @@ } }, "@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1243,9 +1243,9 @@ } }, "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1290,11 +1290,11 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz", + "integrity": "sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g==", "requires": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -1307,12 +1307,12 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz", + "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==", "requires": { "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5" }, @@ -1372,9 +1372,9 @@ } }, "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1388,9 +1388,9 @@ } }, "@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1404,12 +1404,12 @@ } }, "@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz", + "integrity": "sha512-nX8cPFa6+UmbepISvlf5jhQyaC7ASs/7UxHmMkuJ/k5xSHvDPPaibMo+v3TXwU/Pjqhep/nFNpd3zn4YR59pnw==", "requires": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.22.5" @@ -1439,9 +1439,9 @@ } }, "@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1455,9 +1455,9 @@ } }, "@babel/plugin-transform-optional-chaining": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz", - "integrity": "sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.11.tgz", + "integrity": "sha512-7X2vGqH2ZKu7Imx0C+o5OysRwtF/wzdCAqmcD1N1v2Ww8CtOSC+p+VoV76skm47DLvBZ8kBFic+egqxM9S/p4g==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1503,12 +1503,12 @@ } }, "@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -1733,12 +1733,12 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.10.tgz", - "integrity": "sha512-7++c8I/ymsDo4QQBAgbraXLzIM6jmfao11KgIBEYZRReWzNWH9NtNgJcyrZiXsOPh523FQm6LfpLyy/U5fn46A==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz", + "integrity": "sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==", "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.10", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.22.5" }, @@ -1914,9 +1914,9 @@ "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" }, "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -1961,15 +1961,15 @@ } }, "@babel/preset-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", - "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.11.tgz", + "integrity": "sha512-tWY5wyCZYBGY7IlalfKI1rLiGlIfnwsRHZqlky0HVv8qviwQ1Uo/05M6+s+TcTCVa6Bmoo2uJW5TMFX6Wa4qVg==", "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-typescript": "^7.22.5" + "@babel/plugin-transform-modules-commonjs": "^7.22.11", + "@babel/plugin-transform-typescript": "^7.22.11" }, "dependencies": { "@babel/helper-plugin-utils": { @@ -2693,6 +2693,36 @@ "resolve-url": "^0.2.1" } }, + "@floating-ui/core": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", + "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "requires": { + "@floating-ui/utils": "^0.1.1" + } + }, + "@floating-ui/dom": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz", + "integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==", + "requires": { + "@floating-ui/core": "^1.4.1", + "@floating-ui/utils": "^0.1.1" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.1.tgz", + "integrity": "sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==", + "requires": { + "@floating-ui/dom": "^1.3.0" + } + }, + "@floating-ui/utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", + "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" + }, "@fortawesome/fontawesome-common-types": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz", @@ -3202,18 +3232,18 @@ } }, "@mui/styled-engine-sc": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz", - "integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.14.6.tgz", + "integrity": "sha512-7/KXXdDLjpQAmbmIhUs1x7nzqooEiHkidQOXCIH04NiVa4KRxP4v/bOWV/5GpgZi1Aky5ruf9IVyH3jxYIW3JA==", "requires": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.22.10", "prop-types": "^15.8.1" }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6507,9 +6537,9 @@ } }, "browndash-components": { - "version": "0.0.92", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.92.tgz", - "integrity": "sha512-eE/6WQNZiLnaXUKyoaMm0PDYjExUsFJ9VTAIIxROpYPosIBKWNZ743xaOfmehib5us9hEXJb0CvUFJQb8rzDVw==", + "version": "0.0.97", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.97.tgz", + "integrity": "sha512-UO8NQrOJoAq+UQGR8TXCRzr6jX9qSnEot9FHP7zdwlKH1sGntbQpyM5BXdwfkyXo+oh1qstTGkyR4s20CY7Yrw==", "requires": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", @@ -6627,14 +6657,15 @@ "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@mui/base": { - "version": "5.0.0-beta.11", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.11.tgz", - "integrity": "sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA==", + "version": "5.0.0-beta.12", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.12.tgz", + "integrity": "sha512-tZjjXNAyUpwSDT1uRliZMhRQkWYzELJ8Qi61EuOMRpi36HIwnK2T7Nr4RI423Sv8G2EEikDAZj7je33eNd73NQ==", "requires": { - "@babel/runtime": "^7.22.6", + "@babel/runtime": "^7.22.10", "@emotion/is-prop-valid": "^1.2.1", + "@floating-ui/react-dom": "^2.0.1", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.5", + "@mui/utils": "^5.14.6", "@popperjs/core": "^2.11.8", "clsx": "^2.0.0", "prop-types": "^15.8.1", @@ -6642,9 +6673,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6652,21 +6683,21 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.5.tgz", - "integrity": "sha512-+wpGH1USwPcKMFPMvXqYPC6fEvhxM3FzxC8lyDiNK/imLyyJ6y2DPb1Oue7OGIKJWBmYBqrWWtfovrxd1aJHTA==" + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.6.tgz", + "integrity": "sha512-QZEU3pyGWLuaHbxvOlShol7U1FVgzWBR0OH9H8D7L8w4/vto5N5jJVvlqFQS3T0zbR6YGHxFaiL6Ky87jQg7aw==" }, "@mui/material": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz", - "integrity": "sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA==", - "requires": { - "@babel/runtime": "^7.22.6", - "@mui/base": "5.0.0-beta.11", - "@mui/core-downloads-tracker": "^5.14.5", - "@mui/system": "^5.14.5", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.6.tgz", + "integrity": "sha512-C3UgGrmtvcGkQkm0ONBU7bTdapTjQc2Se3b2354xMmU7lgSgW7VM6EP9wIH5XqqoJ60m9l/s9kbTWX0Y+EaWvA==", + "requires": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.12", + "@mui/core-downloads-tracker": "^5.14.6", + "@mui/system": "^5.14.6", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.5", + "@mui/utils": "^5.14.6", "@types/react-transition-group": "^4.4.6", "clsx": "^2.0.0", "csstype": "^3.1.2", @@ -6676,9 +6707,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6686,19 +6717,19 @@ } }, "@mui/private-theming": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.5.tgz", - "integrity": "sha512-cC4C5RrpXpDaaZyH9QwmPhRLgz+f2SYbOty3cPkk4qPSOSfif2ZEcDD9HTENKDDd9deB+xkPKzzZhi8cxIx8Ig==", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.6.tgz", + "integrity": "sha512-3VBLFGizBXfofyk33bwRg6t9L648aKnLmOKPfY1wFuiXq3AEYwobK65iDci/tHKxm/VKbZ6A7PFjLejvB3EvRQ==", "requires": { - "@babel/runtime": "^7.22.6", - "@mui/utils": "^5.14.5", + "@babel/runtime": "^7.22.10", + "@mui/utils": "^5.14.6", "prop-types": "^15.8.1" }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6706,20 +6737,20 @@ } }, "@mui/styled-engine": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", - "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.6.tgz", + "integrity": "sha512-I6zeu/OP1Hk4NsX1Oj85TiYl1dER0JMsLJVn76J1Ihl24A5EbiZQKJp3Mn+ufA79ypkdAvM9aQCAQyiVBFcUHg==", "requires": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.22.10", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6727,24 +6758,24 @@ } }, "@mui/system": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.5.tgz", - "integrity": "sha512-mextXZHDeGcR7E1kx43TRARrVXy+gI4wzpUgNv7MqZs1dvTVXQGVeAT6ydj9d6FUqHBPMNLGV/21vJOrpqsL+w==", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.6.tgz", + "integrity": "sha512-/n0ae1MegWjiV1BpRU8jgg4E0zBjeB2VYsT/68ag/xaDuq3/TaDKJeT9REIvyBvwlG3CI3S2O+tRELktxCD1kg==", "requires": { - "@babel/runtime": "^7.22.6", - "@mui/private-theming": "^5.14.5", - "@mui/styled-engine": "^5.13.2", + "@babel/runtime": "^7.22.10", + "@mui/private-theming": "^5.14.6", + "@mui/styled-engine": "^5.14.6", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.5", + "@mui/utils": "^5.14.6", "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6752,11 +6783,11 @@ } }, "@mui/utils": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.5.tgz", - "integrity": "sha512-6Hzw63VR9C5xYv+CbjndoRLU6Gntal8rJ5W+GUzkyHrGWIyYPWZPa6AevnyGioySNETATe1H9oXS8f/7qgIHJA==", + "version": "5.14.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.6.tgz", + "integrity": "sha512-AznpqLu6hrFnpHgcvsSSMCG+cDbkcCYfo+daUwBVReNYv4l+NQ8+wvBAF4aUMi155N7xWbbgh0cyKs6Wdsm3aA==", "requires": { - "@babel/runtime": "^7.22.6", + "@babel/runtime": "^7.22.10", "@types/prop-types": "^15.7.5", "@types/react-is": "^18.2.1", "prop-types": "^15.8.1", @@ -6764,9 +6795,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", - "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -6911,9 +6942,9 @@ } }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, "glob-parent": { @@ -7063,97 +7094,12 @@ "strip-ansi": "^7.0.1" } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, "strip-ansi": { "version": "7.1.0", "bundled": true, "requires": { "ansi-regex": "^6.0.1" } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } } } }, @@ -8658,7 +8604,7 @@ } }, "string-width-cjs": { - "version": "npm:string-width-cjs@4.2.3", + "version": "npm:string-width@4.2.3", "bundled": true, "requires": { "emoji-regex": "^8.0.0", @@ -8681,7 +8627,7 @@ } }, "strip-ansi-cjs": { - "version": "npm:strip-ansi-cjs@6.0.1", + "version": "npm:strip-ansi@6.0.1", "bundled": true, "requires": { "ansi-regex": "^5.0.1" @@ -8840,7 +8786,7 @@ } }, "wrap-ansi-cjs": { - "version": "npm:wrap-ansi-cjs@7.0.0", + "version": "npm:wrap-ansi@7.0.0", "bundled": true, "requires": { "ansi-styles": "^4.0.0", @@ -10031,11 +9977,34 @@ "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==" }, "core-js-compat": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.0.tgz", - "integrity": "sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw==", + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz", + "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==", "requires": { - "browserslist": "^4.21.9" + "browserslist": "^4.21.10" + }, + "dependencies": { + "browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "requires": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + } + }, + "caniuse-lite": { + "version": "1.0.30001522", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", + "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==" + }, + "electron-to-chromium": { + "version": "1.4.501", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.501.tgz", + "integrity": "sha512-NCF5hZUg73MEP0guvIM+BjPs9W07UeAuc5XCNqRZZTKJxLjE0ZS/Zo5UsV8bbs2y/jeKRPFPzdWdBfOGEZTXKg==" + } } }, "core-js-pure": { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 7c048334e..4dca38b21 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -31,6 +31,7 @@ import { ScriptingGlobals } from "./ScriptingGlobals"; import { ColorScheme, SettingsManager } from "./SettingsManager"; import { UndoManager } from "./UndoManager"; import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; +import { DocumentManager } from "./DocumentManager"; interface Button { // DocumentOptions fields a button can set @@ -747,11 +748,16 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; - Doc.UserDoc().workspaceRecordings = new List; + // Doc.UserDoc().workspaceRecordings = new List; + if (Doc.UserDoc().currentRecording) { + Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); + } Doc.UserDoc().isRecording = false; Doc.UserDoc().isRecPlayback = false; Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().isPlaybackPlaying = false; + Doc.UserDoc().isWorkspaceRecPlaying = false; + Doc.UserDoc().isWorkspaceRecPaused = false; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index dd91660ec..00c12d3d8 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -286,6 +286,10 @@ export class PresBox extends ViewBoxBaseComponent() { // go to documents chain runSubroutines = (childrenToRun: Doc[], normallyNextSlide: Doc) => { console.log(childrenToRun, normallyNextSlide, 'runSUBFUNC'); + if (childrenToRun === undefined) { + console.log('children undefined'); + return; + } if (childrenToRun[0] === normallyNextSlide) { return; } @@ -339,7 +343,8 @@ export class PresBox extends ViewBoxBaseComponent() { // before moving onto next slide, run the subroutines :) const currentDoc = this.childDocs[this.itemIndex]; - this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.(), this.childDocs[this.itemIndex + 1]); + //could i do this.childDocs[this.itemIndex] for first arg? + this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.() , this.childDocs[this.itemIndex + 1]); this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1); progressiveReveal(true); // shows first progressive document, but without a transition effect @@ -723,7 +728,7 @@ export class PresBox extends ViewBoxBaseComponent() { navigateToActiveItem = (afterNav?: () => void) => { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - BranchingTrailManager.Instance.observeDocumentChange(targetDoc, this); + // BranchingTrailManager.Instance.observeDocumentChange(targetDoc, this); const finished = () => { afterNav?.(); console.log('Finish Slide Nav: ' + targetDoc.title); @@ -1113,7 +1118,7 @@ export class PresBox extends ViewBoxBaseComponent() { //Regular click @action selectElement = (doc: Doc, noNav = false) => { - BranchingTrailManager.Instance.observeDocumentChange(doc, this); + // BranchingTrailManager.Instance.observeDocumentChange(doc, this); CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => clip?.ComponentView?.Pause?.()); if (noNav) { const index = this.childDocs.indexOf(doc); -- cgit v1.2.3-70-g09d2 From de343764f5f60bb8e9400139e1a56a8483da90b7 Mon Sep 17 00:00:00 2001 From: monoguitari <113245090+monoguitari@users.noreply.github.com> Date: Mon, 28 Aug 2023 15:38:16 -0400 Subject: Dropdown renders only if workspaceRecordings isn't empty --- package-lock.json | 130 ++++++++++++++------- src/client/util/CurrentUserUtils.ts | 5 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 6 + 3 files changed, 97 insertions(+), 44 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index 0199d3d31..c3190ddb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7094,12 +7094,97 @@ "strip-ansi": "^7.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "strip-ansi": { "version": "7.1.0", "bundled": true, "requires": { "ansi-regex": "^6.0.1" } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } } } }, @@ -8604,7 +8689,7 @@ } }, "string-width-cjs": { - "version": "npm:string-width@4.2.3", + "version": "npm:string-width-cjs@4.2.3", "bundled": true, "requires": { "emoji-regex": "^8.0.0", @@ -8627,7 +8712,7 @@ } }, "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", + "version": "npm:strip-ansi-cjs@6.0.1", "bundled": true, "requires": { "ansi-regex": "^5.0.1" @@ -8786,7 +8871,7 @@ } }, "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", + "version": "npm:wrap-ansi-cjs@7.0.0", "bundled": true, "requires": { "ansi-styles": "^4.0.0", @@ -10360,16 +10445,6 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, "d3": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", @@ -11750,28 +11825,6 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", @@ -11783,7 +11836,6 @@ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "requires": { - "d": "^1.0.1", "ext": "^1.1.2" } }, @@ -27596,12 +27648,6 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 1f130ab1e..873361587 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -20,7 +20,6 @@ import { DashboardView } from "../views/DashboardView"; import { Colors } from "../views/global/globalEnums"; import { OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; -import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; import { OverlayView } from "../views/OverlayView"; import { DragManager, dropActionType } from "./DragManager"; import { MakeTemplate } from "./DropConverter"; @@ -718,7 +717,7 @@ export class CurrentUserUtils { { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected { title: "Video", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, - { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, + { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {hidden: `renderDropdown()`, btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPaused()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, @@ -743,11 +742,13 @@ export class CurrentUserUtils { return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs); } + static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; // Doc.UserDoc().workspaceRecordings = new List; if (Doc.UserDoc().currentRecording) { + //@ts-ignore Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); } Doc.UserDoc().isRecording = false; diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index c73082f78..8a91b8102 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -249,5 +249,11 @@ ScriptingGlobals.add(function getIsRecPlayback() { return Doc.UserDoc().isRecPla ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }) ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { return Doc.UserDoc().isWorkspaceRecPlaying; }) ScriptingGlobals.add(function getIsWorkspaceRecPaused() { return Doc.UserDoc().isWorkspaceRecPaused; }) +ScriptingGlobals.add(function renderDropdown() { + if (!Doc.UserDoc().workspaceRecordings || Array.from(Doc.UserDoc().workspaceRecordings).length === 0) { + return true; + } + return false; +}) -- cgit v1.2.3-70-g09d2 From 349e586b01b18c641a4c753b709f4217a3f3e528 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Aug 2023 12:55:49 -0400 Subject: cleanup --- src/client/util/CurrentUserUtils.ts | 6 ++-- src/client/views/OverlayView.tsx | 2 -- src/client/views/UndoStack.tsx | 2 +- src/client/views/collections/TreeView.scss | 4 +-- .../collectionLinear/CollectionLinearView.tsx | 2 +- .../views/nodes/RecordingBox/RecordingView.tsx | 3 -- src/client/views/nodes/VideoBox.tsx | 4 --- src/client/views/nodes/trails/PresBox.tsx | 12 +++---- src/client/views/nodes/trails/PresElementBox.tsx | 37 +++++++--------------- 9 files changed, 21 insertions(+), 51 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 873361587..b705bde7f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -20,6 +20,7 @@ import { DashboardView } from "../views/DashboardView"; import { Colors } from "../views/global/globalEnums"; import { OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; +import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; import { OverlayView } from "../views/OverlayView"; import { DragManager, dropActionType } from "./DragManager"; import { MakeTemplate } from "./DropConverter"; @@ -28,7 +29,6 @@ import { LinkManager } from "./LinkManager"; import { ScriptingGlobals } from "./ScriptingGlobals"; import { ColorScheme, SettingsManager } from "./SettingsManager"; import { UndoManager } from "./UndoManager"; -import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; interface Button { // DocumentOptions fields a button can set @@ -746,10 +746,8 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; - // Doc.UserDoc().workspaceRecordings = new List; if (Doc.UserDoc().currentRecording) { - //@ts-ignore - Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); + Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); } Doc.UserDoc().isRecording = false; Doc.UserDoc().isRecPlayback = false; diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 7d65914b3..5d95c5fda 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -1,4 +1,3 @@ - import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; @@ -145,7 +144,6 @@ export class OverlayView extends React.Component { @action addWindow(contents: JSX.Element, options: OverlayElementOptions): OverlayDisposer { - console.log("adding window"); const remove = action(() => { const index = this._elements.indexOf(contents); if (index !== -1) this._elements.splice(index, 1); diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index cdc389efe..47853b5e4 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -46,7 +46,7 @@ export class UndoStack extends React.Component { .reverse() .map((name, i) => (
-
+
{StrCast(name).replace(/[^\.]*\./, '')}
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index d3ba23b4e..0cc11bf1c 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -23,7 +23,7 @@ .treeView-bulletIcons { width: 100%; height: 100%; - // position: absolute; + // changes start here. .treeView-expandIcon { display: none; @@ -42,6 +42,7 @@ display: unset; } } + // end changes position: relative; display: flex; flex-direction: row; @@ -140,7 +141,6 @@ filter: opacity(0.2) !important; } } - //align-items: center; ::-webkit-scrollbar { diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 0854bc611..3481d5130 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -210,7 +210,7 @@ export class CollectionLinearView extends CollectionSubView() { text={Cast(this.props.Document.icon, 'string', null)} icon={Cast(this.props.Document.icon, 'string', null) ? undefined : } color={SettingsManager.userColor} - // background={SettingsManager.userVariantColor} + background={SettingsManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} toggleType={ToggleType.BUTTON} diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index 755f1adc0..f7ed82643 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -9,7 +9,6 @@ import { Networking } from '../../../Network'; import { Presentation, TrackMovements } from '../../../util/TrackMovements'; import { ProgressBar } from './ProgressBar'; import './RecordingView.scss'; -import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; export interface MediaSegment { videoChunks: any[]; @@ -164,9 +163,7 @@ export function RecordingView(props: IRecordingViewProps) { // if this is called, then we're done recording all the segments const finish = () => { // call stop on the video recorder if active - console.log(videoRecorder.current?.state); videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop(); - console.log("this it") // end the streams (audio/video) to remove recording icon const stream = videoElementRef.current!.srcObject; stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop()); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 5c2d09b0c..56508abf6 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -191,10 +191,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { // Called when the user activates 'next' - to move to the next part of the pres. trail @action next = () => { - console.log("next"); + console.log('next'); const progressiveReveal = (first: boolean) => { const presIndexed = Cast(this.activeItem?.presentation_indexed, 'number', null); if (presIndexed !== undefined) { @@ -345,7 +345,7 @@ export class PresBox extends ViewBoxBaseComponent() { // before moving onto next slide, run the subroutines :) const currentDoc = this.childDocs[this.itemIndex]; //could i do this.childDocs[this.itemIndex] for first arg? - this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.() , this.childDocs[this.itemIndex + 1]); + this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.(), this.childDocs[this.itemIndex + 1]); this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1); progressiveReveal(true); // shows first progressive document, but without a transition effect @@ -386,7 +386,7 @@ export class PresBox extends ViewBoxBaseComponent() { //it'll also execute the necessary actions if presentation is playing. @undoBatch public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => { - console.log("going to document"); + console.log('going to document'); Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; @@ -747,7 +747,7 @@ export class PresBox extends ViewBoxBaseComponent() { console.log(pinDoc.presData); } - + /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. @@ -759,7 +759,6 @@ export class PresBox extends ViewBoxBaseComponent() { navigateToActiveItem = (afterNav?: () => void) => { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - // BranchingTrailManager.Instance.observeDocumentChange(targetDoc, this); const finished = () => { afterNav?.(); console.log('Finish Slide Nav: ' + targetDoc.title); @@ -1149,17 +1148,14 @@ export class PresBox extends ViewBoxBaseComponent() { //Regular click @action selectElement = (doc: Doc, noNav = false) => { - // BranchingTrailManager.Instance.observeDocumentChange(doc, this); CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => clip?.ComponentView?.Pause?.()); if (noNav) { const index = this.childDocs.indexOf(doc); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; } - console.log("no nav") } else { this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); - console.log('e bitch') } this.updateCurrentPresentation(DocCast(doc.embedContainer)); }; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index d90f96249..121eb87d5 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -316,15 +316,15 @@ export class PresElementBox extends ViewBoxBaseComponent() { console.log('reverting'); // console.log("reverting to previosly saved\n"); // console.log(this.prevTarget); - console.log("Content continuously updating"); + console.log('Content continuously updating'); const target = DocCast(activeItem.annotationOn) ?? activeItem; - console.log(presTargetDoc.pinData) + console.log(presTargetDoc.pinData); PresBox.reversePin(activeItem, target); // console.log("new target\n"); - // console.log(target); + // console.log(target); // PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(this.prevTarget) }, this.prevTarget ? this.prevTarget : target); //figure out how to make it go back to the previously saved one - } + }; /** * Method called for updating the view of the currently selected document @@ -388,7 +388,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { + startRecording = (e: React.MouseEvent, activeItem: Doc) => { e.stopPropagation(); if (PresElementBox.videoIsRecorded(activeItem)) { // if we already have an existing recording @@ -453,7 +453,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { const hasChildren: boolean = Cast(this.rootDoc?.hasChildren, 'boolean') || false; const items: JSX.Element[] = []; - + items.push( Update captured doc layout
}>
() {
); - // items.push( - // Update captured doc content}> - //
setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))} - // style={{ opacity: activeItem.config_pinData || activeItem.config_pinView ? 1 : 0.5, fontWeight: 700, display: 'flex' }}> - // C - //
- //
- // ); items.push( Update captured doc content}>
- , tooltip: "Save data to presentation", val: 'revert', - onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))}, - {icon: , tooltip: "Continously update content", val: "floppy-disk", - onPointerDown: e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.revertToPreviouslySaved(targetDoc, activeItem))}, - ]} /> + className="slideButton" + onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.updateCapturedViewContents(targetDoc, activeItem))} + style={{ opacity: activeItem.config_pinData || activeItem.config_pinView ? 1 : 0.5, fontWeight: 700, display: 'flex' }}> + C
- ) + ); items.push( {this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}}>
(this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> -- cgit v1.2.3-70-g09d2 From 0c4f57875c8aaf599ff111a8b8122895d2addab3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Aug 2023 16:33:37 -0400 Subject: more cleanup --- src/client/util/CurrentUserUtils.ts | 4 +- src/client/util/DragManager.ts | 7 +- src/client/views/DocComponent.tsx | 2 +- src/client/views/MainView.tsx | 2 +- src/client/views/ScriptingRepl.tsx | 23 +++- src/client/views/nodes/DocumentIcon.tsx | 2 + src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 139 ++++++++++++--------- 8 files changed, 105 insertions(+), 76 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b705bde7f..51ef51508 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -715,14 +715,14 @@ export class CurrentUserUtils { { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Video", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, + { title: "Video", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {hidden: `renderDropdown()`, btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPaused()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `addRectoWorkspace(getCurrentRecording())`}}, - { title: "Delete Rec", icon: "trash", toolTip: "delete selected recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `removeWorkspaceRec(getCurrentRecording())`}} + { title: "Delete Rec", icon: "trash", toolTip: "delete selected recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `removeWorkspaceRec(getCurrentRecording())`}} ]; } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 5a11f2dca..065f17139 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -4,7 +4,7 @@ import { Doc, Field, Opt, StrListCast } from '../../fields/Doc'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; import { ScriptField } from '../../fields/ScriptField'; -import { BoolCast, Cast, ScriptCast, StrCast } from '../../fields/Types'; +import { BoolCast, Cast, DocCast, ScriptCast, StrCast } from '../../fields/Types'; import { emptyFunction, Utils } from '../../Utils'; import { Docs, DocUtils } from '../documents/Documents'; import * as globalCssVariables from '../views/global/globalCssVariables.scss'; @@ -236,8 +236,7 @@ export namespace DragManager { return true; } - export function StartDropdownDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, recordingIndex: number, options?: DragOptions, dropEvent?: () => any,) { - + export function StartDropdownDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, recordingIndex: number, options?: DragOptions, dropEvent?: () => any) { const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField()); dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); @@ -245,7 +244,7 @@ export namespace DragManager { }; const finishDrag = async (e: DragCompleteEvent) => { Doc.UserDoc().isAddRecToDocMode = false; - Doc.RemFromMyOverlay(Doc.UserDoc().currentRecording); + Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().isRecPlayback = false; Doc.UserDoc().isWorkspaceRecPlaying = false; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index e076e69ca..6a1efdf9c 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -201,7 +201,7 @@ export function ViewBoxAnnotatableComponent

() const annoDocs = targetDataDoc[annotationKey ?? this.annotationKey] as List; if (annoDocs instanceof List) annoDocs.push(...added.filter(add => !annoDocs.includes(add))); else targetDataDoc[annotationKey ?? this.annotationKey] = new List(added); - targetDataDoc[(annotationKey ?? this.annotationKey) + '_modificationDate'] = new DateField(new Date(Date.now())); + targetDataDoc[(annotationKey ?? this.annotationKey) + '_modificationDate'] = new DateField(); } } return true; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index dde04dcc0..01a26559c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -902,7 +902,7 @@ export class MainView extends React.Component { childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} /> - {['watching', 'recording'].includes(String(this.userDoc?.presentationMode) ?? '') ?

{StrCast(this.userDoc?.presentationMode)}
: <>} + {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ?
{StrCast(this.userDoc?.presentationMode)}
: <>}
); } diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index 2bc2d5e6b..9966dbced 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -5,6 +5,7 @@ import * as React from 'react'; import { DocumentManager } from '../util/DocumentManager'; import { CompileScript, Transformer, ts } from '../util/Scripting'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; +import { SettingsManager } from '../util/SettingsManager'; import { undoable } from '../util/UndoManager'; import { DocumentIconContainer } from './nodes/DocumentIcon'; import { OverlayView } from './OverlayView'; @@ -245,17 +246,29 @@ export class ScriptingRepl extends React.Component { render() { return (
-
+
{this.commands.map(({ command, result }, i) => { return ( -
-
{command ||
}
-
{}
+
+
+ {command ||
} +
+
+ {} +
); })}
- +
); } diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index 6e2ed72b8..bccbd66e8 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -9,6 +9,7 @@ import { action, observable } from 'mobx'; import { Id } from '../../../fields/FieldSymbols'; import { factory } from 'typescript'; import { LightboxView } from '../LightboxView'; +import { SettingsManager } from '../../util/SettingsManager'; @observer export class DocumentIcon extends React.Component<{ view: DocumentView; index: number }> { @@ -29,6 +30,7 @@ export class DocumentIcon extends React.Component<{ view: DocumentView; index: n pointerEvents: 'all', opacity: this._hovered ? 0.3 : 1, position: 'absolute', + background: SettingsManager.userBackgroundColor, transform: `translate(${(left + right) / 2}px, ${top}px)`, }}> {this.props.view.rootDoc.title}}> diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 1cf66fbdc..bb2069cc9 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -235,7 +235,7 @@ export class FontIconBox extends DocComponent() { const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) .map(value => ({ - text: value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), + text: typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), val: value, style: getStyle(value), onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 8a91b8102..9dd673591 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -1,32 +1,27 @@ -import { action, observable, runInAction } from 'mobx'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { VideoField } from '../../../../fields/URLField'; -import { Upload } from '../../../../server/SharedMediaTypes'; -import { ViewBoxBaseComponent } from '../../DocComponent'; -import { FieldView, FieldViewProps } from '../FieldView'; -import { VideoBox } from '../VideoBox'; -import { RecordingView } from './RecordingView'; -import { DocumentType } from '../../../documents/DocumentTypes'; -import { Presentation } from '../../../util/TrackMovements'; +import { formatTime } from '../../../../Utils'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; +import { listSpec } from '../../../../fields/Schema'; import { BoolCast, Cast, DocCast } from '../../../../fields/Types'; -import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; -import { DocumentManager } from '../../../util/DocumentManager'; +import { VideoField } from '../../../../fields/URLField'; +import { Upload } from '../../../../server/SharedMediaTypes'; import { Docs } from '../../../documents/Documents'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; -import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; -import { DocumentView } from '../DocumentView'; -import { SettingsManager } from '../../../util/SettingsManager'; -import { PropertiesView } from '../../PropertiesView'; -import { PropertiesSection } from '../../PropertiesSection'; -import { PropertiesDocContextSelector } from '../../PropertiesDocContextSelector'; -import { listSpec } from '../../../../fields/Schema'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; +import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SelectionManager } from '../../../util/SelectionManager'; -import { AudioBox } from '../AudioBox'; -import { UndoManager, undoBatch } from '../../../util/UndoManager'; +import { Presentation } from '../../../util/TrackMovements'; +import { undoBatch } from '../../../util/UndoManager'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../FieldView'; +import { VideoBox } from '../VideoBox'; +import { RecordingView } from './RecordingView'; +import { DateField } from '../../../../fields/DateField'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -69,8 +64,8 @@ export class RecordingBox extends ViewBoxBaseComponent() { /** * This method toggles whether or not we are currently using the RecordingBox to record with the topbar button - * @param _readOnly_ - * @returns + * @param _readOnly_ + * @returns */ @undoBatch @action @@ -78,33 +73,33 @@ export class RecordingBox extends ViewBoxBaseComponent() { if (_readOnly_) return RecordingBox.screengrabber ? true : false; if (RecordingBox.screengrabber) { //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening - console.log('grabbing screen!') + console.log('grabbing screen!'); RecordingBox.screengrabber.Pause?.(); const remDoc = RecordingBox.screengrabber.rootDoc; setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); RecordingBox.screengrabber!.rootDoc.overlayX = 70; //was 100 RecordingBox.screengrabber!.rootDoc.overlayY = 590; - console.log(RecordingBox.screengrabber) + console.log(RecordingBox.screengrabber); RecordingBox.screengrabber = undefined; }, 100); //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this setTimeout(() => { Doc.RemFromMyOverlay(remDoc); - - }, 1000) + }, 1000); Doc.UserDoc().isRecording = false; - Doc.AddDocToList(Doc.UserDoc(), "workspaceRecordings", RecordingBox.screengrabber.rootDoc); + Doc.AddDocToList(Doc.UserDoc(), 'workspaceRecordings', RecordingBox.screengrabber.rootDoc); } else { //when we first press mic const screengrabber = Docs.Create.WebCamDocument('', { + title: `${Doc.ActiveDashboard?.title ?? ''} ${new DateField()}`, _width: 205, _height: 115, }); screengrabber.overlayX = 70; //was -400 screengrabber.overlayY = 590; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay + Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); @@ -120,21 +115,21 @@ export class RecordingBox extends ViewBoxBaseComponent() { @undoBatch @action public static toggleWorkspaceRecPlayback(value: Doc) { - let docval = undefined; Doc.UserDoc().currentRecording = value; - console.log(value) - value.overlayX =70; + console.log(value); + value.overlayX = 70; value.overlayY = 590; if (!Doc.UserDoc().isAddRecToDocMode) { Doc.UserDoc().isRecPlayback = true; Doc.UserDoc().isWorkspaceRecPlaying = true; Doc.AddToMyOverlay(value); DocumentManager.Instance.AddViewRenderedCb(value, docView => { - Doc.UserDoc().currentRecording = docView.ComponentView as RecordingBox; - SelectionManager.SelectSchemaViewDoc(value); - })} else { - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value); - DragManager.StartDropdownDrag([document.createElement('div')],new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); + Doc.UserDoc().currentRecording = docView.rootDoc; + SelectionManager.SelectSchemaViewDoc(value); + }); + } else { + let recordingIndex = DocListCast(Doc.UserDoc().workspaceRecordings).indexOf(value); + DragManager.StartDropdownDrag([document.createElement('div')], new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); } } @@ -145,11 +140,11 @@ export class RecordingBox extends ViewBoxBaseComponent() { @undoBatch @action public static addRecToWorkspace(value: RecordingBox) { - console.log("adding rec to doc"); + console.log('adding rec to doc'); console.log(value); - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.rootDoc); - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); + let recordingIndex = DocListCast(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); console.log(recordingIndex); Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); Doc.UserDoc().isAddRecToDocMode = false; @@ -187,13 +182,12 @@ export class RecordingBox extends ViewBoxBaseComponent() { Doc.UserDoc().isWorkspaceRecPlaying = false; Doc.UserDoc().isWorkspaceRecPaused = false; Doc.RemFromMyOverlay(value.rootDoc); - } @undoBatch @action public static removeWorkspaceRec(value: VideoBox) { - let recordingIndex = Array.from(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); + let recordingIndex = DocListCast(Doc.UserDoc().workspaceRecordings).indexOf(value.rootDoc); Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); Doc.UserDoc().isAddRecToDocMode = false; Doc.RemFromMyOverlay(value.rootDoc); @@ -202,11 +196,8 @@ export class RecordingBox extends ViewBoxBaseComponent() { Doc.UserDoc().isAddRecToDocMode = false; Doc.UserDoc().isWorkspaceRecPlaying = false; Doc.UserDoc().isWorkspaceRecPaused = false; - } - - Record: undefined | (() => void); Pause: undefined | (() => void); Finish: undefined | (() => void); @@ -234,26 +225,50 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } -ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { RecordingBox.toggleWorkspaceRecording(_readOnly_); }); -ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { RecordingBox.toggleWorkspaceRecPlayback(value); }); -ScriptingGlobals.add(function addRectoWorkspace(value: RecordingBox) { RecordingBox.addRecToWorkspace(value); }); +ScriptingGlobals.add(function toggleRecording(_readOnly_: boolean) { + RecordingBox.toggleWorkspaceRecording(_readOnly_); +}); +ScriptingGlobals.add(function toggleRecPlayback(value: Doc) { + RecordingBox.toggleWorkspaceRecPlayback(value); +}); +ScriptingGlobals.add(function addRectoWorkspace(value: RecordingBox) { + RecordingBox.addRecToWorkspace(value); +}); -ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { RecordingBox.playWorkspaceRec(value); }); -ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { RecordingBox.pauseWorkspaceRec(value); }); -ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { RecordingBox.closeWorkspaceRec(value); }); -ScriptingGlobals.add(function removeWorkspaceRec(value: VideoBox) { RecordingBox.removeWorkspaceRec(value) }); +ScriptingGlobals.add(function playWorkspaceRec(value: VideoBox) { + RecordingBox.playWorkspaceRec(value); +}); +ScriptingGlobals.add(function pauseWorkspaceRec(value: VideoBox) { + RecordingBox.pauseWorkspaceRec(value); +}); +ScriptingGlobals.add(function closeWorkspaceRec(value: VideoBox) { + RecordingBox.closeWorkspaceRec(value); +}); +ScriptingGlobals.add(function removeWorkspaceRec(value: VideoBox) { + RecordingBox.removeWorkspaceRec(value); +}); -ScriptingGlobals.add(function getWorkspaceRecordings() { return Doc.UserDoc().workspaceRecordings }); -ScriptingGlobals.add(function getIsRecording() { return Doc.UserDoc().isRecording; }) -ScriptingGlobals.add(function getIsRecPlayback() { return Doc.UserDoc().isRecPlayback; }) -ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }) -ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { return Doc.UserDoc().isWorkspaceRecPlaying; }) -ScriptingGlobals.add(function getIsWorkspaceRecPaused() { return Doc.UserDoc().isWorkspaceRecPaused; }) +ScriptingGlobals.add(function getWorkspaceRecordings() { + return Doc.UserDoc().workspaceRecordings; +}); +ScriptingGlobals.add(function getIsRecording() { + return Doc.UserDoc().isRecording; +}); +ScriptingGlobals.add(function getIsRecPlayback() { + return Doc.UserDoc().isRecPlayback; +}); +ScriptingGlobals.add(function getCurrentRecording() { + return Doc.UserDoc().currentRecording; +}); +ScriptingGlobals.add(function getIsWorkspaceRecPlaying() { + return Doc.UserDoc().isWorkspaceRecPlaying; +}); +ScriptingGlobals.add(function getIsWorkspaceRecPaused() { + return Doc.UserDoc().isWorkspaceRecPaused; +}); ScriptingGlobals.add(function renderDropdown() { - if (!Doc.UserDoc().workspaceRecordings || Array.from(Doc.UserDoc().workspaceRecordings).length === 0) { + if (!Doc.UserDoc().workspaceRecordings || DocListCast(Doc.UserDoc().workspaceRecordings).length === 0) { return true; } return false; -}) - - +}); -- cgit v1.2.3-70-g09d2 From 7c218639c75e22e1270d4198fb940b439175deee Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 11:50:14 -0400 Subject: reworked recording workspace UI and switched to recording window, not webcam --- src/client/util/CurrentUserUtils.ts | 58 +++--- src/client/util/DragManager.ts | 7 +- src/client/views/DashboardView.tsx | 8 +- .../collectionLinear/CollectionLinearView.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 90 ++++----- .../views/nodes/RecordingBox/RecordingBox.tsx | 215 ++++++++++----------- src/client/views/nodes/ScreenshotBox.tsx | 3 + src/client/views/topbar/TopBar.tsx | 63 ++++-- src/fields/Doc.ts | 3 + 10 files changed, 234 insertions(+), 219 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 51ef51508..04f1ff0d2 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -18,6 +18,7 @@ import { CollectionViewType, DocumentType } from "../documents/DocumentTypes"; import { TreeViewType } from "../views/collections/CollectionTreeView"; import { DashboardView } from "../views/DashboardView"; import { Colors } from "../views/global/globalEnums"; +import { media_state } from "../views/nodes/AudioBox"; import { OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; @@ -51,7 +52,7 @@ interface Button { // fields that do not correspond to DocumentOption fields scripts?: { script?: string; onClick?: string; onDoubleClick?: string } - funcs?: { [key:string]: string }; + funcs?: { [key:string]: any}; subMenu?: Button[]; } @@ -591,7 +592,7 @@ export class CurrentUserUtils { static createToolButton = (opts: DocumentOptions) => Docs.Create.FontIconDocument({ btnType: ButtonType.ToolButton, _forceActive: true, _layout_hideContextMenu: true, _dropPropertiesToRemove: new List([ "_layout_hideContextMenu"]), - _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, isSystem: true, ...opts, + /*_nativeWidth: 40, _nativeHeight: 40, */ _width: 40, _height: 40, isSystem: true, ...opts, }) /// initializes the required buttons in the expanding button menu at the bottom of the Dash window @@ -693,7 +694,6 @@ export class CurrentUserUtils { { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, scripts: { script: '{ return webSetURL(value, _readOnly_); }'} }, ]; } - static contextMenuTools():Button[] { return [ { btnList: new List([CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree, @@ -701,11 +701,11 @@ export class CurrentUserUtils { CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel, CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map, CollectionViewType.Grid, CollectionViewType.NoteTaking]), - title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, + title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: true, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, - { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform + { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, @@ -714,16 +714,8 @@ export class CurrentUserUtils { { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected - { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected - { title: "Video", icon: 'video', toolTip: "Dictate", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `getIsRecording()`}, ignoreClick: true, scripts: { onClick: 'return toggleRecording(_readOnly_)'}}, - { title: "StopRec", icon: "stop", toolTip: "Stop", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecording()`}, ignoreClick: true, scripts: { onClick: `return toggleRecording(_readOnly_)`}}, - { title: "Dropdown", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList, expertMode: false, funcs: {hidden: `renderDropdown()`, btnList: `getWorkspaceRecordings()`}, ignoreClick: true, scripts: { script: `toggleRecPlayback(value)`}}, - { title: "Play Rec",icon: "play", toolTip: "Play recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPlaying()`}, ignoreClick: true, scripts: { onClick: `return playWorkspaceRec(getCurrentRecording())`}}, - { title: "Pause Rec",icon: "pause", toolTip: "Pause recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsWorkspaceRecPaused()`}, ignoreClick: true, scripts: { onClick: `return pauseWorkspaceRec(getCurrentRecording())`}}, - { title: "Stop Rec", icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `return closeWorkspaceRec(getCurrentRecording())`}}, - { title: "Add doc", icon: "down", toolTip: "add to doc", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `addRectoWorkspace(getCurrentRecording())`}}, - { title: "Delete Rec", icon: "trash", toolTip: "delete selected recording", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {hidden: `!getIsRecPlayback()`}, ignoreClick: true, scripts: { onClick: `removeWorkspaceRec(getCurrentRecording())`}} - ]; + { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected + ]; } /// initializes a context menu button for the top bar context menu @@ -749,19 +741,17 @@ export class CurrentUserUtils { if (Doc.UserDoc().currentRecording) { Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); } - Doc.UserDoc().isRecording = false; - Doc.UserDoc().isRecPlayback = false; + Doc.UserDoc().workspaceRecordingState = undefined; + Doc.UserDoc().workspaceReplayingState = undefined; Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().isPlaybackPlaying = false; - Doc.UserDoc().isWorkspaceRecPlaying = false; - Doc.UserDoc().isWorkspaceRecPaused = false; + Doc.UserDoc().workspaceRecordingState = undefined; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } // linear view const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List(['width', "linearView_IsOpen"]), childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: params.scripts?.onClick ? false : true, - linearView_SubMenu: true, linearView_Expandable: params.btnType !== ButtonType.MultiToggleButton}; + linearView_SubMenu: true, linearView_Expandable: true}; const items = (menuBtnDoc?:Doc) => !menuBtnDoc ? [] : subMenu.map(sub => this.setupContextMenuBtn(sub, menuBtnDoc) ); const creator = params.btnType === ButtonType.MultiToggleButton ? this.multiToggleList : this.linearButtonList; @@ -773,11 +763,34 @@ export class CurrentUserUtils { /// Initializes all the default buttons for the top bar context menu static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") { - const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 }; + const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: true, _height: 35 }; const ctxtMenuBtnsDoc = DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined); const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => this.setupContextMenuBtn(params, ctxtMenuBtnsDoc) ); return DocUtils.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts, ctxtMenuBtns); } + /// Initializes all the default buttons for the top bar context menu + static setupTopbarButtons(doc: Doc, field="myTopBarBtns") { + const dockedBtns = DocCast(doc[field]); + const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) => + DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? + CurrentUserUtils.createToolButton(opts), scripts, funcs); + + const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet + { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, + { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`}, scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`}}, + { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`}, scripts: { onClick: `stopWorkspaceRecording()`}}, + { opts: { title: "Play", icon: "play", toolTip: "Play recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}}, + { opts: { title: "Pause", icon: "pause",toolTip: "Pause playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Playing}"`}, scripts: { onClick: `pauseWorkspaceReplaying(getCurrentRecording())`}}, + { opts: { title: "Stop", icon: "stop", toolTip: "Stop playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `stopWorkspaceReplaying(getCurrentRecording())`}}, + { opts: { title: "Delete", icon: "trash",toolTip: "delete selected rec", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `removeWorkspaceReplaying(getCurrentRecording())`}} + ]; + const btns = btnDescs.map(desc => dockBtn({_width: desc.opts.width??30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts, desc.funcs)); + const dockBtnsReqdOpts:DocumentOptions = { + title: "docked buttons", _height: 40, flexGap: 0, layout_boxShadow: "standard", childDragAction: 'move', + childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: true, ignoreClick: true + }; + return DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), dockBtnsReqdOpts, btns); + } /// collection of documents rendered in the overlay layer above all tabs and other UI static setupOverlays(doc: Doc, field = "myOverlayDocs") { @@ -891,6 +904,7 @@ export class CurrentUserUtils { this.setupOverlays(doc); // sets up the overlay panel where documents and other widgets can be added to float over the rest of the dashboard this.setupPublished(doc); // sets up the list doc of all docs that have been published (meaning that they can be auto-linked by typing their title into another text box) this.setupContextMenuButtons(doc); // set up the row of buttons at the top of the dashboard that change depending on what is selected + this.setupTopbarButtons(doc); this.setupDockedButtons(doc); // the bottom bar of font icons this.setupLeftSidebarMenu(doc); // the left-side column of buttons that open their contents in a flyout panel on the left this.setupDocTemplates(doc); // sets up the template menu of templates diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 065f17139..6c0641943 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -243,13 +243,10 @@ export namespace DragManager { return dropDoc; }; const finishDrag = async (e: DragCompleteEvent) => { - Doc.UserDoc().isAddRecToDocMode = false; Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().isRecPlayback = false; - Doc.UserDoc().isWorkspaceRecPlaying = false; - Doc.UserDoc().isWorkspaceRecPaused = false; - Doc.UserDoc().isAddRecToDocMode = false; + Doc.UserDoc().isWorkspaceReplaying = false; + Doc.UserDoc().workspaceRecordingState = undefined; Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); const docDragData = e.docDragData; dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 4387c6e96..3ef6c0814 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -18,7 +18,7 @@ import { CollectionViewType } from '../documents/DocumentTypes'; import { HistoryUtil } from '../util/History'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { SharingManager } from '../util/SharingManager'; -import { undoBatch } from '../util/UndoManager'; +import { undoBatch, UndoManager } from '../util/UndoManager'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { CollectionView } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; @@ -493,6 +493,8 @@ ScriptingGlobals.add(function resetDashboard(dashboard: Doc) { ScriptingGlobals.add(function addToDashboards(dashboard: Doc) { DashboardView.openDashboard(Doc.MakeEmbedding(dashboard)); }, 'adds Dashboard to set of Dashboards'); -ScriptingGlobals.add(function snapshotDashboard() { - DashboardView.snapshotDashboard(); +ScriptingGlobals.add(async function snapshotDashboard() { + const batch = UndoManager.StartBatch('snapshot'); + await DashboardView.snapshotDashboard(); + batch.end(); }, 'creates a snapshot copy of a dashboard'); diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 3481d5130..0cf7d4411 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -229,8 +229,8 @@ export class CollectionLinearView extends CollectionSubView() {
{ <> - {menuOpener} - {!this.layoutDoc.linearView_IsOpen ? null : ( + {!this.layoutDoc.linearView_Expandable ? null :menuOpener} + {!this.layoutDoc.linearView_IsOpen && !this.layoutDoc.linearView_alwaysOpen ? null : (
Doc.Zip(this.props.Document) }); (this.rootDoc._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: 'users' }); if (this.props.removeDocument && Doc.ActiveDashboard !== this.props.Document) { diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index bb2069cc9..8ef9cd792 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -180,55 +180,45 @@ export class FontIconBox extends DocComponent() { * Dropdown list */ @computed get dropdownListButton() { - const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const script = ScriptCast(this.rootDoc.script); let noviceList: string[] = []; let text: string | undefined; - let dropdown = true; let getStyle: (val: string) => any = () => {}; let icon: IconProp = 'caret-down'; - let isViewDropdown: boolean = script?.script.originalScript.startsWith('setView'); - try { - if (isViewDropdown) { - const selectedDocs: Doc[] = SelectionManager.Docs(); - const selected = SelectionManager.Docs().lastElement(); - if (selected) { - if (StrCast(selected.type) === DocumentType.COL) { - text = StrCast(selected._type_collection); + const isViewDropdown = script?.script.originalScript.startsWith('setView'); + if (isViewDropdown) { + const selected = SelectionManager.Docs(); + if (selected.lastElement()) { + if (StrCast(selected.lastElement().type) === DocumentType.COL) { + text = StrCast(selected.lastElement()._type_collection); + } else { + if (selected.length > 1) { + text = selected.length + ' selected'; } else { - dropdown = false; - if (selectedDocs.length > 1) { - text = selectedDocs.length + ' selected'; - } else { - text = Utils.cleanDocumentType(StrCast(selected.type) as DocumentType); - icon = Doc.toIcon(selected); - } - return ( - } - text={text} - type={Type.TERT} - color={SettingsManager.userColor} - background={SettingsManager.userVariantColor} - popup={} - fillWidth - /> - ); + text = Utils.cleanDocumentType(StrCast(selected.lastElement().type) as DocumentType); + icon = Doc.toIcon(selected.lastElement()); } - } else { - dropdown = false; - return
) : null; } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index ad0e548ed..2a1dfbfc7 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -220,6 +220,9 @@ export class Doc extends RefField { public static get MyContextMenuBtns() { return DocCast(Doc.UserDoc().myContextMenuBtns); } + public static get MyTopBarBtns() { + return DocCast(Doc.UserDoc().myTopBarBtns); + } public static get MyRecentlyClosed() { return DocCast(Doc.UserDoc().myRecentlyClosed); } -- cgit v1.2.3-70-g09d2 From 2b85c6e8177134dbfa284656ff492ccd52fe2273 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 11:56:19 -0400 Subject: from last --- src/client/util/CurrentUserUtils.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 04f1ff0d2..539c62833 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -738,13 +738,6 @@ export class CurrentUserUtils { static setupContextMenuBtn(params:Button, menuDoc:Doc):Doc { const menuBtnDoc = DocListCast(menuDoc?.data).find(doc => doc.title === params.title); const subMenu = params.subMenu; - if (Doc.UserDoc().currentRecording) { - Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); - } - Doc.UserDoc().workspaceRecordingState = undefined; - Doc.UserDoc().workspaceReplayingState = undefined; - Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().workspaceRecordingState = undefined; if (!subMenu) { // button does not have a sub menu return this.setupContextMenuButton(params, menuBtnDoc); } @@ -770,6 +763,10 @@ export class CurrentUserUtils { } /// Initializes all the default buttons for the top bar context menu static setupTopbarButtons(doc: Doc, field="myTopBarBtns") { + if (Doc.UserDoc().currentRecording) Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); + Doc.UserDoc().currentRecording = undefined; + Doc.UserDoc().workspaceRecordingState = undefined; + Doc.UserDoc().workspaceReplayingState = undefined; const dockedBtns = DocCast(doc[field]); const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) => DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? -- cgit v1.2.3-70-g09d2 From 7b73406cf7cc2b2cec0482408e8b5fac3a5584f8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 12:00:38 -0400 Subject: from last --- src/client/util/DragManager.ts | 51 ---------------------- .../views/nodes/RecordingBox/RecordingBox.tsx | 2 - 2 files changed, 53 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6c0641943..4ab033555 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -236,57 +236,6 @@ export namespace DragManager { return true; } - export function StartDropdownDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, recordingIndex: number, options?: DragOptions, dropEvent?: () => any) { - const addAudioTag = (dropDoc: any) => { - dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField()); - dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); - return dropDoc; - }; - const finishDrag = async (e: DragCompleteEvent) => { - Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); - Doc.UserDoc().currentRecording = undefined; - Doc.UserDoc().isWorkspaceReplaying = false; - Doc.UserDoc().workspaceRecordingState = undefined; - Cast(Doc.UserDoc().workspaceRecordings, listSpec(Doc), null)?.splice(recordingIndex, 1); - const docDragData = e.docDragData; - dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails - if (docDragData && !docDragData.droppedDocuments.length) { - docDragData.dropAction = dragData.userDropAction || dragData.dropAction; - docDragData.droppedDocuments = ( - await Promise.all( - dragData.draggedDocuments.map(async d => - !dragData.isDocDecorationMove && !dragData.userDropAction && ScriptCast(d.onDragStart) - ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) - : docDragData.dropAction === 'embed' - ? Doc.BestEmbedding(d) - : docDragData.dropAction === 'add' - ? d - : docDragData.dropAction === 'proto' - ? Doc.GetProto(d) - : docDragData.dropAction === 'copy' - ? ( - await Doc.MakeClone(d) - ).clone - : d - ) - ) - ).filter(d => d); - !['same', 'proto'].includes(docDragData.dropAction as any) && - docDragData.droppedDocuments - // .filter(drop => !drop.dragOnlyWithinContainer || ['embed', 'copy'].includes(docDragData.dropAction as any)) - .forEach((drop: Doc, i: number) => { - const dragProps = StrListCast(dragData.draggedDocuments[i].dropPropertiesToRemove); - const remProps = (dragData?.dropPropertiesToRemove || []).concat(Array.from(dragProps)); - [...remProps, 'dropPropertiesToRemove'].map(prop => (drop[prop] = undefined)); - }); - } - return e; - }; - dragData.draggedDocuments.map(d => d.dragFactory); // does this help? trying to make sure the dragFactory Doc is loaded - StartDrag(eles, dragData, downX, downY, options, finishDrag); - return true; - } - // drag a button template and drop a new button export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { const finishDrag = (e: DragCompleteEvent) => { diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index b1b044c25..1b2f63fa2 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -120,8 +120,6 @@ export class RecordingBox extends ViewBoxBaseComponent() { SelectionManager.SelectSchemaViewDoc(value); RecordingBox.resumeWorkspaceReplaying(value); }); - // let recordingIndex = DocListCast(Doc.UserDoc().workspaceRecordings).indexOf(value); - // DragManager.StartDropdownDrag([document.createElement('div')], new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); } /** -- cgit v1.2.3-70-g09d2 From b7295d4747d8eb01d8213c97442cc4916aec77c4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 12:16:09 -0400 Subject: from last again --- src/client/util/DragManager.ts | 4 +--- .../collectionLinear/CollectionLinearView.tsx | 4 ++-- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 3 --- src/client/views/nodes/trails/PresBox.tsx | 2 -- src/client/views/nodes/trails/PresElementBox.tsx | 24 +++++++--------------- 6 files changed, 11 insertions(+), 28 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 4ab033555..6d6eaebec 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -4,17 +4,15 @@ import { Doc, Field, Opt, StrListCast } from '../../fields/Doc'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; import { ScriptField } from '../../fields/ScriptField'; -import { BoolCast, Cast, DocCast, ScriptCast, StrCast } from '../../fields/Types'; +import { ScriptCast, StrCast } from '../../fields/Types'; import { emptyFunction, Utils } from '../../Utils'; import { Docs, DocUtils } from '../documents/Documents'; import * as globalCssVariables from '../views/global/globalCssVariables.scss'; -import { Colors } from '../views/global/globalEnums'; import { DocumentView } from '../views/nodes/DocumentView'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; -import { listSpec } from '../../fields/Schema'; export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 0cf7d4411..47a98bdd1 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -229,8 +229,8 @@ export class CollectionLinearView extends CollectionSubView() {
{ <> - {!this.layoutDoc.linearView_Expandable ? null :menuOpener} - {!this.layoutDoc.linearView_IsOpen && !this.layoutDoc.linearView_alwaysOpen ? null : ( + {!this.layoutDoc.linearView_Expandable ? null : menuOpener} + {!this.layoutDoc.linearView_IsOpen ? null : (
() { return ( script.script.run({ this: this.layoutDoc, self: this.rootDoc, val }), `dropdown select ${this.label}`)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 1b2f63fa2..e9060a605 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -138,7 +138,6 @@ export class RecordingBox extends ViewBoxBaseComponent() { Doc.UserDoc().workspaceRecordingState = undefined; } - @undoBatch @action public static resumeWorkspaceReplaying(doc: Doc) { const docView = DocumentManager.Instance.getDocumentView(doc); @@ -149,7 +148,6 @@ export class RecordingBox extends ViewBoxBaseComponent() { } } - @undoBatch @action public static pauseWorkspaceReplaying(doc: Doc) { const docView = DocumentManager.Instance.getDocumentView(doc); @@ -160,7 +158,6 @@ export class RecordingBox extends ViewBoxBaseComponent() { Doc.UserDoc().workspaceReplayingState = media_state.Paused; } - @undoBatch @action public static stopWorkspaceReplaying(value: Doc) { Doc.RemFromMyOverlay(value); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 02132b7b3..7bb1b80a3 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -303,7 +303,6 @@ export class PresBox extends ViewBoxBaseComponent() { // Called when the user activates 'next' - to move to the next part of the pres. trail @action next = () => { - console.log('next'); const progressiveReveal = (first: boolean) => { const presIndexed = Cast(this.activeItem?.presentation_indexed, 'number', null); if (presIndexed !== undefined) { @@ -386,7 +385,6 @@ export class PresBox extends ViewBoxBaseComponent() { //it'll also execute the necessary actions if presentation is playing. @undoBatch public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => { - console.log('going to document'); Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 121eb87d5..82ed9e8d5 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -6,7 +6,7 @@ import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; -import { Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType } from '../../../documents/DocumentTypes'; @@ -313,17 +313,8 @@ export class PresElementBox extends ViewBoxBaseComponent() { @undoBatch @action revertToPreviouslySaved = (presTargetDoc: Doc, activeItem: Doc) => { - console.log('reverting'); - // console.log("reverting to previosly saved\n"); - // console.log(this.prevTarget); - console.log('Content continuously updating'); const target = DocCast(activeItem.annotationOn) ?? activeItem; - console.log(presTargetDoc.pinData); PresBox.reversePin(activeItem, target); - // console.log("new target\n"); - // console.log(target); - // PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(this.prevTarget) }, this.prevTarget ? this.prevTarget : target); - //figure out how to make it go back to the previously saved one }; /** @@ -426,7 +417,6 @@ export class PresElementBox extends ViewBoxBaseComponent() { @action lfg = (e: React.MouseEvent) => { e.stopPropagation(); - console.log('lfg called'); // TODO: fix this bug const { toggleChildrenRun } = this.rootDoc; TreeView.ToggleChildrenRun.get(this.rootDoc)?.(); @@ -445,12 +435,12 @@ export class PresElementBox extends ViewBoxBaseComponent() { } @computed get presButtons() { - const presBox = this.presBox; //presBox - const presBoxColor: string = StrCast(presBox?._backgroundColor); - const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; - const targetDoc: Doc = this.targetDoc; - const activeItem: Doc = this.rootDoc; - const hasChildren: boolean = Cast(this.rootDoc?.hasChildren, 'boolean') || false; + const presBox = this.presBox; + const presBoxColor = StrCast(presBox?._backgroundColor); + const presColorBool = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; + const targetDoc = this.targetDoc; + const activeItem = this.rootDoc; + const hasChildren = BoolCast(this.rootDoc?.hasChildren); const items: JSX.Element[] = []; -- cgit v1.2.3-70-g09d2 From a60edcbd8fd724ef9c228262370a7ad98f7aadd1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 15:44:46 -0400 Subject: added dragging off of recordings and option for webcam vs screen --- package-lock.json | 304 +++++++++------------ package.json | 2 +- src/client/util/CurrentUserUtils.ts | 4 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 15 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 44 +-- src/client/views/nodes/ScreenshotBox.tsx | 13 +- 6 files changed, 185 insertions(+), 197 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index c3190ddb4..aae7c022c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -164,11 +164,11 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "requires": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" } }, @@ -184,9 +184,9 @@ } }, "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "requires": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -194,9 +194,9 @@ } }, "@babel/parser": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", - "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==" + "version": "7.22.14", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", + "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==" }, "@babel/traverse": { "version": "7.22.11", @@ -579,11 +579,11 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "requires": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" } }, @@ -599,9 +599,9 @@ } }, "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "requires": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -609,9 +609,9 @@ } }, "@babel/parser": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", - "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==" + "version": "7.22.14", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", + "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==" }, "@babel/traverse": { "version": "7.22.11", @@ -1822,9 +1822,9 @@ } }, "@babel/preset-env": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.10.tgz", - "integrity": "sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==", + "version": "7.22.14", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.14.tgz", + "integrity": "sha512-daodMIoVo+ol/g+//c/AH+szBkFj4STQUikvBijRGL72Ph+w+AMTSh55DUETe8KJlPlDT1k/mp7NBfOuiWmoig==", "requires": { "@babel/compat-data": "^7.22.9", "@babel/helper-compilation-targets": "^7.22.10", @@ -1852,41 +1852,41 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.10", + "@babel/plugin-transform-async-generator-functions": "^7.22.11", "@babel/plugin-transform-async-to-generator": "^7.22.5", "@babel/plugin-transform-block-scoped-functions": "^7.22.5", "@babel/plugin-transform-block-scoping": "^7.22.10", "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", "@babel/plugin-transform-classes": "^7.22.6", "@babel/plugin-transform-computed-properties": "^7.22.5", "@babel/plugin-transform-destructuring": "^7.22.10", "@babel/plugin-transform-dotall-regex": "^7.22.5", "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", "@babel/plugin-transform-for-of": "^7.22.5", "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", "@babel/plugin-transform-member-expression-literals": "^7.22.5", "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.11", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", "@babel/plugin-transform-modules-umd": "^7.22.5", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.11", "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.10", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.12", "@babel/plugin-transform-parameters": "^7.22.5", "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", "@babel/plugin-transform-property-literals": "^7.22.5", "@babel/plugin-transform-regenerator": "^7.22.10", "@babel/plugin-transform-reserved-words": "^7.22.5", @@ -1900,7 +1900,7 @@ "@babel/plugin-transform-unicode-regex": "^7.22.5", "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", "@babel/preset-modules": "0.1.6-no-external-plugins", - "@babel/types": "^7.22.10", + "@babel/types": "^7.22.11", "babel-plugin-polyfill-corejs2": "^0.4.5", "babel-plugin-polyfill-corejs3": "^0.8.3", "babel-plugin-polyfill-regenerator": "^0.5.2", @@ -2711,11 +2711,11 @@ } }, "@floating-ui/react-dom": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.1.tgz", - "integrity": "sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", "requires": { - "@floating-ui/dom": "^1.3.0" + "@floating-ui/dom": "^1.5.1" } }, "@floating-ui/utils": { @@ -3232,9 +3232,9 @@ } }, "@mui/styled-engine-sc": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.14.6.tgz", - "integrity": "sha512-7/KXXdDLjpQAmbmIhUs1x7nzqooEiHkidQOXCIH04NiVa4KRxP4v/bOWV/5GpgZi1Aky5ruf9IVyH3jxYIW3JA==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.14.7.tgz", + "integrity": "sha512-so3X2N0SxpXjc61+d6s0aG11OVF9XTDrKusaXd8YE1d9fzEuIGEpvOXizaMJZThqkTqGzNKQuXFEpC55Vb0gdw==", "requires": { "@babel/runtime": "^7.22.10", "prop-types": "^15.8.1" @@ -6537,9 +6537,9 @@ } }, "browndash-components": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.2.tgz", - "integrity": "sha512-5ONrqd6qYYMjWuayhhdwU4tlrtr+7c0n9MAMXg4jccdd9OxnmdlWpjPzOBYl3slE+mSpKcycwKarwYND+eM0NA==", + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.21.tgz", + "integrity": "sha512-xPHuliete1jNXCGYZrVxuKUDmlanleFLWjZm8dC3vII0BT7jNPxMRZyYTxgc/PjYMRgM/BY0FCUPFTrsiYRawQ==", "requires": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", @@ -6657,15 +6657,15 @@ "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@mui/base": { - "version": "5.0.0-beta.12", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.12.tgz", - "integrity": "sha512-tZjjXNAyUpwSDT1uRliZMhRQkWYzELJ8Qi61EuOMRpi36HIwnK2T7Nr4RI423Sv8G2EEikDAZj7je33eNd73NQ==", + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.13.tgz", + "integrity": "sha512-uC0l97pBspfDAp+iz2cJq8YZ8Sd9i73V77+WzUiOAckIVEyCm5dyVDZCCO2/phmzckVEeZCGcytybkjMQuhPQw==", "requires": { "@babel/runtime": "^7.22.10", "@emotion/is-prop-valid": "^1.2.1", "@floating-ui/react-dom": "^2.0.1", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.6", + "@mui/utils": "^5.14.7", "@popperjs/core": "^2.11.8", "clsx": "^2.0.0", "prop-types": "^15.8.1", @@ -6683,21 +6683,21 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.6.tgz", - "integrity": "sha512-QZEU3pyGWLuaHbxvOlShol7U1FVgzWBR0OH9H8D7L8w4/vto5N5jJVvlqFQS3T0zbR6YGHxFaiL6Ky87jQg7aw==" + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.7.tgz", + "integrity": "sha512-sCWTUNElBPgB30iLvWe3PU7SIlTKZNf6/E/sko85iHVeHCM6WPkDw+y89CrZYjhFNmPqt2fIQM/pZu+rP2lFLA==" }, "@mui/material": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.6.tgz", - "integrity": "sha512-C3UgGrmtvcGkQkm0ONBU7bTdapTjQc2Se3b2354xMmU7lgSgW7VM6EP9wIH5XqqoJ60m9l/s9kbTWX0Y+EaWvA==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.7.tgz", + "integrity": "sha512-jIZj9F7zMv6IlyaYDVv5M2Kp20jIX8c0kzuwteySHS/A0IvPVyomQEPtWc51MCbpDNCqzwoZUp3rQtA2lI8k7A==", "requires": { "@babel/runtime": "^7.22.10", - "@mui/base": "5.0.0-beta.12", - "@mui/core-downloads-tracker": "^5.14.6", - "@mui/system": "^5.14.6", + "@mui/base": "5.0.0-beta.13", + "@mui/core-downloads-tracker": "^5.14.7", + "@mui/system": "^5.14.7", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.6", + "@mui/utils": "^5.14.7", "@types/react-transition-group": "^4.4.6", "clsx": "^2.0.0", "csstype": "^3.1.2", @@ -6717,12 +6717,12 @@ } }, "@mui/private-theming": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.6.tgz", - "integrity": "sha512-3VBLFGizBXfofyk33bwRg6t9L648aKnLmOKPfY1wFuiXq3AEYwobK65iDci/tHKxm/VKbZ6A7PFjLejvB3EvRQ==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.7.tgz", + "integrity": "sha512-Y86+hmDnJab2Ka42PgxKpK3oL7EiacbeeX3X/lG9LGO0wSc45wZjHeTfIlVSkkUCkexiMKEJp5NlSjZhr27NRQ==", "requires": { "@babel/runtime": "^7.22.10", - "@mui/utils": "^5.14.6", + "@mui/utils": "^5.14.7", "prop-types": "^15.8.1" }, "dependencies": { @@ -6737,9 +6737,9 @@ } }, "@mui/styled-engine": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.6.tgz", - "integrity": "sha512-I6zeu/OP1Hk4NsX1Oj85TiYl1dER0JMsLJVn76J1Ihl24A5EbiZQKJp3Mn+ufA79ypkdAvM9aQCAQyiVBFcUHg==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.7.tgz", + "integrity": "sha512-hKBETEDsIAkL8/mBwPiQj/vw28OeIhMXC3Tvj4J2bb9snxAKpiZioR1PwqP+6P41twsC/GKBd0Vr9oaWYaHuMg==", "requires": { "@babel/runtime": "^7.22.10", "@emotion/cache": "^11.11.0", @@ -6758,15 +6758,15 @@ } }, "@mui/system": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.6.tgz", - "integrity": "sha512-/n0ae1MegWjiV1BpRU8jgg4E0zBjeB2VYsT/68ag/xaDuq3/TaDKJeT9REIvyBvwlG3CI3S2O+tRELktxCD1kg==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.7.tgz", + "integrity": "sha512-jeZtHglc+Pi6qjGoopT6O4RqYXVBMqHVOsjMGP0hxGSSPm1T4gsAu7jU8eqGx9YwwjvvJ0eotTjFqw7iJ6qE2Q==", "requires": { "@babel/runtime": "^7.22.10", - "@mui/private-theming": "^5.14.6", - "@mui/styled-engine": "^5.14.6", + "@mui/private-theming": "^5.14.7", + "@mui/styled-engine": "^5.14.7", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.6", + "@mui/utils": "^5.14.7", "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -6783,9 +6783,9 @@ } }, "@mui/utils": { - "version": "5.14.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.6.tgz", - "integrity": "sha512-AznpqLu6hrFnpHgcvsSSMCG+cDbkcCYfo+daUwBVReNYv4l+NQ8+wvBAF4aUMi155N7xWbbgh0cyKs6Wdsm3aA==", + "version": "5.14.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.7.tgz", + "integrity": "sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw==", "requires": { "@babel/runtime": "^7.22.10", "@types/prop-types": "^15.7.5", @@ -7094,97 +7094,12 @@ "strip-ansi": "^7.0.1" } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, "strip-ansi": { "version": "7.1.0", "bundled": true, "requires": { "ansi-regex": "^6.0.1" } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } } } }, @@ -8689,7 +8604,7 @@ } }, "string-width-cjs": { - "version": "npm:string-width-cjs@4.2.3", + "version": "npm:string-width@4.2.3", "bundled": true, "requires": { "emoji-regex": "^8.0.0", @@ -8712,7 +8627,7 @@ } }, "strip-ansi-cjs": { - "version": "npm:strip-ansi-cjs@6.0.1", + "version": "npm:strip-ansi@6.0.1", "bundled": true, "requires": { "ansi-regex": "^5.0.1" @@ -8871,7 +8786,7 @@ } }, "wrap-ansi-cjs": { - "version": "npm:wrap-ansi-cjs@7.0.0", + "version": "npm:wrap-ansi@7.0.0", "bundled": true, "requires": { "ansi-styles": "^4.0.0", @@ -8903,9 +8818,9 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -10081,14 +9996,14 @@ } }, "caniuse-lite": { - "version": "1.0.30001524", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz", - "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==" + "version": "1.0.30001525", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz", + "integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==" }, "electron-to-chromium": { - "version": "1.4.503", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.503.tgz", - "integrity": "sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==" + "version": "1.4.506", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz", + "integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA==" } } }, @@ -10445,6 +10360,16 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "d3": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", @@ -11825,6 +11750,28 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", @@ -11836,6 +11783,7 @@ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "requires": { + "d": "^1.0.1", "ext": "^1.1.2" } }, @@ -27648,6 +27596,12 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 5f7289719..de44b31f3 100644 --- a/package.json +++ b/package.json @@ -178,7 +178,7 @@ "body-parser": "^1.19.2", "bootstrap": "^4.6.1", "brotli": "^1.3.3", - "browndash-components": "^0.1.02", + "browndash-components": "^0.1.21", "browser-assert": "^1.2.1", "bson": "^4.6.1", "canvas": "^2.9.3", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 539c62833..9f83f105e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -773,8 +773,8 @@ export class CurrentUserUtils { CurrentUserUtils.createToolButton(opts), scripts, funcs); const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet - { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, - { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`}, scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`}}, + { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, + { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`}, scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}}, { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`}, scripts: { onClick: `stopWorkspaceRecording()`}}, { opts: { title: "Play", icon: "play", toolTip: "Play recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Paused}"`}, scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}}, { opts: { title: "Pause", icon: "pause",toolTip: "Pause playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${media_state.Playing}"`}, scripts: { onClick: `pauseWorkspaceReplaying(getCurrentRecording())`}}, diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 9bc9f2b52..ea7c2de82 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -7,7 +7,7 @@ import * as React from 'react'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { Utils } from '../../../../Utils'; +import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { SettingsManager } from '../../../util/SettingsManager'; @@ -176,6 +176,18 @@ export class FontIconBox extends DocComponent() { ); } + dropdownItemDown = (e: React.PointerEvent, value: string | number) => { + setupMoveUpEvents( + this, + e, + (e: PointerEvent) => { + return ScriptCast(this.rootDoc.onDragScript)?.script.run({ this: this.layoutDoc, self: this.rootDoc, value: { doc: value, e } }).result; + }, + emptyFunction, + emptyFunction + ); + }; + /** * Dropdown list */ @@ -240,6 +252,7 @@ export class FontIconBox extends DocComponent() { background={SettingsManager.userVariantColor} type={Type.TERT} dropdownType={DropdownType.SELECT} + onItemDown={this.dropdownItemDown} items={list} tooltip={this.label} fillWidth diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 3412b2dd2..1f113110b 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -1,10 +1,11 @@ import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; -import { listSpec } from '../../../../fields/Schema'; -import { BoolCast, Cast, DocCast, StrCast } from '../../../../fields/Types'; +import { List } from '../../../../fields/List'; +import { BoolCast, DocCast } from '../../../../fields/Types'; import { VideoField } from '../../../../fields/URLField'; import { Upload } from '../../../../server/SharedMediaTypes'; import { Docs } from '../../../documents/Documents'; @@ -17,12 +18,10 @@ import { Presentation } from '../../../util/TrackMovements'; import { undoBatch } from '../../../util/UndoManager'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { ViewBoxBaseComponent } from '../../DocComponent'; +import { media_state } from '../AudioBox'; import { FieldView, FieldViewProps } from '../FieldView'; import { VideoBox } from '../VideoBox'; import { RecordingView } from './RecordingView'; -import { DateField } from '../../../../fields/DateField'; -import { media_state } from '../AudioBox'; -import { List } from '../../../../fields/List'; @observer export class RecordingBox extends ViewBoxBaseComponent() { @@ -87,15 +86,22 @@ export class RecordingBox extends ViewBoxBaseComponent() { */ @undoBatch @action - public static WorkspaceStartRecording() { - const screengrabber = Docs.Create.ScreenshotDocument({ - title: `${new DateField()}-${Doc.ActiveDashboard?.title ?? ''}`, - _width: 205, - _height: 115, - }); + public static WorkspaceStartRecording(value: string) { + const screengrabber = + value === 'Record Workspace' + ? Docs.Create.ScreenshotDocument({ + title: `${new DateField()}-${Doc.ActiveDashboard?.title ?? ''}`, + _width: 205, + _height: 115, + }) + : Docs.Create.WebCamDocument(`${new DateField()}-${Doc.ActiveDashboard?.title ?? ''}`, { + title: `${new DateField()}-${Doc.ActiveDashboard?.title ?? ''}`, + _width: 205, + _height: 115, + }); screengrabber.overlayX = 70; //was -400 screengrabber.overlayY = 590; //was 0 - screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; + Doc.GetProto(screengrabber)[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; @@ -204,9 +210,6 @@ export class RecordingBox extends ViewBoxBaseComponent() { static screengrabber: RecordingBox | undefined; } -ScriptingGlobals.add(function startWorkspaceRecording() { - RecordingBox.WorkspaceStartRecording(); -}); ScriptingGlobals.add(function stopWorkspaceRecording() { RecordingBox.WorkspaceStopRecording(); }); @@ -222,7 +225,7 @@ ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }); ScriptingGlobals.add(function getWorkspaceRecordings() { - return new List(['Record Workspace', ...DocListCast(Doc.UserDoc().workspaceRecordings)]); + return new List(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]); }); ScriptingGlobals.add(function isWorkspaceRecording() { return Doc.UserDoc().workspaceRecordingState === media_state.Recording; @@ -232,7 +235,7 @@ ScriptingGlobals.add(function isWorkspaceReplaying() { }); ScriptingGlobals.add(function replayWorkspace(value: Doc | string, _readOnly_: boolean) { if (_readOnly_) return DocCast(Doc.UserDoc().currentRecording) ?? 'Record Workspace'; - if (typeof value === 'string') RecordingBox.WorkspaceStartRecording(); + if (typeof value === 'string') RecordingBox.WorkspaceStartRecording(value); else RecordingBox.replayWorkspace(value); }); ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc, _readOnly_: boolean) { @@ -242,6 +245,13 @@ ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc, _readOnly_: b RecordingBox.resumeWorkspaceReplaying(value); }); +ScriptingGlobals.add(function startRecordingDrag(value: { doc: Doc | string; e: React.PointerEvent }) { + if (DocCast(value.doc)) { + DragManager.StartDocumentDrag([value.e.target as HTMLElement], new DragManager.DocumentDragData([DocCast(value.doc)], 'embed'), value.e.clientX, value.e.clientY); + value.e.preventDefault(); + return true; + } +}); ScriptingGlobals.add(function renderDropdown() { if (!Doc.UserDoc().workspaceRecordings || DocListCast(Doc.UserDoc().workspaceRecordings).length === 0) { return true; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 4ebc93165..26ad8b7bb 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -26,6 +26,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import './ScreenshotBox.scss'; import { VideoBox } from './VideoBox'; +import { TrackMovements } from '../../util/TrackMovements'; declare class MediaRecorder { constructor(e: any, options?: any); // whatever MediaRecorder has @@ -236,9 +237,19 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent (this.dataDoc[this.props.fieldKey + '_recordingStart'] = new DateField(new Date())); + this._videoRec.onstart = () => { + if (this.dataDoc[this.props.fieldKey + '_trackScreen']) TrackMovements.Instance.start(); + this.dataDoc[this.props.fieldKey + '_recordingStart'] = new DateField(new Date()); + }; this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data); this._videoRec.onstop = async (e: any) => { + const presentation = TrackMovements.Instance.yieldPresentation(); + if (presentation?.movements) { + const presCopy = { ...presentation }; + presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any; + this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy); + } + TrackMovements.Instance.finish(); const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() }); const [{ result }] = await Networking.UploadFilesToServer({ file }); this.dataDoc[this.fieldKey + '_duration'] = (new Date().getTime() - this.recordingStart!) / 1000; -- cgit v1.2.3-70-g09d2 From 24d61fa2c761e99b5af7925b952d8a1bc03c5b32 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 15:51:37 -0400 Subject: from last --- src/client/util/CurrentUserUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 9f83f105e..11cc5f900 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -300,7 +300,7 @@ export class CurrentUserUtils { { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)}, { toolTip: "Tap or drag to create an audio recorder", title: "Audio", icon: "microphone", dragFactory: doc.emptyAudio as Doc, clickFactory: DocCast(doc.emptyAudio), openFactoryLocation: OpenWhere.overlay}, { toolTip: "Tap or drag to create a map", title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, clickFactory: DocCast(doc.emptyMap)}, - { toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay}, + { toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, clickFactory: DocCast(doc.emptyWebCam), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a button", title: "Button", icon: "bolt", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)}, { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}}, -- cgit v1.2.3-70-g09d2 From aa71a67ea048ba03654bf56a9793c06f857a863b Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 2 Sep 2023 10:49:04 -0400 Subject: switched web default to wikipedia from bing since bing search requires scripts. change link doc preview to use showDocument instead of addDocTab so that existing docs can be found. --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 4 +++- src/client/views/nodes/LinkDocPreview.tsx | 8 +++++++- src/client/views/nodes/WebBox.tsx | 3 +-- 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src/client/util') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 919958b24..bfb07325d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1084,7 +1084,7 @@ export namespace Docs { const nwid = options._nativeWidth || undefined; const nhght = options._nativeHeight || undefined; if (!nhght && width && height && nwid) options._nativeHeight = (Number(nwid) * Number(height)) / Number(width); - return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url ? url : 'http://www.bing.com/'), options); + return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url ? url : 'https://www.wikipedia.org/'), options); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 11cc5f900..af0f62c0f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -8,7 +8,7 @@ import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; import { ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types"; -import { nullAudio } from "../../fields/URLField"; +import { nullAudio, URLField, WebField } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; import { addStyleSheetRule, OmitKeys, Utils } from "../../Utils"; @@ -913,6 +913,8 @@ export class CurrentUserUtils { Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs) Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed) + Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org") + if (doc.activeDashboard instanceof Doc) { // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme; diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 42c8ea6a4..0ee83bc08 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -19,6 +19,7 @@ import { Transform } from '../../util/Transform'; import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView'; import './LinkDocPreview.scss'; import React = require('react'); +import { DocumentManager } from '../../util/DocumentManager'; interface LinkDocPreviewProps { linkDoc?: Doc; @@ -176,7 +177,12 @@ export class LinkDocPreview extends React.Component { const webDoc = Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this.props.hrefs[0]).keys()).lastElement() ?? Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true }); - this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox); + DocumentManager.Instance.showDocument(webDoc, { + openLocation: OpenWhere.lightbox, + willPan: true, + zoomTime: 500, + }); + //this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox); } }; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index a4fac977c..1435dff7c 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -364,14 +364,13 @@ export class WebBox extends ViewBoxAnnotatableComponent { - const sel = this._iframe?.contentWindow?.getSelection?.(); const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!); const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale; const word = getWordAtPoint(e.target, e.clientX, e.clientY); this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale]); - if (word || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) { + if (word || !Object.keys(e.target as any).includes('className') || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) { setTimeout( action(() => (this._marqueeing = undefined)), 100 -- cgit v1.2.3-70-g09d2 From 6a79d66fd3efb478369981661817f51ec9a7f2c7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 4 Sep 2023 13:56:20 -0400 Subject: fixed video import after youtube changes to urls --- src/client/util/DocumentManager.ts | 2 -- src/client/views/collections/CollectionSubView.tsx | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index c2827dac7..28ca37611 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -101,8 +101,6 @@ export class DocumentManager { }) ); this.LinkAnchorBoxViews.push(view); - // this.LinkedDocumentViews.forEach(view => console.log(" LV = " + view.a.props.Document.title + "/" + view.a.props.LayoutTemplateString + " --> " + - // view.b.props.Document.title + "/" + view.b.props.LayoutTemplateString)); } else { this.AddDocumentView(view); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index eb4685834..54a60271a 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -298,7 +298,7 @@ export function CollectionSubView(moreProps?: X) { let source = split; if (split.startsWith('data:image') && split.includes('base64')) { const [{ accessPaths }] = await Networking.PostToServer('/uploadRemoteImage', { sources: [split] }); - if (accessPaths.agnostic.client.indexOf("dashblobstore") === -1) { + if (accessPaths.agnostic.client.indexOf('dashblobstore') === -1) { source = Utils.prepend(accessPaths.agnostic.client); } else { source = accessPaths.agnostic.client; @@ -347,10 +347,10 @@ export function CollectionSubView(moreProps?: X) { } if (uriList || text) { - if ((uriList || text).includes('www.youtube.com/watch') || text.includes('www.youtube.com/embed')) { + if ((uriList || text).includes('www.youtube.com/watch') || text.includes('www.youtube.com/embed') || text.includes('www.youtube.com/shorts')) { const batch = UndoManager.StartBatch('youtube upload'); const generatedDocuments: Doc[] = []; - this.slowLoadDocuments((uriList || text).split('v=')[1].split('&')[0], options, generatedDocuments, text, completed, addDocument).then(batch.end); + this.slowLoadDocuments((uriList || text).split('v=').lastElement().split('&')[0].split('shorts/').lastElement(), options, generatedDocuments, text, completed, addDocument).then(batch.end); return; } -- cgit v1.2.3-70-g09d2 From a63ab5802551887f62265d420b7c5e925b5cd7d6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 5 Sep 2023 01:26:54 -0400 Subject: added ui for specifying wehther to play a/v when following links, and cleaned up ui/etc for pres trails. fixed a bunch of colors in pres properties. fixed a/v anchors to be configs when not adding them to the doc, otherwise labels. --- src/client/util/DocumentManager.ts | 5 +- src/client/util/LinkFollower.ts | 1 + src/client/views/MainView.tsx | 2 +- src/client/views/PropertiesView.tsx | 14 +- src/client/views/UndoStack.tsx | 69 ++++---- .../collections/CollectionStackedTimeline.tsx | 6 +- src/client/views/collections/TabDocView.tsx | 6 +- src/client/views/nodes/AudioBox.tsx | 28 +-- src/client/views/nodes/DocumentView.tsx | 1 + src/client/views/nodes/FontIconBox/FontIconBox.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 13 +- src/client/views/nodes/trails/PresBox.scss | 6 - src/client/views/nodes/trails/PresBox.tsx | 192 ++++++++++++++------- src/client/views/selectedDoc/SelectedDocView.tsx | 61 +++---- 14 files changed, 244 insertions(+), 161 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 28ca37611..bfe0e1b48 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -1,9 +1,9 @@ -import { action, computed, observable, ObservableSet, observe, reaction } from 'mobx'; +import { action, computed, observable, ObservableSet, observe } from 'mobx'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclEdit, Animation } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { listSpec } from '../../fields/Schema'; -import { Cast, DocCast, StrCast } from '../../fields/Types'; +import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { AudioField } from '../../fields/URLField'; import { GetEffectiveAcl } from '../../fields/util'; import { CollectionViewType } from '../documents/DocumentTypes'; @@ -323,6 +323,7 @@ export class DocumentManager { if (docView.ComponentView instanceof FormattedTextBox) docView.ComponentView?.focus(viewSpec, options); PresBox.restoreTargetDocView(docView, viewSpec, options.zoomTime ?? 500); Doc.linkFollowHighlight(viewSpec ? [docView.rootDoc, viewSpec] : docView.rootDoc, undefined, options.effect); + if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.rootDoc._layout_currentTimecode)); if (options.playAudio) DocumentManager.playAudioAnno(docView.rootDoc); if (options.toggleTarget && (!options.didMove || docView.rootDoc.hidden)) docView.rootDoc.hidden = !docView.rootDoc.hidden; if (options.effect) docView.rootDoc[Animation] = options.effect; diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts index b8fea340f..2fc811b09 100644 --- a/src/client/util/LinkFollower.ts +++ b/src/client/util/LinkFollower.ts @@ -73,6 +73,7 @@ export class LinkFollower { const toggleTarget = canToggle && BoolCast(sourceDoc.followLinkToggle); const options: DocFocusOptions = { playAudio: BoolCast(sourceDoc.followLinkAudio), + playMedia: BoolCast(sourceDoc.followLinkVideo), toggleTarget, noSelect: true, willPan: true, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 7ae9a374d..c8b89c1d5 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -805,7 +805,7 @@ export class MainView extends React.Component { {this.dockingContent} {this._hideUI ? null : ( -
+
)} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 5f9439cbc..01329b482 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1538,6 +1538,16 @@ export class PropertiesView extends React.Component {
+
+

Play Target Video

+ +

Zoom Text Selections

- {this.openPresVisibilityAndDuration ?
{PresBox.Instance.visibiltyDurationDropdown}
: null} + {this.openPresVisibilityAndDuration ?
{PresBox.Instance.visibilityDurationDropdown}
: null}
)} {!selectedItem ? null : ( diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index 47853b5e4..1afd5ad22 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -8,6 +8,7 @@ import { Doc } from '../../fields/Doc'; import { Popup, Type, isDark } from 'browndash-components'; import { Colors } from './global/globalEnums'; import { SettingsManager } from '../util/SettingsManager'; +import { Tooltip } from '@mui/material'; interface UndoStackProps { width?: number; @@ -22,39 +23,43 @@ export class UndoStack extends React.Component { const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor; const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor; return this.props.inline && UndoStack.HideInline ? null : ( -
- r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} - style={{ - background, - color, - }}> - {UndoManager.undoStackNames.map((name, i) => ( -
-
{StrCast(name).replace(/[^\.]*\./, '')}
-
- ))} - {Array.from(UndoManager.redoStackNames) - .reverse() - .map((name, i) => ( -
-
- {StrCast(name).replace(/[^\.]*\./, '')} + +
+
+ r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} + style={{ + background, + color, + }}> + {UndoManager.undoStackNames.map((name, i) => ( +
+
{StrCast(name).replace(/[^\.]*\./, '')}
-
- ))} -
- } - /> -
+ ))} + {Array.from(UndoManager.redoStackNames) + .reverse() + .map((name, i) => ( +
+
+ {StrCast(name).replace(/[^\.]*\./, '')} +
+
+ ))} +
+ } + /> +
+
+ ); } } diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index d2be70577..0a5a80936 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -32,7 +32,7 @@ import './CollectionStackedTimeline.scss'; export type CollectionStackedTimelineProps = { Play: () => void; Pause: () => void; - playLink: (linkDoc: Doc) => void; + playLink: (linkDoc: Doc, options: DocFocusOptions) => void; playFrom: (seekTimeInSeconds: number, endTime?: number) => void; playing: () => boolean; setTime: (time: number) => void; @@ -677,7 +677,7 @@ interface StackedTimelineAnchorProps { height: number; toTimeline: (screen_delta: number, width: number) => number; styleProvider?: (doc: Opt, props: Opt, property: string) => any; - playLink: (linkDoc: Doc) => void; + playLink: (linkDoc: Doc, options: DocFocusOptions) => void; setTime: (time: number) => void; startTag: string; endTag: string; @@ -793,7 +793,7 @@ class StackedTimelineAnchor extends React.Component renderInner = computedFn(function (this: StackedTimelineAnchor, mark: Doc, script: undefined | (() => ScriptField), doublescript: undefined | (() => ScriptField), screenXf: () => Transform, width: () => number, height: () => number) { const anchor = observable({ view: undefined as any }); const focusFunc = (doc: Doc, options: DocFocusOptions): number | undefined => { - this.props.playLink(mark); + this.props.playLink(mark, options); return undefined; }; return { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index f6acafa95..6cdb84dea 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -278,10 +278,8 @@ export class TabDocView extends React.Component { if (pinProps.pinViewport) PresBox.pinDocView(pinDoc, pinProps, anchorDoc ?? doc); if (!pinProps?.audioRange && duration !== undefined) { - pinDoc.mediaStart = 'manual'; - pinDoc.mediaStop = 'manual'; - pinDoc.config_clipStart = NumCast(doc.clipStart); - pinDoc.config_clipEnd = NumCast(doc.clipEnd, duration); + pinDoc.presentation_mediaStart = 'manual'; + pinDoc.presentation_mediaStop = 'manual'; } if (pinProps?.activeFrame !== undefined) { pinDoc.config_activeFrame = pinProps?.activeFrame; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 7c409c38c..50b2432d2 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -8,7 +8,7 @@ import { ComputedField } from '../../../fields/ScriptField'; import { Cast, DateCast, NumCast } from '../../../fields/Types'; import { AudioField, nullAudio } from '../../../fields/URLField'; import { emptyFunction, formatTime, returnFalse, setupMoveUpEvents } from '../../../Utils'; -import { DocUtils } from '../../documents/Documents'; +import { Docs, DocUtils } from '../../documents/Documents'; import { Networking } from '../../Network'; import { DragManager } from '../../util/DragManager'; import { LinkManager } from '../../util/LinkManager'; @@ -20,6 +20,7 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComp import './AudioBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import { PinProps, PresBox } from './trails'; +import { DocFocusOptions } from './DocumentView'; /** * AudioBox @@ -134,16 +135,19 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - const anchor = - CollectionStackedTimeline.createAnchor( - this.rootDoc, - this.dataDoc, - this.annotationKey, - this._ele?.currentTime || Cast(this.props.Document._layout_currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined), - undefined, - undefined, - addAsAnnotation - ) || this.rootDoc; + const timecode = Cast(this.layoutDoc._layout_currentTimecode, 'number', null); + const anchor = addAsAnnotation + ? CollectionStackedTimeline.createAnchor( + this.rootDoc, + this.dataDoc, + this.annotationKey, + this._ele?.currentTime || Cast(this.props.Document._layout_currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined), + undefined, + undefined, + addAsAnnotation + ) || this.rootDoc + : Docs.Create.ConfigDocument({ title: '#' + timecode, _timecodeToShow: timecode, annotationOn: this.rootDoc }); + PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), temporal: true } }, this.rootDoc); return anchor; }; @@ -418,7 +422,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + playLink = (link: Doc, options: DocFocusOptions) => { if (link.annotationOn === this.rootDoc) { if (!this.layoutDoc.dontAutoPlayFollowedLinks) { this.playFrom(this.timeline?.anchorStart(link) || 0, this.timeline?.anchorEnd(link)); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 998024cea..f7773ff18 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -100,6 +100,7 @@ export interface DocFocusOptions { effect?: Doc; // animation effect for focus noSelect?: boolean; // whether target should be selected after focusing playAudio?: boolean; // whether to play audio annotation on focus + playMedia?: boolean; // whether to play start target videos openLocation?: OpenWhere; // where to open a missing document zoomTextSelections?: boolean; // whether to display a zoomed overlay of anchor text selections toggleTarget?: boolean; // whether to toggle target on and off diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index ea7c2de82..1eb6fd51c 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -19,7 +19,6 @@ import { SelectedDocView } from '../../selectedDoc'; import { StyleProp } from '../../StyleProvider'; import { OpenWhere } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import { RichTextMenu } from '../formattedText/RichTextMenu'; import './FontIconBox.scss'; import TrailsIcon from './TrailsIcon'; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 56508abf6..9d9aa8a4b 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -29,7 +29,7 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComp import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { AnchorMenu } from '../pdf/AnchorMenu'; import { StyleProp } from '../StyleProvider'; -import { DocumentView, OpenWhere } from './DocumentView'; +import { DocFocusOptions, DocumentView, OpenWhere } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { RecordingBox } from './RecordingBox'; import { PinProps, PresBox } from './trails'; @@ -385,7 +385,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.timeline?.setZoom(zoom); // plays link - playLink = (doc: Doc) => { - const startTime = Math.max(0, this._stackedTimeline?.anchorStart(doc) || 0); + playLink = (doc: Doc, options: DocFocusOptions) => { + const startTime = Math.max(0, NumCast(doc.config_clipStart, this._stackedTimeline?.anchorStart(doc) || 0)); const endTime = this.timeline?.anchorEnd(doc); if (startTime !== undefined) { - if (!this.layoutDoc.dontAutoPlayFollowedLinks) endTime ? this.playFrom(startTime, endTime) : this.playFrom(startTime); + if (options.playMedia) endTime ? this.playFrom(startTime, endTime) : this.playFrom(startTime); else this.Seek(startTime); } }; @@ -1038,7 +1040,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent this._savedAnnotations; render() { const borderRad = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding); diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss index bf56b4d9e..31a003144 100644 --- a/src/client/views/nodes/trails/PresBox.scss +++ b/src/client/views/nodes/trails/PresBox.scss @@ -187,9 +187,6 @@ font-size: 11; font-weight: 200; height: 20; - background-color: $white; - color: $black; - border: solid 1px $black; display: flex; margin-left: 5px; margin-top: 5px; @@ -210,13 +207,11 @@ .ribbon-propertyUpDownItem { cursor: pointer; - color: white; display: flex; justify-content: center; align-items: center; height: 100%; width: 100%; - background: $black; } .ribbon-propertyUpDownItem:hover { @@ -609,7 +604,6 @@ font-weight: 200; height: 20; background-color: $white; - border: solid 1px rgba(0, 0, 0, 0.5); display: flex; color: $black; margin-top: 5px; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 92c130ea1..48f376075 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -391,11 +391,11 @@ export class PresBox extends ViewBoxBaseComponent() { if (from?.mediaStopTriggerList && this.layoutDoc.presentation_status !== PresStatus.Edit) { DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia); } - if (from?.mediaStop === 'auto' && this.layoutDoc.presentation_status !== PresStatus.Edit) { + if (from?.presentation_mediaStop === 'auto' && this.layoutDoc.presentation_status !== PresStatus.Edit) { this.stopTempMedia(from.presentation_targetDoc); } // If next slide is audio / video 'Play automatically' then the next slide should be played - if (this.layoutDoc.presentation_status !== PresStatus.Edit && (this.targetDoc.type === DocumentType.AUDIO || this.targetDoc.type === DocumentType.VID) && this.activeItem.mediaStart === 'auto') { + if (this.layoutDoc.presentation_status !== PresStatus.Edit && (this.targetDoc.type === DocumentType.AUDIO || this.targetDoc.type === DocumentType.VID) && this.activeItem.presentation_mediaStart === 'auto') { this.startTempMedia(this.targetDoc, this.activeItem); } if (!group) this.clearSelectedArray(); @@ -798,8 +798,9 @@ export class PresBox extends ViewBoxBaseComponent() { easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any, zoomTextSelections: BoolCast(activeItem.presentation_zoomText), playAudio: BoolCast(activeItem.presPlayAudio), + playMedia: activeItem.presentation_mediaStart === 'auto', }; - if (activeItem.presOpenInLightbox) { + if (activeItem.presentation_openInLightbox) { const context = DocCast(targetDoc.annotationOn) ?? targetDoc; if (!DocumentManager.Instance.getLightboxDocumentView(context)) { LightboxView.SetLightboxDoc(context); @@ -1075,8 +1076,6 @@ export class PresBox extends ViewBoxBaseComponent() { if (doc.type === DocumentType.LABEL) { const audio = Cast(doc.annotationOn, Doc, null); if (audio) { - audio.mediaStart = 'manual'; - audio.mediaStop = 'manual'; audio.config_clipStart = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */)); audio.config_clipEnd = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */)); audio.presentation_duration = audio.config_clipStart - audio.config_clipEnd; @@ -1472,8 +1471,8 @@ export class PresBox extends ViewBoxBaseComponent() { @undoBatch @action updateOpenDoc = (activeItem: Doc) => { - activeItem.presOpenInLightbox = !activeItem.presOpenInLightbox; - this.selectedArray.forEach(doc => (doc.presOpenInLightbox = activeItem.presOpenInLightbox)); + activeItem.presentation_openInLightbox = !activeItem.presentation_openInLightbox; + this.selectedArray.forEach(doc => (doc.presentation_openInLightbox = activeItem.presentation_openInLightbox)); }; @undoBatch @@ -1501,7 +1500,7 @@ export class PresBox extends ViewBoxBaseComponent() { max={max} value={value} readOnly={true} - style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)` }} + style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)`, background: SettingsManager.userColor, color: SettingsManager.userVariantColor }} className={`toolbar-slider ${active ? '' : 'none'}`} onPointerDown={e => { PresBox._sliderBatch = UndoManager.StartBatch('pres slider'); @@ -1532,7 +1531,7 @@ export class PresBox extends ViewBoxBaseComponent() { }); }; - @computed get visibiltyDurationDropdown() { + @computed get visibilityDurationDropdown() { const activeItem = this.activeItem; if (activeItem && this.targetDoc) { const targetType = this.targetDoc.type; @@ -1541,30 +1540,49 @@ export class PresBox extends ViewBoxBaseComponent() { return (
- {'Hide before presented'}
}> -
this.updateHideBefore(activeItem)}> + Hide before presented
}> +
this.updateHideBefore(activeItem)}> Hide before
{'Hide while presented'}
}> -
this.updateHide(activeItem)}> +
this.updateHide(activeItem)}> Hide
{'Hide after presented'}
}> -
this.updateHideAfter(activeItem)}> +
this.updateHideAfter(activeItem)}> Hide after
{'Open in lightbox view'}
}> -
this.updateOpenDoc(activeItem)}> +
this.updateOpenDoc(activeItem)}> Lightbox
- {'Transition movement style'}
}> -
this.updateEaseFunc(activeItem)}> + Transition movement style
}> +
this.updateEaseFunc(activeItem)}> {`${StrCast(activeItem.presEaseFunc, 'ease')}`}
@@ -1573,10 +1591,10 @@ export class PresBox extends ViewBoxBaseComponent() { <>
Slide Duration
-
+
e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s
-
+
this.updateDurationTime(String(duration), 1000)}>
@@ -1615,7 +1633,7 @@ export class PresBox extends ViewBoxBaseComponent() {
Progressivize Collection
{ activeItem.presentation_indexed = activeItem.presentation_indexed === undefined ? 0 : undefined; @@ -1638,7 +1656,7 @@ export class PresBox extends ViewBoxBaseComponent() {
Progressivize First Bullet
(activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1)} checked={!NumCast(activeItem.presentation_indexedStart)} @@ -1646,7 +1664,13 @@ export class PresBox extends ViewBoxBaseComponent() {
Expand Current Bullet
- (activeItem.presBulletExpand = !activeItem.presBulletExpand)} checked={BoolCast(activeItem.presBulletExpand)} /> + (activeItem.presBulletExpand = !activeItem.presBulletExpand)} + checked={BoolCast(activeItem.presBulletExpand)} + />
@@ -1657,10 +1681,18 @@ export class PresBox extends ViewBoxBaseComponent() { e.stopPropagation(); this._openBulletEffectDropdown = !this._openBulletEffectDropdown; })} - style={{ borderBottomLeftRadius: this._openBulletEffectDropdown ? 0 : 5, border: this._openBulletEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> + style={{ + color: SettingsManager.userColor, + background: SettingsManager.userVariantColor, + borderBottomLeftRadius: this._openBulletEffectDropdown ? 0 : 5, + border: this._openBulletEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`, + }}> {effect?.toString()} -
e.stopPropagation()}> +
e.stopPropagation()}> {bulletEffect(PresEffect.None)} {bulletEffect(PresEffect.Fade)} {bulletEffect(PresEffect.Flip)} @@ -1725,7 +1757,12 @@ export class PresBox extends ViewBoxBaseComponent() { e.stopPropagation(); this._openMovementDropdown = !this._openMovementDropdown; })} - style={{ borderBottomLeftRadius: this._openMovementDropdown ? 0 : 5, border: this._openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> + style={{ + color: SettingsManager.userColor, + background: SettingsManager.userVariantColor, + borderBottomLeftRadius: this._openMovementDropdown ? 0 : 5, + border: this._openMovementDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`, + }}> {this.movementName(activeItem)}
@@ -1738,10 +1775,10 @@ export class PresBox extends ViewBoxBaseComponent() {
Zoom (% screen filled)
-
+
this.updateZoom(e.target.value)} />%
-
+
this.updateZoom(String(zoom), 0.1)}>
@@ -1753,10 +1790,10 @@ export class PresBox extends ViewBoxBaseComponent() { {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}
Transition Time
-
+
e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s
-
+
this.updateTransitionTime(String(transitionSpeed), 1000)}>
@@ -1776,13 +1813,19 @@ export class PresBox extends ViewBoxBaseComponent() { Effects
Play Audio Annotation
- (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))} checked={BoolCast(activeItem.presPlayAudio)} /> + (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))} + checked={BoolCast(activeItem.presPlayAudio)} + />
Zoom Text Selections
(activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText))} checked={BoolCast(activeItem.presentation_zoomText)} @@ -1794,7 +1837,12 @@ export class PresBox extends ViewBoxBaseComponent() { e.stopPropagation(); this._openEffectDropdown = !this._openEffectDropdown; })} - style={{ borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5, border: this._openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}> + style={{ + color: SettingsManager.userColor, + background: SettingsManager.userVariantColor, + borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5, + border: this._openEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`, + }}> {effect?.toString()}
e.stopPropagation()}> @@ -1808,7 +1856,9 @@ export class PresBox extends ViewBoxBaseComponent() {
Effect direction
-
{StrCast(this.activeItem.presentation_effectDirection)}
+
+ {StrCast(this.activeItem.presentation_effectDirection)} +
{presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})} @@ -1830,8 +1880,10 @@ export class PresBox extends ViewBoxBaseComponent() { @computed get mediaOptionsDropdown() { const activeItem = this.activeItem; if (activeItem && this.targetDoc) { - const clipStart = NumCast(activeItem.clipStart); - const clipEnd = NumCast(activeItem.clipEnd, NumCast(activeItem[Doc.LayoutFieldKey(activeItem) + '_duration'])); + const renderTarget = PresBox.targetRenderedDoc(this.activeItem); + const clipStart = NumCast(renderTarget.clipStart); + const clipEnd = NumCast(renderTarget.clipEnd, clipStart + NumCast(renderTarget[Doc.LayoutFieldKey(renderTarget) + '_duration'])); + const config_clipEnd = NumCast(activeItem.config_clipEnd) < NumCast(activeItem.config_clipStart) ? clipEnd - clipStart : NumCast(activeItem.config_clipEnd); return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -1842,7 +1894,7 @@ export class PresBox extends ViewBoxBaseComponent() {
Start time (s)
-
+
() { readOnly={true} value={NumCast(activeItem.config_clipStart).toFixed(2)} onKeyDown={e => e.stopPropagation()} - onChange={action((e: React.ChangeEvent) => { - activeItem.config_clipStart = Number(e.target.value); - })} + onChange={action(e => (activeItem.config_clipStart = Number(e.target.value)))} />
@@ -1860,25 +1910,23 @@ export class PresBox extends ViewBoxBaseComponent() {
Duration (s)
-
- {Math.round((NumCast(activeItem.config_clipEnd) - NumCast(activeItem.config_clipStart)) * 10) / 10} +
+ {Math.round((config_clipEnd - NumCast(activeItem.config_clipStart)) * 10) / 10}
End time (s)
-
+
e.stopPropagation()} style={{ textAlign: 'center', width: '100%', height: 15, fontSize: 10 }} type="number" readOnly={true} - value={NumCast(activeItem.config_clipEnd).toFixed(2)} - onChange={action((e: React.ChangeEvent) => { - activeItem.config_clipEnd = Number(e.target.value); - })} + value={config_clipEnd.toFixed(2)} + onChange={action(e => (activeItem.config_clipEnd = Number(e.target.value)))} />
@@ -1889,16 +1937,15 @@ export class PresBox extends ViewBoxBaseComponent() { step="0.1" min={clipStart} max={clipEnd} - value={NumCast(activeItem.config_clipEnd)} - style={{ gridColumn: 1, gridRow: 1 }} + value={config_clipEnd} + style={{ gridColumn: 1, gridRow: 1, background: SettingsManager.userColor, color: SettingsManager.userVariantColor }} className={`toolbar-slider ${'end'}`} id="toolbar-slider" onPointerDown={e => { this._batch = UndoManager.StartBatch('config_clipEnd'); const endBlock = document.getElementById('endTime'); if (endBlock) { - endBlock.style.color = Colors.LIGHT_GRAY; - endBlock.style.backgroundColor = Colors.MEDIUM_BLUE; + endBlock.style.backgroundColor = SettingsManager.userVariantColor; } e.stopPropagation(); }} @@ -1906,8 +1953,7 @@ export class PresBox extends ViewBoxBaseComponent() { this._batch?.end(); const endBlock = document.getElementById('endTime'); if (endBlock) { - endBlock.style.color = Colors.BLACK; - endBlock.style.backgroundColor = Colors.LIGHT_GRAY; + endBlock.style.backgroundColor = SettingsManager.userBackgroundColor; } }} onChange={(e: React.ChangeEvent) => { @@ -1928,8 +1974,7 @@ export class PresBox extends ViewBoxBaseComponent() { this._batch = UndoManager.StartBatch('config_clipStart'); const startBlock = document.getElementById('startTime'); if (startBlock) { - startBlock.style.color = Colors.LIGHT_GRAY; - startBlock.style.backgroundColor = Colors.MEDIUM_BLUE; + startBlock.style.backgroundColor = SettingsManager.userVariantColor; } e.stopPropagation(); }} @@ -1937,8 +1982,7 @@ export class PresBox extends ViewBoxBaseComponent() { this._batch?.end(); const startBlock = document.getElementById('startTime'); if (startBlock) { - startBlock.style.color = Colors.BLACK; - startBlock.style.backgroundColor = Colors.LIGHT_GRAY; + startBlock.style.backgroundColor = SettingsManager.userBackgroundColor; } }} onChange={(e: React.ChangeEvent) => { @@ -1958,22 +2002,46 @@ export class PresBox extends ViewBoxBaseComponent() {
Start playing:
- (activeItem.mediaStart = 'manual')} checked={activeItem.mediaStart === 'manual'} /> + (activeItem.presentation_mediaStart = 'manual')} + checked={activeItem.presentation_mediaStart === 'manual'} + />
On click
- (activeItem.mediaStart = 'auto')} checked={activeItem.mediaStart === 'auto'} /> + (activeItem.presentation_mediaStart = 'auto')} + checked={activeItem.presentation_mediaStart === 'auto'} + />
Automatically
Stop playing:
- (activeItem.mediaStop = 'manual')} checked={activeItem.mediaStop === 'manual'} /> -
At audio end time
+ (activeItem.presentation_mediaStop = 'manual')} + checked={activeItem.presentation_mediaStop === 'manual'} + /> +
At media end time
- (activeItem.mediaStop = 'auto')} checked={activeItem.mediaStop === 'auto'} /> + (activeItem.presentation_mediaStop = 'auto')} + checked={activeItem.presentation_mediaStop === 'auto'} + />
On slide change
{/*
@@ -2221,8 +2289,8 @@ export class PresBox extends ViewBoxBaseComponent() { const propTitle = SettingsManager.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel'; const mode = StrCast(this.rootDoc._type_collection) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; - const activeColor = Colors.LIGHT_BLUE; - const inactiveColor = Colors.WHITE; + const activeColor = SettingsManager.userVariantColor; + const inactiveColor = SettingsManager.userColor; return mode === CollectionViewType.Carousel3D || Doc.IsInMyOverlay(this.rootDoc) ? null : (
{/*
{"Add new slide"}
}>
this.newDocumentTools = !this.newDocumentTools)}> diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx index 955a4a174..2139919e0 100644 --- a/src/client/views/selectedDoc/SelectedDocView.tsx +++ b/src/client/views/selectedDoc/SelectedDocView.tsx @@ -1,12 +1,14 @@ import React = require('react'); -import { Doc } from "../../../fields/Doc"; -import { observer } from "mobx-react"; -import { computed } from "mobx"; -import { StrCast } from "../../../fields/Types"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Colors, ListBox } from 'browndash-components'; +import { ListBox } from 'browndash-components'; +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import { Doc } from '../../../fields/Doc'; +import { StrCast } from '../../../fields/Types'; import { DocumentManager } from '../../util/DocumentManager'; import { DocFocusOptions } from '../nodes/DocumentView'; +import { emptyFunction } from '../../../Utils'; +import { SettingsManager } from '../../util/SettingsManager'; export interface SelectedDocViewProps { selectedDocs: Doc[]; @@ -14,34 +16,33 @@ export interface SelectedDocViewProps { @observer export class SelectedDocView extends React.Component { - @computed get selectedDocs() { return this.props.selectedDocs; } - render() { - return
- { - const icon = Doc.toIcon(doc); - const iconEle = ; - const text = StrCast(doc.title) - const finished = () => { - - }; - const options: DocFocusOptions = { - playAudio: false, - }; - return { - text: text, - val: StrCast(doc._id), - icon: iconEle, - onClick: () => {DocumentManager.Instance.showDocument(doc, options, finished);} - } - })} - color={StrCast(Doc.UserDoc().userColor)} - /> -
+ return ( +
+ { + const options: DocFocusOptions = { + playAudio: false, + playMedia: false, + willPan: true, + }; + return { + text: StrCast(doc.title), + val: StrCast(doc._id), + color: SettingsManager.userColor, + background: SettingsManager.userBackgroundColor, + icon: , + onClick: () => DocumentManager.Instance.showDocument(doc, options, emptyFunction), + }; + })} + color={SettingsManager.userColor} + background={SettingsManager.userBackgroundColor} + /> +
+ ); } -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From b5605e12c760af341516f5bc0b0fe4afb14a14ca Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 5 Sep 2023 11:11:11 -0400 Subject: change getAnchor to honor addAsAnnotation so that pinning docs doesn't add to annotation list. fixed dragging anchor menu icons so that they appear. --- src/client/util/DocumentManager.ts | 5 +- src/client/views/DocComponent.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 + src/client/views/nodes/DocumentView.tsx | 1 + src/client/views/nodes/ImageBox.tsx | 7 +- src/client/views/nodes/WebBox.tsx | 6 +- src/client/views/pdf/AnchorMenu.tsx | 122 +++++---------------- 7 files changed, 39 insertions(+), 106 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index bfe0e1b48..b9f6059f4 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -11,7 +11,6 @@ import { CollectionDockingView } from '../views/collections/CollectionDockingVie import { TabDocView } from '../views/collections/TabDocView'; import { LightboxView } from '../views/LightboxView'; import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from '../views/nodes/DocumentView'; -import { FormattedTextBox } from '../views/nodes/formattedText/FormattedTextBox'; import { KeyValueBox } from '../views/nodes/KeyValueBox'; import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox'; import { PresBox } from '../views/nodes/trails'; @@ -320,7 +319,9 @@ export class DocumentManager { @action restoreDocView(viewSpec: Opt, docView: DocumentView, options: DocFocusOptions, contextView: Opt, targetDoc: Doc) { if (viewSpec && docView) { - if (docView.ComponentView instanceof FormattedTextBox) docView.ComponentView?.focus(viewSpec, options); + //if (docView.ComponentView instanceof FormattedTextBox) + //viewSpec !== docView.rootDoc && + docView.ComponentView?.focus?.(viewSpec, options); PresBox.restoreTargetDocView(docView, viewSpec, options.zoomTime ?? 500); Doc.linkFollowHighlight(viewSpec ? [docView.rootDoc, viewSpec] : docView.rootDoc, undefined, options.effect); if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.rootDoc._layout_currentTimecode)); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 6a1efdf9c..483b92957 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -139,7 +139,7 @@ export function ViewBoxAnnotatableComponent

() const indocs = doc instanceof Doc ? [doc] : doc; const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin); - docs.forEach(doc => doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true)); + // docs.forEach(doc => doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true)); const targetDataDoc = this.dataDoc; const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]); const toRemove = value.filter(v => docs.includes(v)); @@ -194,6 +194,7 @@ export function ViewBoxAnnotatableComponent

() added.forEach(doc => { doc._dragOnlyWithinContainer = undefined; if (annotationKey ?? this._annotationKeySuffix()) Doc.GetProto(doc).annotationOn = this.rootDoc; + else Doc.GetProto(doc).annotationOn = undefined; Doc.SetContainer(doc, this.rootDoc); inheritParentAcls(targetDataDoc, doc, true); }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 16d6f1270..7768ca547 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -311,6 +311,7 @@ export class CollectionFreeFormView extends CollectionSubView { if (this._lightboxDoc) return; + if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor)) return; const xfToCollection = options?.docTransform ?? Transform.Identity(); const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined }; const cantTransform = this.fitContentsToBox || ((this.rootDoc._isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f7773ff18..ab99f3c6d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -121,6 +121,7 @@ export interface DocComponentView { reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitContentsToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling. shrinkWrap?: () => void; // requests a document to display all of its contents with no white space. currently only implemented (needed?) for freeform views select?: (ctrlKey: boolean, shiftKey: boolean) => void; + focus?: (textAnchor: Doc, options: DocFocusOptions) => Opt; menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected. isAnyChildContentActive?: () => boolean; // is any child content of the document active onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index f5c6a9273..a19cc3555 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -85,8 +85,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent { + const visibleAnchor = this._getAnchor?.(this._savedAnnotations, false); // use marquee anchor, otherwise, save zoom/pan as anchor const anchor = - this._getAnchor?.(this._savedAnnotations, false) ?? // use marquee anchor, otherwise, save zoom/pan as anchor + visibleAnchor ?? Docs.Create.ConfigDocument({ title: 'ImgAnchor:' + this.rootDoc.title, config_panX: NumCast(this.layoutDoc._freeform_panX), @@ -96,8 +97,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent { static Instance: AnchorMenu; private _disposer: IReactionDisposer | undefined; - private _disposer2: IReactionDisposer | undefined; - private _commentCont = React.createRef(); - private _palette = [ - 'rgba(208, 2, 27, 0.8)', - 'rgba(238, 0, 0, 0.8)', - 'rgba(245, 166, 35, 0.8)', - 'rgba(248, 231, 28, 0.8)', - 'rgba(245, 230, 95, 0.616)', - 'rgba(139, 87, 42, 0.8)', - 'rgba(126, 211, 33, 0.8)', - 'rgba(65, 117, 5, 0.8)', - 'rgba(144, 19, 254, 0.8)', - 'rgba(238, 169, 184, 0.8)', - 'rgba(224, 187, 228, 0.8)', - 'rgba(225, 223, 211, 0.8)', - 'rgba(255, 255, 255, 0.8)', - 'rgba(155, 155, 155, 0.8)', - 'rgba(0, 0, 0, 0.8)', - ]; + private _commentRef = React.createRef(); + private _cropRef = React.createRef(); @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)'; @observable public Status: 'marquee' | 'annotation' | '' = ''; // GPT additions - @observable private GPTMode: GPTPopupMode = GPTPopupMode.SUMMARY; @observable private selectedText: string = ''; - @observable private editorView?: EditorView; - @observable private textDoc?: Doc; - @observable private highlightRange: number[] | undefined; - private selectionRange: number[] | undefined; - - @action - setGPTMode = (mode: GPTPopupMode) => { - this.GPTMode = mode; - }; - @action - setHighlightRange(r: number[] | undefined) { - this.highlightRange = r; - } - - @action - public setSelectedText = (txt: string) => { - this.selectedText = txt; - }; - - @action - public setEditorView = (editor: EditorView) => { - this.editorView = editor; - }; - - @action - public setTextDoc = (textDoc: Doc) => { - this.textDoc = textDoc; - }; + public setSelectedText = (txt: string) => (this.selectedText = txt); public onMakeAnchor: () => Opt = () => undefined; // Method to get anchor from text search @@ -105,20 +60,12 @@ export class AnchorMenu extends AntimodeMenu { componentWillUnmount() { this._disposer?.(); - this._disposer2?.(); } componentDidMount() { - this._disposer2 = reaction( - () => this._opacity, - opacity => {}, - { fireImmediately: true } - ); this._disposer = reaction( () => SelectionManager.Views().slice(), - selected => { - AnchorMenu.Instance.fadeOut(true); - } + selected => AnchorMenu.Instance.fadeOut(true) ); } @@ -129,17 +76,12 @@ export class AnchorMenu extends AntimodeMenu { gptSummarize = async (e: React.PointerEvent) => { // move this logic to gptpopup, need to implement generate again GPTPopup.Instance.setVisible(true); - this.setHighlightRange(undefined); GPTPopup.Instance.setMode(GPTPopupMode.SUMMARY); GPTPopup.Instance.setLoading(true); try { const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY); - if (res) { - GPTPopup.Instance.setText(res); - } else { - GPTPopup.Instance.setText('Something went wrong.'); - } + GPTPopup.Instance.setText(res || 'Something went wrong.'); } catch (err) { console.error(err); } @@ -151,7 +93,7 @@ export class AnchorMenu extends AntimodeMenu { this, e, (e: PointerEvent) => { - this.StartDrag(e, this._commentCont.current!); + this.StartDrag(e, this._commentRef.current!); return true; }, returnFalse, @@ -168,7 +110,7 @@ export class AnchorMenu extends AntimodeMenu { this, e, (e: PointerEvent) => { - this.StartCropDrag(e, this._commentCont.current!); + this.StartCropDrag(e, this._cropRef.current!); return true; }, returnFalse, @@ -214,37 +156,21 @@ export class AnchorMenu extends AntimodeMenu { * all selected text available to summarize but its only supported for pdf and web ATM. * @returns Whether the GPT icon for summarization should appear */ - canSummarize = (): boolean => { - const docs = SelectionManager.Docs(); - if (docs.length > 0) { - return docs.some(doc => doc.type === DocumentType.PDF || doc.type === DocumentType.WEB); - } - return false; - }; - - /** - * Returns whether the selected text can be edited. - * @returns Whether the GPT icon for summarization should appear - */ - canEdit = (): boolean => { - const docs = SelectionManager.Docs(); - if (docs.length > 0) { - return docs.some(doc => doc.type === 'rtf'); - } - return false; - }; + canSummarize = () => SelectionManager.Docs().some(doc => [DocumentType.PDF, DocumentType.WEB].includes(doc.type as any)); render() { const buttons = this.Status === 'marquee' ? ( <> {this.highlighter} - } - color={StrCast(Doc.UserDoc().userColor)} - /> +

+ } + color={SettingsManager.userColor} + /> +
{/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/} {AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && ( { color={StrCast(Doc.UserDoc().userColor)} /> {AnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : ( - } - color={StrCast(Doc.UserDoc().userColor)} - /> +
+ } + color={StrCast(Doc.UserDoc().userColor)} + /> +
)} ) : ( -- cgit v1.2.3-70-g09d2 From 530294ae0b4721f07ddbfdd584ed91ff07cdc5e3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Sep 2023 12:11:23 -0400 Subject: added undo for removing dashboards and add to recently closed. fixed link menu to open up link editor more direclty --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/RTFMarkup.tsx | 2 +- src/client/util/SelectionManager.ts | 5 +- src/client/util/ServerStats.tsx | 2 +- src/client/views/DashboardView.tsx | 12 ++-- src/client/views/MainView.tsx | 2 +- .../views/PropertiesDocBacklinksSelector.tsx | 7 ++- src/client/views/PropertiesView.scss | 6 ++ src/client/views/PropertiesView.tsx | 71 ++++++++++++++-------- src/client/views/collections/TabDocView.tsx | 4 +- src/client/views/linking/LinkMenuItem.tsx | 15 +++-- 11 files changed, 81 insertions(+), 47 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index af0f62c0f..836160265 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -488,7 +488,7 @@ export class CurrentUserUtils { const contextMenuLabels = [/*"Create New Dashboard"*/] as string[]; const contextMenuIcons = [/*"plus"*/] as string[]; const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters - const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts const childContextMenuLabels = ["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters const childContextMenuIcons = ["chalkboard", "tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx index 78069d323..9dd14a3c3 100644 --- a/src/client/util/RTFMarkup.tsx +++ b/src/client/util/RTFMarkup.tsx @@ -33,7 +33,7 @@ export class RTFMarkup extends React.Component<{}> { */ @computed get cheatSheet() { return ( -
+

{`wiki:phrase`} {` display wikipedia page for entered text (terminate with carriage return)`} diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index dbf33fcf5..d0f66d124 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -26,9 +26,6 @@ export namespace SelectionManager { // if doc is not in SelectedDocuments, add it if (!manager.SelectedViewsMap.get(docView)) { if (!ctrlPressed) { - if (LinkManager.currentLink && !LinkManager.Links(docView.rootDoc).includes(LinkManager.currentLink) && docView.rootDoc !== LinkManager.currentLink) { - LinkManager.currentLink = undefined; - } this.DeselectAll(); } @@ -54,6 +51,8 @@ export namespace SelectionManager { } @action DeselectAll(): void { + LinkManager.currentLink = undefined; + LinkManager.currentLinkAnchor = undefined; manager.SelectedSchemaDocument = undefined; Array.from(manager.SelectedViewsMap.keys()).forEach(dv => dv.props.whenChildContentsActiveChanged(false)); manager.SelectedViewsMap.clear(); diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx index 3c7c35a7e..ac9fecd5c 100644 --- a/src/client/util/ServerStats.tsx +++ b/src/client/util/ServerStats.tsx @@ -48,7 +48,7 @@ export class ServerStats extends React.Component<{}> { display: 'flex', height: 300, width: 400, - background: SettingsManager.Instance?.userBackgroundColor, + background: SettingsManager.userBackgroundColor, opacity: 0.6, }}>

diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 3ef6c0814..34c752eec 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -18,7 +18,7 @@ import { CollectionViewType } from '../documents/DocumentTypes'; import { HistoryUtil } from '../util/History'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { SharingManager } from '../util/SharingManager'; -import { undoBatch, UndoManager } from '../util/UndoManager'; +import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { CollectionView } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; @@ -270,6 +270,7 @@ export class DashboardView extends React.Component { public static openDashboard = (doc: Doc | undefined, fromHistory = false) => { if (!doc) return false; Doc.AddDocToList(Doc.MyDashboards, 'data', doc); + Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', doc); // this has the side-effect of setting the main container since we're assigning the active/guest dashboard Doc.UserDoc() ? (Doc.ActiveDashboard = doc) : (Doc.GuestDashboard = doc); @@ -307,9 +308,12 @@ export class DashboardView extends React.Component { public static removeDashboard = async (dashboard: Doc) => { const dashboards = await DocListCastAsync(Doc.MyDashboards.data); if (dashboards?.length) { - if (dashboard === Doc.ActiveDashboard) DashboardView.openDashboard(dashboards.find(doc => doc !== dashboard)); - Doc.RemoveDocFromList(Doc.MyDashboards, 'data', dashboard); - if (!dashboards.length) Doc.ActivePage = 'home'; + undoable(() => { + if (dashboard === Doc.ActiveDashboard) DashboardView.openDashboard(dashboards.find(doc => doc !== dashboard)); + Doc.RemoveDocFromList(Doc.MyDashboards, 'data', dashboard); + Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', dashboard, undefined, true, true); + if (!dashboards.length) Doc.ActivePage = 'home'; + }, 'remove dashboard')(); } }; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index c8b89c1d5..8adb28fe1 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -696,7 +696,7 @@ export class MainView extends React.Component { switch (whereFields[0]) { case OpenWhere.lightbox: return LightboxView.AddDocTab(doc, location); case OpenWhere.close: return CollectionDockingView.CloseSplit(doc, whereMods); - case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(doc, whereMods); + case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(doc, whereMods, undefined, "dontSelectOnActivate"); // bcz: hack! mark the toggle so that it won't be selected on activation- this is needed so that the backlinks menu can toggle views of targets on and off without selecting them case OpenWhere.add:default:return CollectionDockingView.AddSplit(doc, whereMods, undefined, undefined, keyValue); } }; diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx index 91a7b3da3..2d1e46361 100644 --- a/src/client/views/PropertiesDocBacklinksSelector.tsx +++ b/src/client/views/PropertiesDocBacklinksSelector.tsx @@ -1,3 +1,4 @@ +import { action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc } from '../../fields/Doc'; @@ -19,16 +20,16 @@ type PropertiesDocBacklinksSelectorProps = { @observer export class PropertiesDocBacklinksSelector extends React.Component { - getOnClick = (link: Doc) => { + getOnClick = action((link: Doc) => { const linkAnchor = this.props.Document; const other = LinkManager.getOppositeAnchor(link, linkAnchor); const otherdoc = !other ? undefined : other.annotationOn && other.type !== DocumentType.RTF ? Cast(other.annotationOn, Doc, null) : other; - + LinkManager.currentLink = link; if (otherdoc) { otherdoc.hidden = false; this.props.addDocTab(Doc.IsDataProto(otherdoc) ? Doc.MakeDelegate(otherdoc) : otherdoc, OpenWhere.toggleRight); } - }; + }); render() { return !SelectionManager.Views().length ? null : ( diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index b116a622c..510defce4 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -26,6 +26,12 @@ display: flex; flex-direction: row; } + .propertiesView-titleExtender { + text-overflow: ellipsis; + max-width: 100%; + white-space: pre; + overflow: hidden; + } overflow-x: hidden; overflow-y: auto; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 01329b482..6f1461fea 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -3,14 +3,12 @@ import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@material-ui/core'; -import { Button, Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; +import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; -import { Lambda, action, computed, observable } from 'mobx'; +import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { ColorState, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" -import { GrCircleInformation } from 'react-icons/gr'; -import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils'; import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData, Height, Width } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -18,28 +16,29 @@ import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; import { ComputedField } from '../../fields/ScriptField'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; -import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util'; +import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { DocumentManager } from '../util/DocumentManager'; import { GroupManager } from '../util/GroupManager'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; +import { SettingsManager } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { UndoManager, undoBatch, undoable } from '../util/UndoManager'; +import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; import { EditableView } from './EditableView'; import { FilterPanel } from './FilterPanel'; import { InkStrokeProperties } from './InkStrokeProperties'; +import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; +import { KeyValueBox } from './nodes/KeyValueBox'; +import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; import { PropertiesButtons } from './PropertiesButtons'; import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector'; import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; import { DefaultStyleProvider } from './StyleProvider'; -import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; -import { KeyValueBox } from './nodes/KeyValueBox'; -import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; -import { SettingsManager } from '../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; interface PropertiesViewProps { @@ -87,13 +86,6 @@ export class PropertiesView extends React.Component { @observable openTransform: boolean = true; @observable openFilters: boolean = false; - /** - * autorun to set up the filter doc of a collection if that collection has been selected and the filters panel is open - */ - private selectedDocListenerDisposer: Opt; - - // @observable selectedUser: string = ""; - // @observable addButtonPressed: boolean = false; @observable layoutDocAcls: boolean = false; //Pres Trails booleans: @@ -105,14 +97,21 @@ export class PropertiesView extends React.Component { @observable inOptions: boolean = false; @observable _controlButton: boolean = false; + private _disposers: { [name: string]: IReactionDisposer } = {}; componentDidMount() { - this.selectedDocListenerDisposer?.(); - // this.selectedDocListenerDisposer = autorun(() => this.openFilters && this.selectedDoc && this.checkFilterDoc()); + this._disposers.link = reaction( + () => LinkManager.currentLink, + link => { + link && this.onDoubleClick(); + link && (this.openLinks = true); + }, + { fireImmediately: true } + ); } componentWillUnmount() { - this.selectedDocListenerDisposer?.(); + Object.values(this._disposers).forEach(disposer => disposer?.()); } @computed get isInk() { @@ -555,9 +554,29 @@ export class PropertiesView extends React.Component { @computed get editableTitle() { const titles = new Set(); - const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title); SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); - return ; + const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title); + return ( +
+ + {LinkManager.currentLinkAnchor ? ( +

+ <> + Anchor: + {LinkManager.currentLinkAnchor.title} + +

+ ) : null} + {LinkManager.currentLink?.title ? ( +

+ <> + Link: + {LinkManager.currentLink.title} + +

+ ) : null} +
+ ); } @computed get currentType() { @@ -1101,7 +1120,7 @@ export class PropertiesView extends React.Component { isOpen={this.openOptions} setInSection={bool => (this.inOptions = bool)} setIsOpen={bool => (this.openOptions = bool)} - onDoubleClick={() => this.onDoubleClick()} + onDoubleClick={this.onDoubleClick} /> ); } @@ -1209,11 +1228,11 @@ export class PropertiesView extends React.Component { } @computed get linksSubMenu() { - return 0 ? this.links : 'There are no current links.'} isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={() => this.onDoubleClick()} />; + return 0 ? this.links : 'There are no current links.'} isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={this.onDoubleClick} />; } @computed get layoutSubMenu() { - return (this.openLayout = bool)} onDoubleClick={() => this.onDoubleClick()} />; + return (this.openLayout = bool)} onDoubleClick={this.onDoubleClick} />; } @computed get description() { @@ -1699,7 +1718,7 @@ export class PropertiesView extends React.Component {
{this.currentType}
{this.optionsSubMenu} {this.linksSubMenu} - {!this.selectedDoc || !LinkManager.currentLink || (!hasSelectedAnchor && this.selectedDoc !== LinkManager.currentLink) ? null : this.linkProperties} + {!LinkManager.currentLink || !this.openLinks ? null : this.linkProperties} {this.inkSubMenu} {this.contextsSubMenu} {this.fieldsSubMenu} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 6cdb84dea..9823dfe91 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -348,7 +348,7 @@ export class TabDocView extends React.Component { private onActiveContentItemChanged(contentItem: any) { if (!contentItem || (this.stack === contentItem.parent && ((contentItem?.tab === this.tab && !this._isActive) || (contentItem?.tab !== this.tab && this._isActive)))) { this._activated = this._isActive = !contentItem || contentItem?.tab === this.tab; - if (!this._view) setTimeout(() => SelectionManager.SelectView(this._view, false)); + if (!this._view && this.tab?.contentItem?.config?.props?.panelName !== 'dontSelectOnActivate') setTimeout(() => SelectionManager.SelectView(this._view, false)); !this._isActive && this._document && Doc.UnBrushDoc(this._document); // bcz: bad -- trying to simulate a pointer leave event when a new tab is opened up on top of an existing one. } } @@ -380,7 +380,7 @@ export class TabDocView extends React.Component { return LightboxView.AddDocTab(doc, location); case OpenWhere.close: return CollectionDockingView.CloseSplit(doc, whereMods); case OpenWhere.replace: return CollectionDockingView.ReplaceTab(doc, whereMods, this.stack, undefined, keyValue); - case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(doc, whereMods, this.stack, undefined, keyValue); + case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(doc, whereMods, this.stack, "dontSelectOnActivate", keyValue); case OpenWhere.add:default:return CollectionDockingView.AddSplit(doc, whereMods, this.stack, undefined, keyValue); } }; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 9bc8f5e8b..0a9d7543b 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -69,10 +69,8 @@ export class LinkMenuItem extends React.Component { } return this.props.sourceDoc; } - @action + onEdit = (e: React.PointerEvent) => { - LinkManager.currentLink = this.props.linkDoc === LinkManager.currentLink ? undefined : this.props.linkDoc; - LinkManager.currentLinkAnchor = this.sourceAnchor; setupMoveUpEvents( this, e, @@ -90,8 +88,11 @@ export class LinkMenuItem extends React.Component { DocumentViewInternal.addDocTabFunc(trail, OpenWhere.replaceRight); } else { SelectionManager.SelectView(this.props.docView, false); + LinkManager.currentLink = this.props.linkDoc === LinkManager.currentLink ? undefined : this.props.linkDoc; + LinkManager.currentLinkAnchor = LinkManager.currentLink ? this.sourceAnchor : undefined; + if ((SettingsManager.propertiesWidth ?? 0) < 100) { - SettingsManager.propertiesWidth = 250; + setTimeout(action(() => (SettingsManager.propertiesWidth = 250))); } } }) @@ -150,7 +151,11 @@ export class LinkMenuItem extends React.Component { className="linkMenu-item" onPointerEnter={action(e => (this._hover = true))} onPointerLeave={action(e => (this._hover = false))} - style={{ background: /*LinkManager.currentLink !== this.props.linkDoc*/ this._hover ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }}> + style={{ + fontSize: this._hover ? 'larger' : undefined, + fontWeight: this._hover ? 'bold' : undefined, + background: LinkManager.currentLink === this.props.linkDoc ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor, + }}>
Date: Wed, 6 Sep 2023 13:53:32 -0400 Subject: fixed up audio annotation to add dictation to sidebar note. --- src/client/util/SearchUtil.ts | 4 +- src/client/views/StyleProvider.tsx | 2 +- src/client/views/global/globalScripts.ts | 4 +- src/client/views/nodes/DocumentView.tsx | 33 +++++++++++------ .../views/nodes/formattedText/FormattedTextBox.tsx | 43 +++++++++++++++------- src/client/views/pdf/AnchorMenu.tsx | 18 ++++----- src/fields/Doc.ts | 2 + src/fields/DocSymbols.ts | 1 + 8 files changed, 67 insertions(+), 40 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 64aa7ba9b..560d6b30f 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -57,8 +57,8 @@ export namespace SearchUtil { const hlights = new Set(); SearchUtil.documentKeys(doc).forEach( key => - Field.toString(doc[key] as Field) - .toLowerCase() + (Field.toString(doc[key] as Field) + Field.toScriptString(doc[key] as Field)) + .toLowerCase() // .includes(query) && hlights.add(key) ); blockedKeys.forEach(key => hlights.delete(key)); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index a9e4ac17d..cdf104a18 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -295,7 +295,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { const audioAnnoState = (doc: Doc) => StrCast(doc.audioAnnoState, 'stopped'); const audioAnnosCount = (doc: Doc) => StrListCast(doc[Doc.LayoutFieldKey(doc) + '_audioAnnotations']).length; - if (!doc || props?.renderDepth === -1 || (!audioAnnosCount(doc) && audioAnnoState(doc) === 'stopped')) return null; + if (!doc || props?.renderDepth === -1 || !audioAnnosCount(doc)) return null; const audioIconColors: { [key: string]: string } = { recording: 'red', playing: 'green', stopped: 'blue' }; return ( {StrListCast(doc[Doc.LayoutFieldKey(doc) + '_audioAnnotations_text']).lastElement()}
}> diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 38bf1042d..9b9cc6d24 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -182,8 +182,8 @@ ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: toggle: () => editorView?.state && RichTextMenu.Instance.changeListType(list) }]); // prettier-ignore const attrs:attrfuncs[] = [ - ['dictation', { checkResult: () => textView?._recording ? true:false, - toggle: () => textView && runInAction(() => (textView._recording = !textView._recording)) }], + ['dictation', { checkResult: () => textView?._recordingDictation ? true:false, + toggle: () => textView && runInAction(() => (textView._recordingDictation = !textView._recordingDictation)) }], ['noAutoLink',{ checkResult: () => (editorView ? RichTextMenu.Instance.noAutoLink : false), toggle: () => editorView && RichTextMenu.Instance?.toggleNoAutoLinkAnchor()}], ['bold', { checkResult: () => (editorView ? RichTextMenu.Instance.bold : (Doc.UserDoc().fontWeight === 'bold') ? true:false), diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ab99f3c6d..dcb2d9d51 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; -import { AclPrivate, Animation, DocData, Width } from '../../../fields/DocSymbols'; +import { AclPrivate, Animation, AudioPlay, DocData, Width } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; @@ -52,6 +52,7 @@ import { LinkAnchorBox } from './LinkAnchorBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps, PresBox } from './trails/PresBox'; import React = require('react'); +import { isThisTypeNode } from 'typescript'; const { Howl } = require('howler'); interface Window { @@ -1054,7 +1055,7 @@ export class DocumentViewInternal extends DocComponent (dataDoc.audioAnnoState = 'recording')); + //runInAction(() => (dataDoc.audioAnnoState = 'recording')); recorder.start(); const stopFunc = () => { recorder.stop(); @@ -1071,16 +1072,24 @@ export class DocumentViewInternal extends DocComponent (self.dataDoc.audioAnnoState = 'stopped')), - }); - this.dataDoc.audioAnnoState = 'playing'; + if (anno instanceof AudioField) { + switch (audioAnnoState) { + case 'stopped': + this.dataDoc[AudioPlay] = new Howl({ + src: [anno.url.href], + format: ['mp3'], + autoplay: true, + loop: false, + volume: 0.5, + onend: action(() => (self.dataDoc.audioAnnoState = 'stopped')), + }); + this.dataDoc.audioAnnoState = 'playing'; + break; + case 'playing': + this.dataDoc[AudioPlay]?.stop(); + this.dataDoc.audioAnnoState = 'stopped'; + break; + } } }; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c9481482f..58b824159 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -153,10 +153,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { !this.layoutDoc.layout_showSidebar && this.toggleSidebar(); const anchor = this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true, true); + setTimeout(() => { const target = this._sidebarRef.current?.anchorMenuClick(anchor); if (target) { anchor.followLinkAudio = true; - DocumentViewInternal.recordAudioAnnotation(Doc.GetProto(target), Doc.LayoutFieldKey(target)); + let stopFunc: any; + Doc.GetProto(target).mediaState = 'recording'; + Doc.GetProto(target).audioAnnoState = 'recording'; + DocumentViewInternal.recordAudioAnnotation(Doc.GetProto(target), Doc.LayoutFieldKey(target), stop => (stopFunc = stop)); + let reactionDisposer = reaction( + () => target.mediaState, + action(dictation => { + if (!dictation) { + Doc.GetProto(target).audioAnnoState = 'stopped'; + stopFunc(); + reactionDisposer(); + } + }) + ); target.title = ComputedField.MakeFunction(`self["text_audioAnnotations_text"].lastElement()`); } }); @@ -948,14 +962,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if (this._editorView && this._recording) { + if (this._editorView && this._recordingDictation) { this.stopDictation(true); this._break = true; const state = this._editorView.state; const to = state.selection.to; const updated = TextSelection.create(state.doc, to, to); this._editorView.dispatch(state.tr.setSelection(updated).insertText('\n', to)); - if (this._recording) { + if (this._recordingDictation) { this.recordDictation(); } } @@ -1245,13 +1259,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this._recording, + () => this._recordingDictation, () => { this.stopDictation(true); - this._recording && this.recordDictation(); - } + this._recordingDictation && this.recordDictation(); + }, + { fireImmediately: true } ); - if (this._recording) setTimeout(this.recordDictation); + if (this._recordingDictation) setTimeout(this.recordDictation); } var quickScroll: string | undefined = ''; this._disposers.scroll = reaction( @@ -1549,8 +1564,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent disposer?.()); this.endUndoTypingBatch(); @@ -1588,7 +1603,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent @@ -1899,7 +1914,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent (this._recording = !this._recording)) + action(e => (this._recordingDictation = !this._recordingDictation)) ) }> diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index a52250145..85c1cce8c 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -132,7 +132,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip={'Click to Highlight'} onClick={this.highlightClicked} colorPicker={this.highlightColor} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> @@ -177,7 +177,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Summarize with AI" // onPointerDown={this.gptSummarize} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( @@ -185,7 +185,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Click to Record Annotation" // onPointerDown={this.audioDown} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} { type={Type.PRIM} icon={} popup={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> {AnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
@@ -201,7 +201,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Click/Drag to create cropped image" // onPointerDown={this.cropDown} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} />
)} @@ -213,7 +213,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Remove Link Anchor" // onPointerDown={this.Delete} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} {this.PinToPres !== returnFalse && ( @@ -221,7 +221,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Pin to Presentation" // onPointerDown={this.PinToPres} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} {this.ShowTargetTrail !== returnFalse && ( @@ -229,7 +229,7 @@ export class AnchorMenu extends AntimodeMenu { tooltip="Show Linked Trail" // onPointerDown={this.ShowTargetTrail} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} {this.IsTargetToggler !== returnFalse && ( @@ -240,7 +240,7 @@ export class AnchorMenu extends AntimodeMenu { toggleStatus={this.IsTargetToggler()} onClick={this.MakeTargetToggle} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 2a1dfbfc7..dd3f11444 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -20,6 +20,7 @@ import { AclPrivate, AclReadonly, Animation, + AudioPlay, CachedUpdates, DirectLinks, DocAcl, @@ -349,6 +350,7 @@ export class Doc extends RefField { @observable public [DocAcl]: { [key: string]: symbol } = {}; @observable public [DocCss]: number = 0; // incrementer denoting a change to CSS layout @observable public [DirectLinks] = new ObservableSet(); + @observable public [AudioPlay]: any; // meant to store sound object from Howl @observable public [Animation]: Opt; @observable public [Highlight]: boolean = false; static __Anim(Doc: Doc) { diff --git a/src/fields/DocSymbols.ts b/src/fields/DocSymbols.ts index 5b743f710..bb974ee74 100644 --- a/src/fields/DocSymbols.ts +++ b/src/fields/DocSymbols.ts @@ -3,6 +3,7 @@ export const Self = Symbol('DocSelf'); export const SelfProxy = Symbol('DocSelfProxy'); export const FieldKeys = Symbol('DocFieldKeys'); export const FieldTuples = Symbol('DocFieldTuples'); +export const AudioPlay = Symbol('DocAudioPlay'); export const Width = Symbol('DocWidth'); export const Height = Symbol('DocHeight'); export const Animation = Symbol('DocAnimation'); -- cgit v1.2.3-70-g09d2 From 44c66891f727093248a5e4cdeeec25a04cc772cc Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Sep 2023 23:00:29 -0400 Subject: disabled expand button for header context linear menu. moved input for stacking view to right-hand side to avoid overlap with undo/redo --- src/client/util/CurrentUserUtils.ts | 4 ++-- src/client/views/collections/CollectionStackingView.scss | 9 ++++++++- .../collections/CollectionStackingViewFieldColumn.tsx | 14 +++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 836160265..aa5f2658a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -756,7 +756,7 @@ export class CurrentUserUtils { /// Initializes all the default buttons for the top bar context menu static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") { - const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: true, _height: 35 }; + const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 }; const ctxtMenuBtnsDoc = DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined); const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => this.setupContextMenuBtn(params, ctxtMenuBtnsDoc) ); return DocUtils.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts, ctxtMenuBtns); @@ -784,7 +784,7 @@ export class CurrentUserUtils { const btns = btnDescs.map(desc => dockBtn({_width: desc.opts.width??30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts, desc.funcs)); const dockBtnsReqdOpts:DocumentOptions = { title: "docked buttons", _height: 40, flexGap: 0, layout_boxShadow: "standard", childDragAction: 'move', - childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: true, ignoreClick: true + childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: false, ignoreClick: true }; return DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), dockBtnsReqdOpts, btns); } diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 255bc3889..dddb3ec71 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -395,16 +395,23 @@ } .collectionStackingView-addDocumentButton { - font-size: 75%; letter-spacing: 2px; cursor: pointer; + .editableView-container-editing { + text-align: right; + } .editableView-input { outline-color: black; letter-spacing: 2px; color: grey; border: 0px; + background: yellow; + text-align: right; padding-top: 10px; // : 12px 10px 11px 10px; + input { + text-align: right; + } } } diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 7a22d4871..3aadeffcd 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -212,15 +212,16 @@ export class CollectionStackingViewFieldColumn extends React.Component { FormattedTextBox.SelectOnLoad = doc[Id]; return this.props.addDocument?.(doc); }, this.props.addDocument, - x, - y, + 0, + 0, true ); @@ -272,8 +273,11 @@ export class CollectionStackingViewFieldColumn extends React.Component Date: Thu, 7 Sep 2023 16:16:53 -0400 Subject: added deleted links to myRecentlyClosed. added drag out of comparison box doc. added all links to Doc.UserDoc().links --- src/client/DocServer.ts | 1 + src/client/util/LinkManager.ts | 11 +++++++---- src/client/views/nodes/ComparisonBox.scss | 2 ++ src/client/views/nodes/ComparisonBox.tsx | 31 +++++++++++++++++++++++++------ 4 files changed, 35 insertions(+), 10 deletions(-) (limited to 'src/client/util') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index fc8a9f3d6..353e11775 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -53,6 +53,7 @@ export namespace DocServer { DocListCast(DocCast(Doc.UserDoc().myLinkDatabase).data).forEach(link => { if (!references.has(DocCast(link.link_anchor_1)) && !references.has(DocCast(link.link_anchor_2))) { Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myLinkDatabase), 'data', link); + Doc.AddDocToList(Doc.MyRecentlyClosed, undefined, link); } }); LinkManager.userLinkDBs.forEach(linkDb => Doc.FindReferences(linkDb, references, undefined)); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index ef4b21b05..a533fdd1f 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -56,10 +56,12 @@ export class LinkManager { Promise.all([lproto?.link_anchor_1 as Doc, lproto?.link_anchor_2 as Doc].map(PromiseValue)).then((lAnchs: Opt[]) => Promise.all(lAnchs.map(lAnch => PromiseValue(lAnch?.proto as Doc))).then((lAnchProtos: Opt[]) => Promise.all(lAnchProtos.map(lAnchProto => PromiseValue(lAnchProto?.proto as Doc))).then( - action(lAnchProtoProtos => { - link && lAnchs[0] && Doc.GetProto(lAnchs[0])[DirectLinks].add(link); - link && lAnchs[1] && Doc.GetProto(lAnchs[1])[DirectLinks].add(link); - }) + link && + action(lAnchProtoProtos => { + Doc.AddDocToList(Doc.UserDoc(), 'links', link); + lAnchs[0] && Doc.GetProto(lAnchs[0])[DirectLinks].add(link); + lAnchs[1] && Doc.GetProto(lAnchs[1])[DirectLinks].add(link); + }) ) ) ) @@ -145,6 +147,7 @@ export class LinkManager { }; public addLink(linkDoc: Doc, checkExists = false) { + Doc.AddDocToList(Doc.UserDoc(), 'links', linkDoc); if (!checkExists || !DocListCast(Doc.LinkDBDoc().data).includes(linkDoc)) { Doc.AddDocToList(Doc.LinkDBDoc(), 'data', linkDoc); setTimeout(DocServer.UPDATE_SERVER_CACHE, 100); diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss index a12f1c12b..39c864b2b 100644 --- a/src/client/views/nodes/ComparisonBox.scss +++ b/src/client/views/nodes/ComparisonBox.scss @@ -60,6 +60,8 @@ opacity: 0.8; pointer-events: all; cursor: pointer; + width: 15px; + height: 15px; } .clear-button.before { diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index a334e75f1..b09fcd882 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -109,12 +109,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { - e.stopPropagation; // prevent click event action (slider movement) in registerSliding - delete this.dataDoc[fieldKey]; - }; + clearDoc = (fieldKey: string) => delete this.dataDoc[fieldKey]; + moveDoc = (doc: Doc, addDocument: (document: Doc | Doc[]) => boolean, which: string) => this.remDoc(doc, which) && addDocument(doc); addDoc = (doc: Doc, which: string) => { + if (this.dataDoc[which]) return false; this.dataDoc[which] = doc; return true; }; @@ -128,6 +127,24 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent (this._isAnyChildContentActive = isActive)); + closeDown = (e: React.PointerEvent, which: string) => { + setupMoveUpEvents( + this, + e, + e => { + const de = new DragManager.DocumentDragData([DocCast(this.dataDoc[which])], 'move'); + de.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => { + this.clearDoc(which); + return addDocument(doc); + }; + de.canEmbed = true; + DragManager.StartDocumentDrag([this._closeRef.current!], de, e.clientX, e.clientY); + return true; + }, + emptyFunction, + e => this.clearDoc(which) + ); + }; docStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (property === StyleProp.PointerEvents) return 'none'; return this.props.styleProvider?.(doc, props, property); @@ -136,13 +153,15 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true); remDoc1 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true); remDoc2 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true); + _closeRef = React.createRef(); render() { const clearButton = (which: string) => { return (
e.stopPropagation()} // prevent triggering slider movement in registerSliding - onClick={e => this.clearDoc(e, which)}> + onPointerDown={e => this.closeDown(e, which)} // prevent triggering slider movement in registerSliding + >
); -- cgit v1.2.3-70-g09d2 From 888ddd78737781f8a2d045b5f1e41788c512c94d Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 8 Sep 2023 17:02:49 -0400 Subject: don't remove current recording from overlay, added closeOnSelect option for dropdown. place recording box on screen. fixe overlayView to keep views on screen. fixed schema view checkboxes. don't cause tab to rerender when colelctoin type changes. add dropdown to filter indicator to find filters. --- package-lock.json | 166 +++++++++++++-------- package.json | 2 +- src/client/util/CurrentUserUtils.ts | 1 - src/client/util/SettingsManager.tsx | 6 +- src/client/util/reportManager/ReportManager.tsx | 2 + src/client/views/DashboardView.tsx | 1 + src/client/views/MainView.tsx | 6 +- src/client/views/OverlayView.tsx | 15 ++ src/client/views/PropertiesButtons.tsx | 1 + src/client/views/PropertiesView.tsx | 39 +++-- src/client/views/StyleProvider.scss | 9 +- src/client/views/StyleProvider.tsx | 41 ++++- src/client/views/UndoStack.tsx | 12 +- src/client/views/collections/TabDocView.tsx | 10 +- .../collectionSchema/CollectionSchemaView.tsx | 8 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 3 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 9 +- 17 files changed, 213 insertions(+), 118 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index b6c03c6ba..6055e9d1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,20 +142,20 @@ "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==" }, "@babel/core": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", - "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz", + "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==", "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.15", + "@babel/helper-module-transforms": "^7.22.17", "@babel/helpers": "^7.22.15", - "@babel/parser": "^7.22.15", + "@babel/parser": "^7.22.16", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/traverse": "^7.22.17", + "@babel/types": "^7.22.17", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -209,9 +209,9 @@ } }, "@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", + "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", "requires": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", @@ -219,16 +219,16 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/parser": "^7.22.16", + "@babel/types": "^7.22.17", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -300,9 +300,9 @@ "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -472,9 +472,9 @@ "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -492,9 +492,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", + "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", "requires": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", @@ -517,9 +517,9 @@ "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -542,13 +542,13 @@ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-remap-async-to-generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", - "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz", + "integrity": "sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA==", "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" + "@babel/helper-wrap-function": "^7.22.17" }, "dependencies": { "@babel/helper-annotate-as-pure": { @@ -611,28 +611,64 @@ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==" }, "@babel/helper-wrap-function": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz", - "integrity": "sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz", + "integrity": "sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q==", "requires": { "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.17" }, "dependencies": { - "@babel/helper-validator-identifier": { + "@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "requires": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + } + }, + "@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==" + }, + "@babel/template": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + } }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" + } } } } @@ -693,9 +729,9 @@ } }, "@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", + "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", "requires": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", @@ -703,16 +739,16 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/parser": "^7.22.16", + "@babel/types": "^7.22.17", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -1691,9 +1727,9 @@ } }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -2028,9 +2064,9 @@ "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==" }, "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.15", @@ -6651,9 +6687,9 @@ } }, "browndash-components": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.23.tgz", - "integrity": "sha512-yZPnSUBXdToufaq4mTYHMgDwrijQWsuVKK8j+NilRKMqmOrkZeqyRhncTDz077DcMLcjeIj+SobT3GPK04TXmQ==", + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.25.tgz", + "integrity": "sha512-YgzUsfeUKwtaOLRYNDcxybZG2Ip7KSQV38VbUrgC+ycwOX/tzq9IWlfw2z4h/EVuVcq+ERCaBS4pb3mMU6pKGQ==", "requires": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", @@ -10110,14 +10146,14 @@ } }, "caniuse-lite": { - "version": "1.0.30001528", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001528.tgz", - "integrity": "sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q==" + "version": "1.0.30001529", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz", + "integrity": "sha512-n2pUQYGAkrLG4QYj2desAh+NqsJpHbNmVZz87imptDdxLAtjxary7Df/psdfyDGmskJK/9Dt9cPnx5RZ3CU4Og==" }, "electron-to-chromium": { - "version": "1.4.510", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.510.tgz", - "integrity": "sha512-xPfLIPFcN/WLXBpQ/K4UgE98oUBO5Tia6BD4rkSR0wE7ep/PwBVlgvPJQrIBpmJGVAmUzwPKuDbVt9XV6+uC2g==" + "version": "1.4.513", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.513.tgz", + "integrity": "sha512-cOB0xcInjm+E5qIssHeXJ29BaUyWpMyFKT5RB3bsLENDheCja0wMkHJyiPl0NBE/VzDI7JDuNEQWhe6RitEUcw==" } } }, diff --git a/package.json b/package.json index c218d80ff..9f0b91628 100644 --- a/package.json +++ b/package.json @@ -178,7 +178,7 @@ "body-parser": "^1.19.2", "bootstrap": "^4.6.1", "brotli": "^1.3.3", - "browndash-components": "^0.1.23", + "browndash-components": "^0.1.25", "browser-assert": "^1.2.1", "bson": "^4.6.1", "canvas": "^2.9.3", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index aa5f2658a..8bedea562 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -763,7 +763,6 @@ export class CurrentUserUtils { } /// Initializes all the default buttons for the top bar context menu static setupTopbarButtons(doc: Doc, field="myTopBarBtns") { - if (Doc.UserDoc().currentRecording) Doc.RemFromMyOverlay(DocCast(Doc.UserDoc().currentRecording)); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().workspaceRecordingState = undefined; Doc.UserDoc().workspaceReplayingState = undefined; diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 720badd40..53cfbc947 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -142,6 +142,7 @@ export class SettingsManager extends React.Component<{}> { formLabel="Theme" size={Size.SMALL} type={Type.TERT} + closeOnSelect={false} selectedVal={userTheme} setSelectedVal={scheme => this.changeColorScheme(scheme as string)} items={colorSchemes.map((scheme, i) => ({ @@ -294,6 +295,7 @@ export class SettingsManager extends React.Component<{}> { }, }; })} + closeOnSelect={true} dropdownType={DropdownType.SELECT} type={Type.TERT} selectedVal={StrCast(Doc.UserDoc().fontFamily)} @@ -373,6 +375,7 @@ export class SettingsManager extends React.Component<{}> {
{
{ { @@ -320,6 +321,7 @@ export class ReportManager extends React.Component<{}> { { diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 1d1d0eaab..014a6358f 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -371,6 +371,7 @@ export class DashboardView extends React.Component { Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc); dashboardDoc['pane-count'] = 1; + freeformDoc.embedContainer = dashboardDoc; Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 8adb28fe1..2b4f4d5f7 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -810,7 +810,11 @@ export class MainView extends React.Component {
)}
- {this.propertiesWidth() < 10 ? null : } + { +
+ +
+ }
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 5d95c5fda..c174befc0 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -16,6 +16,7 @@ import { LightboxView } from './LightboxView'; import { DocumentView, DocumentViewInternal } from './nodes/DocumentView'; import './OverlayView.scss'; import { DefaultStyleProvider } from './StyleProvider'; +const _global = (window /* browser */ || global) /* node */ as any; export type OverlayDisposer = () => void; @@ -115,6 +116,20 @@ export class OverlayView extends React.Component { super(props); if (!OverlayView.Instance) { OverlayView.Instance = this; + new _global.ResizeObserver( + action((entries: any) => { + for (const entry of entries) { + DocListCast(Doc.MyOverlayDocs?.data).forEach(doc => { + if (NumCast(doc.overlayX) > entry.contentRect.width - 10) { + doc.overlayX = entry.contentRect.width - 10; + } + if (NumCast(doc.overlayY) > entry.contentRect.height - 10) { + doc.overlayY = entry.contentRect.height - 10; + } + }); + } + }) + ).observe(window.document.body); } } diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 42db0b9be..d939470e9 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -376,6 +376,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { this.handleOptionChange(val as string)} title={'Choose onClick behaviour'} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 72ff906f6..9cc75b1c6 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -52,6 +52,12 @@ interface PropertiesViewProps { export class PropertiesView extends React.Component { private _widthUndo?: UndoManager.Batch; + public static Instance: PropertiesView | undefined; + constructor(props: any) { + super(props); + PropertiesView.Instance = this; + } + @computed get MAX_EMBED_HEIGHT() { return 200; } @@ -75,6 +81,7 @@ export class PropertiesView extends React.Component { } @observable layoutFields: boolean = false; + @observable layoutDocAcls: boolean = false; @observable openOptions: boolean = true; @observable openSharing: boolean = true; @@ -86,8 +93,6 @@ export class PropertiesView extends React.Component { @observable openTransform: boolean = true; @observable openFilters: boolean = false; - @observable layoutDocAcls: boolean = false; - //Pres Trails booleans: @observable openPresTransitions: boolean = true; @observable openPresProgressivize: boolean = false; @@ -103,7 +108,7 @@ export class PropertiesView extends React.Component { this._disposers.link = reaction( () => LinkManager.currentLink, link => { - link && this.onDoubleClick(); + link && this.CloseAll(); link && (this.openLinks = true); }, { fireImmediately: true } @@ -970,7 +975,7 @@ export class PropertiesView extends React.Component { }; @action - onDoubleClick = () => { + CloseAll = () => { this.openContexts = false; this.openLinks = false; this.openOptions = false; @@ -1120,7 +1125,7 @@ export class PropertiesView extends React.Component { isOpen={this.openOptions} setInSection={bool => (this.inOptions = bool)} setIsOpen={bool => (this.openOptions = bool)} - onDoubleClick={this.onDoubleClick} + onDoubleClick={this.CloseAll} /> ); } @@ -1147,7 +1152,7 @@ export class PropertiesView extends React.Component { } isOpen={this.openSharing} setIsOpen={bool => (this.openSharing = bool)} - onDoubleClick={() => this.onDoubleClick()} + onDoubleClick={() => this.CloseAll()} /> ); } @@ -1187,7 +1192,7 @@ export class PropertiesView extends React.Component { } isOpen={this.openFilters} setIsOpen={bool => (this.openFilters = bool)} - onDoubleClick={() => this.onDoubleClick()} + onDoubleClick={() => this.CloseAll()} /> ); } @@ -1197,8 +1202,8 @@ export class PropertiesView extends React.Component { return ( <> - (this.openAppearance = bool)} onDoubleClick={() => this.onDoubleClick()} /> - (this.openTransform = bool)} onDoubleClick={() => this.onDoubleClick()} /> + (this.openAppearance = bool)} onDoubleClick={() => this.CloseAll()} /> + (this.openTransform = bool)} onDoubleClick={() => this.CloseAll()} /> ); } @@ -1210,29 +1215,23 @@ export class PropertiesView extends React.Component { content={
{Doc.noviceMode ? this.noviceFields : this.expandedField}
} isOpen={this.openFields} setIsOpen={bool => (this.openFields = bool)} - onDoubleClick={() => this.onDoubleClick()} + onDoubleClick={() => this.CloseAll()} /> ); } @computed get contextsSubMenu() { return ( - 0 ? this.contexts : 'There are no other contexts.'} - isOpen={this.openContexts} - setIsOpen={bool => (this.openContexts = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + 0 ? this.contexts : 'There are no other contexts.'} isOpen={this.openContexts} setIsOpen={bool => (this.openContexts = bool)} onDoubleClick={() => this.CloseAll()} /> ); } @computed get linksSubMenu() { - return 0 ? this.links : 'There are no current links.'} isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={this.onDoubleClick} />; + return 0 ? this.links : 'There are no current links.'} isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={this.CloseAll} />; } @computed get layoutSubMenu() { - return (this.openLayout = bool)} onDoubleClick={this.onDoubleClick} />; + return (this.openLayout = bool)} onDoubleClick={this.CloseAll} />; } @computed get description() { @@ -1723,7 +1722,7 @@ export class PropertiesView extends React.Component { {this.contextsSubMenu} {this.fieldsSubMenu} {isNovice ? null : this.sharingSubMenu} - {isNovice ? null : this.filtersSubMenu} + {this.filtersSubMenu} {isNovice ? null : this.layoutSubMenu}
); diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index c06bb287e..f069e7e1b 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -18,10 +18,15 @@ cursor: default; } .styleProvider-filter { - right: 0; + right: 15; + .styleProvider-filterShift { + left: 0; + top: 0; + position: absolute; + } } .styleProvider-audio { - right: 15; + right: 30; } .styleProvider-lock:hover, .styleProvider-audio:hover, diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 069bfd049..8a5ad3139 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; -import { IconButton, Shadows, Size } from 'browndash-components'; +import { Dropdown, DropdownType, IconButton, IListItemProps, ListBox, ListItem, Popup, Shadows, Size, Type } from 'browndash-components'; import { action, runInAction } from 'mobx'; import { extname } from 'path'; import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs'; @@ -24,6 +24,8 @@ import { KeyValueBox } from './nodes/KeyValueBox'; import { SliderBox } from './nodes/SliderBox'; import './StyleProvider.scss'; import React = require('react'); +import { PropertiesView } from './PropertiesView'; +import { FaFilter } from 'react-icons/fa'; export enum StyleProp { TreeViewIcon = 'treeView_Icon', @@ -283,13 +285,44 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { const showFilterIcon = StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length - ? '#18c718bd' //'hasFilter' + ? 'green' // #18c718bd' //'hasFilter' : docProps?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragsDocFilter).length || docProps?.childFiltersByRanges().length ? 'orange' //'inheritsFilter' : undefined; return !showFilterIcon ? null : ( -
(SettingsManager.propertiesWidth = 250))}> - +
+
} + closeOnSelect={true} + setSelectedVal={ + action((dv) => { + (dv as any).select(false); + (SettingsManager.propertiesWidth = 250); + setTimeout(action(() => { + if (PropertiesView.Instance) { + PropertiesView.Instance.CloseAll(); + PropertiesView.Instance.openFilters = true; + } + })); + }) + } + size={Size.XSMALL} + width={15} + height={15} + title={showFilterIcon === 'green' ? + "This view is filtered. Click to view/change filters": + "this view inherits filters from one of its parents"} + color={SettingsManager.userColor} + background={showFilterIcon} + items={[...(props?.docViewPath?.()??[]), ...(props?.DocumentView?[props?.DocumentView?.()]:[])].map(dv => ({ + text: StrCast(dv.rootDoc.title), + val: dv as any, + style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor}, + } as IListItemProps)) } + />
); }; diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index 1afd5ad22..093bb8b9c 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -1,14 +1,12 @@ -import { action, observable } from 'mobx'; +import { Tooltip } from '@mui/material'; +import { Popup, Type } from 'browndash-components'; +import { observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { UndoManager } from '../util/UndoManager'; -import './UndoStack.scss'; import { StrCast } from '../../fields/Types'; -import { Doc } from '../../fields/Doc'; -import { Popup, Type, isDark } from 'browndash-components'; -import { Colors } from './global/globalEnums'; import { SettingsManager } from '../util/SettingsManager'; -import { Tooltip } from '@mui/material'; +import { UndoManager } from '../util/UndoManager'; +import './UndoStack.scss'; interface UndoStackProps { width?: number; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 9ea1ed2de..d9faab063 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -17,6 +17,7 @@ import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes' import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; +import { SettingsManager } from '../../util/SettingsManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoable, UndoManager } from '../../util/UndoManager'; @@ -33,7 +34,6 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV import { CollectionView } from './CollectionView'; import './TabDocView.scss'; import React = require('react'); -import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; interface TabDocViewProps { @@ -420,7 +420,7 @@ export class TabDocView extends React.Component { PanelHeight = () => this._panelHeight; miniMapColor = () => Colors.MEDIUM_GRAY; tabView = () => this._view; - disableMinimap = () => !this._document || this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._type_collection !== CollectionViewType.Freeform; + disableMinimap = () => !this._document; whenChildContentActiveChanges = (isActive: boolean) => (this._isAnyChildContentActive = isActive); isContentActive = () => this._isContentActive; waitForDoubleClick = () => (DocumentView.ExploreMode ? 'never' : undefined); @@ -461,9 +461,7 @@ export class TabDocView extends React.Component { bringToFront={emptyFunction} pinToPres={TabDocView.PinDoc} /> - {this.disableMinimap() || this._document._type_collection !== CollectionViewType.Freeform ? null : ( - - )} + {this.disableMinimap() ? null : } ); } @@ -615,7 +613,7 @@ export class TabMinimapView extends React.Component { ); }; render() { - return ( + return this.props.document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this.props.document)) || this.props.document?._type_collection !== CollectionViewType.Freeform ? null : (
} color={SettingsManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement={'top-end'} popup={this.popup} />
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 182a33fd1..5c7dcc1a4 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -609,10 +609,10 @@ export class CollectionSchemaView extends CollectionSubView() { this._menuKeys = this.documentKeys.filter(value => value.toLowerCase().includes(this._menuValue.toLowerCase())); }; - getFieldFilters = (field: string) => StrListCast(this.Document._childFilters).filter(filter => filter.split(':')[0] == field); + getFieldFilters = (field: string) => StrListCast(this.Document._childFilters).filter(filter => filter.split(Doc.FilterSep)[0] == field); removeFieldFilters = (field: string) => { - this.getFieldFilters(field).forEach(filter => Doc.setDocFilter(this.Document, field, filter.split(':')[1], 'remove')); + this.getFieldFilters(field).forEach(filter => Doc.setDocFilter(this.Document, field, filter.split(Doc.FilterSep)[1], 'remove')); }; onFilterKeyDown = (e: React.KeyboardEvent) => { @@ -766,8 +766,8 @@ export class CollectionSchemaView extends CollectionSubView() { return keyOptions.map(key => { let bool = false; if (filters !== undefined) { - const ind = filters.findIndex(filter => filter.split(':')[1] === key); - const fields = ind === -1 ? undefined : filters[ind].split(':'); + const ind = filters.findIndex(filter => filter.split(Doc.FilterSep)[1] === key); + const fields = ind === -1 ? undefined : filters[ind].split(Doc.FilterSep); bool = fields ? fields[2] === 'check' : false; } return ( diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 1eb6fd51c..0a59818ad 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -246,10 +246,11 @@ export class FontIconBox extends DocComponent() { return ( script.script.run({ this: this.layoutDoc, self: this.rootDoc, val }), `dropdown select ${this.label}`)} + setSelectedVal={undoable(value => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), `dropdown select ${this.label}`)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} + closeOnSelect={false} dropdownType={DropdownType.SELECT} onItemDown={this.dropdownItemDown} items={list} diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 1f113110b..481e43feb 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -119,7 +119,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { public static replayWorkspace(value: Doc) { Doc.UserDoc().currentRecording = value; value.overlayX = 70; - value.overlayY = 590; + value.overlayY = window.innerHeight - 180; Doc.AddToMyOverlay(value); DocumentManager.Instance.AddViewRenderedCb(value, docView => { Doc.UserDoc().currentRecording = docView.rootDoc; @@ -147,11 +147,10 @@ export class RecordingBox extends ViewBoxBaseComponent() { @action public static resumeWorkspaceReplaying(doc: Doc) { const docView = DocumentManager.Instance.getDocumentView(doc); - const videoBox = docView?.ComponentView as VideoBox; - if (videoBox) { - videoBox.Play(); - Doc.UserDoc().workspaceReplayingState = media_state.Playing; + if (docView?.ComponentView instanceof VideoBox) { + docView.ComponentView.Play(); } + Doc.UserDoc().workspaceReplayingState = media_state.Playing; } @action -- cgit v1.2.3-70-g09d2 From 3a048ae3acbbf63611bfbb7cded772fc3decd526 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 11 Sep 2023 22:58:56 -0400 Subject: usercolor cleanup --- src/client/util/RTFMarkup.tsx | 2 +- src/client/views/AntimodeMenu.tsx | 7 +- src/client/views/ContextMenu.tsx | 7 +- src/client/views/PropertiesButtons.tsx | 5 +- src/client/views/PropertiesSection.tsx | 7 +- src/client/views/PropertiesView.tsx | 21 +++--- src/client/views/StyleProvider.tsx | 8 +-- src/client/views/collections/CollectionMenu.tsx | 6 +- .../views/collections/CollectionStackingView.tsx | 3 +- src/client/views/collections/TreeView.tsx | 5 +- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 38 ++--------- src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 75 +++++++++++----------- src/client/views/nodes/MapBox/MapBox.tsx | 3 +- 13 files changed, 82 insertions(+), 105 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx index 9dd14a3c3..c8940194c 100644 --- a/src/client/util/RTFMarkup.tsx +++ b/src/client/util/RTFMarkup.tsx @@ -137,7 +137,7 @@ export class RTFMarkup extends React.Component<{}> { render() { return ( extends React.Co left: this._left, top: this._top, opacity: this._opacity, - background: StrCast(Doc.UserDoc().userBackgroundColor), + background: SettingsManager.userBackgroundColor, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, @@ -176,7 +177,7 @@ export abstract class AntimodeMenu extends React.Co height: 'inherit', width: 200, opacity: this._opacity, - background: StrCast(Doc.UserDoc().userBackgroundColor), + background: SettingsManager.userBackgroundColor, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, @@ -199,7 +200,7 @@ export abstract class AntimodeMenu extends React.Co left: this._left, top: this._top, opacity: this._opacity, - background: StrCast(Doc.UserDoc().userBackgroundColor), + background: SettingsManager.userBackgroundColor, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 8412a9aae..adefc7e9c 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -7,6 +7,7 @@ import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextM import { Utils } from '../../Utils'; import { StrCast } from '../../fields/Types'; import { Doc } from '../../fields/Doc'; +import { SettingsManager } from '../util/SettingsManager'; @observer export class ContextMenu extends React.Component { @@ -195,7 +196,7 @@ export class ContextMenu extends React.Component {
{value.join(' -> ')}
@@ -222,8 +223,8 @@ export class ContextMenu extends React.Component { style={{ left: this.pageX, ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }), - background: StrCast(Doc.UserDoc().userBackgroundColor), - color: StrCast(Doc.UserDoc().userColor), + background: SettingsManager.userBackgroundColor, + color: SettingsManager.userColor, }}> {!this.itemsNeedSearch ? null : ( diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 8b2b77aca..40d42a4de 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -32,6 +32,7 @@ import { TfiBarChart } from 'react-icons/tfi'; import { CiGrid31 } from 'react-icons/ci'; import { RxWidth } from 'react-icons/rx'; import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components'; +import { SettingsManager } from '../util/SettingsManager'; enum UtilityButtonState { Default, @@ -57,7 +58,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { { selectedVal={this.onClickVal} setSelectedVal={val => this.handleOptionChange(val as string)} title={'Choose onClick behaviour'} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} dropdownType={DropdownType.SELECT} type={Type.SEC} fillWidth diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx index 0e7cd7e92..bd586b2f9 100644 --- a/src/client/views/PropertiesSection.tsx +++ b/src/client/views/PropertiesSection.tsx @@ -5,6 +5,7 @@ import { observer } from 'mobx-react'; import './PropertiesSection.scss'; import { Doc } from '../../fields/Doc'; import { StrCast } from '../../fields/Types'; +import { SettingsManager } from '../util/SettingsManager'; export interface PropertiesSectionProps { title: string; @@ -19,15 +20,15 @@ export interface PropertiesSectionProps { @observer export class PropertiesSection extends React.Component { @computed get color() { - return StrCast(Doc.UserDoc().userColor); + return SettingsManager.userColor; } @computed get backgroundColor() { - return StrCast(Doc.UserDoc().userBackgroundColor); + return SettingsManager.userBackgroundColor; } @computed get variantColor() { - return StrCast(Doc.UserDoc().userVariantColor); + return SettingsManager.userVariantColor; } @observable isDouble: boolean = false; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index b25ac7903..699aafe80 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -368,7 +368,7 @@ export class PropertiesView extends React.Component { } size={Size.XSMALL} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} onClick={action(() => { if (this.selectedDocumentView || this.selectedDoc) { SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc); @@ -518,7 +518,7 @@ export class PropertiesView extends React.Component {


Individuals with Access to this Document
-
+
{
{individualTableEntries}
}
{groupTableEntries.length > 0 ? ( @@ -526,7 +526,7 @@ export class PropertiesView extends React.Component {


Groups with Access to this Document
-
+
{
{groupTableEntries}
}
@@ -546,15 +546,15 @@ export class PropertiesView extends React.Component { toggleCheckbox = () => (this.layoutFields = !this.layoutFields); @computed get color() { - return StrCast(Doc.UserDoc().userColor); + return SettingsManager.userColor; } @computed get backgroundColor() { - return StrCast(Doc.UserDoc().userBackgroundColor); + return SettingsManager.userBackgroundColor; } @computed get variantColor() { - return StrCast(Doc.UserDoc().userVariantColor); + return SettingsManager.userVariantColor; } @computed get editableTitle() { @@ -585,8 +585,6 @@ export class PropertiesView extends React.Component { } @computed get currentType() { - // console.log("current type " + this.selectedDoc?.type) - const documentType = StrCast(this.selectedDoc?.type); var currentType: string = documentType; var capitalizedDocType = Utils.cleanDocumentType(currentType as DocumentType); @@ -610,9 +608,8 @@ export class PropertiesView extends React.Component { if (iconName) { const Icon = Icons[iconName as keyof typeof Icons]; return ; - } else { - return ; } + return ; } @undoBatch @@ -1683,8 +1680,8 @@ export class PropertiesView extends React.Component {
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 8a5ad3139..85aa5ad83 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -162,8 +162,8 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color)); if (docColor) return docColor; const docView = props?.DocumentView?.(); @@ -196,7 +196,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?.[fieldKey + '_backgroundColor'], StrCast(doc?._backgroundColor, isCaption ? 'rgba(0,0,0,0.4)' : '')); // prettier-ignore switch (doc?.type) { @@ -350,7 +350,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt void) { - const color = StrCast(Doc.UserDoc().userColor); + const color = SettingsManager.userColor; return ( { 0} icon={} @@ -167,7 +167,7 @@ export class CollectionMenu extends AntimodeMenu { 0} icon={} @@ -183,7 +183,7 @@ export class CollectionMenu extends AntimodeMenu { className="collectionMenu-container" style={{ background: SettingsManager.userBackgroundColor, - // borderColor: StrCast(Doc.UserDoc().userColor) + // borderColor: SettingsManager.userColor }}> {this.contMenuButtons} {hardCodedButtons} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index e4a0d6dad..9ba4cb6cf 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -31,6 +31,7 @@ import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow'; import './CollectionStackingView.scss'; import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn'; import { CollectionSubView } from './CollectionSubView'; +import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; export type collectionStackingViewProps = { @@ -426,7 +427,7 @@ export class CollectionStackingView extends CollectionSubView + style={{ cursor: this._cursor, color: SettingsManager.userColor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}>
); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index f1268119e..71e9f4dfa 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -36,6 +36,7 @@ import './TreeView.scss'; import React = require('react'); import { IconButton, Size } from 'browndash-components'; import { TreeSort } from './TreeSort'; +import { SettingsManager } from '../../util/SettingsManager'; export interface TreeViewProps { treeView: CollectionTreeView; @@ -736,7 +737,7 @@ export class TreeView extends React.Component { @computed get renderBullet() { TraceMobx(); const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':open' : !this.childDocs.length ? ':empty' : '')) || 'question'; - const color = StrCast(Doc.UserDoc().userColor); + const color = SettingsManager.userColor; const checked = this.onCheckedClick ? this.doc.treeView_Checked ?? 'unchecked' : undefined; return (
{ @observable headerEleWidth = 0; @computed get titleButtons() { const customHeaderButtons = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decorations); - const color = StrCast(Doc.UserDoc().userColor); + const color = SettingsManager.userColor; return this.props.treeViewHideHeaderFields() || this.doc.treeView_HideHeaderFields ? null : ( <> {customHeaderButtons} {/* e.g.,. hide button is set by dashboardStyleProvider */} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index 71900c63f..607f9fb95 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -8,6 +8,7 @@ import { IconButton } from 'browndash-components'; import { StrCast } from '../../../../fields/Types'; import { Doc } from '../../../../fields/Doc'; import { computed } from 'mobx'; +import { SettingsManager } from '../../../util/SettingsManager'; @observer export class MarqueeOptionsMenu extends AntimodeMenu { @@ -27,43 +28,18 @@ export class MarqueeOptionsMenu extends AntimodeMenu { } @computed get userColor() { - return StrCast(Doc.UserDoc().userColor) + return SettingsManager.userColor; } render() { const presPinWithViewIcon = ; const buttons = ( <> - } - color={this.userColor} - /> - this.createCollection(e, true)} - icon={} - color={this.userColor} - /> - } - color={this.userColor} - /> - } - color={this.userColor} - /> - } - color={this.userColor} - /> + } color={this.userColor} /> + this.createCollection(e, true)} icon={} color={this.userColor} /> + } color={this.userColor} /> + } color={this.userColor} /> + } color={this.userColor} /> ); return this.getElement(buttons); diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index f731763af..f0827936b 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -6,7 +6,7 @@ import { ColorState } from 'react-color'; import { Doc, Opt } from '../../../../fields/Doc'; import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../../Utils'; import { SelectionManager } from '../../../util/SelectionManager'; -import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu" +import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; import { LinkPopup } from '../../linking/LinkPopup'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; // import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup'; @@ -15,6 +15,7 @@ import './MapAnchorMenu.scss'; import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; import { StrCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { SettingsManager } from '../../../util/SettingsManager'; @observer export class MapAnchorMenu extends AntimodeMenu { @@ -24,9 +25,6 @@ export class MapAnchorMenu extends AntimodeMenu { private _disposer2: IReactionDisposer | undefined; private _commentCont = React.createRef(); - - - public onMakeAnchor: () => Opt = () => undefined; // Method to get anchor from text search public Center: () => void = unimplementedFunction; @@ -90,41 +88,39 @@ export class MapAnchorMenu extends AntimodeMenu { // ); // }; - static top = React.createRef(); // public get Top(){ // return this.top // } - render() { - const buttons =( - <> - {( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - {( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - {( - } - color={StrCast(Doc.UserDoc().userColor)} - /> - )} - {/* {this.IsTargetToggler !== returnFalse && ( + const buttons = ( + <> + { + } + color={SettingsManager.userColor} + /> + } + { + } + color={SettingsManager.userColor} + /> + } + { + } + color={SettingsManager.userColor} + /> + } + {/* {this.IsTargetToggler !== returnFalse && ( { toggleStatus={this.IsTargetToggler()} onClick={this.MakeTargetToggle} icon={} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} /> )} */} - - ); + + ); - return this.getElement(
- {buttons} -
+ return this.getElement( +
+ {buttons} +
); } } diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 01810fa00..81ca3ff36 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -760,8 +760,9 @@ export class MapBox extends ViewBoxAnnotatableComponent !anno.layout_unrendered) - .map(pushpin => ( + .map((pushpin, i) => ( Date: Tue, 12 Sep 2023 20:43:20 -0400 Subject: dropping link button on same collection makes a pushpin. fixed broken undo typing to crate doc in sidebar. fixed min/max scaling for cropped images and made annotationOverlays start to use it. Fixed nested text boxes to stopPropagation on pointer down to enable editing of translations in sidebar. moved sidebar filters onto doc's filters. Added metadata filters back to sidebar. Added an -any- option to filtersPanel. fixed schema view preview window, added buttons and sliders. --- package-lock.json | 119 ++++++++++++++++----- package.json | 4 +- src/client/documents/Documents.ts | 7 +- src/client/util/CurrentUserUtils.ts | 10 +- src/client/views/FilterPanel.tsx | 20 ++-- src/client/views/PropertiesView.tsx | 7 +- src/client/views/SidebarAnnos.tsx | 30 +++--- src/client/views/StyleProvider.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- .../CollectionStackingViewFieldColumn.tsx | 6 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 44 +++++--- .../collectionSchema/CollectionSchemaView.scss | 8 +- .../collectionSchema/CollectionSchemaView.tsx | 1 + .../collections/collectionSchema/SchemaRowBox.tsx | 4 +- .../collectionSchema/SchemaTableCell.tsx | 26 ++++- src/client/views/global/globalScripts.ts | 8 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/ImageBox.tsx | 10 +- src/client/views/nodes/PDFBox.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 51 ++++++--- src/fields/Doc.ts | 1 + 21 files changed, 255 insertions(+), 110 deletions(-) (limited to 'src/client/util') diff --git a/package-lock.json b/package-lock.json index e0e54769a..fbfdf0136 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7244,12 +7244,97 @@ "strip-ansi": "^7.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "strip-ansi": { "version": "7.1.0", "bundled": true, "requires": { "ansi-regex": "^6.0.1" } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } } } }, @@ -8754,7 +8839,7 @@ } }, "string-width-cjs": { - "version": "npm:string-width@4.2.3", + "version": "npm:string-width-cjs@4.2.3", "bundled": true, "requires": { "emoji-regex": "^8.0.0", @@ -8777,7 +8862,7 @@ } }, "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", + "version": "npm:strip-ansi-cjs@6.0.1", "bundled": true, "requires": { "ansi-regex": "^5.0.1" @@ -8936,7 +9021,7 @@ } }, "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", + "version": "npm:wrap-ansi-cjs@7.0.0", "bundled": true, "requires": { "ansi-styles": "^4.0.0", @@ -14742,6 +14827,11 @@ "node-forge": "^0.10.0" } }, + "google-translate-api-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz", + "integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A==" + }, "googleapis": { "version": "40.0.1", "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-40.0.1.tgz", @@ -27327,29 +27417,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, - "translate-google-api": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/translate-google-api/-/translate-google-api-1.0.4.tgz", - "integrity": "sha512-KVXmo4+64/H1vIbnzf2zNiJ2JLeEB3jrEnNRP2EFNAGNqna/5bmw/Cps3pCHu0n3BzTOoWh9u6wFvrRYdzQ6Iw==", - "requires": { - "axios": "^0.20.0" - }, - "dependencies": { - "axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - } - } - }, "traverse-chain": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", diff --git a/package.json b/package.json index 67fdedeb2..d013ad74d 100644 --- a/package.json +++ b/package.json @@ -164,6 +164,7 @@ "@types/three": "^0.126.2", "@types/web": "0.0.53", "@webscopeio/react-textarea-autocomplete": "^4.9.1", + "D": "^1.0.0", "adm-zip": "^0.4.16", "archiver": "^3.1.1", "array-batcher": "^1.2.3", @@ -196,7 +197,6 @@ "cors": "^2.8.5", "csv-parser": "^3.0.0", "csv-stringify": "^6.3.0", - "D": "^1.0.0", "d3": "^7.6.1", "depcheck": "^0.9.2", "equation-editor-react": "github:bobzel/equation-editor-react#useLocally", @@ -219,6 +219,7 @@ "golden-layout": "^1.5.9", "google-auth-library": "^4.2.4", "google-maps-react": "^2.0.6", + "google-translate-api-browser": "^3.0.1", "googleapis": "^40.0.0", "googlephotos": "^0.2.5", "got": "^12.0.1", @@ -327,7 +328,6 @@ "textarea-caret": "^3.1.0", "three": "^0.127.0", "tough-cookie": "^4.0.0", - "translate-google-api": "^1.0.4", "typescript-collections": "^1.3.3", "typescript-language-server": "^0.4.0", "url-loader": "^1.1.2", diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index bb60cb329..85ee4ef59 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -145,7 +145,6 @@ class CTypeInfo extends FInfo { class DTypeInfo extends FInfo { fieldType? = 'enumeration'; values? = Array.from(Object.keys(DocumentType)); - readOnly = true; } class DateInfo extends FInfo { fieldType? = 'date'; @@ -338,11 +337,13 @@ export class DocumentOptions { // freeform properties _freeform_backgroundGrid?: BOOLt = new BoolInfo('whether background grid is shown on freeform collections'); + _freeform_scale_min?: NUMt = new NumInfo('how far out a view can zoom (used by image/videoBoxes that are clipped'); + _freeform_scale_max?: NUMt = new NumInfo('how far in a view can zoom (used by sidebar freeform views'); _freeform_scale?: NUMt = new NumInfo('how much a freeform view has been scaled (zoomed)'); _freeform_panX?: NUMt = new NumInfo('horizontal pan location of a freeform view'); _freeform_panY?: NUMt = new NumInfo('vertical pan location of a freeform view'); _freeform_noAutoPan?: BOOLt = new BoolInfo('disables autopanning when this item is dragged'); - _freeform_noZoom?: BOOLt = new BoolInfo('disables zooming'); + _freeform_noZoom?: BOOLt = new BoolInfo('disables zooming (used by Pile docs)'); //BUTTONS buttonText?: string; @@ -426,7 +427,7 @@ export class DocumentOptions { treeView_FreezeChildren?: STRt = new StrInfo('set (add, remove, add|remove) to disable adding, removing or both from collection'); sidebar_color?: string; // background color of text sidebar - sidebar_collectionType?: string; // collection type of text sidebar + sidebar_type_collection?: string; // collection type of text sidebar data_dashboards?: List; // list of dashboards used in shareddocs; text?: string; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8bedea562..527f251f9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -627,6 +627,11 @@ export class CurrentUserUtils { { title: "Z order", icon: "z", toolTip: "Keep Z order on Drag", btnType: ButtonType.ToggleButton, expertMode: false, funcs: {}, scripts: { onClick: '{ return toggleRaiseOnDrag(_readOnly_);}'}}, // Only when floating document is selected in freeform ] } + static stackTools(): Button[] { + return [ + { title: "Center", icon: "align-center", toolTip: "Center Align Stack", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"center", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform + ] + } static viewTools(): Button[] { return [ { title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"snaplines", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform @@ -682,8 +687,8 @@ export class CurrentUserUtils { static schemaTools():Button[] { return [ - {title: "Show preview", toolTip: "Show selection preview", btnType: ButtonType.ToggleButton, buttonText: "Show Preview", icon: "eye", scripts:{ onClick: '{ return toggleSchemaPreview(_readOnly_); }'} }, - {title: "Single Lines", toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, buttonText: "Single Line", icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} }, + {title: "Preview", toolTip: "Show selection preview", btnType: ButtonType.ToggleButton, icon: "portrait", scripts:{ onClick: '{ return toggleSchemaPreview(_readOnly_); }'} }, + {title: "1 Line",toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} }, ]; } @@ -713,6 +718,7 @@ export class CurrentUserUtils { { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available + { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Schema is selected ]; diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 0d4f4df5a..a601706ce 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -235,7 +235,7 @@ export class FilterPanel extends React.Component { facetValues = (facetHeader: string) => { const allCollectionDocs = new Set(); SearchUtil.foreachRecursiveDoc(this.targetDocChildren, (depth: number, doc: Doc) => allCollectionDocs.add(doc)); - const set = new Set([String.fromCharCode(127) + '--undefined--']); + const set = new Set([String.fromCharCode(127) + '--undefined--', Doc.FilterAny]); if (facetHeader === 'tags') allCollectionDocs.forEach(child => StrListCast(child[facetHeader]) @@ -257,24 +257,16 @@ export class FilterPanel extends React.Component { }; render() { - // console.log('this is frist one today ' + this._allFacets); - this._allFacets.forEach(element => console.log(element)); - // const options = Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => pair[1].filterable ).map(facet => value: facet, label: facet) //this._allFacets.filter(facet => this.activeFacetHeaders.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); - // console.log('HEELLLLLL ' + DocumentOptions); - - let filteredOptions: string[] = ['author', 'tags', 'text', 'acl-Guest']; + let filteredOptions: string[] = ['author', 'tags', 'text', 'acl-Guest', ...this._allFacets.filter(facet => facet[0] === facet.charAt(0).toUpperCase())]; Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => { if (pair[1].filterable) { filteredOptions.push(pair[0]); - console.log('THIS IS FILTERABLE ALKDJFIIEII' + filteredOptions); } }); let options = filteredOptions.map(facet => ({ value: facet, label: facet })); - // Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => console.log('this is first piar ' + pair[0] + ' this is second piar ' + pair[1].filterable)); - return (
@@ -398,13 +390,13 @@ export class FilterPanel extends React.Component {
filter.split(Doc.FilterSep)[0] === facetHeader && filter.split(Doc.FilterSep)[1] == facetValue) - ?.split(Doc.FilterSep)[2] === 'check' - } + ?.split(Doc.FilterSep)[2] ?? '' + )} type={type} - onChange={undoable(e => Doc.setDocFilter(this.targetDoc, facetHeader, fval, e.target.checked ? 'check' : 'remove'), 'set filter')} + onChange={undoable(e => Doc.setDocFilter(this.targetDoc, facetHeader, fval, e.target.checked ? (fval === Doc.FilterAny ? 'exists' : 'check') : 'remove'), 'set filter')} /> {facetValue}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 699aafe80..21b6bfac5 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -18,7 +18,7 @@ import { ComputedField } from '../../fields/ScriptField'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../Utils'; -import { DocumentType } from '../documents/DocumentTypes'; +import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { DocumentManager } from '../util/DocumentManager'; import { GroupManager } from '../util/GroupManager'; import { LinkManager } from '../util/LinkManager'; @@ -122,6 +122,9 @@ export class PropertiesView extends React.Component { @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; } + @computed get isStack() { + return this.selectedDoc?.type_collection === CollectionViewType.Stacking; + } rtfWidth = () => (!this.selectedDoc ? 0 : Math.min(this.selectedDoc?.[Width](), this.props.width - 20)); rtfHeight = () => (!this.selectedDoc ? 0 : this.rtfWidth() <= this.selectedDoc?.[Width]() ? Math.min(this.selectedDoc?.[Height](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT); @@ -1096,6 +1099,8 @@ export class PropertiesView extends React.Component { @computed get transformEditor() { return (
+ {!this.isStack ? null : this.getNumber('Gap', ' px', 0, 200, NumCast(this.selectedDoc!.gridGap), (val: number) => !isNaN(val) && (this.selectedDoc!.gridGap = val))} + {!this.isStack ? null : this.getNumber('xMargin', ' px', 0, 500, NumCast(this.selectedDoc!.xMargin), (val: number) => !isNaN(val) && (this.selectedDoc!.xMargin = val))} {this.isInk ? this.controlPointsButton : null} {this.getNumber('Width', ' px', 0, Math.max(1000, this.shapeWid), this.shapeWid, (val: number) => !isNaN(val) && (this.shapeWid = val), 1000, 1)} {this.getNumber('Height', ' px', 0, Math.max(1000, this.shapeHgt), this.shapeHgt, (val: number) => !isNaN(val) && (this.shapeHgt = val), 1000, 1)} diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index ff347d65f..1e1b8e0e6 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -62,12 +62,9 @@ export class SidebarAnnos extends React.Component { DocListCast(this.props.rootDoc[this.sidebarKey]).forEach(doc => keys.add(StrCast(doc.author))); return Array.from(keys.keys()).sort(); } - get filtersKey() { - return '_' + this.sidebarKey + '_childFilters'; - } anchorMenuClick = (anchor: Doc, filterExlusions?: string[]) => { - const startup = StrListCast(this.props.rootDoc.childFilters) + const startup = this.childFilters() .map(filter => filter.split(':')[0]) .join(' '); const target = Docs.Create.TextDocument(startup, { @@ -151,8 +148,9 @@ export class SidebarAnnos extends React.Component { }; makeDocUnfiltered = (doc: Doc) => { if (DocListCast(this.props.rootDoc[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { - if (this.props.layoutDoc[this.filtersKey]) { - this.props.layoutDoc[this.filtersKey] = new List(); + if (this.childFilters()) { + // if any child filters exist, get rid of them + this.props.layoutDoc._childFilters = new List(); } return true; } @@ -178,7 +176,7 @@ export class SidebarAnnos extends React.Component { addDocument = (doc: Doc | Doc[]) => this.props.sidebarAddDocument(doc, this.sidebarKey); moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey); removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey); - childFilters = () => [...StrListCast(this.props.layoutDoc._childFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])]; + childFilters = () => StrListCast(this.props.layoutDoc._childFilters); layout_showTitle = () => 'title'; setHeightCallback = (height: number) => this.props.setHeight?.(height + this.filtersHeight()); sortByLinkAnchorY = (a: Doc, b: Doc) => { @@ -188,25 +186,25 @@ export class SidebarAnnos extends React.Component { }; render() { const renderTag = (tag: string) => { - const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`tags::${tag}::check`); + const active = this.childFilters().includes(`tags${Doc.FilterSep}${tag}${Doc.FilterSep}check`); return ( -
Doc.setDocFilter(this.props.rootDoc, 'tags', tag, 'check', true, this.sidebarKey, e.shiftKey)}> +
Doc.setDocFilter(this.props.rootDoc, 'tags', tag, 'check', true, undefined, e.shiftKey)}> {tag}
); }; const renderMeta = (tag: string, dflt: FieldResult) => { - const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${dflt}:exists`); + const active = this.childFilters().includes(`${tag}${Doc.FilterSep}${Doc.FilterAny}${Doc.FilterSep}exists`); return ( -
Doc.setDocFilter(this.props.rootDoc, tag, dflt, 'exists', true, this.sidebarKey, e.shiftKey)}> +
Doc.setDocFilter(this.props.rootDoc, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}> {tag}
); }; const renderUsers = (user: string) => { - const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`author:${user}:check`); + const active = this.childFilters().includes(`author:${user}:check`); return ( -
Doc.setDocFilter(this.props.rootDoc, 'author', user, 'check', true, this.sidebarKey, e.shiftKey)}> +
Doc.setDocFilter(this.props.rootDoc, 'author', user, 'check', true, undefined, e.shiftKey)}> {user}
); @@ -224,11 +222,11 @@ export class SidebarAnnos extends React.Component { height: '100%', }}>
e.stopPropagation()}> - {this.allUsers.map(renderUsers)} + {this.allUsers.length > 1 ? this.allUsers.map(renderUsers) : null} {this.allHashtags.map(renderTag)} - {/* {Array.from(this.allMetadata.keys()) + {Array.from(this.allMetadata.keys()) .sort() - .map(key => renderMeta(key, this.allMetadata.get(key)))} */} + .map(key => renderMeta(key, this.allMetadata.get(key)))}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 85aa5ad83..0a14b93f7 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -317,7 +317,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ({ + items={[ DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard)!, ...(props?.docViewPath?.()??[]), ...(props?.DocumentView?[props?.DocumentView?.()]:[])].map(dv => ({ text: StrCast(dv.rootDoc.title), val: dv as any, style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor}, diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 9ba4cb6cf..8c40567d3 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -138,7 +138,7 @@ export class CollectionStackingView extends CollectionSubView diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 3aadeffcd..3598d548a 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -361,7 +361,11 @@ export class CollectionStackingViewFieldColumn extends React.Component +
e.stopPropagation()} + className="collectionStackingView-addDocumentButton" + style={{ width: 'calc(100% - 25px)', maxWidth: this.props.columnWidth / this.props.numGroupColumns - 25, marginBottom: 10 }}> number; @@ -421,11 +422,27 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.Document._isGroup || this.Document._freeform_noZoom) return; + if (this.Document._isGroup || this.Document[this.scaleFieldKey + '_noZoom']) return; let deltaScale = deltaY > 0 ? 1 / 1.05 : 1.05; if (deltaScale < 0) deltaScale = -deltaScale; const [x, y] = this.getTransform().transformPoint(pointX, pointY); @@ -1032,12 +1049,15 @@ export class CollectionFreeFormView extends CollectionSubView 20) { deltaScale = 20 / invTransform.Scale; } - if (deltaScale < 1 && invTransform.Scale <= NumCast(this.rootDoc._freeform_scale_min, 1) && this.isAnnotationOverlay) { + if (deltaScale < 1 && invTransform.Scale <= NumCast(this.rootDoc[this.scaleFieldKey + '_min'])) { this.setPan(0, 0); return; } - if (deltaScale * invTransform.Scale < NumCast(this.rootDoc._freeform_scale_min, 1) && this.isAnnotationOverlay) { - deltaScale = NumCast(this.rootDoc._freeform_scale_min, 1) / invTransform.Scale; + if (deltaScale * invTransform.Scale > NumCast(this.rootDoc[this.scaleFieldKey + '_max'], Number.MAX_VALUE)) { + deltaScale = NumCast(this.rootDoc[this.scaleFieldKey + '_max'], 1) / invTransform.Scale; + } + if (deltaScale * invTransform.Scale < NumCast(this.rootDoc[this.scaleFieldKey + '_min'], this.isAnnotationOverlay ? 1 : 0)) { + deltaScale = NumCast(this.rootDoc[this.scaleFieldKey + '_min'], 1) / invTransform.Scale; } const localTransform = invTransform.scaleAbout(deltaScale, x, y); @@ -1527,12 +1547,6 @@ export class CollectionFreeFormView extends CollectionSubView .schema-column-header:nth-child(2) > .left { @@ -205,7 +211,7 @@ overflow-x: hidden; overflow-y: auto; padding: 5px; - display: inline-block; + display: inline-flex; } .schema-row { diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 5c7dcc1a4..d757d5349 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -836,6 +836,7 @@ export class CollectionSchemaView extends CollectionSubView() {
this.props.isContentActive() && e.stopPropagation()} ref={r => { // prevent wheel events from passively propagating up through containers diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 5b4fc34bb..4e418728f 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -16,7 +16,7 @@ import { CollectionSchemaView } from './CollectionSchemaView'; import './CollectionSchemaView.scss'; import { SchemaTableCell } from './SchemaTableCell'; import { Transform } from '../../../util/Transform'; -import { IconButton } from 'browndash-components'; +import { IconButton, Size } from 'browndash-components'; import { CgClose } from 'react-icons/cg'; import { FaExternalLinkAlt } from 'react-icons/fa'; import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils'; @@ -117,6 +117,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { } + size={Size.XSMALL} onPointerDown={e => setupMoveUpEvents( this, @@ -133,6 +134,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { } + size={Size.XSMALL} onPointerDown={e => setupMoveUpEvents( this, diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 1c9c0de53..e18f27fb0 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -325,10 +325,34 @@ export class SchemaEnumerationCell extends React.Component const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this.props); const options = this.props.options?.map(facet => ({ value: facet, label: facet })); return ( -
+
(this.showLayoutAcl = !this.showLayoutAcl))} /> @@ -843,11 +844,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
) : null}   */} +
-
- ) : ( -
- ); + ) : ( +
+ ); const titleArea = this._editingTitle ? ( Date: Mon, 18 Sep 2023 17:39:20 -0400 Subject: prepare merge --- src/client/util/reportManager/ReportManager.tsx | 1 + .../util/reportManager/reportManagerUtils.ts | 1 + src/client/views/pdf/GPTPopup/GPTPopup.tsx | 255 ++++++++++++++------- 3 files changed, 180 insertions(+), 77 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx index e684bd637..e6de410a7 100644 --- a/src/client/util/reportManager/ReportManager.tsx +++ b/src/client/util/reportManager/ReportManager.tsx @@ -128,6 +128,7 @@ export class ReportManager extends React.Component<{}> { let formattedLinks: string[] = []; if (this.formData.mediaFiles.length > 0) { const links = await uploadFilesToServer(this.formData.mediaFiles); + console.log('Links', links); if (links) { formattedLinks = links; } diff --git a/src/client/util/reportManager/reportManagerUtils.ts b/src/client/util/reportManager/reportManagerUtils.ts index b95417aa1..1bbb60f7a 100644 --- a/src/client/util/reportManager/reportManagerUtils.ts +++ b/src/client/util/reportManager/reportManagerUtils.ts @@ -111,6 +111,7 @@ export const uploadFilesToServer = async (mediaFiles: FileData[]): Promise ({ file: file.file }))); + console.log('Raw links', links); return (links ?? []).map(getServerPath).map(fileLinktoServerLink); } catch (err) { if (err instanceof Error) { diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 8bd060d4f..9b754588a 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -1,82 +1,227 @@ import React = require('react'); +import './GPTPopup.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import ReactLoading from 'react-loading'; import Typist from 'react-typist'; import { Doc } from '../../../../fields/Doc'; -import { Docs } from '../../../documents/Documents'; -import './GPTPopup.scss'; +import { DocUtils, Docs } from '../../../documents/Documents'; +import { Button, IconButton, Type } from 'browndash-components'; +import { NumCast, StrCast } from '../../../../fields/Types'; +import { CgClose } from 'react-icons/cg'; +import { AnchorMenu } from '../AnchorMenu'; +import { gptImageCall } from '../../../apis/gpt/GPT'; +import { Networking } from '../../../Network'; +import { Utils } from '../../../../Utils'; export enum GPTPopupMode { SUMMARY, EDIT, + IMAGE, } -interface GPTPopupProps { - visible: boolean; - text: string; - loading: boolean; - mode: GPTPopupMode; - callSummaryApi: (e: React.PointerEvent) => Promise; - callEditApi: (e: React.PointerEvent) => Promise; - replaceText: (replacement: string) => void; - highlightRange?: number[]; -} +interface GPTPopupProps {} @observer export class GPTPopup extends React.Component { static Instance: GPTPopup; @observable - private done: boolean = false; + public visible: boolean = false; + @action + public setVisible = (vis: boolean) => { + this.visible = vis; + }; @observable - private sidebarId: string = ''; + public loading: boolean = false; + @action + public setLoading = (loading: boolean) => { + this.loading = loading; + }; + @observable + public text: string = ''; + @action + public setText = (text: string) => { + this.text = text; + }; + + @observable + public imgDesc: string = ''; + @action + public setImgDesc = (text: string) => { + this.imgDesc = text; + }; + @observable + public imgUrls: string[][] = []; + @action + public setImgUrls = (imgs: string[][]) => { + this.imgUrls = imgs; + }; + + @observable + public mode: GPTPopupMode = GPTPopupMode.SUMMARY; + @action + public setMode = (mode: GPTPopupMode) => { + this.mode = mode; + }; + + @observable + public highlightRange: number[] = []; + @action callSummaryApi = () => {}; + @action callEditApi = () => {}; + @action replaceText = (replacement: string) => {}; + + @observable + private done: boolean = false; @action public setDone = (done: boolean) => { this.done = done; }; + + // change what can be a ref into a ref + @observable + private sidebarId: string = ''; @action public setSidebarId = (id: string) => { this.sidebarId = id; }; + @observable + private imgTargetDoc: Doc | undefined; + @action + public setImgTargetDoc = (anchor: Doc) => { + this.imgTargetDoc = anchor; + }; + + @observable + private textAnchor: Doc | undefined; + @action + public setTextAnchor = (anchor: Doc) => { + this.textAnchor = anchor; + }; + public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false; + public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; + + /** + * Generates a Dalle image and uploads it to the server. + */ + generateImage = async () => { + if (this.imgDesc === '') return; + this.setImgUrls([]); + this.setMode(GPTPopupMode.IMAGE); + this.setVisible(true); + this.setLoading(true); + + try { + let image_urls = await gptImageCall(this.imgDesc); + if (image_urls && image_urls[0]) { + // need to fix this + const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [image_urls[0]] }); + console.log('Result', result); + console.log('Client', result.accessPaths.agnostic.client); + const source = Utils.prepend(result.accessPaths.agnostic.client); + this.setImgUrls([[image_urls[0], source]]); + } + } catch (err) { + console.log(err); + } + GPTPopup.Instance.setLoading(false); + }; /** * Transfers the summarization text to a sidebar annotation text document. */ private transferToText = () => { - const newDoc = Docs.Create.TextDocument(this.props.text.trim(), { + const newDoc = Docs.Create.TextDocument(this.text.trim(), { _width: 200, _height: 50, _layout_fitWidth: true, _layout_autoHeight: true, }); this.addDoc(newDoc, this.sidebarId); + const anchor = AnchorMenu.Instance?.GetAnchor(undefined, false); + if (anchor) { + DocUtils.MakeLink(newDoc, anchor, { + link_relationship: 'GPT Summary', + }); + } + }; + + /** + * Transfers the image urls to actual image docs + */ + private transferToImage = (source: string) => { + const textAnchor = this.imgTargetDoc; + if (!textAnchor) return; + const newDoc = Docs.Create.ImageDocument(source, { + x: NumCast(textAnchor.x) + NumCast(textAnchor._width) + 10, + y: NumCast(textAnchor.y), + _height: 200, + _width: 200, + data_nativeWidth: 1024, + data_nativeHeight: 1024, + }); + if (Doc.IsInMyOverlay(textAnchor)) { + newDoc.overlayX = textAnchor.x; + newDoc.overlayY = NumCast(textAnchor.y) + NumCast(textAnchor._height); + Doc.AddToMyOverlay(newDoc); + } else { + this.addToCollection?.(newDoc); + } + // Create link between prompt and image + DocUtils.MakeLink(textAnchor, newDoc, { link_relationship: 'Image Prompt' }); }; + private getPreviewUrl = (source: string) => source.split('.').join('_m.'); + constructor(props: GPTPopupProps) { super(props); GPTPopup.Instance = this; } componentDidUpdate = () => { - if (this.props.loading) { + if (this.loading) { this.setDone(false); } }; + imageBox = () => { + return ( +
+ {this.heading('GENERATED IMAGE')} +
+ {this.imgUrls.map(rawSrc => ( +
+
+ dalle generation +
+
+
+
+ ))} +
+ {!this.loading && ( + <> + } color={StrCast(Doc.UserDoc().userVariantColor)} /> + + )} +
+ ); + }; + summaryBox = () => ( <>
{this.heading('SUMMARY')}
- {!this.props.loading && + {!this.loading && (!this.done ? ( { @@ -84,39 +229,32 @@ export class GPTPopup extends React.Component { this.setDone(true); }, 500); }}> - {this.props.text} + {this.text} ) : ( - this.props.text + this.text ))}
- {!this.props.loading && ( + {!this.loading && (
{this.done ? ( <> - - + } color={StrCast(Doc.UserDoc().userVariantColor)} /> + + }} + color={StrCast(Doc.UserDoc().userVariantColor)} + type={Type.TERT} + />
)}
@@ -124,43 +262,6 @@ export class GPTPopup extends React.Component { ); - editBox = () => { - const hr = this.props.highlightRange; - return ( - <> -
- {this.heading('TEXT EDIT SUGGESTIONS')} -
- {hr && ( -
- {this.props.text.slice(0, hr[0])} {this.props.text.slice(hr[0], hr[1])} {this.props.text.slice(hr[1])} -
- )} -
-
- {hr && !this.props.loading && ( - <> -
- <> - - - -
- {this.aiWarning()} - - )} - - ); - }; - aiWarning = () => this.done ? (
@@ -174,14 +275,14 @@ export class GPTPopup extends React.Component { heading = (headingText: string) => (
- {this.props.loading && } + {this.loading ? : } onClick={() => this.setVisible(false)} />}
); render() { return ( -
- {this.props.mode === GPTPopupMode.SUMMARY ? this.summaryBox() : this.editBox()} +
+ {this.mode === GPTPopupMode.SUMMARY ? this.summaryBox() : this.mode === GPTPopupMode.IMAGE ? this.imageBox() : <>}
); } -- cgit v1.2.3-70-g09d2 From 9bff82f5d53f7d13802f8affc4759db0953d7dc7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 14:15:52 -0400 Subject: made goldenlayout tabs/buttons follow color scheme + added hover highlights. got rid of old color scheme code. --- src/client/goldenLayout.js | 14 +- src/client/util/CurrentUserUtils.ts | 14 +- src/client/views/DocumentDecorations.tsx | 10 +- src/client/views/MainView.scss | 90 +---- src/client/views/MainView.tsx | 9 +- src/client/views/StyleProvider.tsx | 26 +- .../views/collections/CollectionDockingView.scss | 396 +++++++++++++++++++-- .../views/collections/CollectionDockingView.tsx | 57 +-- src/client/views/collections/TabDocView.tsx | 1 + .../CollectionFreeFormLayoutEngines.tsx | 2 +- .../views/nodes/formattedText/DashDocView.tsx | 2 +- src/mobile/MobileInterface.tsx | 5 +- 12 files changed, 448 insertions(+), 178 deletions(-) (limited to 'src/client/util') diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js index 843b8bb5f..00ec5e439 100644 --- a/src/client/goldenLayout.js +++ b/src/client/goldenLayout.js @@ -1606,10 +1606,10 @@ dragProxyHeight: 200 }, labels: { - close: 'close', - maximise: 'maximise', + close: 'close tab stack', + maximise: 'maximize stack', minimise: 'minimise', - popout: 'new tab', + popout: 'create new collection tab', popin: 'pop in', tabDropdown: 'additional tabs' } @@ -2922,7 +2922,7 @@ * @type {String} */ lm.controls.Tab._template = '
  • ' + - '
    ' + + '
    ' + '
  • '; lm.utils.copy(lm.controls.Tab.prototype, { @@ -5083,10 +5083,10 @@ 'column', 'stack', 'component', - 'close', - 'maximise', + 'close tab stack', + 'maximize stack', 'minimise', - 'new tab' + 'create new collection tab' ]; }; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 452bb74cd..2983d778f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -476,7 +476,6 @@ export class CurrentUserUtils { static setupDashboards(doc: Doc, field:string) { var myDashboards = DocCast(doc[field]); - const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`; const newDashboard = `createNewDashboard()`; const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, @@ -487,10 +486,10 @@ export class CurrentUserUtils { const contextMenuScripts = [/*newDashboard*/] as string[]; const contextMenuLabels = [/*"Create New Dashboard"*/] as string[]; const contextMenuIcons = [/*"plus"*/] as string[]; - const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters - const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts - const childContextMenuLabels = ["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters - const childContextMenuIcons = ["chalkboard", "tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters + const childContextMenuScripts = [`toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + const childContextMenuLabels = ["Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters + const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { title: "My Dashboards", childHideLinkButton: true, treeView_FreezeChildren: "remove|add", treeView_HideTitle: true, layout_boxShadow: "0 0", childDontRegisterViews: true, dropAction: "same", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, @@ -892,7 +891,6 @@ export class CurrentUserUtils { doc.defaultAclPrivate ?? (doc.defaultAclPrivate = false); doc.savedFilters ?? (doc.savedFilters = new List()); doc.userBackgroundColor ?? (doc.userBackgroundColor = Colors.DARK_GRAY); - addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${doc.userBackgroundColor} !important` }); doc.userVariantColor ?? (doc.userVariantColor = Colors.MEDIUM_BLUE); doc.userColor ?? (doc.userColor = Colors.LIGHT_GRAY); doc.userTheme ?? (doc.userTheme = ColorScheme.Dark); @@ -920,10 +918,6 @@ export class CurrentUserUtils { Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org") - if (doc.activeDashboard instanceof Doc) { - // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) - doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme; - } new LinkManager(); DocServer.CacheNeedsUpdate && setTimeout(DocServer.UPDATE_SERVER_CACHE, 2500); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 7e55b0ebc..327bb5585 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -804,8 +804,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); - const colorScheme = StrCast(Doc.ActiveDashboard?.colorScheme); - const leftBounds = this.props.boundsLeft; const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop; bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; @@ -818,7 +816,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const useRotation = !hideResizers && seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.props.CollectionFreeFormDocumentView; // when do we want an object to not rotate? const rotation = SelectionManager.Views().length == 1 ? NumCast(seldocview.rootDoc._rotation) : 0; - const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; + const resizerScheme = ''; // Radius constants const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView; @@ -853,7 +851,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const titleArea = this._editingTitle ? ( {hideTitle ? null : ( - + {this.selectionTitle} )} @@ -887,7 +885,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); return ( -
    +
    ; @computed private get mainContainer() { if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') { @@ -800,7 +797,7 @@ export class MainView extends React.Component { return ( <> {this._hideUI ? null : this.leftMenuPanel} -
    +
    {this.flyout}
    @@ -1003,7 +1000,7 @@ export class MainView extends React.Component { render() { return (
    @@ -135,7 +131,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt, props: Opt 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (darkScheme() ? Colors.BLACK : Colors.MEDIUM_GRAY)); + (Colors.DARK_GRAY) + : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY)); break; //if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)"; - default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); + default: docColor = docColor || (Colors.WHITE); } return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor; } @@ -247,7 +243,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt .lm_item { + float: left; +} +.lm_content { + overflow: hidden; + position: relative; +} +.lm_dragging, +.lm_dragging * { + cursor: move !important; + user-select: none; +} +.lm_maximised { + position: absolute; + top: 0; + left: 0; + z-index: 40; +} +.lm_maximise_placeholder { + display: none; +} +.lm_splitter { + position: relative; + z-index: 20; +} +.lm_splitter:hover, +.lm_splitter.lm_dragging { + background: orange; +} +.lm_splitter.lm_vertical .lm_drag_handle { + width: 100%; + position: absolute; + cursor: ns-resize; +} +.lm_splitter.lm_horizontal { + float: left; + height: 100%; +} +.lm_splitter.lm_horizontal .lm_drag_handle { + height: 100%; + position: absolute; + cursor: ew-resize; +} +.lm_header { + overflow: visible; + position: relative; + z-index: 1; +} +// .lm_header [class^='lm_'] { +// box-sizing: content-box !important; +// } +.lm_header .lm_controls { + position: absolute; + right: 3px; +} +.lm_header .lm_controls > li { + cursor: pointer; + float: left; + width: 18px; + height: 18px; + text-align: center; +} +.lm_header ul { + margin: 0; + padding: 0; + list-style-type: none; +} +.lm_header .lm_tabs { + position: absolute; +} +.lm_header .lm_tab { + cursor: pointer; + float: left; + height: 25px; + padding: 0 10px 5px; + padding-right: 25px; + position: relative; + box-shadow: unset !important; +} +.lm_header .lm_tab i { + width: 2px; + height: 19px; + position: absolute; +} +.lm_header .lm_tab i.lm_left { + top: 0; + left: -2px; +} +.lm_header .lm_tab i.lm_right { + top: 0; + right: -2px; +} +.lm_header .lm_tab .lm_title { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; +} +.lm_header .lm_tab .lm_close_tab { + width: 14px; + height: 14px; + position: absolute; + top: 0; + right: 0; + text-align: center; +} +.lm_stack.lm_left .lm_header, +.lm_stack.lm_right .lm_header { + height: 100%; +} +.lm_dragProxy.lm_left .lm_header, +.lm_dragProxy.lm_right .lm_header, +.lm_stack.lm_left .lm_header, +.lm_stack.lm_right .lm_header { + width: 20px; + float: left; + vertical-align: top; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs, +.lm_dragProxy.lm_right .lm_header .lm_tabs, +.lm_stack.lm_left .lm_header .lm_tabs, +.lm_stack.lm_right .lm_header .lm_tabs { + transform-origin: left top; + top: 0; + width: 1000px; +} +.lm_dragProxy.lm_left .lm_header .lm_controls, +.lm_dragProxy.lm_right .lm_header .lm_controls, +.lm_stack.lm_left .lm_header .lm_controls, +.lm_stack.lm_right .lm_header .lm_controls { + bottom: 0; +} +.lm_dragProxy.lm_left .lm_items, +.lm_dragProxy.lm_right .lm_items, +.lm_stack.lm_left .lm_items, +.lm_stack.lm_right .lm_items { + float: left; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs, +.lm_stack.lm_left .lm_header .lm_tabs { + transform: rotate(-90deg) scaleX(-1); + left: 0; +} +.lm_dragProxy.lm_left .lm_header .lm_tabs .lm_tab, +.lm_stack.lm_left .lm_header .lm_tabs .lm_tab { + transform: scaleX(-1); + margin-top: 1px; +} +.lm_dragProxy.lm_left .lm_header .lm_tabdropdown_list, +.lm_stack.lm_left .lm_header .lm_tabdropdown_list { + top: initial; + right: initial; + left: 20px; +} +.lm_dragProxy.lm_right .lm_content { + float: left; +} +.lm_dragProxy.lm_right .lm_header .lm_tabs, +.lm_stack.lm_right .lm_header .lm_tabs { + transform: rotate(90deg) scaleX(1); + left: 100%; + margin-left: 0; +} +.lm_dragProxy.lm_right .lm_header .lm_controls, +.lm_stack.lm_right .lm_header .lm_controls { + left: 3px; +} +.lm_dragProxy.lm_right .lm_header .lm_tabdropdown_list, +.lm_stack.lm_right .lm_header .lm_tabdropdown_list { + top: initial; + right: 20px; +} +.lm_dragProxy.lm_bottom .lm_header .lm_tab, +.lm_stack.lm_bottom .lm_header .lm_tab { + margin-top: 0; + border-top: none; +} +.lm_dragProxy.lm_bottom .lm_header .lm_controls, +.lm_stack.lm_bottom .lm_header .lm_controls { + top: 3px; +} +.lm_dragProxy.lm_bottom .lm_header .lm_tabdropdown_list, +.lm_stack.lm_bottom .lm_header .lm_tabdropdown_list { + top: initial; + bottom: 20px; +} +.lm_drop_tab_placeholder { + float: left; + width: 100px; + height: 10px; + visibility: hidden; +} +.lm_header .lm_controls .lm_tabdropdown:before { + content: ''; + width: 0; + height: 0; + vertical-align: middle; + display: inline-block; + border-top: 5px dashed; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + color: white; +} +.lm_header .lm_tabdropdown_list { + position: absolute; + top: 20px; + right: 0; + z-index: 5; + overflow: hidden; +} +.lm_header .lm_tabdropdown_list .lm_tab { + clear: both; + padding-right: 10px; + margin: 0; +} +.lm_header .lm_tabdropdown_list .lm_tab .lm_title { + width: 100px; +} +.lm_header .lm_tabdropdown_list .lm_close_tab { + display: none !important; +} +.lm_dragProxy { + position: absolute; + top: 0; + left: 0; + z-index: 30; +} +.lm_dragProxy .lm_header { + background: transparent; +} +.lm_dragProxy .lm_content { + border-top: none; + overflow: hidden; +} +.lm_dropTargetIndicator { + display: none; + position: absolute; + z-index: 20; +} +.lm_dropTargetIndicator .lm_inner { + width: 100%; + height: 100%; + position: relative; + top: 0; + left: 0; +} +.lm_transition_indicator { + display: none; + width: 20px; + height: 20px; + position: absolute; + top: 0; + left: 0; + z-index: 20; +} +.lm_popin { + width: 20px; + height: 20px; + position: absolute; + bottom: 0; + right: 0; + z-index: 9999; +} +.lm_popin > * { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} +.lm_popin > .lm_bg { + z-index: 10; +} +.lm_popin > .lm_icon { + z-index: 20; +} /*# sourceMappingURL=goldenlayout-base.css.map */ + @import '../../../../node_modules/golden-layout/src/css/goldenlayout-dark-theme.css'; .lm_title { @@ -46,18 +325,33 @@ // font-weight: 700; } +.lm_header .lm_tabs { + overflow-y: hidden; + width: 100%; +} +ul.lm_tabs::before { + content: ' '; + position: absolute; + bottom: 0; + width: 100%; + z-index: 1; + pointer-events: none; + border: solid 1px black; +} .lm_header .lm_tab { // padding: 0px; // moved to MainView.scss, othwerise they get overridden by default stylings // opacity: 0.7; // box-shadow: none; // height: 25px; // border-bottom: black solid; + border-bottom: unset !important; + border-top-right-radius: 5px; + border-top-left-radius: 5px; .collectionDockingView-gear { display: none; } } - .lm_header .lm_tab.lm_active { padding: 0; opacity: 1; @@ -65,7 +359,11 @@ box-shadow: none; height: 27px; margin-right: 2px; - // border-bottom: unset; + z-index: 2 !important; + border-right: solid 2px; + border-left: solid 2px; + border-top: solid 2px; + border-color: black; .collectionDockingView-gear { display: inline-block; @@ -123,20 +421,63 @@ } .lm_close_tab { + display: inline-flex !important; + opacity: 0 !important; padding: 0; align-self: center; margin-right: 5px; - background-color: black; border-radius: 3px; - opacity: 1 !important; width: 15px !important; height: 15px !important; position: relative !important; - display: inline-flex !important; align-items: center; top: 0 !important; right: unset !important; left: 0 !important; + background-image: unset !important; + &::before { + content: 'x'; + color: rgb(50, 50, 50); + margin: auto; + position: relative; + top: -2px; + } + &:hover { + display: inline-flex !important; + &::before { + color: white; + } + } +} +.lm_close { + background-image: unset !important; + &:hover { + background: gray; + color: white !important; + } + &::before { + content: 'x'; + margin: auto; + position: relative; + top: -2; + font-size: medium; + font-family: sans-serif; + } +} +.lm_active .lm_close_tab { + opacity: 1 !important; +} +.lm_tab:hover { + .lm_close_tab { + opacity: 1 !important; + } +} + +.lm_iconWrap { + &:hover { + background: gray; + color: white !important; + } } .lm_tab, @@ -154,14 +495,6 @@ top: 0; left: 0; - // overflow: hidden; // bcz: menus don't show up when this is on (e.g., the parentSelectorMenu) - .collectionDockingView-gear { - padding-left: 5px; - height: 15px; - width: 18px; - margin: auto; - } - .collectionDockingView-drag { touch-action: none; position: absolute; @@ -180,7 +513,6 @@ display: flex; align-content: center; justify-content: center; - background: $dark-gray; } .lm_controls > li { @@ -190,14 +522,38 @@ } .lm_controls .lm_popout { - transform: rotate(45deg); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAQUlEQVR4nHXOQQ4AMAgCQeT/f6aXpsGK3jSTuCVJAAr7iBdoAwCKd0nwfaAdHbYERw5b44+E8JoBjEYGMBq5gAYP3usUDu2IvoUAAAAASUVORK5CYII=); + background-image: unset; + left: -3; + &:hover { + background: gray; + color: white !important; + } + } + li.lm_popout::before { + content: '+'; + margin: auto; + font-size: x-large; + top: -8; + position: relative; + } + .lm_maximise { + background-image: unset !important; + &::before { + content: '\25A3'; + margin: auto; + font-size: medium; + position: relative; + } + &:hover { + background: gray; + color: white !important; + } } .lm_maximised .lm_controls .lm_maximise { - opacity: 1; - transform: scale(0.8); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKElEQVR4nGP8////fwYCgImQAgYGBgYWKM2IR81/okwajIpgvsMbVgAwgQYRVakEKQAAAABJRU5ErkJggg==) !important; + &::before { + content: '\25A2'; + } } .flexlayout__layout { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 8472c59db..4873a61ff 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -10,7 +10,7 @@ import { List } from '../../../fields/List'; import { ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { GetEffectiveAcl, inheritParentAcls } from '../../../fields/util'; -import { emptyFunction, incrementTitleCopy } from '../../../Utils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, incrementTitleCopy } from '../../../Utils'; import { DocServer } from '../../DocServer'; import { Docs } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; @@ -31,6 +31,7 @@ import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; import React = require('react'); +import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; @observer @@ -60,7 +61,7 @@ export class CollectionDockingView extends CollectionSubView() { return this._goldenLayout._maximisedItem !== null; } private _goldenLayout: any = null; - + static _highlightStyleSheet: any = addStyleSheet(); constructor(props: SubCollectionViewProps) { super(props); if (this.props.renderDepth < 0) runInAction(() => (CollectionDockingView.Instance = this)); @@ -330,6 +331,16 @@ export class CollectionDockingView extends CollectionSubView() { width => !this._goldenLayout && width > 20 && setTimeout(() => this.setupGoldenLayout()), // need to wait for the collectiondockingview-container to have it's width/height since golden layout reads that to configure its windows { fireImmediately: true } ); + reaction( + () => [SettingsManager.userBackgroundColor, SettingsManager.userBackgroundColor], + () => { + clearStyleSheetRules(CollectionDockingView._highlightStyleSheet); + addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { background: `${SettingsManager.userBackgroundColor} !important` }); + addStyleSheetRule(CollectionDockingView._highlightStyleSheet, 'lm_controls', { color: `${SettingsManager.userColor} !important` }); + addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${SettingsManager.userBackgroundColor} !important` }); + }, + { fireImmediately: true } + ); } }; @@ -505,6 +516,23 @@ export class CollectionDockingView extends CollectionSubView() { } }); + let addNewDoc = action(() => { + const dashboard = Doc.ActiveDashboard; + if (dashboard) { + dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; + const docToAdd = Docs.Create.FreeformDocument([], { + _width: this.props.PanelWidth(), + _height: this.props.PanelHeight(), + _layout_fitWidth: true, + _freeform_backgroundGrid: true, + title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, + }); + Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd); + inheritParentAcls(this.dataDoc, docToAdd, false); + CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack); + } + }); + stack.header?.controlsContainer .find('.lm_close') //get the close icon .off('click') //unbind the current click handler @@ -524,31 +552,18 @@ export class CollectionDockingView extends CollectionSubView() { }) ); + stack.element.click((e: any) => { + if (stack.contentItems.length === 0 && Array.from(document.elementsFromPoint(e.originalEvent.x, e.originalEvent.y)).some(ele => ele?.className === 'empty-tabs-message')) { + addNewDoc(); + } + }); stack.header?.controlsContainer .find('.lm_maximise') //get the close icon .click(() => setTimeout(this.stateChanged)); stack.header?.controlsContainer .find('.lm_popout') //get the popout icon .off('click') //unbind the current click handler - .click( - action(() => { - // stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size - const dashboard = Doc.ActiveDashboard; - if (dashboard) { - dashboard['pane-count'] = NumCast(dashboard['pane-count']) + 1; - const docToAdd = Docs.Create.FreeformDocument([], { - _width: this.props.PanelWidth(), - _height: this.props.PanelHeight(), - _layout_fitWidth: true, - _freeform_backgroundGrid: true, - title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`, - }); - Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd); - inheritParentAcls(this.dataDoc, docToAdd, false); - CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack); - } - }) - ); + .click(addNewDoc); }; render() { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index dab53b671..26aa5a121 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -132,6 +132,7 @@ export class TabDocView extends React.Component { if (tab.element[0].children[1].children.length === 1) { iconWrap.className = 'lm_iconWrap lm_moreInfo'; + iconWrap.title = 'click for menu, drag to embed in document'; const dragBtnDown = (e: React.PointerEvent) => { setupMoveUpEvents( this, diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 1e76d373c..15b6e1d37 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -350,7 +350,7 @@ export function computeTimelineLayout(poolData: Map, pivotDoc: groupNames.push({ type: 'text', text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined }); } - const divider = { type: 'div', color: Doc.ActiveDashboard?.colorScheme === ColorScheme.Dark ? 'dimgray' : 'black', x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; + const divider = { type: 'div', color: 'black', x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined }; return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]); function layoutDocsAtTime(keyDocs: Doc[], key: number) { diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 48f4c2afd..5349e6966 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -22,7 +22,7 @@ export class DashDocView { this.dom = document.createElement('span'); this.dom.style.position = 'relative'; this.dom.style.textIndent = '0'; - this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, Doc.ActiveDashboard?.colorScheme === ColorScheme.Dark ? 'dimgray' : 'lightGray'); + this.dom.style.border = '1px solid ' + StrCast(tbox.layoutDoc.color, 'lightGray'); this.dom.style.width = node.attrs.width; this.dom.style.height = node.attrs.height; this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index c16a1c124..498bec6ed 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -588,11 +588,10 @@ export class MobileInterface extends React.Component { const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row'); - const toggleTheme = ScriptField.MakeScript(`self.colorScheme = self.colorScheme ? undefined: ${ColorScheme.Dark}}`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`); - dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, cloneDashboard!]); - dashboardDoc.contextMenuLabels = new List(['Toggle Theme Colors', 'Toggle Comic Mode', 'New Dashboard Layout']); + dashboardDoc.contextMenuScripts = new List([toggleComic!, cloneDashboard!]); + dashboardDoc.contextMenuLabels = new List(['Toggle Comic Mode', 'New Dashboard Layout']); Doc.AddDocToList(scens, 'data', dashboardDoc); }; -- cgit v1.2.3-70-g09d2 From 8c8bbfe3ac8e17f9716abaf4560f6490538dc004 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 19 Sep 2023 16:19:25 -0400 Subject: fixed match system color settings. --- src/client/util/SettingsManager.tsx | 43 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 085ff4bb1..dc852596f 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -20,10 +20,9 @@ import { undoBatch } from './UndoManager'; export enum ColorScheme { Dark = 'Dark', Light = 'Light', - CoolBlue = 'Cool Blue', - Cupcake = 'Cupcake', - System = 'Match System', Custom = 'Custom', + CoolBlue = 'CoolBlue', + Cupcake = 'Cupcake', } export enum freeformScrollMode { @@ -50,7 +49,21 @@ export class SettingsManager extends React.Component<{}> { constructor(props: {}) { super(props); SettingsManager.Instance = this; + this.matchSystem(); + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + if (Doc.UserDoc().userThemeSystem) { + if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark); + if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light); + } + // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) + }); } + matchSystem = () => { + if (Doc.UserDoc().userThemeSystem) { + if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark); + if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light); + } + }; public close = action(() => (this.isOpen = false)); public open = action(() => (this.isOpen = true)); @@ -88,6 +101,10 @@ export class SettingsManager extends React.Component<{}> { }); @undoBatch switchUserColor = action((color: string) => (Doc.UserDoc().userColor = color)); @undoBatch switchUserVariantColor = action((color: string) => (Doc.UserDoc().userVariantColor = color)); + @undoBatch userThemeSystemToggle = action(() => { + Doc.UserDoc().userThemeSystem = !Doc.UserDoc().userThemeSystem; + this.matchSystem(); + }); @undoBatch playgroundModeToggle = action(() => { this.playgroundMode = !this.playgroundMode; if (this.playgroundMode) { @@ -123,18 +140,11 @@ export class SettingsManager extends React.Component<{}> { break; case ColorScheme.Custom: break; - case ColorScheme.System: - default: - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) - }); - break; } }); @computed get colorsContent() { - const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.Cupcake, ColorScheme.CoolBlue, ColorScheme.Custom, ColorScheme.System]; - const schemeMap = ['Light', 'Dark', 'Cupcake', 'Cool Blue', 'Custom', 'Match System']; + const schemeMap = Array.from(Object.keys(ColorScheme)); const userTheme = StrCast(Doc.UserDoc().userTheme); return (
    @@ -144,15 +154,20 @@ export class SettingsManager extends React.Component<{}> { type={Type.TERT} closeOnSelect={false} selectedVal={userTheme} - setSelectedVal={scheme => this.changeColorScheme(scheme as string)} - items={colorSchemes.map((scheme, i) => ({ - text: schemeMap[i], + setSelectedVal={scheme => { + this.changeColorScheme(scheme as string); + Doc.UserDoc().userThemeSystem = false; + }} + items={Object.keys(ColorScheme).map((scheme, i) => ({ + text: schemeMap[i].replace(/([a-z])([A-Z])/, '$1 $2'), val: scheme, }))} dropdownType={DropdownType.SELECT} color={SettingsManager.userColor} fillWidth /> + + {userTheme === ColorScheme.Custom && ( Date: Tue, 19 Sep 2023 16:52:57 -0400 Subject: turned off ink and dragging in explore mode. --- src/client/util/CurrentUserUtils.ts | 11 ++++++----- src/client/util/DragManager.ts | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2983d778f..cbdc2fc81 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -8,10 +8,10 @@ import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; import { ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types"; -import { nullAudio, URLField, WebField } from "../../fields/URLField"; +import { nullAudio, WebField } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; -import { addStyleSheetRule, OmitKeys, Utils } from "../../Utils"; +import { OmitKeys, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents"; import { CollectionViewType, DocumentType } from "../documents/DocumentTypes"; @@ -19,7 +19,7 @@ import { TreeViewType } from "../views/collections/CollectionTreeView"; import { DashboardView } from "../views/DashboardView"; import { Colors } from "../views/global/globalEnums"; import { media_state } from "../views/nodes/AudioBox"; -import { OpenWhere } from "../views/nodes/DocumentView"; +import { DocumentView, OpenWhere } from "../views/nodes/DocumentView"; import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox"; import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox"; import { OverlayView } from "../views/OverlayView"; @@ -28,7 +28,7 @@ import { MakeTemplate } from "./DropConverter"; import { FollowLinkScript } from "./LinkFollower"; import { LinkManager } from "./LinkManager"; import { ScriptingGlobals } from "./ScriptingGlobals"; -import { ColorScheme, SettingsManager } from "./SettingsManager"; +import { ColorScheme } from "./SettingsManager"; import { UndoManager } from "./UndoManager"; interface Button { @@ -714,7 +714,7 @@ export class CurrentUserUtils { { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available - { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available + { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available @@ -1022,6 +1022,7 @@ export class CurrentUserUtils { } ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "document containing all shared Docs"); +ScriptingGlobals.add(function IsExploreMode() { return DocumentView.ExploreMode; }, "is Dash in exploration mode"); ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode"); ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6d6eaebec..ed22e70bd 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -324,7 +324,7 @@ export namespace DragManager { export let CanEmbed = false; export let DocDragData: DocumentDragData | undefined; export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void, dragUndoName?: string) { - if (dragData.dropAction === 'none') return; + if (dragData.dropAction === 'none' || DocumentView.ExploreMode) return; DocDragData = dragData as DocumentDragData; const batch = UndoManager.StartBatch(dragUndoName ?? 'document drag'); eles = eles.filter(e => e); -- cgit v1.2.3-70-g09d2 From b6920e6ffc50eb46f3ac3657c9d5b4fe45e1dd0a Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 20 Sep 2023 01:25:40 -0400 Subject: shifted carousel fwd/back buttons away from edges of screen. made caption width of carousel inset by 30. made 3d carousel images bigger vertically. made properties dragger handle smaller when minimized. --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/MainView.scss | 6 +++++- src/client/views/MainView.tsx | 6 +++++- .../collections/CollectionCarousel3DView.scss | 4 ++-- .../views/collections/CollectionCarouselView.scss | 23 +++++++++++----------- .../views/collections/CollectionCarouselView.tsx | 16 ++++++++------- src/client/views/global/globalCssVariables.scss | 2 +- 7 files changed, 35 insertions(+), 24 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index cbdc2fc81..259c028cc 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -707,8 +707,8 @@ export class CurrentUserUtils { CollectionViewType.Grid, CollectionViewType.NoteTaking]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, - { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: true, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, + { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}, funcs: {hidden: "IsNoneSelected()"}}, // Only when a document is selected { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: '{ return toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 98367969b..4fb2ac279 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -96,6 +96,7 @@ h1, top: 0; } +.mainView-propertiesDragger-minified, .mainView-propertiesDragger { //background-color: rgb(140, 139, 139); background-color: $light-gray; @@ -108,9 +109,9 @@ h1, border-bottom-left-radius: 10px; border-right: unset; z-index: 41; // lm_maximised has a z-index of 40 and this needs to be above that - display: flex; align-items: center; padding: 4px; + display: flex; .mainView-propertiesDragger-icon { width: 10px; @@ -124,6 +125,9 @@ h1, cursor: grab; } } +.mainView-propertiesDragger-minified { + width: 10px; +} .mainView-innerContent { display: contents; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 6d08c01fa..d6f5d63fe 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -809,7 +809,11 @@ export class MainView extends React.Component { {this.dockingContent} {this._hideUI ? null : ( -
    +
    )} diff --git a/src/client/views/collections/CollectionCarousel3DView.scss b/src/client/views/collections/CollectionCarousel3DView.scss index 6bd1d9f5f..7622043e3 100644 --- a/src/client/views/collections/CollectionCarousel3DView.scss +++ b/src/client/views/collections/CollectionCarousel3DView.scss @@ -87,13 +87,13 @@ .carousel3DView-fwd, .carousel3DView-fwd-scroll, .carousel3DView-fwd-scroll-hidden { - right: 0; + right: 20; } .carousel3DView-back, .carousel3DView-back-scroll, .carousel3DView-back-scroll-hidden { - left: 0; + left: 20; } .carousel3DView-fwd-scroll-hidden, diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss index 8660113cd..130b31325 100644 --- a/src/client/views/collections/CollectionCarouselView.scss +++ b/src/client/views/collections/CollectionCarouselView.scss @@ -1,8 +1,7 @@ - .collectionCarouselView-outer { - height : 100%; + height: 100%; .collectionCarouselView-caption { - height: 50; + height: 50; display: inline-block; width: 100%; } @@ -13,7 +12,8 @@ user-select: none; } } -.carouselView-back, .carouselView-fwd { +.carouselView-back, +.carouselView-fwd { position: absolute; display: flex; top: 42.5%; @@ -22,18 +22,19 @@ align-items: center; border-radius: 5px; justify-content: center; - color: rgba(255,255,255,0.5); - background : rgba(0,0,0, 0.1); + color: rgba(255, 255, 255, 0.5); + background: rgba(0, 0, 0, 0.1); &:hover { - color:white; + color: white; } } .carouselView-fwd { - right: 0; + right: 20; } .carouselView-back { - left: 0; + left: 20; } -.carouselView-back:hover, .carouselView-fwd:hover { +.carouselView-back:hover, +.carouselView-fwd:hover { background: lightgray; -} \ No newline at end of file +} diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 7fa36d228..040a584b8 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, Opt } from '../../../fields/Doc'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnFalse, returnZero, StopEvent } from '../../../Utils'; +import { emptyFunction, returnFalse, returnOne, returnZero, StopEvent } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; @@ -44,12 +44,14 @@ export class CollectionCarouselView extends CollectionSubView() { panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._layout_showCaption) ? 50 : 0); onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); + @computed get marginX() { + return NumCast(this.layoutDoc.caption_xMargin, 50); + } + captionWidth = () => this.props.PanelWidth() - 2 * this.marginX; @computed get content() { const index = NumCast(this.layoutDoc._carousel_index); const curDoc = this.childLayoutPairs?.[index]; - const captionProps = { ...this.props, fieldKey: 'caption', setHeight: undefined, setContentView: undefined }; - const marginX = NumCast(this.layoutDoc['caption_xMargin']); - const marginY = NumCast(this.layoutDoc['caption_yMargin']); + const captionProps = { ...this.props, NativeScaling: returnOne, PanelWidth: this.captionWidth, fieldKey: 'caption', setHeight: undefined, setContentView: undefined }; const show_captions = StrCast(this.layoutDoc._layout_showCaption); return !(curDoc?.layout instanceof Doc) ? null : ( <> @@ -80,9 +82,9 @@ export class CollectionCarouselView extends CollectionSubView() { style={{ display: show_captions ? undefined : 'none', borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding), - marginRight: marginX, - marginLeft: marginX, - width: `calc(100% - ${marginX * 2}px)`, + marginRight: this.marginX, + marginLeft: this.marginX, + width: `calc(100% - ${this.marginX * 2}px)`, }}>
    diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss index 7b2ac5713..ddd99c836 100644 --- a/src/client/views/global/globalCssVariables.scss +++ b/src/client/views/global/globalCssVariables.scss @@ -71,7 +71,7 @@ $LEFT_MENU_WIDTH: 60px; $TREE_BULLET_WIDTH: 20px; $CAROUSEL3D_CENTER_SCALE: 1.3; -$CAROUSEL3D_SIDE_SCALE: 0.3; +$CAROUSEL3D_SIDE_SCALE: 0.6; $CAROUSEL3D_TOP: 15; :export { -- cgit v1.2.3-70-g09d2 From 34f3bab0f4d55b2f55f38e451bfd024994ecff42 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 20 Sep 2023 13:20:53 -0400 Subject: added carousel3D to novice and fixed it's button positions and its focus so that it works with trails. added dragging documents within single collection for rearranging order of docs in a tab collection. fixed freeform views set to fitWidth to show decorations properly. turned off scaling of tree views. updated lightbox buttons. fixed tooltips on properties toggles. --- src/client/util/CurrentUserUtils.ts | 4 +- src/client/util/DragManager.ts | 2 +- src/client/views/LightboxView.scss | 11 +-- src/client/views/LightboxView.tsx | 106 +++++++++++++-------- src/client/views/PropertiesButtons.tsx | 12 ++- .../views/collections/CollectionCarousel3DView.tsx | 17 +++- src/client/views/collections/CollectionSubView.tsx | 5 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/TreeView.tsx | 6 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 9 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 +- 11 files changed, 109 insertions(+), 69 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 259c028cc..2ea5972ee 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -492,8 +492,8 @@ export class CurrentUserUtils { const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { title: "My Dashboards", childHideLinkButton: true, treeView_FreezeChildren: "remove|add", treeView_HideTitle: true, layout_boxShadow: "0 0", childDontRegisterViews: true, - dropAction: "same", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, - layout_headerButton: newDashboardButton, childDragAction: "none", + dropAction: "inSame", treeView_Type: TreeViewType.fileSystem, isFolder: true, isSystem: true, treeView_TruncateTitleWidth: 350, ignoreClick: true, + layout_headerButton: newDashboardButton, childDragAction: "inSame", _layout_showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true, contextMenuLabels:new List(contextMenuLabels), contextMenuIcons:new List(contextMenuIcons), diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index ed22e70bd..f86f9a3e5 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -14,7 +14,7 @@ import { SelectionManager } from './SelectionManager'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; -export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove +export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'inSame' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove /** * Initialize drag diff --git a/src/client/views/LightboxView.scss b/src/client/views/LightboxView.scss index f86a1d211..9a9b8a437 100644 --- a/src/client/views/LightboxView.scss +++ b/src/client/views/LightboxView.scss @@ -5,7 +5,6 @@ top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -17,11 +16,10 @@ .lightboxView-tabBtn { margin: auto; position: absolute; - right: 38; + right: 45; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -33,11 +31,10 @@ .lightboxView-penBtn { margin: auto; position: absolute; - right: 70; + right: 80; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -49,11 +46,10 @@ .lightboxView-exploreBtn { margin: auto; position: absolute; - right: 100; + right: 115; top: 10; background: transparent; border-radius: 8; - color: white; opacity: 0.7; width: 25; flex-direction: column; @@ -68,7 +64,6 @@ left: 0; width: 100%; height: 100%; - background: #000000bb; z-index: 1000; .lightboxView-contents { position: absolute; diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 8f081b321..93eaec959 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,15 +1,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { InkTool } from '../../fields/InkField'; -import { Cast, NumCast, StrCast } from '../../fields/Types'; +import { BoolCast, Cast, NumCast, StrCast } from '../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../Utils'; import { DocUtils } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; +import { SettingsManager } from '../util/SettingsManager'; import { Transform } from '../util/Transform'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline'; @@ -118,7 +120,7 @@ export class LightboxView extends React.Component { width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]), bottom, }}> -
    +
    {color}
    @@ -229,6 +231,7 @@ export class LightboxView extends React.Component { downx = e.clientX; downy = e.clientY; }} + style={{ background: SettingsManager.userBackgroundColor }} onClick={e => { if (Math.abs(downx - e.clientX) < 4 && Math.abs(downy - e.clientY) < 4) { LightboxView.SetLightboxDoc(undefined); @@ -242,6 +245,8 @@ export class LightboxView extends React.Component { width: this.lightboxWidth(), height: this.lightboxHeight(), clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`, + background: SettingsManager.userBackgroundColor, + color: SettingsManager.userColor, }}> {/* TODO:glr This is where it would go*/} @@ -299,47 +304,68 @@ export class LightboxView extends React.Component { this.future()?.length.toString() )} -
    { - e.stopPropagation(); - LightboxView.LightboxDoc!._layout_fitWidth = !LightboxView.LightboxDoc!._layout_fitWidth; - }}> - +
    + { + e.stopPropagation(); + LightboxView.LightboxDoc!._layout_fitWidth = !LightboxView.LightboxDoc!._layout_fitWidth; + }} + icon={} + />
    -
    { - const lightdoc = LightboxView._docTarget || LightboxView._doc!; - e.stopPropagation(); - Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', lightdoc); - CollectionDockingView.AddSplit(lightdoc, OpenWhereMod.none); - SelectionManager.DeselectAll(); - LightboxView.SetLightboxDoc(undefined); - }}> - +
    + } + onClick={e => { + const lightdoc = LightboxView._docTarget || LightboxView._doc!; + e.stopPropagation(); + Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', lightdoc); + CollectionDockingView.AddSplit(lightdoc, OpenWhereMod.none); + SelectionManager.DeselectAll(); + LightboxView.SetLightboxDoc(undefined); + }} + />
    -
    { - e.stopPropagation(); - Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; - }}> - +
    + } + onClick={e => { + e.stopPropagation(); + Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; + }} + />
    -
    { - e.stopPropagation(); - DocumentView.ExploreMode = !DocumentView.ExploreMode; - })}> - +
    + } + onClick={action(e => { + e.stopPropagation(); + DocumentView.ExploreMode = !DocumentView.ExploreMode; + })} + />
    ); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 40d42a4de..d1561fd67 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -57,6 +57,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !targetDoc ? null : ( { @computed get forceActiveButton() { //select text return this.propertyToggleBtn( - on => (on ? 'INACTIVE INTERACTION' : 'ACTIVE INTERACTION'), + on => (on ? 'SELECT TO INTERACT' : 'ALWAYS INTERACTIVE'), '_forceActive', - on => `${on ? 'Select to activate' : 'Contents always active'} `, + on => `${on ? 'Document must be selected to interact with its contents' : 'Contents always active (respond to click/drag events)'} `, on => // 'eye' ); } @@ -210,9 +211,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get layout_fitWidthButton() { return this.propertyToggleBtn( - on => (on ? 'RESTRICT WIDTH' : 'FIT WIDTH'), //'Fit\xA0Width', + on => (on ? 'SCALED VIEW' : 'READING VIEW'), //'Fit\xA0Width', '_layout_fitWidth', - on => `${on ? "Don't" : 'Do'} fit content to width of container`, + on => + on + ? "Scale document so it's width and height fit container (no effect when document is viewed on freeform canvas)" + : "Scale document so it's width fits container and its height expands/contracts to fit available space (no effect when document is viewed on freeform canvas)", on => (on ? : ) // 'arrows-alt-h' ); } diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index d94e552b4..cd59a91a1 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -2,14 +2,15 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc } from '../../../fields/Doc'; +import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; +import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { returnFalse, returnZero, Utils } from '../../../Utils'; +import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } from '../global/globalCssVariables.scss'; -import { DocumentView } from '../nodes/DocumentView'; +import { DocFocusOptions, DocumentView } from '../nodes/DocumentView'; import { StyleProp } from '../StyleProvider'; import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; @@ -46,6 +47,15 @@ export class CollectionCarousel3DView extends CollectionSubView() { .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this.props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) .scale(1 / this.centerScale); + focus = (anchor: Doc, options: DocFocusOptions) => { + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; + options.didMove = true; + const target = DocCast(anchor.annotationOn) ?? anchor; + const index = docs.indexOf(target); + index !== -1 && (this.layoutDoc._carousel_index = index); + return undefined; + }; @computed get content() { const currentIndex = NumCast(this.layoutDoc._carousel_index); const displayDoc = (childPair: { layout: Doc; data: Doc }) => { @@ -61,6 +71,7 @@ export class CollectionCarousel3DView extends CollectionSubView() { LayoutTemplateString={this.props.childLayoutString} Document={childPair.layout} DataDoc={childPair.data} + focus={this.focus} ScreenToLocalTransform={this.childScreenToLocal} isContentActive={this.isChildContentActive} isDocumentActive={this.props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this.props.isDocumentActive : this.isContentActive} diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 54a60271a..26272d2ee 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -210,11 +210,12 @@ export function CollectionSubView(moreProps?: X) { const targetDocments = DocListCast(this.dataDoc[this.props.fieldKey]); const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag)); if (someMoved) docDragData.droppedDocuments = docDragData.droppedDocuments.map((drop, i) => (targetDocments.includes(docDragData.draggedDocuments[i]) ? docDragData.draggedDocuments[i] : drop)); - if ((!dropAction || dropAction === 'same' || dropAction === 'move' || someMoved) && docDragData.moveDocument) { + if ((!dropAction || dropAction === 'inSame' || dropAction === 'same' || dropAction === 'move' || someMoved) && docDragData.moveDocument) { const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); if (movedDocs.length) { - const canAdd = de.embedKey || dropAction || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.rootDoc); + const canAdd = + (de.embedKey || dropAction || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.rootDoc)) && (dropAction !== 'inSame' || docDragData.draggedDocuments.every(d => d.embedContainer === this.rootDoc)); const moved = docDragData.moveDocument(movedDocs, this.rootDoc, canAdd ? this.addDocument : returnFalse); added = canAdd || moved ? moved : undefined; } else { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index eed04b3ee..9e5ac77d9 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -149,7 +149,7 @@ export class CollectionTreeView extends CollectionSubView {!(this.doc instanceof Doc) || !this.treeChildren ? null : this.doc.treeView_HasOverlay ? ( diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index cd526c77e..f89aa065b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -433,9 +433,9 @@ export class TreeView extends React.Component { return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && innerAdd(doc), true as boolean); }; const addDoc = inside ? localAdd : parentAddDoc; - const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same') && moveDocument; + const move = (!dropAction || dropAction === 'proto' || dropAction === 'move' || dropAction === 'same' || dropAction === 'inSame') && moveDocument; const canAdd = (!this.props.treeView.outlineMode && !StrCast((inside ? this.props.document : this.props.treeViewParent)?.treeView_FreezeChildren).includes('add')) || forceAdd; - if (canAdd) { + if (canAdd && (dropAction !== 'inSame' || droppedDocuments.every(d => d.embedContainer === this.props.parentTreeView?.doc))) { this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = true); const res = droppedDocuments.reduce((added, d) => (move ? move(d, undefined, addDoc) || (dropAction === 'proto' ? addDoc(d) : false) : addDoc(d)) || added, false); this.props.parentTreeView instanceof TreeView && (this.props.parentTreeView.dropping = false); @@ -598,7 +598,7 @@ export class TreeView extends React.Component { } const dataIsComputed = ComputedField.WithoutComputed(() => FieldValue(this.dataDoc[key])) instanceof ComputedField; const added = (!dataIsComputed || (this.dropping && this.moving)) && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); - !dataIsComputed && added && Doc.SetContainer(doc, DocCast(this.doc.embedContainer)); + !dataIsComputed && added && Doc.SetContainer(doc, this.doc); return added; }; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8a812c671..9df96fabc 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -33,7 +33,6 @@ import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { COLLECTION_BORDER_WIDTH } from '../../../views/global/globalCssVariables.scss'; import { Timeline } from '../../animationtimeline/Timeline'; import { ContextMenu } from '../../ContextMenu'; -import { DocumentDecorations } from '../../DocumentDecorations'; import { GestureOverlay } from '../../GestureOverlay'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke'; import { LightboxView } from '../../LightboxView'; @@ -187,7 +186,10 @@ export class CollectionFreeFormView extends CollectionSubView + const segments = this.segmentInkStroke(intersect.inkView, intersect.t); + segments.forEach(segment => this.forceStrokeGesture( e, GestureUtils.Gestures.Stroke, diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 394108be4..14a3d16ef 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -226,7 +226,7 @@ export class FontIconBox extends DocComponent() { } else { return
    ); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 26272d2ee..158f9d8ee 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -31,7 +31,6 @@ export function CollectionSubView(moreProps?: X) { @observable _focusFilters: Opt; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it @observable _focusRangeFilters: Opt; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it protected createDashEventsTarget = (ele: HTMLDivElement | null) => { - //used for stacking and masonry view this.dropDisposer?.(); this.gestureDisposer?.(); this._multiTouchDisposer?.(); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index e4ae251c8..c90fdf013 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -11,6 +11,15 @@ touch-action: none; border-radius: inherit; } +.collectionFreeForm-groupDropper { + width: 10000; + height: 10000; + left: -5000; + top: -5000; + position: absolute; + background: transparent; + pointer-events: all; +} .collectionfreeformview-grid { transform-origin: top left; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a64ccbb2c..676e96714 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -124,7 +124,7 @@ export class CollectionFreeFormView extends CollectionSubView(); @observable _marqueeRef: HTMLDivElement | null = null; @observable _marqueeViewRef = React.createRef(); - @observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. + @observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. @observable _brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 }; // highlighted region of freeform canvas used by presentations to indicate a region constructor(props: any) { @@ -342,7 +342,6 @@ export class CollectionFreeFormView extends CollectionSubView Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight); + /// + /// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS + /// the view is a group, in which case this does nothing (since Groups calculate their own scale and center) + /// + @undoBatch + resetView = () => { + if (!this.props.Document._isGroup) { + this.props.Document[this.panXFieldKey] = this.props.Document[this.panYFieldKey] = 0; + this.props.Document[this.scaleFieldKey] = 1; + } + }; + onContextMenu = (e: React.MouseEvent) => { if (this.props.isAnnotationOverlay || !ContextMenu.Instance) return; const appearance = ContextMenu.Instance.findByDescription('Appearance...'); const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : []; - !this.props.Document._isGroup && - appearanceItems.push({ - description: 'Reset View', - event: () => CollectionFreeFormView.ResetView(this), - icon: 'compress-arrows-alt', - }); + !this.props.Document._isGroup && appearanceItems.push({ description: 'Reset View', event: this.resetView, icon: 'compress-arrows-alt' }); !Doc.noviceMode && appearanceItems.push({ description: 'Toggle auto arrange', @@ -1975,15 +1981,6 @@ export class CollectionFreeFormView extends CollectionSubView this.nativeDimScaling; - private groupDropDisposer?: DragManager.DragDropDisposer; - protected createGroupEventsTarget = (ele: HTMLDivElement) => { - //used for stacking and masonry view - this.groupDropDisposer?.(); - if (ele) { - this.groupDropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this)); - } - }; - @action brushView = (viewport: { width: number; height: number; panX: number; panY: number }, transTime: number) => { this._brushtimer1 && clearTimeout(this._brushtimer1); @@ -2068,51 +2065,18 @@ export class CollectionFreeFormView extends CollectionSubView - {this._hLines?.map(l => ( - - ))} - {this._vLines?.map(l => ( - - ))} + {(this._hLines ?? []) + .map(l => ) // + .concat((this._vLines ?? []).map(l => )) ?? []}
    - {this.props.Document._isGroup && SnappingManager.GetIsDragging() && this.ChildDrag ? ( -
    - ) : null} + {this.GroupChildDrag ?
    : null} )}
    ); } - /// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS - // the view is a group, in which case this does nothing (since Groups calculate their own scale and center) - static ResetView(view?: CollectionFreeFormView) { - if (view) { - if (view.props.Document._isGroup) return; - view.props.Document[view.panXFieldKey] = view.props.Document[view.panYFieldKey] = 0; - view.props.Document[view.scaleFieldKey] = 1; - } else { - SelectionManager.Docs() - .filter(doc => !doc._isGroup) - .forEach(doc => { - doc._freeform_panX = doc._freeform_panY = 0; - doc._freeform_scale = 1; - }); - } - } } interface CollectionFreeFormOverlayViewProps { @@ -2358,6 +2322,3 @@ ScriptingGlobals.add(function bringToFront() { ScriptingGlobals.add(function sendToBack(doc: Doc) { SelectionManager.Views().forEach(view => view.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView.bringToFront(view.rootDoc, true)); }); -ScriptingGlobals.add(function resetView() { - CollectionFreeFormView.ResetView(); -}); diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 4092d9722..9d5b533d1 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -272,7 +272,7 @@ export class SchemaRTFCell extends React.Component { fieldProps.isContentActive = this.selectedFunc; return (
    - {this.selected ? : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))} + {this.selected ? : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
    ); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ef96e64be..e4fc6c4a2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -394,18 +394,15 @@ export class DocumentViewInternal extends DocComponent (ffview.ChildDrag = this.props.DocumentView())); DragManager.StartDocumentDrag( selected.map(dv => dv.docView!._mainCont.current!), dragData, x, y, - { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) }, - () => setTimeout(action(() => ffview && (ffview.ChildDrag = undefined))) + { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) } ); // this needs to happen after the drop event is processed. - ffview?.setupDragLines(false); } } @@ -495,11 +492,10 @@ export class DocumentViewInternal extends DocComponent - sendToBack - ? this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.bringToFront(this.rootDoc, true) - : this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ?? this.props.select(e.ctrlKey || e.metaKey || e.shiftKey)); + // prettier-ignore + clickFunc ?? (() => (sendToBack ? this.props.DocumentView().props.bringToFront(this.rootDoc, true) : + this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ?? + this.props.select(e.ctrlKey || e.metaKey || e.shiftKey))); const waitFordblclick = this.props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick; if ((clickFunc && waitFordblclick !== 'never') || waitFordblclick === 'always') { this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout); @@ -1099,7 +1095,6 @@ export class DocumentViewInternal extends DocComponent, props: Opt, property: string) => this.props?.styleProvider?.(doc, props, property + ':caption'); @computed get innards() { TraceMobx(); - const ffscale = () => this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.ScreenToLocalTransform().Scale || 1; const showTitle = this.layout_showTitle?.split(':')[0]; const showTitleHover = this.layout_showTitle?.includes(':hover'); const captionView = !this.layout_showCaption ? null : ( @@ -1107,8 +1102,6 @@ export class DocumentViewInternal extends DocComponent @@ -1117,7 +1110,6 @@ export class DocumentViewInternal extends DocComponent { static Instance: MapAnchorMenu; private _disposer: IReactionDisposer | undefined; - private _disposer2: IReactionDisposer | undefined; - private _commentCont = React.createRef(); + private _commentRef = React.createRef(); public onMakeAnchor: () => Opt = () => undefined; // Method to get anchor from text search public Center: () => void = unimplementedFunction; - // public OnClick: (e: PointerEvent) => void = unimplementedFunction; + public OnClick: (e: PointerEvent) => void = unimplementedFunction; // public OnAudio: (e: PointerEvent) => void = unimplementedFunction; - // public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; - // public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; + public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap, addAsAnnotation?: boolean) => Opt = (color: string, isTargetToggler: boolean) => undefined; public GetAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = (savedAnnotations: Opt>, addAsAnnotation: boolean) => undefined; public Delete: () => void = unimplementedFunction; - public LinkNote: () => void = unimplementedFunction; // public MakeTargetToggle: () => void = unimplementedFunction; // public ShowTargetTrail: () => void = unimplementedFunction; public IsTargetToggler: () => boolean = returnFalse; @@ -52,23 +43,12 @@ export class MapAnchorMenu extends AntimodeMenu { componentWillUnmount() { this._disposer?.(); - this._disposer2?.(); } componentDidMount() { - this._disposer2 = reaction( - () => this._opacity, - opacity => { - if (!opacity) { - } - }, - { fireImmediately: true } - ); this._disposer = reaction( () => SelectionManager.Views().slice(), - selected => { - MapAnchorMenu.Instance.fadeOut(true); - } + selected => MapAnchorMenu.Instance.fadeOut(true) ); } // audioDown = (e: React.PointerEvent) => { @@ -87,6 +67,18 @@ export class MapAnchorMenu extends AntimodeMenu { // e => this.OnCrop?.(e) // ); // }; + notePointerDown = (e: React.PointerEvent) => { + setupMoveUpEvents( + this, + e, + (e: PointerEvent) => { + this.StartDrag(e, this._commentRef.current!); + return true; + }, + returnFalse, + e => this.OnClick(e) + ); + }; static top = React.createRef(); // public get Top(){ @@ -105,12 +97,14 @@ export class MapAnchorMenu extends AntimodeMenu { /> } { - } - color={SettingsManager.userColor} - /> +
    + } + color={SettingsManager.userColor} + /> +
    } { { + e.preventDefault(); + e.stopPropagation(); + + const sourceAnchorCreator = action(() => { + const note = this.getAnchor(true); + if (note && this.selectedPin) { + note.latitude = this.selectedPin.latitude; + note.longitude = this.selectedPin.longitude; + note.map = this.selectedPin.map; + } + return note as Doc; + }); + + const targetCreator = (annotationOn: Doc | undefined) => { + const target = DocUtils.GetNewTextDoc('Note linked to ' + this.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow'); + FormattedTextBox.SelectOnLoad = target[Id]; + return target; + }; + const docView = this.props.DocumentView?.(); + docView && + DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, { + dragComplete: e => { + if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) { + e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.Document; + e.annoDragData.linkSourceDoc.followLinkZoom = false; + } + }, + }); + }; + createNoteAnnotation = () => { const createFunc = undoable( action(() => { @@ -388,7 +421,8 @@ export class MapBox extends ViewBoxAnnotatableComponent, dataDoc: Doc) => void; -export interface FormattedTextBoxProps { - allowScroll?: boolean; -} +export interface FormattedTextBoxProps {} @observer export class FormattedTextBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldStr: string) { @@ -562,7 +560,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { if (de.complete.annoDragData) { de.complete.annoDragData.dropDocCreator = () => this.getAnchor(true); - e.stopPropagation(); return true; } const dragData = de.complete.docDragData; @@ -2067,10 +2064,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { -- cgit v1.2.3-70-g09d2 From 0df1fc3fd85c1dea84dcaec5a934fc08f0da6832 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 4 Oct 2023 07:46:05 -0400 Subject: several fixes for webclips, linking to pdf/web, fonticon dropdowns. removed sliderbox. reduce uses of scriptContext fixed web clipping annotations to be in correct spot and not to crash because of using a url that it doesn't have. fixed pdf/web links to not use anchor from other end of link. because of sharing of GetAnchor global. added a backup when presbox overwrites a doc's data field. removed sliderBox. fixed fontIcon dropdowns to not call click script twice. removed scriptContext where it wasn't needed which is everywhere except TreeViews. --- src/client/documents/DocumentTypes.ts | 3 +- src/client/documents/Documents.ts | 8 -- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/MainView.tsx | 2 - src/client/views/StyleProvider.tsx | 2 - .../views/collections/CollectionNoteTakingView.tsx | 1 - .../collections/CollectionStackedTimeline.tsx | 37 +++----- .../views/collections/CollectionStackingView.tsx | 1 - .../collectionSchema/CollectionSchemaView.tsx | 1 - src/client/views/nodes/DocumentContentsView.tsx | 2 - src/client/views/nodes/FontIconBox/FontIconBox.tsx | 1 - src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/SliderBox.scss | 19 ---- src/client/views/nodes/SliderBox.tsx | 103 --------------------- src/client/views/nodes/WebBox.scss | 1 - src/client/views/nodes/WebBox.tsx | 80 +++++++++++----- src/client/views/nodes/trails/PresBox.tsx | 7 +- src/client/views/pdf/PDFViewer.tsx | 5 +- 18 files changed, 82 insertions(+), 195 deletions(-) delete mode 100644 src/client/views/nodes/SliderBox.scss delete mode 100644 src/client/views/nodes/SliderBox.tsx (limited to 'src/client/util') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index f8d129e79..87010f770 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -30,14 +30,13 @@ export enum DocumentType { // special purpose wrappers that either take no data or are compositions of lower level types LINK = 'link', IMPORT = 'import', - SLIDER = 'slider', PRES = 'presentation', PRESELEMENT = 'preselement', COLOR = 'color', YOUTUBE = 'youtube', COMPARISON = 'comparison', GROUP = 'group', - PUSHPIN = "pushpin", + PUSHPIN = 'pushpin', SCRIPTDB = 'scriptdb', // database of scripts GROUPDB = 'groupdb', // database of groups diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f7ceef4f4..a79a62b57 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -54,7 +54,6 @@ import { PhysicsSimulationBox } from '../views/nodes/PhysicsBox/PhysicsSimulatio import { RecordingBox } from '../views/nodes/RecordingBox/RecordingBox'; import { ScreenshotBox } from '../views/nodes/ScreenshotBox'; import { ScriptingBox } from '../views/nodes/ScriptingBox'; -import { SliderBox } from '../views/nodes/SliderBox'; import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import { PresBox } from '../views/nodes/trails/PresBox'; import { PresElementBox } from '../views/nodes/trails/PresElementBox'; @@ -628,13 +627,6 @@ export namespace Docs { options: {}, }, ], - [ - DocumentType.SLIDER, - { - layout: { view: SliderBox, dataField: defaultDataKey }, - options: {}, - }, - ], [ DocumentType.PRES, { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2ea5972ee..cc8f72ddf 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -820,7 +820,7 @@ export class CurrentUserUtils { // When the user views one of these documents, it will be added to the sharing documents 'viewed' list field // The sharing document also stores the user's color value which helps distinguish shared documents from personal documents static setupSharedDocs(doc: Doc, sharingDocumentId: string) { - const dblClkScript = "{scriptContext.openLevel(documentView); addDocToList(scriptContext.props.treeView.props.Document, 'viewed', documentView.rootDoc);}"; + const dblClkScript = "{scriptContext.openLevel(documentView); addDocToList(documentView.props.treeViewDoc, 'viewed', documentView.rootDoc);}"; const sharedScripts = { treeView_ChildDoubleClick: dblClkScript, } const sharedDocOpts:DocumentOptions = { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index d6f5d63fe..0a3389fc2 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -728,7 +728,6 @@ export class MainView extends React.Component { PanelHeight={this.leftMenuFlyoutHeight} renderDepth={0} isContentActive={returnTrue} - scriptContext={CollectionDockingView.Instance?.props.Document} focus={emptyFunction} whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -766,7 +765,6 @@ export class MainView extends React.Component { childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} - scriptContext={this} />
    ); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d7537bffb..8417a6f5b 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -21,7 +21,6 @@ import { InkingStroke } from './InkingStroke'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { KeyValueBox } from './nodes/KeyValueBox'; -import { SliderBox } from './nodes/SliderBox'; import './StyleProvider.scss'; import React = require('react'); import { PropertiesView } from './PropertiesView'; @@ -215,7 +214,6 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index ad3160a08..c4650647c 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -58,9 +58,7 @@ export class CollectionStackedTimeline extends CollectionSubView CollectionStackedTimeline.RangeScript; - rangePlayScript = () => CollectionStackedTimeline.RangePlayScript; + @computed get rangeClick() { + // prettier-ignore + return ScriptField.MakeFunction('stackedTimeline.clickAnchor(this, clientX)', + { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any } + )!; + } + @computed get rangePlay() { + // prettier-ignore + return ScriptField.MakeFunction('stackedTimeline.playOnClick(this, clientX)', + { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any })!; + } + rangeClickScript = () => this.rangeClick; + rangePlayScript = () => this.rangePlay; // handles key events for for creating key anchors, scrubbing, exiting trim @action @@ -835,7 +825,6 @@ class StackedTimelineAnchor extends React.Component hideResizeHandles={true} bringToFront={emptyFunction} contextMenuItems={this.contextMenuItems} - scriptContext={this.props.stackedTimeline} /> ), }; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 36f8bc101..c43a9d2b8 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -361,7 +361,6 @@ export class CollectionStackingView extends CollectionSubView ); diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index d2b61167e..f73c037f4 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -972,7 +972,6 @@ class CollectionSchemaViewDocs extends React.Component
    ); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 8ac9d6804..e1de2fa76 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -41,7 +41,6 @@ import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox'; import { RecordingBox } from './RecordingBox'; import { ScreenshotBox } from './ScreenshotBox'; import { ScriptingBox } from './ScriptingBox'; -import { SliderBox } from './SliderBox'; import { PresBox } from './trails/PresBox'; import { VideoBox } from './VideoBox'; import { WebBox } from './WebBox'; @@ -240,7 +239,6 @@ export class DocumentContentsView extends React.Component< FontIconBox, LabelBox, EquationBox, - SliderBox, FieldView, CollectionFreeFormView, CollectionDockingView, diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 14a3d16ef..d2e1293da 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -240,7 +240,6 @@ export class FontIconBox extends DocComponent() { text: typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title), val: value, style: getStyle(value), - onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), // shortcut: '#', })); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 73a5be90a..cf44649a2 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -242,7 +242,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { - public static LayoutString(fieldKey: string) { - return FieldView.LayoutString(SliderBox, fieldKey); - } - - get minThumbKey() { - return this.fieldKey + '-minThumb'; - } - get maxThumbKey() { - return this.fieldKey + '-maxThumb'; - } - get minKey() { - return this.fieldKey + '-min'; - } - get maxKey() { - return this.fieldKey + '-max'; - } - specificContextMenu = (e: React.MouseEvent): void => { - const funcs: ContextMenuProps[] = []; - funcs.push({ description: 'Edit Thumb Change Script', icon: 'edit', event: (obj: any) => ScriptBox.EditButtonScript('On Thumb Change ...', this.props.Document, 'onThumbChange', obj.x, obj.y) }); - ContextMenu.Instance.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' }); - }; - onChange = (values: readonly number[]) => - runInAction(() => { - this.dataDoc[this.minThumbKey] = values[0]; - this.dataDoc[this.maxThumbKey] = values[1]; - ScriptCast(this.layoutDoc.onThumbChanged, null)?.script.run({ - self: this.rootDoc, - scriptContext: this.props.scriptContext, - range: values, - this: this.layoutDoc, - }); - }); - - render() { - const domain = [NumCast(this.layoutDoc[this.minKey]), NumCast(this.layoutDoc[this.maxKey])]; - const defaultValues = [NumCast(this.dataDoc[this.minThumbKey]), NumCast(this.dataDoc[this.maxThumbKey])]; - return domain[1] <= domain[0] ? null : ( -
    e.stopPropagation()} style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow) }}> -
    - - {railProps => } - - {({ handles, activeHandleID, getHandleProps }) => ( -
    - {handles.map((handle, i) => { - const value = i === 0 ? defaultValues[0] : defaultValues[1]; - return ( -
    - -
    - ); - })} -
    - )} -
    - - {({ tracks, getTrackProps }) => ( -
    - {tracks.map(({ id, source, target }) => ( - - ))} -
    - )} -
    - - {({ ticks }) => ( -
    - {ticks.map(tick => ( - val.toString()} /> - ))} -
    - )} -
    -
    -
    -
    - ); - } -} diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index 75847c100..511c91da0 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -176,7 +176,6 @@ width: 100%; height: 100%; transform-origin: top left; - overflow: auto; .webBox-iframe { width: 100%; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 27c19105f..d4ba7a48f 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -62,10 +62,8 @@ export class WebBox extends ViewBoxAnnotatableComponent(); private _searchString = ''; private _scrollTimer: any; + private _getAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = () => undefined; - private get _getAnchor() { - return AnchorMenu.Instance?.GetAnchor; - } @observable private _webUrl = ''; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't want the src parameter to also change as that would cause an unnecessary re-render. @observable private _hackHide = false; // apparently changing the value of the 'sandbox' prop doesn't necessarily apply it to the active iframe. so thisforces the ifrmae to be rebuilt when allowScripts is toggled @observable private _searching: boolean = false; @@ -186,13 +184,15 @@ export class WebBox extends ViewBoxAnnotatableComponent { - this._annotationKeySuffix = () => this._urlHash + '_annotations'; - const reqdFuncs: { [key: string]: string } = {}; + this._annotationKeySuffix = () => (this._urlHash ? this._urlHash + '_' : '') + 'annotations'; // bcz: need to make sure that doc.data_annotations points to the currently active web page's annotations (this could/should be when the doc is created) - reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"])`; - reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"] = value`; - reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_sidebar"])`; - DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs); + if (this._url) { + const reqdFuncs: { [key: string]: string } = {}; + reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"])`; + reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"] = value`; + reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"sidebar"])`; + DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs); + } }); this._disposers.urlchange = reaction( () => WebCast(this.rootDoc.data), @@ -264,14 +264,16 @@ export class WebBox extends ViewBoxAnnotatableComponent this.createTextAnnotation(sel, !sel.isCollapsed ? sel.getRangeAt(0) : undefined); AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale); // Changing which document to add the annotation to (the currently selected WebBox) - GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash}_sidebar`); + GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`); GPTPopup.Instance.addDoc = this.sidebarAddDocument; } } }; @action + webClipDown = (e: React.PointerEvent) => { + const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!); + const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale; + const word = getWordAtPoint(e.target, e.clientX, e.clientY); + this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc); + MarqueeAnnotator.clearAnnotations(this._savedAnnotations); + e.button !== 2 && (this._marqueeing = [e.clientX, e.clientY]); + if (word || (e.target as any)?.className?.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) { + e.stopPropagation(); + setTimeout( + action(() => (this._marqueeing = undefined)), + 100 + ); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it. + } else { + this._isAnnotating = true; + this.props.select(false); + e.stopPropagation(); + e.preventDefault(); + } + document.addEventListener('pointerup', this.webClipUp); + }; + webClipUp = (e: PointerEvent) => { + document.removeEventListener('pointerup', this.webClipUp); + this._getAnchor = AnchorMenu.Instance?.GetAnchor; // need to save AnchorMenu's getAnchor since a subsequent selection on another doc will overwrite this value + const sel = window.getSelection(); + if (sel && !sel.isCollapsed) { + const selRange = sel.getRangeAt(0); + this._selectionText = sel.toString(); + AnchorMenu.Instance.setSelectedText(sel.toString()); + this._textAnnotationCreator = () => this.createTextAnnotation(sel, selRange); + AnchorMenu.Instance.jumpTo(e.clientX, e.clientY); + // Changing which document to add the annotation to (the currently selected WebBox) + GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`); + GPTPopup.Instance.addDoc = this.sidebarAddDocument; + } + }; + @action iframeDown = (e: PointerEvent) => { const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!); const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale; @@ -396,9 +435,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { - return 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1; - }; + isFirefox = () => 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1; iframeClick = () => this._iframeClick; iframeScaling = () => 1 / this.props.ScreenToLocalTransform().Scale; @@ -722,10 +759,11 @@ export class WebBox extends ViewBoxAnnotatableComponent { + this._getAnchor = AnchorMenu.Instance?.GetAnchor; this._marqueeing = undefined; this._isAnnotating = false; this._iframeClick = undefined; - const sel = this._iframe?.contentDocument?.getSelection(); + const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection(); if (sel?.empty) sel.empty(); // Chrome else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox if (x !== undefined && y !== undefined) { @@ -750,7 +788,7 @@ export class WebBox extends ViewBoxAnnotatableComponent e.stopPropagation()} dangerouslySetInnerHTML={{ __html: field.html }} />; + return r && (this._scrollHeight = Number(getComputedStyle(r).height.replace('px', '')))} contentEditable onPointerDown={this.webClipDown} dangerouslySetInnerHTML={{ __html: field.html }} />; } if (field instanceof WebField) { const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl; @@ -775,7 +813,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { - (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url))); + this._url && (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url))); return this.addDocument(doc, annotationKey); }; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 2a3b232bd..383b400c8 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -465,7 +465,11 @@ export class PresBox extends ViewBoxBaseComponent() { const fkey = Doc.LayoutFieldKey(bestTarget); const setData = bestTargetView?.ComponentView?.setData; if (setData) setData(activeItem.config_data); - else Doc.GetProto(bestTarget)[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; + else { + const current = Doc.GetProto(bestTarget)[fkey]; + Doc.GetProto(bestTarget)[fkey + '_' + Date.now()] = current instanceof ObjectField ? current[Copy]() : current; + Doc.GetProto(bestTarget)[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data; + } bestTarget[fkey + '_usePath'] = activeItem.config_usePath; setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); } @@ -2650,7 +2654,6 @@ export class PresBox extends ViewBoxBaseComponent() { removeDocument={returnFalse} dontRegisterView={true} focus={this.focusElement} - scriptContext={this} ScreenToLocalTransform={this.getTransform} AddToMap={this.AddToMap} RemFromMap={this.RemFromMap} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 2a191477b..23dc084ad 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -82,9 +82,7 @@ export class PDFViewer extends React.Component { private _ignoreScroll = false; private _initialScroll: { loc: Opt; easeFunc: 'linear' | 'ease' | undefined } | undefined; private _forcedScroll = true; - get _getAnchor() { - return AnchorMenu.Instance?.GetAnchor; - } + _getAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = () => undefined; selectionText = () => this._selectionText; selectionContent = () => this._selectionContent; @@ -400,6 +398,7 @@ export class PDFViewer extends React.Component { @action finishMarquee = (x?: number, y?: number) => { + this._getAnchor = AnchorMenu.Instance?.GetAnchor; this.isAnnotating = false; this._marqueeing = undefined; this._textSelecting = true; -- cgit v1.2.3-70-g09d2