aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/util/CurrentUserUtils.ts38
-rw-r--r--src/client/util/SharingManager.tsx2
-rw-r--r--src/client/views/DashboardView.tsx62
-rw-r--r--src/client/views/MainView.tsx11
-rw-r--r--src/client/views/collections/TabDocView.tsx130
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx12
-rw-r--r--src/fields/Doc.ts10
-rw-r--r--src/mobile/MobileInterface.tsx2
9 files changed, 155 insertions, 117 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 57a24b304..75024d9c9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -596,6 +596,7 @@ export namespace Docs {
DocumentType.PRESELEMENT,
{
layout: { view: PresElementBox, dataField: defaultDataKey },
+ options: { title: 'pres element template', _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: 'data' },
},
],
[
@@ -1132,8 +1133,8 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.FILTER), undefined, { ...(options || {}) });
}
- export function PresElementBoxDocument(options?: DocumentOptions) {
- return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) });
+ export function PresElementBoxDocument() {
+ return Prototypes.get(DocumentType.PRESELEMENT);
}
export function DataVizDocument(url: string, options?: DocumentOptions, overwriteDoc?: Doc) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 9d3f19e50..7419750b1 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,3 +1,4 @@
+import { forOwn } from "lodash";
import { reaction } from "mobx";
import * as rp from 'request-promise';
import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
@@ -6,7 +7,7 @@ import { List } from "../../fields/List";
import { PrefetchProxy } from "../../fields/Proxy";
import { RichTextField } from "../../fields/RichTextField";
import { listSpec } from "../../fields/Schema";
-import { ScriptField } from "../../fields/ScriptField";
+import { ComputedField, ScriptField } from "../../fields/ScriptField";
import { Cast, DateCast, DocCast, PromiseValue, StrCast } from "../../fields/Types";
import { nullAudio } from "../../fields/URLField";
import { SetCachedGroups, SharingPermissions } from "../../fields/util";
@@ -154,7 +155,7 @@ export class CurrentUserUtils {
/// Initializes collection of templates for notes and click functions
static setupDocTemplates(doc: Doc, field="myTemplates") {
- DocUtils.AssignDocField(doc, "presElement", opts => Docs.Create.PresElementBoxDocument(opts), { title: "pres element template", type: DocumentType.PRESELEMENT, _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"});
+ DocUtils.AssignDocField(doc, "presElement", opts => Docs.Create.PresElementBoxDocument(), { });
const templates = [
CurrentUserUtils.setupNoteTemplates(doc),
CurrentUserUtils.setupClickEditorTemplates(doc)
@@ -322,7 +323,8 @@ export class CurrentUserUtils {
/// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents
static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] {
- const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())";
+ const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())";
+ const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails";
return [
{ title: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", },
{ title: "Search", target: this.setupSearcher(doc, "mySearcher"), icon: "search", },
@@ -330,8 +332,8 @@ export class CurrentUserUtils {
{ title: "Tools", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", funcs: {hidden: "IsNoviceMode()"} },
{ title: "Imports", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", },
{ title: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", },
- { title: "Shared Docs", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}},
- { title: "Trails", target: this.setupTrails(doc, "myTrails"), icon: "pres-trail", },
+ { title: "Shared Docs", target: Doc.MySharedDocs, icon: "users", funcs:{badgeValue:badgeValue}},
+ { title: "Trails", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}},
{ title: "User Doc View", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}}));
}
@@ -493,31 +495,6 @@ export class CurrentUserUtils {
return myDashboards;
}
- /// initializes the left sidebar Trails pane
- static setupTrails(doc: Doc, field:string) {
- var myTrails = DocCast(doc[field]);
- const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true,
- title: "New trail", toolTip: "Create new trail", btnType: ButtonType.ClickButton, buttonText: "New trail", icon: "plus", system: true };
- const reqdBtnScript = {onClick: `createNewPresentation()`};
- const newTrailButton = DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(myTrails?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
-
- const reqdOpts:DocumentOptions = {
- title: "My Trails", _showTitle: "title", _height: 100,
- treeViewHideTitle: true, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newTrailButton,
- contextMenuIcons: new List<string>(["plus"]),
- contextMenuLabels: new List<string>(["Create New Trail"]),
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
- explainer: "All of the trails that you have created will appear here."
- };
- myTrails = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), reqdOpts);
- const contextMenuScripts = [reqdBtnScript.onClick];
- if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) {
- myTrails.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
- }
- return myTrails;
- }
-
/// initializes the left sidebar File system pane
static setupFilesystem(doc: Doc, field:string) {
var myFilesystem = DocCast(doc[field]);
@@ -956,6 +933,7 @@ ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "docu
ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode");
ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering");
ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance.createNewPresentation(); }, "creates a new presentation when called");
+ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called");
ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called");
ScriptingGlobals.add(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, "returns all the links to the document or its annotations", "(doc: any)");
ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar");
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 895bd3374..4b0310e76 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -374,7 +374,7 @@ export class SharingManager extends React.Component<{}> {
if (!uniform) dropdownValues.unshift('-multiple-');
if (override) dropdownValues.unshift('None');
return dropdownValues
- .filter(permission => !Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any))
+ .filter(permission => !Doc.noviceMode || ![SharingPermissions.SelfEdit].includes(permission as any))
.map(permission => (
<option key={permission} value={permission}>
{permission}
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 84b1017b4..d1926951d 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -5,9 +5,11 @@ import * as React from 'react';
import { DataSym, Doc, DocListCast, DocListCastAsync } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
-import { Cast, ImageCast, StrCast } from '../../fields/Types';
+import { listSpec } from '../../fields/Schema';
+import { ScriptField } from '../../fields/ScriptField';
+import { Cast, DocCast, ImageCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
-import { Docs, DocumentOptions } from '../documents/Documents';
+import { Docs, DocumentOptions, DocUtils } from '../documents/Documents';
import { CollectionViewType } from '../documents/DocumentTypes';
import { HistoryUtil } from '../util/History';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
@@ -18,6 +20,7 @@ import { CollectionView } from './collections/CollectionView';
import { ContextMenu } from './ContextMenu';
import './DashboardView.scss';
import { MainViewModal } from './MainViewModal';
+import { ButtonType } from './nodes/button/FontIconBox';
enum DashboardGroup {
MyDashboards,
@@ -254,7 +257,6 @@ export class DashboardView extends React.Component {
};
public static createNewDashboard = (id?: string, name?: string) => {
- const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true);
const dashboards = Doc.MyDashboards;
const dashboardCount = DocListCast(dashboards.data).length + 1;
const freeformOptions: DocumentOptions = {
@@ -266,7 +268,7 @@ export class DashboardView extends React.Component {
_backgroundGridShow: true,
title: `Untitled Tab 1`,
};
- const title = name ? name : `Dashboard ${dashboardCount}`;
+ const title = name ?? `Dashboard ${dashboardCount}`;
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
freeformDoc.context = dashboardDoc;
@@ -276,12 +278,60 @@ export class DashboardView extends React.Component {
dashboardDoc.data = new List<Doc>(dashboardTabs);
dashboardDoc['pane-count'] = 1;
- Doc.ActivePresentation = presentation;
-
Doc.AddDocToList(dashboards, 'data', dashboardDoc);
+
+ // this section is creating the button document itself === myTrails = new Button
+ const reqdBtnOpts: DocumentOptions = {
+ _forceActive: true,
+ _width: 30,
+ _height: 30,
+ _stayInCollection: true,
+ _hideContextMenu: true,
+ title: 'New trail',
+ toolTip: 'Create new trail',
+ btnType: ButtonType.ClickButton,
+ buttonText: 'New trail',
+ icon: 'plus',
+ system: true,
+ };
+ const reqdBtnScript = { onClick: `createNewPresentation()` };
+ const myTrailsBtn = DocUtils.AssignScripts(Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
+
+ // createa a list of presentations (as a tree view collection) and store it on the new dashboard
+ // instead of assigning Doc.UserDoc().myrails we want to assign Doc.AxtiveDashboard.myTrails
+ // but we don't want to create the list of trails here-- but rather in createDashboard
+ const reqdOpts: DocumentOptions = {
+ title: 'My Trails',
+ _showTitle: 'title',
+ _height: 100,
+ treeViewHideTitle: true,
+ _fitWidth: true,
+ _gridGap: 5,
+ _forceActive: true,
+ childDropAction: 'alias',
+ treeViewTruncateTitleWidth: 150,
+ ignoreClick: true,
+ buttonMenu: true,
+ buttonMenuDoc: myTrailsBtn,
+ contextMenuIcons: new List<string>(['plus']),
+ contextMenuLabels: new List<string>(['Create New Trail']),
+ _lockedPosition: true,
+ boxShadow: '0 0',
+ childDontRegisterViews: true,
+ targetDropAction: 'same',
+ system: true,
+ explainer: 'All of the trails that you have created will appear here.',
+ };
+ dashboardDoc.myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeViewChildDoubleClick: 'openPresentation(documentView.rootDoc)' });
+
// open this new dashboard
Doc.ActiveDashboard = dashboardDoc;
Doc.ActivePage = 'dashboard';
+ Doc.ActivePresentation = undefined;
+ const contextMenuScripts = [reqdBtnScript.onClick];
+ if (Cast(Doc.MyTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) {
+ Doc.MyTrails.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
+ }
};
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 24dae8816..09ab49d1c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -9,6 +9,7 @@ import 'normalize.css';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { List } from '../../fields/List';
import { ScriptField } from '../../fields/ScriptField';
import { StrCast } from '../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils';
@@ -520,11 +521,19 @@ export class MainView extends React.Component {
};
@action
- createNewPresentation = async () => {
+ createNewPresentation = () => {
const pres = Docs.Create.PresDocument({ title: 'Untitled Trail', _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: 'alias', _chromeHidden: true, boxShadow: '0 0' });
CollectionDockingView.AddSplit(pres, 'left');
+ Doc.MyTrails && Doc.AddDocToList(Doc.MyTrails, 'data', pres); // Doc.MyTrails should be created in createDashboard
Doc.ActivePresentation = pres;
+ };
+
+ @action
+ openPresentation = (pres: Doc) => {
+ CollectionDockingView.AddSplit(pres, 'left');
+ Doc.MyTrails && (Doc.ActivePresentation = pres);
Doc.AddDocToList(Doc.MyTrails, 'data', pres);
+ this.closeFlyout();
};
@action
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index bead5825c..042d39285 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -213,73 +213,75 @@ export class TabDocView extends React.Component<TabDocViewProps> {
public static PinDoc(docs: Doc | Doc[], pinProps?: PinProps) {
const docList = docs instanceof Doc ? [docs] : docs;
- // all docs will be added to the ActivePresentation as stored on CurrentUserUtils
- const curPres = Doc.ActivePresentation;
- if (curPres) {
- const batch = UndoManager.StartBatch('pinning doc');
- docList.forEach(doc => {
- // Edge Case 1: Cannot pin document to itself
- if (doc === curPres) {
- alert('Cannot pin presentation document to itself');
- return;
- }
- const pinDoc = Doc.MakeAlias(doc);
- pinDoc.presentationTargetDoc = doc;
- pinDoc.title = doc.title + ' - Slide';
- pinDoc.data = new List<Doc>(); // the children of the alias' layout are the presentation slide children. the alias' data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
- pinDoc.presMovement = PresMovement.Zoom;
- pinDoc.groupWithUp = false;
- pinDoc.context = curPres;
- // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
- pinDoc.treeViewRenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
- pinDoc.treeViewHeaderWidth = '100%'; // forces the header to grow to be the same size as its largest sibling.
- pinDoc.treeViewChildrenOnRoot = true; // tree view will look for hierarchical children on the root doc, not the data doc.
- pinDoc.treeViewFieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
- pinDoc.treeViewExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
- pinDoc.treeViewGrowsHorizontally = true; // the document expands horizontally when displayed as a tree view header
- pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
- const presArray: Doc[] = PresBox.Instance?.sortArray();
- const size: number = PresBox.Instance?.selectedArray.size;
- const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
- const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
+ const batch = UndoManager.StartBatch('pinning doc');
+ const curPres = Doc.ActivePresentation ?? Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true);
- PresBox.pinDocView(pinDoc, pinProps, doc);
- pinDoc.onClick = ScriptField.MakeFunction('navigateToDoc(self.presentationTargetDoc, self)');
- Doc.AddDocToList(curPres, 'data', pinDoc, presSelected);
- if (!pinProps?.audioRange && duration !== undefined) {
- pinDoc.mediaStart = 'manual';
- pinDoc.mediaStop = 'manual';
- pinDoc.presStartTime = NumCast(doc.clipStart);
- pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
- }
- //save position
- if (pinProps?.activeFrame !== undefined) {
- pinDoc.presActiveFrame = pinProps?.activeFrame;
- pinDoc.title = doc.title + ' (move)';
- pinDoc.presMovement = PresMovement.Pan;
- }
- if (pinDoc.isInkMask) {
- pinDoc.presHideAfter = true;
- pinDoc.presHideBefore = true;
- pinDoc.presMovement = PresMovement.None;
- }
- if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
- PresBox.Instance?.clearSelectedArray();
- pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); //Update selected array
- });
- if (
- CollectionDockingView.Instance &&
- !Array.from(CollectionDockingView.Instance.tabMap)
- .map(d => d.DashDoc)
- .includes(curPres)
- ) {
- const docs = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), []);
- if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1);
- CollectionDockingView.AddSplit(curPres, 'right');
- setTimeout(() => DocumentManager.Instance.jumpToDocument(docList.lastElement(), false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
+ if (!Doc.ActivePresentation) {
+ Doc.AddDocToList(Doc.MyTrails, 'data', curPres);
+ Doc.ActivePresentation = curPres;
+ }
+
+ docList.forEach(doc => {
+ // Edge Case 1: Cannot pin document to itself
+ if (doc === curPres) {
+ alert('Cannot pin presentation document to itself');
+ return;
+ }
+ const pinDoc = Doc.MakeAlias(doc);
+ pinDoc.presentationTargetDoc = doc;
+ pinDoc.title = doc.title + ' - Slide';
+ pinDoc.data = new List<Doc>(); // the children of the alias' layout are the presentation slide children. the alias' data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
+ pinDoc.presMovement = PresMovement.Zoom;
+ pinDoc.groupWithUp = false;
+ pinDoc.context = curPres;
+ // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
+ pinDoc.treeViewRenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
+ pinDoc.treeViewHeaderWidth = '100%'; // forces the header to grow to be the same size as its largest sibling.
+ pinDoc.treeViewChildrenOnRoot = true; // tree view will look for hierarchical children on the root doc, not the data doc.
+ pinDoc.treeViewFieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
+ pinDoc.treeViewExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
+ pinDoc.treeViewGrowsHorizontally = true; // the document expands horizontally when displayed as a tree view header
+ pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
+ const presArray: Doc[] = PresBox.Instance?.sortArray();
+ const size: number = PresBox.Instance?.selectedArray.size;
+ const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
+ const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
+
+ PresBox.pinDocView(pinDoc, pinProps, doc);
+ pinDoc.onClick = ScriptField.MakeFunction('navigateToDoc(self.presentationTargetDoc, self)');
+ Doc.AddDocToList(curPres, 'data', pinDoc, presSelected);
+ if (!pinProps?.audioRange && duration !== undefined) {
+ pinDoc.mediaStart = 'manual';
+ pinDoc.mediaStop = 'manual';
+ pinDoc.presStartTime = NumCast(doc.clipStart);
+ pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
+ }
+ //save position
+ if (pinProps?.activeFrame !== undefined) {
+ pinDoc.presActiveFrame = pinProps?.activeFrame;
+ pinDoc.title = doc.title + ' (move)';
+ pinDoc.presMovement = PresMovement.Pan;
+ }
+ if (pinDoc.isInkMask) {
+ pinDoc.presHideAfter = true;
+ pinDoc.presHideBefore = true;
+ pinDoc.presMovement = PresMovement.None;
}
- setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
+ if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
+ PresBox.Instance?.clearSelectedArray();
+ pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); //Update selected array
+ });
+ if (
+ !Array.from(CollectionDockingView.Instance?.tabMap ?? [])
+ .map(d => d.DashDoc)
+ .includes(curPres)
+ ) {
+ const docs = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), []);
+ if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1);
+ CollectionDockingView.AddSplit(curPres, 'left');
+ setTimeout(() => DocumentManager.Instance.jumpToDocument(docList.lastElement(), false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
}
+ setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
}
componentDidMount() {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 847617378..1325a9d67 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -88,11 +88,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
private _disposers: { [name: string]: IReactionDisposer } = {};
public selectedArray = new ObservableSet<Doc>();
- constructor(props: any) {
- super(props);
- if ((Doc.ActivePresentation = this.rootDoc)) runInAction(() => (PresBox.Instance = this));
- }
-
@observable public static Instance: PresBox;
@observable static startMarquee: boolean = false; // onclick "+ new slide" in presentation mode, set as true, then when marquee selection finish, onPointerUp automatically triggers PinWithView
@@ -199,7 +194,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.layoutDoc._gridGap = 0;
this.layoutDoc._yMargin = 0;
this.turnOffEdit(true);
- DocListCastAsync(Doc.MyTrails.data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.MyTrails, 'data', this.rootDoc));
this._disposers.selection = reaction(
() => SelectionManager.Views(),
views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation()
@@ -2320,7 +2314,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
return (
- <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
+ <div className="presBox-buttons" style={{ background: Doc.ActivePresentation === this.rootDoc ? 'green' : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
{isMini ? null : (
<select className="presBox-viewPicker" style={{ display: this.layoutDoc.presStatus === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}>
<option onPointerDown={StopEvent} value={CollectionViewType.Stacking}>
@@ -2582,7 +2576,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
return DocListCast(Doc.MyOverlayDocs?.data).includes(this.rootDoc) ? (
<div className="miniPres" onClick={e => e.stopPropagation()} onPointerEnter={action(e => (this._forceKeyEvents = true))}>
- <div className="presPanelOverlay" style={{ display: 'inline-flex', height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: this._presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
+ <div
+ className="presPanelOverlay"
+ style={{ display: 'inline-flex', height: 30, background: Doc.ActivePresentation === this.rootDoc ? 'green' : '#323232', top: 0, zIndex: 3000000, boxShadow: this._presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
<Tooltip title={<div className="dash-tooltip">{'Loop'}</div>}>
<div
className="presPanel-button"
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 3ce22bacb..cf505c45b 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -180,7 +180,7 @@ export class Doc extends RefField {
return DocCast(Doc.UserDoc().myRecentlyClosed);
}
public static get MyTrails() {
- return DocCast(Doc.UserDoc().myTrails);
+ return DocCast(Doc.ActiveDashboard?.myTrails);
}
public static get MyOverlayDocs() {
return DocCast(Doc.UserDoc().myOverlayDocs);
@@ -225,11 +225,13 @@ export class Doc extends RefField {
public static get ActiveTool(): InkTool {
return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool;
}
- public static get ActivePresentation() {
- return DocCast(Doc.UserDoc().activePresentation);
+ public static get ActivePresentation(): Opt<Doc> {
+ return DocCast(Doc.ActiveDashboard?.activePresentation);
}
public static set ActivePresentation(val) {
- Doc.UserDoc().activePresentation = new PrefetchProxy(val);
+ if (Doc.ActiveDashboard) {
+ Doc.ActiveDashboard.activePresentation = val;
+ }
}
constructor(id?: FieldId, forceSave?: boolean) {
super(id);
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index f19496d25..8265de445 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -832,7 +832,7 @@ export class MobileInterface extends React.Component {
</div>
{this.switchMenuView}
{this.inkMenu}
- <GestureOverlay>
+ <GestureOverlay isActive={true}>
<div style={{ display: 'none' }}>
<RichTextMenu key="rich" />
</div>