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/views/collections/TreeView.scss | 5 +-- src/client/views/collections/TreeView.tsx | 51 ++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 7eab03e1d..cb6432687 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -25,10 +25,11 @@ width: 100%; height: 100%; position: absolute; + left: 10px; .treeView-expandIcon { - display: none; - left: -10px; + // display: none; + left: -8px; position: absolute; } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 75e76019e..153c2c71a 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -227,6 +227,37 @@ export class TreeView extends React.Component { } }; + @undoBatch + @action + recurToggle = (childList: Doc[]) => { + if (childList.length > 0) { + childList.forEach(child => { + console.log(child); + child.runProcess = !!!child.runProcess; + child.toggleChildrenRun?.(); + }); + } + }; + + @undoBatch + @action + getRunningChildren = (childList: Doc[]) => { + if (childList.length === 0) { + return []; + } + + const runningChildren = []; + childList.forEach(child => { + if (child.runProcess && child.getChildrenToRun) { + if (child.runProcess) { + runningChildren.push(child); + } + runningChildren.push(...(child.getChildrenToRun?.() ?? [])); + } + }); + return runningChildren; + }; + constructor(props: any) { super(props); if (!TreeView._openLevelScript) { @@ -235,6 +266,18 @@ export class TreeView extends React.Component { } this._openScript = Doc.IsSystem(this.props.document) ? undefined : () => TreeView._openLevelScript!; this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!; + + // set for child processing highligting + // this.dataDoc.testing = 'testing'; + this.dataDoc.hasChildren = this.childDocs.length > 0; + // this.dataDoc.children = this.childDocs; + this.dataDoc.toggleChildrenRun = () => { + this.recurToggle(this.childDocs); + }; + + this.dataDoc.getChildrenToRun = () => { + return this.getRunningChildren(this.childDocs); + }; } _treeEle: any; @@ -696,7 +739,11 @@ export class TreeView extends React.Component { ) : (
- + = 1 ? 'block' : 'none' }} + icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} + />
{this.onCheckedClick ? null : typeof iconType === 'string' ? : iconType}
@@ -899,7 +946,7 @@ export class TreeView extends React.Component { })} Document={this.doc} fitWidth={returnTrue} - DataDoc={undefined} + DataDoc={this.dataDoc} scriptContext={this} hideDecorationTitle={this.props.treeView.outlineMode} hideResizeHandles={this.props.treeView.outlineMode} -- 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/views/collections') 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 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/views/collections') 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: Mon, 28 Aug 2023 22:33:54 -0400 Subject: adjusted placement of new Node in schema to not hide behind undo/redo --- src/client/views/UndoStack.tsx | 2 +- .../collectionSchema/CollectionSchemaView.scss | 20 ++++++++++++++++++++ .../collectionSchema/CollectionSchemaView.tsx | 20 +++++++++++--------- 3 files changed, 32 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx index 4f971742b..8f3ae8e87 100644 --- a/src/client/views/UndoStack.tsx +++ b/src/client/views/UndoStack.tsx @@ -24,7 +24,7 @@ export class UndoStack extends React.Component { return this.props.inline && UndoStack.HideInline ? null : (
(); @observable _menuKeys: string[] = []; @@ -869,14 +869,16 @@ export class CollectionSchemaView extends CollectionSubView() { {this._columnMenuIndex !== undefined && this.renderColumnMenu} {this._filterColumnIndex !== undefined && this.renderFilterMenu} (this._tableContentRef = ref)} /> - (value ? this.addRow(Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true })) : false), 'add text doc')} - placeholder={"Type ':' for commands"} - contents={'+ New Node'} - menuCallback={this.menuCallback} - height={CollectionSchemaView._newNodeInputHeight} - /> +
+ (value ? this.addRow(Docs.Create.TextDocument(value, { title: value, _layout_autoHeight: true })) : false), 'add text doc')} + placeholder={"Type text to create note or ':' to create specific type"} + contents={'+ New Node'} + menuCallback={this.menuCallback} + height={CollectionSchemaView._newNodeInputHeight} + /> +
{this.previewWidth > 0 &&
} {this.previewWidth > 0 && ( -- 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/views/collections') 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 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/views/collections') 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 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/views/collections') 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 5651f5428f8464ae0f131c73601b69aba11dff98 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 31 Aug 2023 12:36:33 -0400 Subject: fixed properties view text colors --- src/client/views/MainView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 3 --- src/client/views/nodes/trails/PresBox.tsx | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 01a26559c..7ae9a374d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -809,7 +809,7 @@ export class MainView extends React.Component {
)} -
+
{this.propertiesWidth() < 10 ? null : }
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 4f9310434..8dd1c8ee8 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -227,7 +227,6 @@ export class TreeView extends React.Component { recurToggle = (childList: Doc[]) => { if (childList.length > 0) { childList.forEach(child => { - console.log(child); child.runProcess = !!!child.runProcess; TreeView.ToggleChildrenRun.get(child)?.(); }); @@ -265,8 +264,6 @@ export class TreeView extends React.Component { this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!; // set for child processing highligting - // this.dataDoc.testing = 'testing'; - console.log(this.doc, this.dataDoc, this.childDocs); this.dataDoc.hasChildren = this.childDocs.length > 0; // this.dataDoc.children = this.childDocs; TreeView.ToggleChildrenRun.set(this.doc, () => { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 7bb1b80a3..92c130ea1 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1691,7 +1691,7 @@ export class PresBox extends ViewBoxBaseComponent() {
); const presDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => { - const color = activeItem.presentation_effectDirection === direction || (direction === PresEffectDirection.Center && !activeItem.presentation_effectDirection) ? Colors.LIGHT_BLUE : 'black'; + const color = activeItem.presentation_effectDirection === direction || (direction === PresEffectDirection.Center && !activeItem.presentation_effectDirection) ? SettingsManager.userVariantColor : SettingsManager.userColor; return ( {direction}
}>
Date: Thu, 31 Aug 2023 19:19:34 -0400 Subject: fixed compile errors and switched to use_azure = false for server. --- package-lock.json | 91 ++++++++++++++++++++++++- package.json | 2 +- src/client/views/collections/CollectionView.tsx | 4 +- src/client/views/nodes/MapBox/MapBox.tsx | 6 +- src/client/views/nodes/MapBox/MapBox2.tsx | 4 +- src/client/views/nodes/WebBox.tsx | 8 +-- src/client/views/pdf/PDFViewer.tsx | 8 +-- 7 files changed, 104 insertions(+), 19 deletions(-) (limited to 'src/client/views/collections') diff --git a/package-lock.json b/package-lock.json index aae7c022c..8ba450f51 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", diff --git a/package.json b/package.json index de44b31f3..080132f2e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "child_process": "empty" }, "scripts": { - "start-release": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts", + "start-release": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts", "start-release-debug": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts", "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts", "oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts", diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 88f892efc..ce19b3f9b 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,7 +1,7 @@ import { computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast } from '../../../fields/Doc'; +import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { ObjectField } from '../../../fields/ObjectField'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; @@ -40,7 +40,7 @@ interface CollectionViewProps_ extends FieldViewProps { isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently) layoutEngine?: () => string; - setPreviewCursor?: (func: (x: number, y: number, drag: boolean, hide: boolean) => void) => void; + setPreviewCursor?: (func: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void) => void; setBrushViewer?: (func?: (view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void) => void; ignoreUnrendered?: boolean; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index f0106dbbb..504e8bbb9 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -70,7 +70,7 @@ export class MapBox extends ViewBoxAnnotatableComponent(); private _ref: React.RefObject = React.createRef(); private _disposers: { [key: string]: IReactionDisposer } = {}; - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); @observable private _marqueeing: number[] | undefined; @observable private _savedAnnotations = new ObservableMap(); @@ -236,7 +236,7 @@ export class MapBox extends ViewBoxAnnotatableComponent void) => (this._setPreviewCursor = func); + setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void) => (this._setPreviewCursor = func); @action onMarqueeDown = (e: React.PointerEvent) => { @@ -257,7 +257,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { this._marqueeing = undefined; - x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false); + x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false, this.rootDoc); }; addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => this.addDocument(doc, annotationKey); diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx index a54bdcd5e..407a91dd0 100644 --- a/src/client/views/nodes/MapBox/MapBox2.tsx +++ b/src/client/views/nodes/MapBox/MapBox2.tsx @@ -98,7 +98,7 @@ export class MapBox2 extends ViewBoxAnnotatableComponent void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); @computed get inlineTextAnnotations() { return this.allMapMarkers.filter(a => a.text_inlineAnnotations); } @@ -502,7 +502,7 @@ export class MapBox2 extends ViewBoxAnnotatableComponent { this._marqueeing = undefined; this._isAnnotating = false; - x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false); + x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false, this.props.Document); }; addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index febf8341e..a4fac977c 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -50,7 +50,7 @@ export class WebBox extends ViewBoxAnnotatableComponent void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void); private _mainCont: React.RefObject = React.createRef(); private _outerRef: React.RefObject = React.createRef(); @@ -368,7 +368,7 @@ export class WebBox extends ViewBoxAnnotatableComponent) => (this._searchString = e.currentTarget.value); showInfo = action((anno: Opt) => (this._overlayAnnoInfo = anno)); - setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); + setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void) => (this._setPreviewCursor = func); panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth; panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index c3027f51f..2a191477b 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -67,7 +67,7 @@ export class PDFViewer extends React.Component { private _pdfViewer: any; private _styleRule: any; // stylesheet rule for making hyperlinks clickable private _retries = 0; // number of times tried to create the PDF viewer - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void); private _annotationLayer: React.RefObject = React.createRef(); private _disposers: { [name: string]: IReactionDisposer } = {}; @@ -375,7 +375,7 @@ export class PDFViewer extends React.Component { this._downY = e.clientY; if ((this.props.Document._freeform_scale || 1) !== 1) return; if ((e.button !== 0 || e.altKey) && this.props.isContentActive(true)) { - this._setPreviewCursor?.(e.clientX, e.clientY, true, false); + this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this.props.Document); } if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { this.props.select(false); @@ -464,12 +464,12 @@ export class PDFViewer extends React.Component { onClick = (e: React.MouseEvent) => { this._scrollStopper?.(); if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { - this._setPreviewCursor(e.clientX, e.clientY, false, false); + this._setPreviewCursor(e.clientX, e.clientY, false, false, this.props.Document); } // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks }; - setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); + setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void) => (this._setPreviewCursor = func); setBrushViewer = (func?: (view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void) => (this._setBrushViewer = func); @action -- 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/views/collections') 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/views/collections') 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/views/collections') 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 ff458c1cc2619803b8f8ba6e1a2b713b8d3bafe7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 5 Sep 2023 11:29:05 -0400 Subject: changed tree view drag behavior --- src/client/views/collections/TreeView.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 8dd1c8ee8..f1268119e 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -332,7 +332,7 @@ export class TreeView extends React.Component { const pt = [e.clientX, e.clientY]; const rect = this._header.current!.getBoundingClientRect(); const before = pt[1] < rect.top + rect.height / 2; - const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * 0.75) || (!before && this.treeViewOpen && this.childDocs?.length); + const inside = pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length); this._header.current!.className = 'treeView-header'; if (!this.props.treeView.outlineMode || DragManager.DocDragData?.treeViewDoc === this.props.treeView.rootDoc) { if (inside) this._header.current!.className += ' treeView-header-inside'; @@ -392,7 +392,7 @@ export class TreeView extends React.Component { if (!this._header.current) return false; const rect = this._header.current.getBoundingClientRect(); const before = pt[1] < rect.top + rect.height / 2; - const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > Math.min(rect.left + 75, rect.left + rect.width * 0.75) || (!before && this.treeViewOpen && this.childDocs?.length ? true : false); + const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length ? true : false); if (de.complete.linkDragData) { const sourceDoc = de.complete.linkDragData.linkSourceGetAnchor(); const destDoc = this.doc; @@ -1140,7 +1140,7 @@ export class TreeView extends React.Component { const pt = [de.clientX, de.clientY]; const rect = this._header.current!.getBoundingClientRect(); const before = pt[1] < rect.top + rect.height / 2; - const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > Math.min(rect.left + 75, rect.left + rect.width * 0.75) || (!before && this.treeViewOpen && this.childDocs?.length ? true : false); + const inside = this.props.treeView.fileSysMode && !this.doc.isFolder ? false : pt[0] > rect.left + rect.width * 0.33 || (!before && this.treeViewOpen && this.childDocs?.length ? true : false); const docs = this.props.treeView.onTreeDrop(de, (docs: Doc[]) => this.dropDocuments(docs, before, inside, 'copy', undefined, undefined, false)); }; -- 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/views/collections') 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 12:21:11 -0400 Subject: made link sizes a developer feature --- .../views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 89deb733a..f940eb4bf 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -258,7 +258,7 @@ export class CollectionFreeFormLinkView extends React.Component= linkRelationshipSizes.length ? -1 : linkRelationshipSizes[currRelationshipIndex]; + const linkSize = Doc.noviceMode || currRelationshipIndex === -1 || currRelationshipIndex >= linkRelationshipSizes.length ? -1 : linkRelationshipSizes[currRelationshipIndex]; //access stroke color using index of the relationship in the color list (default black) const stroke = currRelationshipIndex === -1 || currRelationshipIndex >= linkColorList.length ? StrCast(link._backgroundColor, 'black') : linkColorList[currRelationshipIndex]; -- cgit v1.2.3-70-g09d2 From 1e9f2b5832ef22cca1dc5dec4ec0b1d717718b9a Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Sep 2023 16:22:22 -0400 Subject: updated header view to show tooltips. added initial tab to header. --- src/client/views/DashboardView.tsx | 1 + .../collectionMulticolumn/CollectionMulticolumnView.tsx | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index c574e266f..1d1d0eaab 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -369,6 +369,7 @@ export class DashboardView extends React.Component { const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row'); + Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc); dashboardDoc['pane-count'] = 1; Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 80da4e1a2..81453c0b8 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -1,4 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@mui/material'; import { Button } from 'browndash-components'; import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; @@ -7,6 +8,7 @@ import { Doc, DocListCast } from '../../../../fields/Doc'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { returnFalse } from '../../../../Utils'; import { DragManager, dropActionType } from '../../../util/DragManager'; +import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { undoable, undoBatch } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; @@ -301,13 +303,13 @@ export class CollectionMulticolumnView extends CollectionSubView() { .scale(this.props.NativeDimScaling?.() || 1); const shouldNotScale = () => this.props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox); collector.push( -
- {this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)} -
, + +
+ {this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)} +
+
, 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/views/collections') 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 01:28:27 -0400 Subject: truncate link descriptions over link lines. Fix schema view issues with multiline inputs. fix '#' field assignment for title bar of docs. fixed dashFieldView to read fields from texstbox by fixing FindDocByTitle to not match undefind. Don't end link_description input on Enter to allow multiline inputs. --- src/client/DocServer.ts | 8 +++-- src/client/views/EditableView.scss | 4 ++- src/client/views/EditableView.tsx | 40 +++++++++++----------- src/client/views/PropertiesView.tsx | 8 ++--- .../CollectionFreeFormLinkView.tsx | 4 +-- .../collectionLinear/CollectionLinearView.tsx | 10 +++--- src/client/views/linking/LinkMenuItem.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 5 ++- .../views/nodes/formattedText/RichTextRules.ts | 2 +- 9 files changed, 42 insertions(+), 41 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 5fdea131b..fc8a9f3d6 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -32,9 +32,11 @@ export namespace DocServer { let _cache: { [id: string]: RefField | Promise> } = {}; export function FindDocByTitle(title: string) { - const foundDocId = Array.from(Object.keys(_cache)) - .filter(key => _cache[key] instanceof Doc) - .find(key => (_cache[key] as Doc).title === title); + const foundDocId = + title && + Array.from(Object.keys(_cache)) + .filter(key => _cache[key] instanceof Doc) + .find(key => (_cache[key] as Doc).title === title); return foundDocId ? (_cache[foundDocId] as Doc) : undefined; } diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss index 0955ba8ff..f7c03caf9 100644 --- a/src/client/views/EditableView.scss +++ b/src/client/views/EditableView.scss @@ -3,7 +3,8 @@ overflow-wrap: break-word; word-wrap: break-word; hyphens: auto; - overflow: hidden; + overflow: auto; + height: 100%; min-width: 20; text-overflow: ellipsis; } @@ -11,6 +12,7 @@ .editableView-container-editing-oneLine { width: 100%; height: max-content; + overflow: hidden; span { p { diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 147921596..ca4ffaf3a 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -231,7 +231,7 @@ export class EditableView extends React.Component { onChange: this.props.autosuggestProps.onChange, }} /> - ) : ( + ) : this.props.oneLine !== false && this.props.GetValue()?.toString().indexOf('\n') === -1 ? ( (this._inputref = r)} @@ -247,31 +247,31 @@ export class EditableView extends React.Component { onClick={this.stopPropagation} onPointerUp={this.stopPropagation} /> + ) : ( +