diff options
author | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 10:17:05 -0700 |
---|---|---|
committer | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 10:17:05 -0700 |
commit | 3bedd60eb0044cbe24e1f4f2d6b55c85cee79959 (patch) | |
tree | fc5ffcaa03c371fc7cfd5eda5b0bafa13dfe462c | |
parent | a01f3541a40f119dbfd73236dbd5f99de9d78ff7 (diff) | |
parent | ea6e63648b21c46672b1b7cb1da0cbaa6857d0c1 (diff) |
Merge branch 'master' into geireann-eslint-prettier
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 2726 | ||||
-rw-r--r-- | src/client/util/DropConverter.ts | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackedTimeline.tsx | 6 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 6 |
4 files changed, 646 insertions, 2094 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index a7b24c426..a39081d10 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1,61 +1,38 @@ -import { computed, observable, reaction } from 'mobx'; +import { computed, observable, reaction } from "mobx"; import * as rp from 'request-promise'; -import { - DataSym, - Doc, - DocListCast, - DocListCastAsync, - Opt, -} from '../../fields/Doc'; -import { Id } from '../../fields/FieldSymbols'; -import { InkTool } from '../../fields/InkField'; -import { List } from '../../fields/List'; -import { PrefetchProxy } from '../../fields/Proxy'; -import { RichTextField } from '../../fields/RichTextField'; -import { listSpec } from '../../fields/Schema'; -import { ComputedField, ScriptField } from '../../fields/ScriptField'; -import { - Cast, - DateCast, - DocCast, - FieldValue, - NumCast, - PromiseValue, - ScriptCast, - StrCast, -} from '../../fields/Types'; -import { ImageField, nullAudio } from '../../fields/URLField'; -import { SharingPermissions } from '../../fields/util'; -import { OmitKeys, Utils } from '../../Utils'; -import { DocServer } from '../DocServer'; -import { Docs, DocumentOptions, DocUtils, FInfo } from '../documents/Documents'; -import { DocumentType } from '../documents/DocumentTypes'; -import { CollectionDockingView } from '../views/collections/CollectionDockingView'; -import { CollectionFreeFormView } from '../views/collections/collectionFreeForm'; -import { TreeViewType } from '../views/collections/CollectionTreeView'; -import { - CollectionView, - CollectionViewType, -} from '../views/collections/CollectionView'; -import { TreeView } from '../views/collections/TreeView'; -import { Colors } from '../views/global/globalEnums'; -import { MainView } from '../views/MainView'; -import { ButtonType, NumButtonType } from '../views/nodes/button/FontIconBox'; -import { CollectionFreeFormDocumentView } from '../views/nodes/CollectionFreeFormDocumentView'; -import { DocumentView } from '../views/nodes/DocumentView'; -import { OverlayView } from '../views/OverlayView'; -import { DocumentManager } from './DocumentManager'; -import { DragManager } from './DragManager'; -import { makeTemplate, MakeTemplate } from './DropConverter'; -import { HistoryUtil } from './History'; -import { LinkManager } from './LinkManager'; -import { ScriptingGlobals } from './ScriptingGlobals'; -import { SearchUtil } from './SearchUtil'; -import { SelectionManager } from './SelectionManager'; -import { ColorScheme } from './SettingsManager'; -import { SharingManager } from './SharingManager'; -import { SnappingManager } from './SnappingManager'; -import { UndoManager } from './UndoManager'; +import { DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; +import { Id } from "../../fields/FieldSymbols"; +import { InkTool } from "../../fields/InkField"; +import { List } from "../../fields/List"; +import { PrefetchProxy } from "../../fields/Proxy"; +import { RichTextField } from "../../fields/RichTextField"; +import { listSpec } from "../../fields/Schema"; +import { ComputedField, ScriptField } from "../../fields/ScriptField"; +import { Cast, DateCast, DocCast, FieldValue, NumCast, PromiseValue, ScriptCast, StrCast } from "../../fields/Types"; +import { nullAudio } from "../../fields/URLField"; +import { SharingPermissions } from "../../fields/util"; +import { OmitKeys, Utils } from "../../Utils"; +import { DocServer } from "../DocServer"; +import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents"; +import { DocumentType } from "../documents/DocumentTypes"; +import { CollectionDockingView } from "../views/collections/CollectionDockingView"; +import { TreeViewType } from "../views/collections/CollectionTreeView"; +import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; +import { TreeView } from "../views/collections/TreeView"; +import { Colors } from "../views/global/globalEnums"; +import { MainView } from "../views/MainView"; +import { ButtonType, NumButtonType } from "../views/nodes/button/FontIconBox"; +import { OverlayView } from "../views/OverlayView"; +import { DragManager } from "./DragManager"; +import { MakeTemplate } from "./DropConverter"; +import { HistoryUtil } from "./History"; +import { LinkManager } from "./LinkManager"; +import { ScriptingGlobals } from "./ScriptingGlobals"; +import { SelectionManager } from "./SelectionManager"; +import { ColorScheme } from "./SettingsManager"; +import { SharingManager } from "./SharingManager"; +import { SnappingManager } from "./SnappingManager"; +import { UndoManager } from "./UndoManager"; interface Button { // DocumentOptions fields a button can set @@ -73,29 +50,21 @@ interface Button { buttonText?: string; // fields that do not correspond to DocumentOption fields - scripts?: { script?: string; onClick?: string }; - funcs?: { [key: string]: string }; + scripts?: { script?: string; onClick?: string; } + funcs?: { [key:string]: string }; subMenu?: Button[]; } -export let resolvedPorts: { server: number; socket: number }; +export let resolvedPorts: { server: number, socket: number }; export class CurrentUserUtils { private static curr_id: string; //TODO tfs: these should be temporary... private static mainDocId: string | undefined; - public static get id() { - return this.curr_id; - } - public static get MainDocId() { - return this.mainDocId; - } - public static set MainDocId(id: string | undefined) { - this.mainDocId = id; - } - @computed public static get UserDocument() { - return Doc.UserDoc(); - } + public static get id() { return this.curr_id; } + public static get MainDocId() { return this.mainDocId; } + public static set MainDocId(id: string | undefined) { this.mainDocId = id; } + @computed public static get UserDocument() { return Doc.UserDoc(); } @observable public static GuestTarget: Doc | undefined; @observable public static GuestDashboard: Doc | undefined; @@ -104,393 +73,143 @@ export class CurrentUserUtils { @observable public static headerBarHeight: number = 0; @observable public static searchPanelWidth: number = 0; - static AssignScripts( - doc: Doc, - scripts?: { [key: string]: string }, - funcs?: { [key: string]: string } - ) { - scripts && - Object.keys(scripts).map((key) => { - if ( - ScriptCast(doc[key])?.script.originalScript !== - scripts[key] && - scripts[key] - ) { - doc[key] = ScriptField.MakeScript( - scripts[key], - { - dragData: DragManager.DocumentDragData.name, - value: 'any', - scriptContext: 'any', - documentView: Doc.name, - }, - { _readOnly_: true } - ); - } - }); - funcs && - Object.keys(funcs).map((key) => { - const cfield = ComputedField.WithoutComputed(() => - FieldValue(doc[key]) - ); - if ( - ScriptCast(cfield)?.script.originalScript !== funcs[key] && - funcs[key] - ) { - doc[key] = ComputedField.MakeFunction( - funcs[key], - { dragData: DragManager.DocumentDragData.name }, - { _readOnly_: true } - ); - } - }); + static AssignScripts(doc:Doc, scripts?:{ [key: string]: string;}, funcs?:{[key:string]: string}) { + scripts && Object.keys(scripts).map(key => { + if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && scripts[key]) { + doc[key] = ScriptField.MakeScript(scripts[key], { dragData: DragManager.DocumentDragData.name, value:"any", scriptContext: "any", documentView:Doc.name}, {"_readOnly_": true}); + } + }); + funcs && Object.keys(funcs).map(key => { + const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); + if (ScriptCast(cfield)?.script.originalScript !== funcs[key] && funcs[key]) { + doc[key] = ComputedField.MakeFunction(funcs[key], { dragData: DragManager.DocumentDragData.name }, {"_readOnly_": true}); + } + }); return doc; } - static AssignOpts( - doc: Doc | undefined, - reqdOpts: DocumentOptions, - items?: Doc[] - ) { + static AssignOpts(doc:Doc|undefined, reqdOpts:DocumentOptions, items?:Doc[]) { if (doc) { - const compareValues = (val1: any, val2: any) => { - if ( - val1 instanceof List && - val2 instanceof List && - val1.length === val2.length - ) { - return ( - !val1.some((v) => !val2.includes(v)) || - !val2.some((v) => val1.includes(v)) - ); + const compareValues = (val1:any, val2:any) => { + if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) { + return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v)); } return val1 === val2; - }; - Object.entries(reqdOpts).forEach((pair) => { - const targetDoc = pair[0].startsWith('_') - ? doc - : Doc.GetProto(doc as Doc); - if ( - !Object.getOwnPropertyNames(targetDoc).includes( - pair[0].replace(/^_/, '') - ) || - !compareValues(pair[1], targetDoc[pair[0]]) - ) { + } + Object.entries(reqdOpts).forEach(pair => { + const targetDoc = pair[0].startsWith("_") ? doc : Doc.GetProto(doc as Doc); + if (!Object.getOwnPropertyNames(targetDoc).includes(pair[0].replace(/^_/,"")) || + !compareValues(pair[1], targetDoc[pair[0]])) { targetDoc[pair[0]] = pair[1]; } }); - items?.forEach( - (item) => - !DocListCast(doc.data).includes(item) && - Doc.AddDocToList(Doc.GetProto(doc), 'data', item) - ); - items && - DocListCast(doc.data).forEach( - (item) => - !items.includes(item) && - Doc.RemoveDocFromList(Doc.GetProto(doc), 'data', item) - ); + items?.forEach(item => !DocListCast(doc.data).includes(item) && Doc.AddDocToList(Doc.GetProto(doc), "data", item)); + items && DocListCast(doc.data).forEach(item => !items.includes(item) && Doc.RemoveDocFromList(Doc.GetProto(doc), "data", item)); } return doc; } - static AssignDocField( - doc: Doc, - field: string, - creator: (reqdOpts: DocumentOptions, items?: Doc[]) => Doc, - reqdOpts: DocumentOptions, - items?: Doc[], - scripts?: { [key: string]: string }, - funcs?: { [key: string]: string } - ) { - return this.AssignScripts( - this.AssignOpts(DocCast(doc[field]), reqdOpts, items) ?? - (doc[field] = creator(reqdOpts, items)), - scripts, - funcs - ); + static AssignDocField(doc:Doc, field:string, creator:(reqdOpts:DocumentOptions, items?:Doc[]) => Doc, reqdOpts:DocumentOptions, items?: Doc[], scripts?:{[key:string]:string}, funcs?:{[key:string]:string}) { + return this.AssignScripts(this.AssignOpts(DocCast(doc[field]), reqdOpts, items) ?? (doc[field] = creator(reqdOpts, items)), scripts, funcs); } // initializes experimental advanced template views - slideView, headerView - static setupExperimentalTemplateButtons(doc: Doc, tempDocs?: Doc) { - const requiredTypeNameFields: { - btnOpts: DocumentOptions; - templateOpts: DocumentOptions; - template: (opts: DocumentOptions) => Doc; - }[] = [ + static setupExperimentalTemplateButtons(doc: Doc, tempDocs?:Doc) { + const requiredTypeNameFields:{btnOpts:DocumentOptions, templateOpts:DocumentOptions, template:(opts:DocumentOptions) => Doc}[] = [ { - btnOpts: { title: 'slide', icon: 'address-card' }, - templateOpts: { - _width: 400, - _height: 300, - title: 'slideView', - childDocumentsActive: true, - _xMargin: 3, - _yMargin: 3, - system: true, - }, - template: (opts: DocumentOptions) => - Docs.Create.MultirowDocument( - [ - Docs.Create.MulticolumnDocument([], { - title: 'data', - _height: 200, - system: true, - }), - Docs.Create.TextDocument('', { - title: 'text', - _fitWidth: true, - _height: 100, - system: true, - _fontFamily: StrCast(Doc.UserDoc()._fontFamily), - _fontSize: StrCast(Doc.UserDoc()._fontSize), - }), - ], - opts - ), + btnOpts: { title: "slide", icon: "address-card" }, + templateOpts: { _width: 400, _height: 300, title: "slideView", childDocumentsActive: true, _xMargin: 3, _yMargin: 3, system: true }, + template: (opts:DocumentOptions) => Docs.Create.MultirowDocument( + [ + Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }), + Docs.Create.TextDocument("", { title: "text", _fitWidth:true, _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) }) + ], opts) }, { - btnOpts: { title: 'mobile', icon: 'mobile' }, - templateOpts: { - title: 'NEW MOBILE BUTTON', - onClick: undefined, - }, - template: (opts: DocumentOptions) => - this.mobileButton(opts, [ - this.createToolButton({ - ignoreClick: true, - icon: 'mobile', - backgroundColor: 'transparent', - }), - this.mobileTextContainer({}, [ - this.mobileButtonText({}, 'NEW MOBILE BUTTON'), - this.mobileButtonInfo( - {}, - 'You can customize this button and make it your own.' - ), - ]), - ]), + btnOpts: { title: "mobile", icon: "mobile" }, + templateOpts: { title: "NEW MOBILE BUTTON", onClick: undefined, }, + template: (opts:DocumentOptions) => this.mobileButton(opts, + [this.createToolButton({ ignoreClick: true, icon: "mobile", backgroundColor: "transparent" }), + this.mobileTextContainer({}, + [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")]) + ] + ) }, ]; - const requiredTypes = requiredTypeNameFields.map( - ({ btnOpts, template, templateOpts }) => { - const tempBtn = DocListCast(tempDocs?.data)?.find( - (doc) => doc.title === btnOpts.title - ); - const reqdScripts = { - onDragStart: - '{ return copyDragFactory(this.dragFactory); }', - }; - const assignBtnAndTempOpts = ( - templateBtn: Opt<Doc>, - btnOpts: DocumentOptions, - templateOptions: DocumentOptions - ) => { - if (templateBtn) { - this.AssignOpts(templateBtn, btnOpts); - this.AssignDocField( - templateBtn, - 'dragFactory', - (opts) => template(opts), - templateOptions - ); - } - return templateBtn; - }; - const makeTemp = (doc: Doc) => { - doc.isTemplateDoc = makeTemplate(doc); - return doc; - }; - return this.AssignScripts( - assignBtnAndTempOpts(tempBtn, btnOpts, templateOpts) ?? - this.createToolButton({ - ...btnOpts, - dragFactory: makeTemp(template(templateOpts)), - }), - reqdScripts - ); - } - ); + const requiredTypes = requiredTypeNameFields.map(({ btnOpts, template, templateOpts }) => { + const tempBtn = DocListCast(tempDocs?.data)?.find(doc => doc.title === btnOpts.title); + const reqdScripts = { onDragStart: '{ return copyDragFactory(this.dragFactory); }' }; + const assignBtnAndTempOpts = (templateBtn:Opt<Doc>, btnOpts:DocumentOptions, templateOptions:DocumentOptions) => { + if (templateBtn) { + this.AssignOpts(templateBtn,btnOpts); + this.AssignDocField(templateBtn, "dragFactory", opts => template(opts), templateOptions); + } + return templateBtn; + }; + return this.AssignScripts(assignBtnAndTempOpts(tempBtn, btnOpts, templateOpts) ?? this.createToolButton( {...btnOpts, dragFactory: MakeTemplate(template(templateOpts))}), reqdScripts); + }); - const reqdOpts: DocumentOptions = { - title: 'Experimental Tools', - _xMargin: 0, - _showTitle: 'title', - _chromeHidden: true, - _stayInCollection: true, - _hideContextMenu: true, - _forceActive: true, - system: true, - childDocumentsActive: true, - _autoHeight: true, - _width: 500, - _height: 300, - _fitWidth: true, - _columnWidth: 35, - ignoreClick: true, - _lockedPosition: true, + const reqdOpts:DocumentOptions = { + title: "Experimental Tools", _xMargin: 0, _showTitle: "title", _chromeHidden: true, + _stayInCollection: true, _hideContextMenu: true, _forceActive: true, system: true, childDocumentsActive: true, + _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, }; - const reqdScripts = { dropConverter: 'convertToButtons(dragData)' }; - const reqdFuncs = { hidden: 'IsNoviceMode()' }; - return this.AssignScripts( - this.AssignOpts(tempDocs, reqdOpts, requiredTypes) ?? - Docs.Create.MasonryDocument(requiredTypes, reqdOpts), - reqdScripts, - reqdFuncs - ); + const reqdScripts = { dropConverter : "convertToButtons(dragData)" }; + const reqdFuncs = { hidden: "IsNoviceMode()" }; + return this.AssignScripts(this.AssignOpts(tempDocs, reqdOpts, requiredTypes) ?? Docs.Create.MasonryDocument(requiredTypes, reqdOpts), reqdScripts, reqdFuncs); } /// Initializes templates that can be applied to notes - static setupNoteTemplates(doc: Doc, field = 'template-notes') { + static setupNoteTemplates(doc: Doc, field="template-notes") { const tempNotes = DocCast(doc[field]); - const reqdTempOpts: DocumentOptions[] = [ - { - noteType: 'Note', - backgroundColor: 'yellow', - icon: 'sticky-note', - }, - { noteType: 'Idea', backgroundColor: 'pink', icon: 'lightbulb' }, - { - noteType: 'Topic', - backgroundColor: 'lightblue', - icon: 'book-open', - }, - ]; - const reqdNoteList = reqdTempOpts.map((opts) => { - const reqdOpts = { ...opts, title: 'text', system: true }; - const noteType = tempNotes - ? DocListCast(tempNotes.data).find( - (doc) => doc.noteType === opts.noteType - ) - : undefined; - const makeTemp = (doc: Doc, noteType?: string) => { - doc.isTemplateDoc = makeTemplate(doc, true, noteType ?? 'Note'); - return doc; - }; - return ( - this.AssignOpts(noteType, reqdOpts) ?? - makeTemp(Docs.Create.TextDocument('', reqdOpts), opts.noteType) - ); + const reqdTempOpts:DocumentOptions[] = [ + { noteType: "Note", backgroundColor: "yellow", icon: "sticky-note"}, + { noteType: "Idea", backgroundColor: "pink", icon: "lightbulb" }, + { noteType: "Topic", backgroundColor: "lightblue", icon: "book-open" }]; + const reqdNoteList = reqdTempOpts.map(opts => { + const reqdOpts = {...opts, title: "text", system: true}; + const noteType = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.noteType === opts.noteType): undefined; + return this.AssignOpts(noteType, reqdOpts) ?? MakeTemplate(Docs.Create.TextDocument("",reqdOpts), true, opts.noteType??"Note"); }); - const reqdOpts: DocumentOptions = { - title: 'Note Layouts', - _height: 75, - system: true, - }; - return ( - this.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? - (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts)) - ); + const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, system: true }; + return this.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts)); } /// Initializes collection of templates for notes and click functions - static setupDocTemplates(doc: Doc, field = 'myTemplates') { - this.AssignDocField( - doc, - 'presElement', - (opts) => Docs.Create.PresElementBoxDocument(opts), - { - title: 'pres element template', - type: DocumentType.PRESELEMENT, - _fitWidth: true, - _xMargin: 0, - isTemplateDoc: true, - isTemplateForField: 'data', - } - ); + static setupDocTemplates(doc: Doc, field="myTemplates") { + this.AssignDocField(doc, "presElement", opts => Docs.Create.PresElementBoxDocument(opts), { title: "pres element template", type: DocumentType.PRESELEMENT, _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"}); const templates = [ DocCast(doc.presElement), CurrentUserUtils.setupNoteTemplates(doc), - CurrentUserUtils.setupClickEditorTemplates(doc), + CurrentUserUtils.setupClickEditorTemplates(doc) ]; - const reqdOpts = { - title: 'template layouts', - _xMargin: 0, - system: true, - }; - const reqdScripts = { dropConverter: 'convertToButtons(dragData)' }; - return this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.TreeDocument(items ?? [], opts), - reqdOpts, - templates, - reqdScripts - ); + const reqdOpts = { title: "template layouts", _xMargin: 0, system: true, }; + const reqdScripts = { dropConverter: "convertToButtons(dragData)" }; + return this.AssignDocField(doc, field, (opts,items) => Docs.Create.TreeDocument(items??[], opts), reqdOpts, templates, reqdScripts); } // setup templates for different document types when they are iconified from Document Decorations - static setupDefaultIconTemplates(doc: Doc, field = 'template-icons') { - const reqdOpts = { title: 'icon templates', _height: 75, system: true }; - const templateIconsDoc = - this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? - (doc[field] = Docs.Create.TreeDocument([], reqdOpts)); - - const makeIconTemplate = ( - type: DocumentType | undefined, - templateField: string, - opts: DocumentOptions - ) => { - const iconFieldName = 'icon' + (type ? '_' + type : ''); + static setupDefaultIconTemplates(doc: Doc, field="template-icons") { + const reqdOpts = { title: "icon templates", _height: 75, system: true }; + const templateIconsDoc = this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([], reqdOpts)); + + const makeIconTemplate = (type: DocumentType | undefined, templateField: string, opts:DocumentOptions) => { + const iconFieldName = "icon" + (type ? "_" + type : ""); const curIcon = DocCast(templateIconsDoc[iconFieldName]); let creator = labelBox; switch (opts.iconTemplate) { - case DocumentType.IMG: - creator = imageBox; - break; - case DocumentType.FONTICON: - creator = fontBox; - break; + case DocumentType.IMG : creator = imageBox; break; + case DocumentType.FONTICON: creator = fontBox; break; } - const allopts = { system: true, ...opts }; - return this.AssignScripts( - (curIcon?.iconTemplate === opts.iconTemplate - ? this.AssignOpts(curIcon, allopts) - : undefined) ?? - (templateIconsDoc[iconFieldName] = MakeTemplate( - creator(allopts), - true, - iconFieldName, - templateField - )), - { onClick: 'deiconifyView(documentView)' } - ); + const allopts = {system: true, ...opts}; + return this.AssignScripts( (curIcon?.iconTemplate === opts.iconTemplate ? + this.AssignOpts(curIcon, allopts):undefined) ?? ((templateIconsDoc[iconFieldName] = MakeTemplate(creator(allopts), true, iconFieldName, templateField))), + {onClick:"deiconifyView(documentView)"}); }; - const labelBox = (opts: DocumentOptions, data?: string) => - Docs.Create.LabelDocument({ - textTransform: 'unset', - letterSpacing: 'unset', - _singleLine: false, - _minFontSize: 14, - _maxFontSize: 24, - borderRounding: '5px', - _width: 150, - _height: 70, - _xPadding: 10, - _yPadding: 10, - ...opts, - }); - const imageBox = (opts: DocumentOptions, url?: string) => - Docs.Create.ImageDocument( - url ?? 'http://www.cs.brown.edu/~bcz/noImage.png', - { - 'icon-nativeWidth': 360 / 4, - 'icon-nativeHeight': 270 / 4, - iconTemplate: DocumentType.IMG, - _width: 360 / 4, - _height: 270 / 4, - _showTitle: 'title', - ...opts, - } - ); - const fontBox = (opts: DocumentOptions, data?: string) => - Docs.Create.FontIconDocument({ - _nativeHeight: 30, - _nativeWidth: 30, - _width: 30, - _height: 30, - ...opts, - }); - // prettier-ignore + const labelBox = (opts: DocumentOptions, data?:string) => Docs.Create.LabelDocument({ + textTransform: "unset", letterSpacing: "unset", _singleLine: false, _minFontSize: 14, _maxFontSize: 24, borderRounding: "5px", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, ...opts + }); + const imageBox = (opts: DocumentOptions, url?:string) => Docs.Create.ImageDocument(url ?? "http://www.cs.brown.edu/~bcz/noImage.png", { "icon-nativeWidth": 360 / 4, "icon-nativeHeight": 270 / 4, iconTemplate:DocumentType.IMG, _width: 360 / 4, _height: 270 / 4, _showTitle: "title", ...opts }); + const fontBox = (opts:DocumentOptions, data?:string) => Docs.Create.FontIconDocument({ _nativeHeight: 30, _nativeWidth: 30, _width: 30, _height: 30, ...opts }); const iconTemplates = [ makeIconTemplate(undefined, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "dimgray"}), makeIconTemplate(DocumentType.AUDIO, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "lightgreen"}), @@ -510,88 +229,47 @@ export class CurrentUserUtils { /// initalizes the set of "empty<DocType>" versions of each document type with default fields. e.g.,. emptyNote, emptyPresentation static creatorBtnDescriptors(doc: Doc): { - title: string; - toolTip: string; - icon: string; - ignoreClick?: boolean; - dragFactory?: Doc; - backgroundColor?: string; - clickFactory?: Doc; - scripts?: { onClick?: string; onDragStart?: string }; - funcs?: { onDragStart?: string; hidden?: string }; + title: string, toolTip: string, icon: string, ignoreClick?: boolean, dragFactory?: Doc, + backgroundColor?: string, clickFactory?: Doc, scripts?: { onClick?: string, onDragStart?: string}, funcs?: {onDragStart?:string, hidden?: string}, }[] { - const standardOps = (key: string) => ({ - title: 'Untitled ' + key, - _fitWidth: true, - system: true, - 'dragFactory-count': 0, - cloneFieldFilter: new List<string>(['system']), - }); + const standardOps = (key:string) => ({ title : "Untitled "+ key, _fitWidth: true, system: true, "dragFactory-count": 0, cloneFieldFilter: new List<string>(["system"]) }); const json = { doc: { - type: 'doc', + type: "doc", content: [ { - type: 'paragraph', - attrs: {}, - content: [ - { - type: 'dashField', - attrs: { - fieldKey: 'author', - docid: '', - hideKey: false, - }, - marks: [{ type: 'strong' }], - }, - { - type: 'dashField', - attrs: { - fieldKey: 'creationDate', - docid: '', - hideKey: false, - }, - marks: [{ type: 'strong' }], - }, - ], - }, - ], + type: "paragraph", attrs: {}, content: [{ + type: "dashField", + attrs: { fieldKey: "author", docid: "", hideKey: false }, + marks: [{ type: "strong" }] + }, { + type: "dashField", + attrs: { fieldKey: "creationDate", docid: "", hideKey: false }, + marks: [{ type: "strong" }] + }] + }] }, - selection: { type: 'text', anchor: 1, head: 1 }, - storedMarks: [], + selection: { type: "text", anchor: 1, head: 1 }, + storedMarks: [] }; const headerBtnHgt = 10; - const headerTemplate = (opts: DocumentOptions) => { - const header = Docs.Create.RTFDocument( - new RichTextField(JSON.stringify(json), ''), - { - ...opts, - title: 'text', - layout: - "<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>" + - ` <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight||0}px)'/>` + - " <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize||9}px' height='{(this._headerHeight||0)}px' background='{this._headerColor || MySharedDocs().userColor||`lightGray`}' />" + - ` <HTMLdiv fontSize='${ - headerBtnHgt - 1 - }px' height='${headerBtnHgt}px' background='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(0,this._height-30),this._headerHeight===0?50:0)) + (this._autoHeightMargins=this._headerHeight ? this._headerHeight+${headerBtnHgt}:0)’} >Metadata</HTMLdiv>` + - '</HTMLdiv>', - }, - 'header' - ); + const headerTemplate = (opts:DocumentOptions) => { + const header = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { ...opts, title: "text", + layout: + "<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>" + + ` <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight||0}px)'/>` + + " <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize||9}px' height='{(this._headerHeight||0)}px' background='{this._headerColor || MySharedDocs().userColor||`lightGray`}' />" + + ` <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' background='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(0,this._height-30),this._headerHeight===0?50:0)) + (this._autoHeightMargins=this._headerHeight ? this._headerHeight+${headerBtnHgt}:0)’} >Metadata</HTMLdiv>` + + "</HTMLdiv>" + }, "header"); // "<div style={'height:100%'}>" + // " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._headerPointerEvents||`none`}' fontSize='{this._headerFontSize}px' height='{this._headerHeight}px' background='{this._headerColor||this.target.mySharedDocs.userColor}' />" + // " <FormattedTextBox {...props} fieldKey={'text'} position='absolute' top='{(this._headerHeight)*scale}px' height='calc({100/scale}% - {this._headerHeight}px)'/>" + // "</div>"; - Doc.GetProto(header).isTemplateDoc = makeTemplate( - Doc.GetProto(header), - true, - 'headerView' - ); - Doc.GetProto(header).title = 'Untitled Header'; - return header; - }; - // prettier-ignore + MakeTemplate(Doc.GetProto(header), true, "Untitled Header"); + return header; + } const emptyThings:{key:string, // the field name where the empty thing will be stored opts:DocumentOptions, // the document options that are required for the empty thing funcs?:{[key:string]: any}, // computed fields that are rquired for the empth thing @@ -619,18 +297,8 @@ export class CurrentUserUtils { }, funcs: {title: 'self.text?.Text'}}, ]; - emptyThings.forEach((thing) => - this.AssignDocField( - doc, - 'empty' + thing.key, - (opts) => thing.creator(opts), - { ...standardOps(thing.key), ...thing.opts }, - undefined, - undefined, - thing.funcs - ) - ); - // prettier-ignore + emptyThings.forEach(thing => this.AssignDocField(doc, "empty"+thing.key, (opts) => thing.creator(opts), {...standardOps(thing.key), ...thing.opts}, undefined, undefined, thing.funcs)); + return [ { toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, }, { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab), scripts: { onClick: 'openOnRight(copyDragFactory(this.clickFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, }, @@ -650,82 +318,29 @@ export class CurrentUserUtils { } /// Initalizes the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools - static setupCreatorButtons(doc: Doc, dragCreatorDoc?: Doc): Doc { - const creatorBtns = CurrentUserUtils.creatorBtnDescriptors(doc).map( - (reqdOpts) => { - const btn = dragCreatorDoc - ? DocListCast(dragCreatorDoc.data).find( - (doc) => doc.title === reqdOpts.title - ) - : undefined; - const opts: DocumentOptions = { - ...OmitKeys(reqdOpts, [ - 'funcs', - 'scripts', - 'backgroundColor', - ]).omit, - _nativeWidth: 50, - _nativeHeight: 50, - _width: 35, - _height: 35, - _hideContextMenu: true, - _stayInCollection: true, - _dropAction: 'alias', - btnType: ButtonType.ToolButton, - backgroundColor: - reqdOpts.backgroundColor ?? Colors.DARK_GRAY, - color: Colors.WHITE, - system: true, - _removeDropProperties: new List<string>([ - '_stayInCollection', - ]), + static setupCreatorButtons(doc: Doc, dragCreatorDoc?:Doc):Doc { + const creatorBtns = CurrentUserUtils.creatorBtnDescriptors(doc).map((reqdOpts) => { + const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(doc => doc.title === reqdOpts.title): undefined; + const opts:DocumentOptions = {...OmitKeys(reqdOpts, ["funcs", "scripts", "backgroundColor"]).omit, + _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35, _hideContextMenu: true, _stayInCollection: true, _dropAction: "alias", + btnType: ButtonType.ToolButton, backgroundColor: reqdOpts.backgroundColor ?? Colors.DARK_GRAY, color: Colors.WHITE, system: true, + _removeDropProperties: new List<string>(["_stayInCollection"]), }; - return this.AssignScripts( - this.AssignOpts(btn, opts) ?? - Docs.Create.FontIconDocument(opts), - reqdOpts.scripts, - reqdOpts.funcs - ); - } - ); + return this.AssignScripts(this.AssignOpts(btn, opts) ?? Docs.Create.FontIconDocument(opts), reqdOpts.scripts, reqdOpts.funcs); + }); - const reqdOpts: DocumentOptions = { - title: 'Basic Item Creators', - _showTitle: 'title', - _xMargin: 0, - _stayInCollection: true, - _hideContextMenu: true, - _chromeHidden: true, - system: true, - _autoHeight: true, - _width: 500, - _height: 300, - _fitWidth: true, - _columnWidth: 40, - ignoreClick: true, - _lockedPosition: true, - _forceActive: true, - childDocumentsActive: true, + const reqdOpts:DocumentOptions = { + title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, system: true, + _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true, _forceActive: true, + childDocumentsActive: true }; - const reqdScripts = { dropConverter: 'convertToButtons(dragData)' }; - return this.AssignScripts( - this.AssignOpts(dragCreatorDoc, reqdOpts, creatorBtns) ?? - Docs.Create.MasonryDocument(creatorBtns, reqdOpts), - reqdScripts - ); + const reqdScripts = { dropConverter: "convertToButtons(dragData)" }; + return this.AssignScripts(this.AssignOpts(dragCreatorDoc, reqdOpts, creatorBtns) ?? Docs.Create.MasonryDocument(creatorBtns, reqdOpts), reqdScripts); } /// 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())"; - // prettier-ignore + 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())"; return [ { title: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", }, { title: "Search", target: this.setupSearcher(doc, "mySearcher"), icon: "search", }, @@ -740,110 +355,40 @@ export class CurrentUserUtils { } /// the empty panel that is filled with whichever left menu button's panel has been selected - static setupLeftSidebarPanel(doc: Doc, field = 'myLeftSidebarPanel') { - this.AssignDocField( - doc, - field, - (opts) => - ((doc: Doc) => { - doc.system = true; - return doc; - })(new Doc()), - { system: true } - ); + static setupLeftSidebarPanel(doc: Doc, field="myLeftSidebarPanel") { + this.AssignDocField(doc, field, (opts) => ((doc:Doc) => {doc.system = true; return doc;})(new Doc()), {system:true}); } /// Initializes the left sidebar menu buttons and the panels they open up - static setupLeftSidebarMenu(doc: Doc, field = 'myLeftSidebarMenu') { + static setupLeftSidebarMenu(doc: Doc, field="myLeftSidebarMenu") { this.setupLeftSidebarPanel(doc); const myLeftSidebarMenu = DocCast(doc[field]); - const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions( - doc - ).map(({ title, target, icon, scripts, funcs }) => { - const btnDoc = myLeftSidebarMenu - ? DocListCast(myLeftSidebarMenu.data).find( - (doc) => doc.title === title - ) - : undefined; - const reqdBtnOpts: DocumentOptions = { - title, - icon, - target, - btnType: ButtonType.MenuButton, - system: true, - dontUndo: true, - dontRegisterView: true, - _width: 60, - _height: 60, - _stayInCollection: true, - _hideContextMenu: true, - _chromeHidden: true, - _dropAction: 'alias', - _removeDropProperties: new List<string>([ - 'dropAction', - '_stayInCollection', - ]), + const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, scripts, funcs }) => { + const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined; + const reqdBtnOpts:DocumentOptions = { + title, icon, target, btnType: ButtonType.MenuButton, system: true, dontUndo: true, dontRegisterView: true, + _width: 60, _height: 60, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, _dropAction: "alias", + _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]), }; - return this.AssignScripts( - this.AssignOpts(btnDoc, reqdBtnOpts) ?? - Docs.Create.FontIconDocument(reqdBtnOpts), - scripts, - funcs - ); + return this.AssignScripts(this.AssignOpts(btnDoc, reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), scripts, funcs); }); - const reqdStackOpts: DocumentOptions = { - title: 'menuItemPanel', - childDropAction: 'alias', - backgroundColor: Colors.DARK_GRAY, - boxShadow: 'rgba(0,0,0,0)', - dontRegisterView: true, - ignoreClick: true, - _chromeHidden: true, - _gridGap: 0, - _yMargin: 0, - _yPadding: 0, - _xMargin: 0, - _autoHeight: false, - _width: 60, - _columnWidth: 60, - _lockedPosition: true, - system: true, + const reqdStackOpts:DocumentOptions ={ + title: "menuItemPanel", childDropAction: "alias", backgroundColor: Colors.DARK_GRAY, boxShadow: "rgba(0,0,0,0)", dontRegisterView: true, ignoreClick: true, + _chromeHidden: true, _gridGap: 0, _yMargin: 0, _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, system: true }; - return this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.StackingDocument(items ?? [], opts), - reqdStackOpts, - menuBtns, - { dropConverter: 'convertToButtons(dragData)' } - ); + return this.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdStackOpts, menuBtns, { dropConverter: "convertToButtons(dragData)" }); } // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu - static setupActiveMobileMenu(doc: Doc, field = 'activeMobileMenu') { - const reqdOpts = { - _width: 980, - ignoreClick: true, - _lockedPosition: false, - title: 'home', - _yMargin: 100, - system: true, - _chromeHidden: true, - }; - this.AssignDocField( - doc, - field, - (opts, items) => - Docs.Create.StackingDocument(this.setupMobileButtons(), opts), - reqdOpts - ); + static setupActiveMobileMenu(doc: Doc, field="activeMobileMenu") { + const reqdOpts = { _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeHidden: true,}; + this.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(this.setupMobileButtons(), opts), reqdOpts); } // Sets up mobile buttons for inside mobile menu static setupMobileButtons(doc?: Doc, buttons?: string[]) { return []; - // prettier-ignore const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ { title: "DASHBOARDS", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Dashboards from your mobile, and navigate through all of your documents. " }, { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." }, @@ -853,97 +398,45 @@ export class CurrentUserUtils { { title: "SETTINGS", icon: "cog", click: 'openMobileSettings()', backgroundColor: "lightgrey", info: "Change your password, log out, or manage your account security." } ]; // returns a list of mobile buttons - return docProtoData - .filter((d) => !buttons || !buttons.includes(d.title)) - .map((data) => - this.mobileButton( - { - title: data.title, - _lockedPosition: true, - onClick: data.click - ? ScriptField.MakeScript(data.click) - : undefined, - backgroundColor: data.backgroundColor, - system: true, - }, - [ - this.createToolButton({ - ignoreClick: true, - icon: data.icon, - backgroundColor: 'rgba(0,0,0,0)', - system: true, - btnType: ButtonType.ClickButton, - }), - this.mobileTextContainer({}, [ - this.mobileButtonText({}, data.title), - this.mobileButtonInfo({}, data.info), - ]), - ] - ) - ); + return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => + this.mobileButton({ + title: data.title, + _lockedPosition: true, + onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, + backgroundColor: data.backgroundColor, system: true + }, + [this.createToolButton({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])]) + ); } // sets up the main document for the mobile button - static mobileButton = (opts: DocumentOptions, docs: Doc[]) => - Docs.Create.MulticolumnDocument(docs, { - ...opts, - _removeDropProperties: new List<string>(['dropAction']), - _nativeWidth: 900, - _nativeHeight: 250, - _width: 900, - _height: 250, - _yMargin: 15, - borderRounding: '5px', - boxShadow: '0 0', - system: true, - }) as any as Doc; + static mobileButton = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MulticolumnDocument(docs, { + ...opts, + _removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 900, _nativeHeight: 250, _width: 900, _height: 250, _yMargin: 15, + borderRounding: "5px", boxShadow: "0 0", system: true + }) as any as Doc // sets up the text container for the information contained within the mobile button - static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => - Docs.Create.MultirowDocument(docs, { - ...opts, - _removeDropProperties: new List<string>(['dropAction']), - _nativeWidth: 450, - _nativeHeight: 250, - _width: 450, - _height: 250, - _yMargin: 25, - backgroundColor: 'rgba(0,0,0,0)', - borderRounding: '0', - boxShadow: '0 0', - ignoreClick: true, - system: true, - }) as any as Doc; + static mobileTextContainer = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.MultirowDocument(docs, { + ...opts, + _removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 450, _nativeHeight: 250, _width: 450, _height: 250, _yMargin: 25, + backgroundColor: "rgba(0,0,0,0)", borderRounding: "0", boxShadow: "0 0", ignoreClick: true, system: true + }) as any as Doc // Sets up the title of the button - static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => - Docs.Create.TextDocument(buttonTitle, { - ...opts, - title: buttonTitle, - _fontSize: '37px', - _xMargin: 0, - _yMargin: 0, - ignoreClick: true, - backgroundColor: 'rgba(0,0,0,0)', - system: true, - }) as any as Doc; + static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, { + ...opts, + title: buttonTitle, _fontSize: "37px", _xMargin: 0, _yMargin: 0, ignoreClick: true, backgroundColor: "rgba(0,0,0,0)", system: true + }) as any as Doc // Sets up the description of the button - static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => - Docs.Create.TextDocument(buttonInfo, { - ...opts, - title: 'info', - _fontSize: '25px', - _xMargin: 0, - _yMargin: 0, - ignoreClick: true, - backgroundColor: 'rgba(0,0,0,0)', - _dimMagnitude: 2, - system: true, - }) as any as Doc; + static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, { + ...opts, + title: "info", _fontSize: "25px", _xMargin: 0, _yMargin: 0, ignoreClick: true, backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2, system: true + }) as any as Doc + static setupThumbButtons(doc: Doc) { - // prettier-ignore const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, clipboard?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [ { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue" }, { title: "use highlighter", icon: "highlighter", pointerUp: "resetPen()", pointerDown: 'setPen(20, this.backgroundColor)', backgroundColor: "yellow" }, @@ -951,58 +444,29 @@ export class CurrentUserUtils { { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", backgroundColor: "orange" }, { title: "ignore gestures", icon: "signature", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('ignoregesture')", backgroundColor: "green" }, ]; - return docProtoData.map((data) => - Docs.Create.FontIconDocument({ - _nativeWidth: 10, - _nativeHeight: 10, - _width: 10, - _height: 10, - title: data.title, - icon: data.icon, - _dropAction: data.pointerDown ? 'copy' : undefined, - ignoreClick: data.ignoreClick, - onDragStart: data.drag - ? ScriptField.MakeFunction(data.drag) - : undefined, - clipboard: data.clipboard, - onPointerUp: data.pointerUp - ? ScriptField.MakeScript(data.pointerUp) - : undefined, - onPointerDown: data.pointerDown - ? ScriptField.MakeScript(data.pointerDown) - : undefined, - backgroundColor: data.backgroundColor, - _removeDropProperties: new List<string>(['dropAction']), - dragFactory: data.dragFactory, - system: true, - }) - ); + return docProtoData.map(data => Docs.Create.FontIconDocument({ + _nativeWidth: 10, _nativeHeight: 10, _width: 10, _height: 10, title: data.title, icon: data.icon, + _dropAction: data.pointerDown ? "copy" : undefined, + ignoreClick: data.ignoreClick, + onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, + clipboard: data.clipboard, + onPointerUp: data.pointerUp ? ScriptField.MakeScript(data.pointerUp) : undefined, + onPointerDown: data.pointerDown ? ScriptField.MakeScript(data.pointerDown) : undefined, + backgroundColor: data.backgroundColor, + _removeDropProperties: new List<string>(["dropAction"]), + dragFactory: data.dragFactory, + system: true + })); } static setupThumbDoc(userDoc: Doc) { if (!userDoc.thumbDoc) { - const thumbDoc = Docs.Create.LinearDocument( - CurrentUserUtils.setupThumbButtons(userDoc), - { - _width: 100, - _height: 50, - ignoreClick: true, - _lockedPosition: true, - title: 'buttons', - _autoHeight: true, - _yMargin: 5, - linearViewIsExpanded: true, - backgroundColor: 'white', - system: true, - } - ); + const thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), { + _width: 100, _height: 50, ignoreClick: true, _lockedPosition: true, title: "buttons", + _autoHeight: true, _yMargin: 5, linearViewIsExpanded: true, backgroundColor: "white", system: true + }); thumbDoc.inkToTextDoc = Docs.Create.LinearDocument([], { - _width: 300, - _height: 25, - _autoHeight: true, - linearViewIsExpanded: true, - flexDirection: 'column', - system: true, + _width: 300, _height: 25, _autoHeight: true, linearViewIsExpanded: true, flexDirection: "column", system: true }); userDoc.thumbDoc = thumbDoc; } @@ -1010,451 +474,154 @@ export class CurrentUserUtils { } static setupMobileInkingDoc(userDoc: Doc) { - return Docs.Create.FreeformDocument([], { - title: 'Mobile Inking', - backgroundColor: 'white', - system: true, - }); + return Docs.Create.FreeformDocument([], { title: "Mobile Inking", backgroundColor: "white", system: true }); } static setupMobileUploadDoc(userDoc: Doc) { // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" }) - const webDoc = Docs.Create.WebDocument( - 'https://www.britannica.com/biography/Miles-Davis', - { - title: 'Upload Images From the Web', - _lockedPosition: true, - system: true, - } - ); + const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", { + title: "Upload Images From the Web", _lockedPosition: true, system: true + }); const uploadDoc = Docs.Create.StackingDocument([], { - title: 'Mobile Upload Collection', - backgroundColor: 'white', - _lockedPosition: true, - system: true, - _chromeHidden: true, + title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true, _chromeHidden: true, }); return Docs.Create.StackingDocument([webDoc, uploadDoc], { - _width: screen.width, - _lockedPosition: true, - title: 'Upload', - _autoHeight: true, - _yMargin: 80, - backgroundColor: 'lightgray', - system: true, - _chromeHidden: true, + _width: screen.width, _lockedPosition: true, title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true, _chromeHidden: true, }); } /// Search option on the left side button panel - static setupSearcher(doc: Doc, field: string) { - return this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.SearchDocument(opts), - { - dontRegisterView: true, - backgroundColor: 'dimgray', - ignoreClick: true, - title: 'Search Panel', - system: true, - childDropAction: 'alias', - _lockedPosition: true, - _viewType: CollectionViewType.Schema, - _searchDoc: true, - } - ); + static setupSearcher(doc: Doc, field:string) { + return this.AssignDocField(doc, field, (opts, items) => Docs.Create.SearchDocument(opts), { + dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Search Panel", system: true, childDropAction: "alias", + _lockedPosition: true, _viewType: CollectionViewType.Schema, _searchDoc: true, }); } /// Initializes the panel of draggable tools that is opened from the left sidebar. - static setupToolsBtnPanel(doc: Doc, field: string) { + static setupToolsBtnPanel(doc: Doc, field:string) { const myTools = DocCast(doc[field]); - const creatorBtns = CurrentUserUtils.setupCreatorButtons( - doc, - DocListCast(myTools?.data)?.length - ? DocListCast(myTools.data)[0] - : undefined - ); - const templateBtns = CurrentUserUtils.setupExperimentalTemplateButtons( - doc, - DocListCast(myTools?.data)?.length > 1 - ? DocListCast(myTools.data)[1] - : undefined - ); - const reqdToolOps: DocumentOptions = { - title: 'My Tools', - system: true, - ignoreClick: true, - boxShadow: '0 0', - _showTitle: 'title', - _width: 500, - _yMargin: 20, - _lockedPosition: true, - _forceActive: true, - _stayInCollection: true, - _hideContextMenu: true, - _chromeHidden: true, + const creatorBtns = CurrentUserUtils.setupCreatorButtons(doc, DocListCast(myTools?.data)?.length ? DocListCast(myTools.data)[0]:undefined); + const templateBtns = CurrentUserUtils.setupExperimentalTemplateButtons(doc,DocListCast(myTools?.data)?.length > 1 ? DocListCast(myTools.data)[1]:undefined); + const reqdToolOps:DocumentOptions = { + title: "My Tools", system: true, ignoreClick: true, boxShadow: "0 0", + _showTitle: "title", _width: 500, _yMargin: 20, _lockedPosition: true, _forceActive: true, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, }; - return this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.StackingDocument(items ?? [], opts), - reqdToolOps, - [creatorBtns, templateBtns] - ); + return this.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdToolOps, [creatorBtns, templateBtns]); } /// initializes the left sidebar dashboard pane - static setupDashboards(doc: Doc, field: string) { + static setupDashboards(doc: Doc, field:string) { var myDashboards = DocCast(doc[field]); const newDashboard = `createNewDashboard()`; - const reqdBtnOpts: DocumentOptions = { - _forceActive: true, - _width: 30, - _height: 30, - _stayInCollection: true, - _hideContextMenu: true, - title: 'new dashboard', - btnType: ButtonType.ClickButton, - toolTip: 'Create new dashboard', - buttonText: 'New trail', - icon: 'plus', - system: true, - }; - const reqdBtnScript = { onClick: newDashboard }; - const newDashboardButton = this.AssignScripts( - this.AssignOpts( - DocCast(myDashboards?.buttonMenuDoc), - reqdBtnOpts - ) ?? Docs.Create.FontIconDocument(reqdBtnOpts), - reqdBtnScript - ); - - const reqdOpts: DocumentOptions = { - title: 'My Dashboards', - childHideLinkButton: true, - freezeChildren: 'remove|add', - treeViewHideTitle: true, - boxShadow: '0 0', - childDontRegisterViews: true, - targetDropAction: 'same', - treeViewType: TreeViewType.fileSystem, - isFolder: true, - system: true, - treeViewTruncateTitleWidth: 150, - ignoreClick: true, - buttonMenu: true, - buttonMenuDoc: newDashboardButton, - childDropAction: 'alias', - _showTitle: 'title', - _height: 400, - _gridGap: 5, - _forceActive: true, - _lockedPosition: true, - contextMenuLabels: new List<string>(['Create New Dashboard']), - contextMenuIcons: new List<string>(['plus']), - childContextMenuLabels: new List<string>([ - 'Toggle Dark Theme', - 'Toggle Comic Mode', - 'Snapshot Dashboard', - 'Share Dashboard', - 'Remove Dashboard', - ]), // entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters - childContextMenuIcons: new List<string>([ - 'chalkboard', - 'tv', - 'camera', - 'users', - 'times', - ]), // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters - explainer: - 'This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files.', + const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, + title: "new dashboard", btnType: ButtonType.ClickButton, toolTip: "Create new dashboard", buttonText: "New trail", icon: "plus", system: true }; + const reqdBtnScript = {onClick: newDashboard,} + const newDashboardButton = this.AssignScripts(this.AssignOpts(DocCast(myDashboards?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript); + + const reqdOpts:DocumentOptions = { + title: "My Dashboards", childHideLinkButton: true, freezeChildren: "remove|add", treeViewHideTitle: true, boxShadow: "0 0", childDontRegisterViews: true, + targetDropAction: "same", treeViewType: TreeViewType.fileSystem, isFolder: true, system: true, treeViewTruncateTitleWidth: 150, ignoreClick: true, + buttonMenu: true, buttonMenuDoc: newDashboardButton, childDropAction: "alias", + _showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true, + contextMenuLabels: new List<string>(["Create New Dashboard"]), + contextMenuIcons: new List<string>(["plus"]), + childContextMenuLabels: new List<string>(["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]),// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters + childContextMenuIcons: new List<string>(["chalkboard", "tv", "camera", "users", "times"]), // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters + explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files." }; - myDashboards = this.AssignDocField( - doc, - field, - (opts) => Docs.Create.TreeDocument([], opts), - reqdOpts - ); + myDashboards = this.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), reqdOpts); const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`; const contextMenuScripts = [newDashboard]; - const childContextMenuScripts = [ - toggleDarkTheme, - `toggleComicMode()`, - `snapshotDashboard()`, - `shareDashboard(self)`, - 'removeDashboard(self)', - ]; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters - const childContextMenuFilters = [ - '!IsNoviceMode()', - '!IsNoviceMode()', - '!IsNoviceMode()', - undefined as any, - undefined as any, - ]; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts - if ( - Cast(myDashboards.contextMenuScripts, listSpec(ScriptField), null) - ?.length !== contextMenuScripts.length - ) { - myDashboards.contextMenuScripts = new List<ScriptField>( - contextMenuScripts.map( - (script) => ScriptField.MakeFunction(script)! - ) - ); - } - if ( - Cast( - myDashboards.childContextMenuScripts, - listSpec(ScriptField), - null - )?.length !== childContextMenuScripts.length - ) { - myDashboards.childContextMenuScripts = new List<ScriptField>( - childContextMenuScripts.map( - (script) => ScriptField.MakeFunction(script)! - ) - ); - } - if ( - Cast( - myDashboards.childContextMenuFilters, - listSpec(ScriptField), - null - )?.length !== childContextMenuFilters.length - ) { - myDashboards.childContextMenuFilters = new List<ScriptField>( - childContextMenuFilters.map((script) => - !script ? script : ScriptField.MakeFunction(script)! - ) - ); + const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + if (Cast(myDashboards.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { + myDashboards.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); + } + if (Cast(myDashboards.childContextMenuScripts, listSpec(ScriptField), null)?.length !== childContextMenuScripts.length) { + myDashboards.childContextMenuScripts = new List<ScriptField>(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); + } + if (Cast(myDashboards.childContextMenuFilters, listSpec(ScriptField), null)?.length !== childContextMenuFilters.length) { + myDashboards.childContextMenuFilters = new List<ScriptField>(childContextMenuFilters.map(script => !script ? script: ScriptField.MakeFunction(script)!)); } return myDashboards; } /// initializes the left sidebar Trails pane - static setupTrails(doc: Doc, field: string) { + 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 = this.AssignScripts( - this.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.', + 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 = this.AssignScripts(this.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 = this.AssignDocField( - doc, - field, - (opts) => Docs.Create.TreeDocument([], opts), - reqdOpts - ); + myTrails = this.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)! - ) - ); + 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) { + static setupFilesystem(doc: Doc, field:string) { var myFilesystem = DocCast(doc[field]); - const myFileOrphans = this.AssignDocField( - doc, - 'myFileOrphans', - (opts) => Docs.Create.TreeDocument([], opts), - { - title: 'Unfiled', - _stayInCollection: true, - system: true, - isFolder: true, - } - ); - + const myFileOrphans = this.AssignDocField(doc, "myFileOrphans", (opts) => Docs.Create.TreeDocument([], opts), { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true }); + const newFolder = `makeTopLevelFolder()`; const newFolderOpts: DocumentOptions = { - _forceActive: true, - _stayInCollection: true, - _hideContextMenu: true, - _width: 30, - _height: 30, - title: 'New folder', - btnType: ButtonType.ClickButton, - toolTip: 'Create new folder', - buttonText: 'New folder', - icon: 'folder-plus', - system: true, + _forceActive: true, _stayInCollection: true, _hideContextMenu: true, _width: 30, _height: 30, + title: "New folder", btnType: ButtonType.ClickButton, toolTip: "Create new folder", buttonText: "New folder", icon: "folder-plus", system: true }; - const newFolderScript = { onClick: newFolder }; - const newFolderButton = this.AssignScripts( - this.AssignOpts( - DocCast(myFilesystem?.buttonMenuDoc), - newFolderOpts - ) ?? Docs.Create.FontIconDocument(newFolderOpts), - newFolderScript - ); - - const reqdOpts: DocumentOptions = { - _showTitle: 'title', - _height: 100, - _gridGap: 5, - _forceActive: true, - _lockedPosition: true, - title: 'My Documents', - buttonMenu: true, - buttonMenuDoc: newFolderButton, - treeViewHideTitle: true, - targetDropAction: 'proto', - system: true, - isFolder: true, - treeViewType: TreeViewType.fileSystem, - childHideLinkButton: true, - boxShadow: '0 0', - childDontRegisterViews: true, - treeViewTruncateTitleWidth: 150, - ignoreClick: true, - childDropAction: 'alias', - childContextMenuLabels: new List<string>(['Create new folder']), - childContextMenuIcons: new List<string>(['plus']), - explainer: - 'This is your file manager where you can create folders to keep track of documents independently of your dashboard.', + const newFolderScript = { onClick: newFolder}; + const newFolderButton = this.AssignScripts(this.AssignOpts(DocCast(myFilesystem?.buttonMenuDoc), newFolderOpts) ?? Docs.Create.FontIconDocument(newFolderOpts), newFolderScript); + + const reqdOpts:DocumentOptions = { _showTitle: "title", _height: 100, _gridGap: 5, _forceActive: true, _lockedPosition: true, + title: "My Documents", buttonMenu: true, buttonMenuDoc: newFolderButton, treeViewHideTitle: true, targetDropAction: "proto", system: true, + isFolder: true, treeViewType: TreeViewType.fileSystem, childHideLinkButton: true, boxShadow: "0 0", childDontRegisterViews: true, + treeViewTruncateTitleWidth: 150, ignoreClick: true, childDropAction: "alias", + childContextMenuLabels: new List<string>(["Create new folder"]), + childContextMenuIcons: new List<string>(["plus"]), + explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard." }; - myFilesystem = this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.TreeDocument(items ?? [], opts), - reqdOpts, - [myFileOrphans] - ); + myFilesystem = this.AssignDocField(doc, field, (opts, items) => Docs.Create.TreeDocument(items??[], opts), reqdOpts, [myFileOrphans]); const childContextMenuScripts = [newFolder]; - if ( - Cast( - myFilesystem.childContextMenuScripts, - listSpec(ScriptField), - null - )?.length !== childContextMenuScripts.length - ) { - myFilesystem.childContextMenuScripts = new List<ScriptField>( - childContextMenuScripts.map( - (script) => ScriptField.MakeFunction(script)! - ) - ); + if (Cast(myFilesystem.childContextMenuScripts, listSpec(ScriptField), null)?.length !== childContextMenuScripts.length) { + myFilesystem.childContextMenuScripts = new List<ScriptField>(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); } return myFilesystem; } /// initializes the panel displaying docs that have been recently closed - static setupRecentlyClosed(doc: Doc, field: string) { - const reqdOpts: DocumentOptions = { - _showTitle: 'title', - _lockedPosition: true, - _gridGap: 5, - _forceActive: true, - title: 'My Recently Closed', - buttonMenu: true, - childHideLinkButton: true, - treeViewHideTitle: true, - childDropAction: 'alias', - system: true, - treeViewTruncateTitleWidth: 150, - ignoreClick: true, - boxShadow: '0 0', - childDontRegisterViews: true, - targetDropAction: 'same', - contextMenuLabels: new List<string>(['Empty recently closed']), - contextMenuIcons: new List<string>(['trash']), - explainer: - 'Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list.', + static setupRecentlyClosed(doc: Doc, field:string) { + const reqdOpts:DocumentOptions = { _showTitle: "title", _lockedPosition: true, _gridGap: 5, _forceActive: true, + title: "My Recently Closed", buttonMenu: true, childHideLinkButton: true, treeViewHideTitle: true, childDropAction: "alias", system: true, + treeViewTruncateTitleWidth: 150, ignoreClick: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", + contextMenuLabels: new List<string>(["Empty recently closed"]), + contextMenuIcons:new List<string>(["trash"]), + explainer: "Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list." }; - const recentlyClosed = this.AssignDocField( - doc, - field, - (opts) => Docs.Create.TreeDocument([], opts), - reqdOpts - ); - - const clearAll = (target: string) => - `getProto(${target}).data = new List([])`; - const clearBtnsOpts: DocumentOptions = { - _width: 30, - _height: 30, - _forceActive: true, - _stayInCollection: true, - _hideContextMenu: true, - title: 'Empty', - target: recentlyClosed, - btnType: ButtonType.ClickButton, - buttonText: 'Empty', - icon: 'trash', - system: true, - toolTip: 'Empty recently closed', - }; - const clearDocsButton = this.AssignDocField( - recentlyClosed, - 'clearDocsBtn', - (opts) => Docs.Create.FontIconDocument(opts), - clearBtnsOpts, - undefined, - { onClick: clearAll('self.target') } - ); - - if (recentlyClosed.buttonMenuDoc !== clearDocsButton) - Doc.GetProto(recentlyClosed).buttonMenuDoc = clearDocsButton; - - if ( - !Cast( - recentlyClosed.contextMenuScripts, - listSpec(ScriptField), - null - )?.find( - (script) => script.script.originalScript === clearAll('self') - ) - ) { - recentlyClosed.contextMenuScripts = new List<ScriptField>([ - ScriptField.MakeScript(clearAll('self'))!, - ]); + const recentlyClosed = this.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), reqdOpts); + + const clearAll = (target:string) => `getProto(${target}).data = new List([])`; + const clearBtnsOpts:DocumentOptions = { _width: 30, _height: 30, _forceActive: true, _stayInCollection: true, _hideContextMenu: true, + title: "Empty", target: recentlyClosed, btnType: ButtonType.ClickButton, buttonText: "Empty", icon: "trash", system: true, + toolTip: "Empty recently closed",}; + const clearDocsButton = this.AssignDocField(recentlyClosed, "clearDocsBtn", (opts) => Docs.Create.FontIconDocument(opts), clearBtnsOpts, undefined, {onClick: clearAll("self.target")}); + + if (recentlyClosed.buttonMenuDoc !== clearDocsButton) Doc.GetProto(recentlyClosed).buttonMenuDoc = clearDocsButton; + + if (!Cast(recentlyClosed.contextMenuScripts, listSpec(ScriptField),null)?.find((script) => script.script.originalScript === clearAll("self"))) { + recentlyClosed.contextMenuScripts = new List<ScriptField>([ScriptField.MakeScript(clearAll("self"))!]) } return recentlyClosed; } @@ -1462,184 +629,60 @@ export class CurrentUserUtils { /// creates a new, empty filter doc static createFilterDoc() { const clearAll = `getProto(self).data = new List([])`; - const reqdOpts: DocumentOptions = { - _lockedPosition: true, - _autoHeight: true, - _fitWidth: true, - _height: 150, - _xPadding: 5, - _yPadding: 5, - _gridGap: 5, - _forceActive: true, - title: 'Unnamed Filter', - filterBoolean: 'AND', - boxShadow: '0 0', - childDontRegisterViews: true, - targetDropAction: 'same', - ignoreClick: true, - system: true, - childDropAction: 'none', - treeViewHideTitle: true, - treeViewTruncateTitleWidth: 150, - childContextMenuLabels: new List<string>(['Clear All']), - childContextMenuScripts: new List<ScriptField>([ - ScriptField.MakeFunction(clearAll)!, - ]), + const reqdOpts:DocumentOptions = { + _lockedPosition: true, _autoHeight: true, _fitWidth: true, _height: 150, _xPadding: 5, _yPadding: 5, _gridGap: 5, _forceActive: true, + title: "Unnamed Filter", filterBoolean: "AND", boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", ignoreClick: true, system: true, + childDropAction: "none", treeViewHideTitle: true, treeViewTruncateTitleWidth: 150, + childContextMenuLabels: new List<string>(["Clear All"]), + childContextMenuScripts: new List<ScriptField>([ScriptField.MakeFunction(clearAll)!]), }; return Docs.Create.FilterDocument(reqdOpts); } /// initializes the left sidebar panel view of the UserDoc - static setupUserDocView(doc: Doc, field: string) { - const reqdOpts: DocumentOptions = { - _lockedPosition: true, - _gridGap: 5, - _forceActive: true, - title: Doc.CurrentUserEmail + '-view', - boxShadow: '0 0', - childDontRegisterViews: true, - targetDropAction: 'same', - ignoreClick: true, - system: true, - treeViewHideTitle: true, - treeViewTruncateTitleWidth: 150, + static setupUserDocView(doc: Doc, field:string) { + const reqdOpts:DocumentOptions = { + _lockedPosition: true, _gridGap: 5, _forceActive: true, title: Doc.CurrentUserEmail +"-view", + boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", ignoreClick: true, system: true, + treeViewHideTitle: true, treeViewTruncateTitleWidth: 150 }; - if (!doc[field]) - this.AssignOpts(doc, { - treeViewOpen: true, - treeViewExpandedView: 'fields', - }); - return this.AssignDocField( - doc, - field, - (opts, items) => Docs.Create.TreeDocument(items ?? [], opts), - reqdOpts, - [doc] - ); + if (!doc[field]) this.AssignOpts(doc, {treeViewOpen: true, treeViewExpandedView: "fields" }); + return this.AssignDocField(doc, field, (opts, items) => Docs.Create.TreeDocument(items??[], opts), reqdOpts, [doc]); } - static linearButtonList = (opts: DocumentOptions, docs: Doc[]) => - Docs.Create.LinearDocument(docs, { - ...opts, - _gridGap: 0, - _xMargin: 5, - _yMargin: 5, - boxShadow: '0 0', - _forceActive: true, - dropConverter: ScriptField.MakeScript( - 'convertToButtons(dragData)', - { - dragData: DragManager.DocumentDragData.name, - } - ), - _lockedPosition: true, - system: true, - flexDirection: 'row', - }); + static linearButtonList = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.LinearDocument(docs, { + ...opts, _gridGap: 0, _xMargin: 5, _yMargin: 5, boxShadow: "0 0", _forceActive: true, + dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), + _lockedPosition: true, system: true, flexDirection: "row" + }) - static createToolButton = (opts: DocumentOptions) => - Docs.Create.FontIconDocument({ - btnType: ButtonType.ToolButton, - _forceActive: true, - _dropAction: 'alias', - _hideContextMenu: true, - _removeDropProperties: new List<string>([ - '_dropAction', - '_hideContextMenu', - 'stayInCollection', - ]), - _nativeWidth: 40, - _nativeHeight: 40, - _width: 40, - _height: 40, - system: true, - ...opts, - }); + static createToolButton = (opts: DocumentOptions) => Docs.Create.FontIconDocument({ + btnType: ButtonType.ToolButton, _forceActive: true, _dropAction: "alias", _hideContextMenu: true, + _removeDropProperties: new List<string>(["_dropAction", "_hideContextMenu", "stayInCollection"]), + _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true, ...opts, + }) /// initializes the required buttons in the expanding button menu at the bottom of the Dash window - static setupDockedButtons(doc: Doc, field = 'myDockedBtns') { + static setupDockedButtons(doc: Doc, field="myDockedBtns") { const dockedBtns = DocCast(doc[field]); - const dockBtn = ( - opts: DocumentOptions, - scripts: { [key: string]: string } - ) => - this.AssignScripts( - this.AssignOpts( - DocListCast(dockedBtns?.data)?.find( - (doc) => doc.title === opts.title - ), - opts - ) ?? CurrentUserUtils.createToolButton(opts), - scripts - ); - - 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 - { - scripts: { onClick: 'undo()' }, - opts: { - title: 'undo', - icon: 'undo-alt', - toolTip: 'Click to undo', - }, - }, - { - scripts: { onClick: 'redo()' }, - opts: { - title: 'redo', - icon: 'redo-alt', - toolTip: 'Click to redo', - }, - }, + const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string}) => + this.AssignScripts(this.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? + CurrentUserUtils.createToolButton(opts), scripts); + + 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 + { scripts: { onClick: "undo()"}, opts: { title: "undo", icon: "undo-alt", toolTip: "Click to undo" }}, + { scripts: { onClick: "redo()"}, opts: { title: "redo", icon: "redo-alt", toolTip: "Click to redo" }} ]; - const btns = btnDescs.map((desc) => - dockBtn( - { - _width: 30, - _height: 30, - dontUndo: true, - _stayInCollection: true, - ...desc.opts, - }, - desc.scripts - ) - ); + const btns = btnDescs.map(desc => dockBtn({_width: 30, _height: 30, dontUndo: true, _stayInCollection: true, ...desc.opts}, desc.scripts)); const dockBtnsReqdOpts = { - title: 'docked buttons', - _height: 40, - flexGap: 0, - linearViewFloating: true, - childDontRegisterViews: true, - linearViewIsExpanded: true, - linearViewExpandable: true, - ignoreClick: true, + title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true, + childDontRegisterViews: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true }; - reaction( - () => UndoManager.redoStack.slice(), - () => - (Doc.GetProto( - btns.find((btn) => btn.title === 'redo')! - ).opacity = UndoManager.CanRedo() ? 1 : 0.4), - { fireImmediately: true } - ); - reaction( - () => UndoManager.undoStack.slice(), - () => - (Doc.GetProto( - btns.find((btn) => btn.title === 'undo')! - ).opacity = UndoManager.CanUndo() ? 1 : 0.4), - { fireImmediately: true } - ); - return this.AssignDocField( - doc, - field, - (opts, items) => this.linearButtonList(opts, items ?? []), - dockBtnsReqdOpts, - btns - ); + reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true }); + reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true }); + return this.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), dockBtnsReqdOpts, btns); } - // prettier-ignore static textTools():Button[] { return [ { title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true, scripts: {script: 'setFont(value, _readOnly_)'}, @@ -1648,7 +691,7 @@ export class CurrentUserUtils { { title: "Color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, scripts: {script: '{ return setFontColor(value, _readOnly_); }'}}, { title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", scripts: {onClick: '{ return toggleBold(_readOnly_); }'} }, { title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", scripts: {onClick: '{ return toggleItalic(_readOnly_);}'} }, - { title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", scripts: {onClick:'{ return toggleUnderline(_readOnly_);}'} }, + { title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", scripts: {onClick: '{ return toggleUnderline(_readOnly_);}'} }, { title: "Bullets", toolTip: "Bullet List", btnType: ButtonType.ToggleButton, icon: "list", scripts: {onClick: '{ return setBulletList("bullet", _readOnly_);}'} }, { title: "#", toolTip: "Number List", btnType: ButtonType.ToggleButton, icon: "list-ol", scripts: {onClick: '{ return setBulletList("decimal", _readOnly_);}'} }, @@ -1662,7 +705,6 @@ export class CurrentUserUtils { ]; } - // prettier-ignore static inkTools():Button[] { return [ { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen-nib", scripts: {onClick:'{ return setActiveTool("pen", _readOnly_);}' }}, @@ -1678,22 +720,10 @@ export class CurrentUserUtils { ]; } - static schemaTools(): Button[] { - return [ - { - title: 'Show preview', - toolTip: 'Show preview of selected document', - btnType: ButtonType.ToggleButton, - buttonText: 'Show Preview', - icon: 'eye', - scripts: { - onClick: '{return toggleSchemaPreview(_readOnly_);}', - }, - }, - ]; + static schemaTools():Button[] { + return [{ title: "Show preview", toolTip: "Show preview of selected document", btnType: ButtonType.ToggleButton, buttonText: "Show Preview", icon: "eye", scripts:{ onClick: '{return toggleSchemaPreview(_readOnly_);}'}, }]; } - // prettier-ignore static webTools() { return [ { title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", scripts: { onClick: '{ return webBack(_readOnly_); }' }}, @@ -1703,7 +733,6 @@ export class CurrentUserUtils { ]; } - // prettier-ignore static contextMenuTools():Button[] { return [ { btnList: new List<string>([CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree, @@ -1725,570 +754,261 @@ export class CurrentUserUtils { } /// initializes a context menu button for the top bar context menu - static setupContextMenuButton(params: Button, btnDoc?: Doc) { - const reqdOpts: DocumentOptions = { - ...OmitKeys(params, ['scripts', 'funcs', 'subMenu']).omit, - backgroundColor: params.scripts?.onClick - ? undefined - : 'transparent', /// a bit hacky. if an onClick is specified, then assume a toggle uses onClick to get the backgroundColor (see below). Otherwise, assume a transparent background - color: Colors.WHITE, - system: true, - dontUndo: true, - _nativeWidth: params.width ?? 30, - _width: params.width ?? 30, - _height: 30, - _nativeHeight: 30, - _stayInCollection: true, - _hideContextMenu: true, - _lockedPosition: true, - _dropAction: 'alias', - _removeDropProperties: new List<string>([ - 'dropAction', - '_stayInCollection', - ]), + static setupContextMenuButton(params:Button, btnDoc?:Doc) { + const reqdOpts:DocumentOptions = { + ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, + backgroundColor: params.scripts?.onClick ? undefined: "transparent", /// a bit hacky. if an onClick is specified, then assume a toggle uses onClick to get the backgroundColor (see below). Otherwise, assume a transparent background + color: Colors.WHITE, system: true, dontUndo: true, + _nativeWidth: params.width ?? 30, _width: params.width ?? 30, + _height: 30, _nativeHeight: 30, + _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, + _dropAction: "alias", _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]), }; - const reqdFuncs: { [key: string]: any } = { + const reqdFuncs:{[key:string]:any} = { ...params.funcs, - backgroundColor: params.scripts?.onClick, /// a bit hacky. if onClick is set, then we assume it returns a color value when queried with '_readOnly_'. This will be true for toggle buttons, but not generally - }; - return this.AssignScripts( - this.AssignOpts(btnDoc, reqdOpts) ?? - Docs.Create.FontIconDocument(reqdOpts), - params.scripts, - reqdFuncs - ); + backgroundColor: params.scripts?.onClick /// a bit hacky. if onClick is set, then we assume it returns a color value when queried with '_readOnly_'. This will be true for toggle buttons, but not generally + } + return this.AssignScripts(this.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs); } /// Initializes all the default buttons for the top bar context menu - static setupContextMenuButtons(doc: Doc, field = 'myContextMenuBtns') { - const reqdCtxtOpts = { - title: 'context menu buttons', - flexGap: 0, - childDontRegisterViews: true, - linearViewIsExpanded: true, - ignoreClick: true, - linearViewExpandable: false, - _height: 35, - }; - const ctxtMenuBtnsDoc = this.AssignDocField( - doc, - field, - (opts, items) => this.linearButtonList(opts, items ?? []), - reqdCtxtOpts, - undefined - ); - const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map( - (params) => { - const menuBtnDoc = DocListCast(ctxtMenuBtnsDoc?.data).find( - (doc) => doc.title === params.title + static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") { + const reqdCtxtOpts = { title: "context menu buttons", flexGap: 0, childDontRegisterViews: true, linearViewIsExpanded: true, ignoreClick: true, linearViewExpandable: false, _height: 35 }; + const ctxtMenuBtnsDoc = this.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined); + const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => { + const menuBtnDoc = DocListCast(ctxtMenuBtnsDoc?.data).find(doc => doc.title === params.title); + if (!params.subMenu) { + return this.setupContextMenuButton(params, menuBtnDoc); + } else { + const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, + childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: true, + linearViewSubMenu: true, linearViewExpandable: true, }; + const items = params.subMenu?.map(sub => + this.setupContextMenuButton(sub, DocListCast(menuBtnDoc?.data).find(doc => doc.title === sub.title)) ); - if (!params.subMenu) { - return this.setupContextMenuButton(params, menuBtnDoc); - } else { - const reqdSubMenuOpts = { - ...OmitKeys(params, ['scripts', 'funcs', 'subMenu']) - .omit, - childDontRegisterViews: true, - flexGap: 0, - _height: 30, - ignoreClick: true, - linearViewSubMenu: true, - linearViewExpandable: true, - }; - return this.AssignScripts( - this.AssignOpts(menuBtnDoc, reqdSubMenuOpts) ?? - (ctxtMenuBtnsDoc[StrCast(params.title)] = - this.linearButtonList( - reqdSubMenuOpts, - params.subMenu.map((sub) => - this.setupContextMenuButton( - sub, - DocListCast(menuBtnDoc?.data).find( - (doc) => doc.title === sub.title - ) - ) - ) - )), - undefined, - params.funcs - ); - } + return this.AssignScripts( + this.AssignDocField(ctxtMenuBtnsDoc, StrCast(params.title), (opts) => this.linearButtonList(opts, items??[]), reqdSubMenuOpts, items), undefined, params.funcs); } - ); + }); return this.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts, ctxtMenuBtns); } /// collection of documents rendered in the overlay layer above all tabs and other UI - static setupOverlays(doc: Doc, field = 'myOverlayDocs') { - return this.AssignDocField( - doc, - field, - (opts) => Docs.Create.FreeformDocument([], opts), - { - title: 'overlay documents', - backgroundColor: '#aca3a6', - system: true, - } - ); + static setupOverlays(doc: Doc, field = "myOverlayDocs") { + return this.AssignDocField(doc, field, (opts) => Docs.Create.FreeformDocument([], opts), { title: "overlay documents", backgroundColor: "#aca3a6", system: true }); } - static setupPublished(doc: Doc, field = 'myPublishedDocs') { - return this.AssignDocField( - doc, - field, - (opts) => Docs.Create.TreeDocument([], opts), - { - title: 'published docs', - backgroundColor: '#aca3a6', - system: true, - } - ); + static setupPublished(doc:Doc, field = "myPublishedDocs") { + return this.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), { title: "published docs", backgroundColor: "#aca3a6", system: true }); } - + /// The database of all links on all documents static setupLinkDocs(doc: Doc, linkDatabaseId: string) { if (!(Docs.newAccount ? undefined : DocCast(doc.myLinkDatabase))) { const linkDocs = new Doc(linkDatabaseId, true); - linkDocs.title = 'LINK DATABASE: ' + Doc.CurrentUserEmail; + linkDocs.title = "LINK DATABASE: " + Doc.CurrentUserEmail; linkDocs.author = Doc.CurrentUserEmail; linkDocs.data = new List<Doc>([]); - linkDocs['acl-Public'] = SharingPermissions.Augment; + linkDocs["acl-Public"] = SharingPermissions.Augment; doc.myLinkDatabase = new PrefetchProxy(linkDocs); } } /// Shared documents option on the left side button panel - // A user's sharing document is where all documents that are shared to that user are placed. + // A user's sharing document is where all documents that are shared to that user are placed. // When the user views one of these documents, it will be added to the sharing documents 'viewed' list field // The sharing document also stores the user's color value which helps distinguish shared documents from personal documents static setupSharedDocs(doc: Doc, sharingDocumentId: string) { const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`); - const dashboardFilter = ScriptField.MakeFunction( - `doc._viewType === '${CollectionViewType.Docking}'`, - { doc: Doc.name } - ); - const dblClkScript = - "{scriptContext.openLevel(documentView); addDocToList(scriptContext.props.treeView.props.Document, 'viewed', documentView.rootDoc);}"; - - const sharedScripts = { treeViewChildDoubleClick: dblClkScript }; - const sharedDocOpts: DocumentOptions = { - title: 'My Shared Docs', - userColor: 'rgb(202, 202, 202)', - childContextMenuFilters: new List<ScriptField>([dashboardFilter!]), - childContextMenuScripts: new List<ScriptField>([addToDashboards!]), - childContextMenuLabels: new List<string>(['Add to Dashboards']), - childContextMenuIcons: new List<string>(['user-plus']), - 'acl-Public': SharingPermissions.Augment, - '_acl-Public': SharingPermissions.Augment, - childDropAction: 'alias', - system: true, - contentPointerEvents: 'all', - childLimitHeight: 0, - _yMargin: 50, - _gridGap: 15, + const dashboardFilter = ScriptField.MakeFunction(`doc._viewType === '${CollectionViewType.Docking}'`, { doc: Doc.name }); + const dblClkScript = "{scriptContext.openLevel(documentView); addDocToList(scriptContext.props.treeView.props.Document, 'viewed', documentView.rootDoc);}"; + + const sharedScripts = { treeViewChildDoubleClick: dblClkScript, } + const sharedDocOpts:DocumentOptions = { + title: "My Shared Docs", + userColor: "rgb(202, 202, 202)", + childContextMenuFilters: new List<ScriptField>([dashboardFilter!,]), + childContextMenuScripts: new List<ScriptField>([addToDashboards!,]), + childContextMenuLabels: new List<string>(["Add to Dashboards",]), + childContextMenuIcons: new List<string>(["user-plus",]), + "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment, + childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, // NOTE: treeViewHideTitle & _showTitle is for a TreeView's editable title, _showTitle is for DocumentViews title bar - _showTitle: 'title', - treeViewHideTitle: true, - ignoreClick: true, - _lockedPosition: true, - boxShadow: '0 0', - _chromeHidden: true, - dontRegisterView: true, - explainer: - "This is where documents or dashboards that other users have shared with you will appear. To share a document or dashboard right click and select 'Share'", + _showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", _chromeHidden: true, dontRegisterView: true, + explainer: "This is where documents or dashboards that other users have shared with you will appear. To share a document or dashboard right click and select 'Share'" }; - - this.AssignDocField( - doc, - 'mySharedDocs', - (opts) => - Docs.Create.TreeDocument( - [], - opts, - sharingDocumentId + 'layout', - sharingDocumentId - ), - sharedDocOpts, - undefined, - sharedScripts - ); + + this.AssignDocField(doc, "mySharedDocs", opts => Docs.Create.TreeDocument([], opts, sharingDocumentId + "layout", sharingDocumentId), sharedDocOpts, undefined, sharedScripts); } - /// Import option on the left side button panel - static setupImportSidebar(doc: Doc, field: string) { - const reqdOpts: DocumentOptions = { - title: 'My Imports', - _forceActive: true, - buttonMenu: true, - ignoreClick: true, - _showTitle: 'title', - _stayInCollection: true, - _hideContextMenu: true, - childLimitHeight: 0, - childDropAction: 'copy', - _autoHeight: true, - _yMargin: 50, - _gridGap: 15, - boxShadow: '0 0', - _lockedPosition: true, - system: true, - _chromeHidden: true, - dontRegisterView: true, - explainer: - 'This is where documents that are Imported into Dash will go.', - }; - const myImports = this.AssignDocField( - doc, - field, - (opts) => Docs.Create.StackingDocument([], opts), - reqdOpts - ); - - const reqdBtnOpts: DocumentOptions = { - _forceActive: true, - toolTip: 'Import from computer', - _width: 30, - _height: 30, - _stayInCollection: true, - _hideContextMenu: true, - title: 'Import', - btnType: ButtonType.ClickButton, - buttonText: 'Import', - icon: 'upload', - system: true, + /// Import option on the left side button panel + static setupImportSidebar(doc: Doc, field:string) { + const reqdOpts:DocumentOptions = { + title: "My Imports", _forceActive: true, buttonMenu: true, ignoreClick: true, _showTitle: "title", + _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, + childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true, + dontRegisterView: true, explainer: "This is where documents that are Imported into Dash will go." }; - this.AssignDocField( - myImports, - 'buttonMenuDoc', - (opts) => Docs.Create.FontIconDocument(opts), - reqdBtnOpts, - undefined, - { onClick: 'importDocument()' } - ); + const myImports = this.AssignDocField(doc, field, (opts) => Docs.Create.StackingDocument([], opts), reqdOpts); + + const reqdBtnOpts:DocumentOptions = { _forceActive: true, toolTip: "Import from computer", + _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Import", btnType: ButtonType.ClickButton, + buttonText: "Import", icon: "upload", system: true }; + this.AssignDocField(myImports, "buttonMenuDoc", (opts) => Docs.Create.FontIconDocument(opts), reqdBtnOpts, undefined, { onClick: "importDocument()" }); return myImports; } static setupClickEditorTemplates(doc: Doc) { - if (doc['clickFuncs-child'] === undefined) { + if (doc["clickFuncs-child"] === undefined) { // to use this function, select it from the context menu of a collection. then edit the onChildClick script. Add two Doc variables: 'target' and 'thisContainer', then assign 'target' to some target collection. After that, clicking on any document in the initial collection will open it in the target - const openInTarget = Docs.Create.ScriptingDocument( - ScriptField.MakeScript( - 'docCast(thisContainer.target).then((target) => target && (target.proto.data = new List([self]))) ', - { thisContainer: Doc.name } - ), - { - title: 'Click to open in target', - _width: 300, - _height: 200, - targetScriptKey: 'onChildClick', - system: true, - } - ); - - const openDetail = Docs.Create.ScriptingDocument( - ScriptField.MakeScript('openOnRight(self.doubleClickView)', {}), - { - title: 'Double click to open doubleClickView', - _width: 300, - _height: 200, - targetScriptKey: 'onChildDoubleClick', - system: true, - } - ); + const openInTarget = Docs.Create.ScriptingDocument(ScriptField.MakeScript( + "docCast(thisContainer.target).then((target) => target && (target.proto.data = new List([self]))) ", + { thisContainer: Doc.name }), { + title: "Click to open in target", _width: 300, _height: 200, + targetScriptKey: "onChildClick", system: true + }); + + const openDetail = Docs.Create.ScriptingDocument(ScriptField.MakeScript( "openOnRight(self.doubleClickView)", {}), + { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick", system: true }); - doc['clickFuncs-child'] = Docs.Create.TreeDocument( - [openInTarget, openDetail], - { title: 'on Child Click function templates', system: true } - ); + doc["clickFuncs-child"] = Docs.Create.TreeDocument([openInTarget, openDetail], { title: "on Child Click function templates", system: true }); } // this is equivalent to using PrefetchProxies to make sure all the childClickFuncs have been retrieved. - PromiseValue(Cast(doc['clickFuncs-child'], Doc)).then( - (func) => func && PromiseValue(func.data).then(DocListCast) - ); + PromiseValue(Cast(doc["clickFuncs-child"], Doc)).then(func => func && PromiseValue(func.data).then(DocListCast)); if (doc.clickFuncs === undefined) { - const onClick = Docs.Create.ScriptingDocument( - undefined, - { - title: 'onClick', - 'onClick-rawScript': "console.log('click')", - isTemplateDoc: true, - isTemplateForField: 'onClick', - _width: 300, - _height: 200, - system: true, - }, - 'onClick' - ); - const onChildClick = Docs.Create.ScriptingDocument( - undefined, - { - title: 'onChildClick', - 'onChildClick-rawScript': "console.log('child click')", - isTemplateDoc: true, - isTemplateForField: 'onChildClick', - _width: 300, - _height: 200, - system: true, - }, - 'onChildClick' - ); - const onDoubleClick = Docs.Create.ScriptingDocument( - undefined, - { - title: 'onDoubleClick', - 'onDoubleClick-rawScript': "console.log('double click')", - isTemplateDoc: true, - isTemplateForField: 'onDoubleClick', - _width: 300, - _height: 200, - system: true, - }, - 'onDoubleClick' - ); - const onChildDoubleClick = Docs.Create.ScriptingDocument( - undefined, - { - title: 'onChildDoubleClick', - 'onChildDoubleClick-rawScript': - "console.log('child double click')", - isTemplateDoc: true, - isTemplateForField: 'onChildDoubleClick', - _width: 300, - _height: 200, - system: true, - }, - 'onChildDoubleClick' - ); - const onCheckedClick = Docs.Create.ScriptingDocument( - undefined, - { - title: 'onCheckedClick', - 'onCheckedClick-rawScript': - 'console.log(heading + checked + containingTreeView)', - 'onCheckedClick-params': new List<string>([ - 'heading', - 'checked', - 'containingTreeView', - ]), - isTemplateDoc: true, - isTemplateForField: 'onCheckedClick', - _width: 300, - _height: 200, - system: true, - }, - 'onCheckedClick' - ); - doc.clickFuncs = Docs.Create.TreeDocument( - [onClick, onChildClick, onDoubleClick, onCheckedClick], - { title: 'onClick funcs', system: true } - ); + const onClick = Docs.Create.ScriptingDocument(undefined, { + title: "onClick", "onClick-rawScript": "console.log('click')", + isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200, system: true + }, "onClick"); + const onChildClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildClick", "onChildClick-rawScript": "console.log('child click')", + isTemplateDoc: true, isTemplateForField: "onChildClick", _width: 300, _height: 200, system: true + }, "onChildClick"); + const onDoubleClick = Docs.Create.ScriptingDocument(undefined, { + title: "onDoubleClick", "onDoubleClick-rawScript": "console.log('double click')", + isTemplateDoc: true, isTemplateForField: "onDoubleClick", _width: 300, _height: 200, system: true + }, "onDoubleClick"); + const onChildDoubleClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildDoubleClick", "onChildDoubleClick-rawScript": "console.log('child double click')", + isTemplateDoc: true, isTemplateForField: "onChildDoubleClick", _width: 300, _height: 200, system: true + }, "onChildDoubleClick"); + const onCheckedClick = Docs.Create.ScriptingDocument(undefined, { + title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)", + "onCheckedClick-params": new List<string>(["heading", "checked", "containingTreeView"]), isTemplateDoc: true, + isTemplateForField: "onCheckedClick", _width: 300, _height: 200, system: true + }, "onCheckedClick"); + doc.clickFuncs = Docs.Create.TreeDocument([onClick, onChildClick, onDoubleClick, onCheckedClick], { title: "onClick funcs", system: true }); } - PromiseValue(Cast(doc.clickFuncs, Doc)).then( - (func) => func && PromiseValue(func.data).then(DocListCast) - ); + PromiseValue(Cast(doc.clickFuncs, Doc)).then(func => func && PromiseValue(func.data).then(DocListCast)); return doc.clickFuncs as Doc; } + /// Updates the UserDoc to have all required fields, docs, etc. No changes should need to be /// written to the server if the code hasn't changed. However, choices need to be made for each Doc/field /// whether to revert to "default" values, or to leave them as the user/system last set them. - static updateUserDocument( - doc: Doc, - sharingDocumentId: string, - linkDatabaseId: string - ) { - this.AssignDocField( - doc, - 'globalGroupDatabase', - () => Docs.Prototypes.MainGroupDocument(), - {} - ); - reaction( - () => - DateCast(DocCast(doc.globalGroupDatabase)['data-lastModified']), + static updateUserDocument(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) { + this.AssignDocField(doc, "globalGroupDatabase", () => Docs.Prototypes.MainGroupDocument(), {}); + reaction(() => DateCast(DocCast(doc.globalGroupDatabase)["data-lastModified"]), async () => { - const groups = await DocListCastAsync( - DocCast(doc.globalGroupDatabase).data - ); - const mygroups = - groups?.filter((group) => - JSON.parse(StrCast(group.members)).includes( - Doc.CurrentUserEmail - ) - ) || []; - SnappingManager.SetCachedGroups([ - 'Public', - ...mygroups?.map((g) => StrCast(g.title)), - ]); - }, - { fireImmediately: true } - ); + const groups = await DocListCastAsync(DocCast(doc.globalGroupDatabase).data); + const mygroups = groups?.filter(group => JSON.parse(StrCast(group.members)).includes(Doc.CurrentUserEmail)) || []; + SnappingManager.SetCachedGroups(["Public", ...mygroups?.map(g => StrCast(g.title))]); + }, { fireImmediately: true }); doc.system ?? (doc.system = true); doc.title ?? (doc.title = Doc.CurrentUserEmail); Doc.noviceMode ?? (Doc.noviceMode = true); doc._raiseWhenDragged ?? (doc._raiseWhenDragged = true); doc._showLabel ?? (doc._showLabel = true); - doc.textAlign ?? (doc.textAlign = 'left'); - doc.activeInkColor ?? (doc.activeInkColor = 'rgb(0, 0, 0)'); + doc.textAlign ?? (doc.textAlign = "left"); + doc.activeInkColor ?? (doc.activeInkColor = "rgb(0, 0, 0)");; doc.activeInkWidth ?? (doc.activeInkWidth = 1); - doc.activeInkBezier ?? (doc.activeInkBezier = '0'); - doc.activeFillColor ?? (doc.activeFillColor = ''); - doc.activeArrowStart ?? (doc.activeArrowStart = ''); - doc.activeArrowEnd ?? (doc.activeArrowEnd = ''); - doc.activeDash ?? doc.activeDash == '0'; - doc.fontSize ?? (doc.fontSize = '12px'); - doc.fontFamily ?? (doc.fontFamily = 'Arial'); - doc.fontColor ?? (doc.fontColor = 'black'); - doc.fontHighlight ?? (doc.fontHighlight = ''); + doc.activeInkBezier ?? (doc.activeInkBezier = "0"); + doc.activeFillColor ?? (doc.activeFillColor = ""); + doc.activeArrowStart ?? (doc.activeArrowStart = ""); + doc.activeArrowEnd ?? (doc.activeArrowEnd = ""); + doc.activeDash ?? (doc.activeDash == "0"); + doc.fontSize ?? (doc.fontSize = "12px"); + doc.fontFamily ?? (doc.fontFamily = "Arial"); + doc.fontColor ?? (doc.fontColor = "black"); + doc.fontHighlight ?? (doc.fontHighlight = ""); doc.defaultAclPrivate ?? (doc.defaultAclPrivate = false); doc.savedFilters ?? (doc.savedFilters = new List<Doc>()); doc.filterDocCount = 0; - doc.freezeChildren = 'remove|add'; + doc.freezeChildren = "remove|add"; this.setupLinkDocs(doc, linkDatabaseId); - this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing - this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon + this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing + this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile - 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.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.setupDockedButtons(doc); // the bottom bar of font icons + 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 this.setupFieldInfos(doc); // sets up the collection of field info descriptions for each possible DocumentOption - this.AssignDocField( - doc, - 'globalScriptDatabase', - (opts) => Docs.Prototypes.MainScriptDocument(), - {} - ); - this.AssignDocField( - doc, - 'myHeaderBar', - (opts) => Docs.Create.MulticolumnDocument([], opts), - { title: 'header bar', system: true } - ); // drop down panel at top of dashboard for stashing documents - + this.AssignDocField(doc, "globalScriptDatabase", (opts) => Docs.Prototypes.MainScriptDocument(), {}); + this.AssignDocField(doc, "myHeaderBar", (opts) => Docs.Create.MulticolumnDocument([], opts), { title: "header bar", system: true }); // drop down panel at top of dashboard for stashing documents + if (doc.activeDashboard instanceof Doc) { // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss) - doc.activeDashboard.colorScheme = - doc.activeDashboard.colorScheme === ColorScheme.Light - ? undefined - : doc.activeDashboard.colorScheme; + doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme; } new LinkManager(); DocServer.UPDATE_SERVER_CACHE(); return doc; } - static setupFieldInfos(doc: Doc, field = 'fieldInfos') { - const fieldInfoOpts = { title: 'Field Infos', system: true }; // bcz: all possible document options have associated field infos which are stored onn the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object - const infos = this.AssignDocField( - doc, - field, - (opts) => Doc.assign(new Doc(), opts as any), - fieldInfoOpts - ); + static setupFieldInfos(doc:Doc, field="fieldInfos") { + const fieldInfoOpts = { title: "Field Infos", system: true}; // bcz: all possible document options have associated field infos which are stored onn the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object + const infos = this.AssignDocField(doc, field, opts => Doc.assign(new Doc(), opts as any), fieldInfoOpts); const entries = Object.entries(new DocumentOptions()); - entries.forEach((pair) => { + entries.forEach(pair => { if (!Array.from(Object.keys(fieldInfoOpts)).includes(pair[0])) { const options = pair[1] as FInfo; - const opts: DocumentOptions = { - system: true, - title: pair[0], - ...OmitKeys(options, ['values']).omit, - fieldIsLayout: pair[0].startsWith('_'), - }; + const opts:DocumentOptions = { system: true, title: pair[0], ...OmitKeys(options, ["values"]).omit, fieldIsLayout: pair[0].startsWith("_")}; switch (options.fieldType) { - case 'boolean': - opts.fieldValues = new List<boolean>( - options.values as any - ); - break; - case 'number': - opts.fieldValues = new List<number>( - options.values as any - ); - break; - case 'Doc': - opts.fieldValues = new List<Doc>(options.values as any); - break; - default: - opts.fieldValues = new List<string>( - options.values as any - ); - break; // string, pointerEvents, dimUnit, dropActionType + case "boolean": opts.fieldValues = new List<boolean>(options.values as any); break; + case "number": opts.fieldValues = new List<number>(options.values as any); break; + case Doc.name: opts.fieldValues = new List<Doc>(options.values as any); break; + default: opts.fieldValues = new List<string>(options.values as any); break;// string, pointerEvents, dimUnit, dropActionType } - this.AssignDocField( - infos, - pair[0], - (opts) => - Doc.assign(new Doc(), OmitKeys(opts, ['values']).omit), - opts - ); + this.AssignDocField(infos, pair[0], opts => Doc.assign(new Doc(), OmitKeys(opts,["values"]).omit), opts); } }); } public static async loadCurrentUser() { - return rp - .get(Utils.prepend('/getCurrentUser')) - .then(async (response) => { - if (response) { - const result: { - id: string; - email: string; - cacheDocumentIds: string; - } = JSON.parse(response); - Doc.CurrentUserEmail = result.email; - resolvedPorts = JSON.parse( - await (await fetch('/resolvedPorts')).text() - ); - DocServer.init( - window.location.protocol, - window.location.hostname, - resolvedPorts.socket, - result.email - ); - result.cacheDocumentIds && - (await DocServer.GetRefFields( - result.cacheDocumentIds.split(';') - )); - return result; - } else { - throw new Error( - "There should be a user! Why does Dash think there isn't one?" - ); - } - }); + return rp.get(Utils.prepend("/getCurrentUser")).then(async response => { + if (response) { + const result: { id: string, email: string, cacheDocumentIds: string } = JSON.parse(response); + Doc.CurrentUserEmail = result.email; + resolvedPorts = JSON.parse(await (await fetch("/resolvedPorts")).text()); + DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, result.email); + result.cacheDocumentIds && (await DocServer.GetRefFields(result.cacheDocumentIds.split(";"))); + return result; + } else { + throw new Error("There should be a user! Why does Dash think there isn't one?"); + } + }); } public static async loadUserDocument(id: string) { this.curr_id = id; - await rp.get(Utils.prepend('/getUserDocumentIds')).then((ids) => { - const { userDocumentId, sharingDocumentId, linkDatabaseId } = - JSON.parse(ids); - if (userDocumentId !== 'guest') { - return DocServer.GetRefField(userDocumentId).then( - async (field) => { - Docs.newAccount = !(field instanceof Doc); - await Docs.Prototypes.initialize(); - const userDoc = Docs.newAccount - ? new Doc(userDocumentId, true) - : (field as Doc); - Docs.newAccount && (userDoc.activePage = 'home'); - return this.updateUserDocument( - Doc.SetUserDoc(userDoc), - sharingDocumentId, - linkDatabaseId - ); - } - ); + await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { + const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); + if (userDocumentId !== "guest") { + return DocServer.GetRefField(userDocumentId).then(async field => { + Docs.newAccount = !(field instanceof Doc); + await Docs.Prototypes.initialize(); + const userDoc = Docs.newAccount ? new Doc(userDocumentId, true) : field as Doc; + Docs.newAccount &&(userDoc.activePage = "home"); + return this.updateUserDocument(Doc.SetUserDoc(userDoc), sharingDocumentId, linkDatabaseId); + }); } else { - throw new Error( - "There should be a user id! Why does Dash think there isn't one?" - ); + throw new Error("There should be a user id! Why does Dash think there isn't one?"); } }); } @@ -2297,31 +1017,25 @@ export class CurrentUserUtils { /// opens a dashboard as the ActiveDashboard (and adds the dashboard to the users list of dashboards if it's not already there). /// this also sets the readonly state of the dashboard based on the current mode of dash (from its url) - public static openDashboard = ( - doc: Doc | undefined, - fromHistory = false - ) => { + public static openDashboard = (doc: Doc|undefined, fromHistory = false) => { if (!doc) return false; CurrentUserUtils.MainDocId = doc[Id]; - Doc.AddDocToList(CurrentUserUtils.MyDashboards, 'data', doc); + Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", doc); // this has the side-effect of setting the main container since we're assigning the active/guest dashboard - Doc.UserDoc() - ? (CurrentUserUtils.ActiveDashboard = doc) - : (CurrentUserUtils.GuestDashboard = doc); - + Doc.UserDoc() ? (CurrentUserUtils.ActiveDashboard = doc) : (CurrentUserUtils.GuestDashboard = doc); + const state = CurrentUserUtils._urlState; if (state.sharing === true && !Doc.UserDoc()) { DocServer.Control.makeReadOnly(); } else { - fromHistory || - HistoryUtil.pushState({ - type: 'doc', - docId: doc[Id], - readonly: state.readonly, - nro: state.nro, - sharing: false, - }); + fromHistory || HistoryUtil.pushState({ + type: "doc", + docId: doc[Id], + readonly: state.readonly, + nro: state.nro, + sharing: false, + }); if (state.readonly === true || state.readonly === null) { DocServer.Control.makeReadOnly(); } else if (state.safe) { @@ -2329,11 +1043,7 @@ export class CurrentUserUtils { DocServer.Control.makeReadOnly(); } CollectionView.SetSafeMode(true); - } else if ( - state.nro || - state.nro === null || - state.readonly === false - ) { + } else if (state.nro || state.nro === null || state.readonly === false) { } else if (doc.readOnly) { DocServer.Control.makeReadOnly(); } else { @@ -2342,15 +1052,15 @@ export class CurrentUserUtils { } return true; - }; + } public static importDocument = () => { - const input = document.createElement('input'); - input.type = 'file'; + const input = document.createElement("input"); + input.type = "file"; input.multiple = true; - input.accept = '.zip, application/pdf, video/*, image/*, audio/*'; - input.onchange = async (_e) => { - const upload = Utils.prepend('/uploadDoc'); + input.accept = ".zip, application/pdf, video/*, image/*, audio/*"; + input.onchange = async _e => { + const upload = Utils.prepend("/uploadDoc"); const formData = new FormData(); const file = input.files?.[0]; if (file?.type === 'application/zip') { @@ -2359,69 +1069,38 @@ export class CurrentUserUtils { // setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => // docs.docs.forEach(d => LinkManager.Instance.addLink(d))), 2000); // need to give solr some time to update so that this query will find any link docs we've added. // } - const list = Cast( - CurrentUserUtils.MyImports.data, - listSpec(Doc), - null - ); + const list = Cast(CurrentUserUtils.MyImports.data, listSpec(Doc), null); doc instanceof Doc && list?.splice(0, 0, doc); } else if (input.files && input.files.length !== 0) { const disposer = OverlayView.ShowSpinner(); - const results = await DocUtils.uploadFilesToDocs( - Array.from(input.files || []), - {} - ); + const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); if (results.length !== input.files?.length) { - alert( - 'Error uploading files - possibly due to unsupported file types' - ); + alert("Error uploading files - possibly due to unsupported file types"); } - const list = Cast( - CurrentUserUtils.MyImports.data, - listSpec(Doc), - null - ); + const list = Cast(CurrentUserUtils.MyImports.data, listSpec(Doc), null); list?.splice(0, 0, ...results); disposer(); } else { - console.log('No file selected'); + console.log("No file selected"); } }; input.click(); - }; - - public static snapshotDashboard() { - return CollectionDockingView.TakeSnapshot( - CurrentUserUtils.ActiveDashboard - ); } + + public static snapshotDashboard() { return CollectionDockingView.TakeSnapshot(CurrentUserUtils.ActiveDashboard); } - public static closeActiveDashboard = () => { - CurrentUserUtils.ActiveDashboard = undefined; - }; + public static closeActiveDashboard = () => { CurrentUserUtils.ActiveDashboard = undefined; } - public static removeDashboard = async (dashboard: Doc) => { - const dashboards = await DocListCastAsync( - CurrentUserUtils.MyDashboards.data - ); + public static removeDashboard = async (dashboard:Doc) => { + const dashboards = await DocListCastAsync(CurrentUserUtils.MyDashboards.data); if (dashboards?.length) { - if (dashboard === CurrentUserUtils.ActiveDashboard) - CurrentUserUtils.openDashboard( - dashboards.find((doc) => doc !== dashboard) - ); - Doc.RemoveDocFromList( - CurrentUserUtils.MyDashboards, - 'data', - dashboard - ); - if (!dashboards.length) CurrentUserUtils.ActivePage = 'home'; + if (dashboard === CurrentUserUtils.ActiveDashboard) CurrentUserUtils.openDashboard(dashboards.find(doc => doc !== dashboard)); + Doc.RemoveDocFromList(CurrentUserUtils.MyDashboards, "data", dashboard); + if (!dashboards.length) CurrentUserUtils.ActivePage = "home"; } - }; + } public static createNewDashboard = (id?: string, name?: string) => { - const presentation = Doc.MakeCopy( - Doc.UserDoc().emptyPresentation as Doc, - true - ); + const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true); const dashboards = CurrentUserUtils.MyDashboards; const dashboardCount = DocListCast(dashboards.data).length + 1; const freeformOptions: DocumentOptions = { @@ -2433,211 +1112,84 @@ export class CurrentUserUtils { _backgroundGridShow: true, title: `Untitled Tab 1`, }; - const title = name ? name : `Dashboard ${dashboardCount}`; - const freeformDoc = - CurrentUserUtils.GuestTarget || - Docs.Create.FreeformDocument([], freeformOptions); - const dashboardDoc = Docs.Create.StandardCollectionDockingDocument( - [{ doc: freeformDoc, initialWidth: 600 }], - { title: title }, - id, - 'row' - ); + const title = name ? name : `Dashboard ${dashboardCount}` + const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); + const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, "row"); freeformDoc.context = dashboardDoc; // switching the tabs from the datadoc to the regular doc const dashboardTabs = DocListCast(dashboardDoc[DataSym].data); dashboardDoc.data = new List<Doc>(dashboardTabs); - dashboardDoc['pane-count'] = 1; + dashboardDoc["pane-count"] = 1; CurrentUserUtils.ActivePresentation = presentation; - Doc.AddDocToList(dashboards, 'data', dashboardDoc); - // open this new dashboard + Doc.AddDocToList(dashboards, "data", dashboardDoc); + // open this new dashboard CurrentUserUtils.ActiveDashboard = dashboardDoc; - CurrentUserUtils.ActivePage = 'dashboard'; - }; - - public static GetNewTextDoc( - title: string, - x: number, - y: number, - width?: number, - height?: number, - noMargins?: boolean, - annotationOn?: Doc, - maxHeight?: number, - backgroundColor?: string - ) { - const tbox = Docs.Create.TextDocument('', { - _xMargin: noMargins ? 0 : undefined, - _yMargin: noMargins ? 0 : undefined, - annotationOn, - docMaxAutoHeight: maxHeight, - backgroundColor: backgroundColor, - _width: width || 200, - _height: 35, - x: x, - y: y, - _fitWidth: true, - _autoHeight: true, - title, + CurrentUserUtils.ActivePage = "dashboard"; + } + + public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number, backgroundColor?: string) { + const tbox = Docs.Create.TextDocument("", { + _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight, backgroundColor: backgroundColor, + _width: width || 200, _height: 35, x: x, y: y, _fitWidth: true, _autoHeight: true, title }); const template = Doc.UserDoc().defaultTextLayout; if (template instanceof Doc) { tbox._width = NumCast(template._width); - tbox.layoutKey = 'layout_' + StrCast(template.title); + tbox.layoutKey = "layout_" + StrCast(template.title); Doc.GetProto(tbox)[StrCast(tbox.layoutKey)] = template; } return tbox; } - public static get MyUserDocView() { - return DocCast(Doc.UserDoc().myUserDocView); - } - public static get MyDockedBtns() { - return DocCast(Doc.UserDoc().myDockedBtns); - } - public static get MySearcher() { - return DocCast(Doc.UserDoc().mySearcher); - } - public static get MyFilesystem() { - return DocCast(Doc.UserDoc().myFilesystem); - } - public static get MyHeaderBar() { - return DocCast(Doc.UserDoc().myHeaderBar); - } - public static get MyTools() { - return DocCast(Doc.UserDoc().myTools); - } - public static get MyDashboards() { - return DocCast(Doc.UserDoc().myDashboards); - } - public static get MyFileOrphans() { - return DocCast(Doc.UserDoc().myFileOrphans); - } - public static get MyTemplates() { - return DocCast(Doc.UserDoc().myTemplates); - } - public static get MyLeftSidebarMenu() { - return DocCast(Doc.UserDoc().myLeftSidebarMenu); - } - public static get MyLeftSidebarPanel() { - return DocCast(Doc.UserDoc().myLeftSidebarPanel); - } - public static get MySharedDocs() { - return DocCast(Doc.UserDoc().mySharedDocs); - } - public static get MyTrails() { - return DocCast(Doc.UserDoc().myTrails); - } - public static get MyImports() { - return DocCast(Doc.UserDoc().myImports); - } - public static get MyContextMenuBtns() { - return DocCast(Doc.UserDoc().myContextMenuBtns); - } - public static get MyRecentlyClosed() { - return DocCast(Doc.UserDoc().myRecentlyClosed); - } - public static get MyOverlayDocs() { - return DocCast(Doc.UserDoc().myOverlayDocs); - } - public static get MyPublishedDocs() { - return DocCast(Doc.UserDoc().myPublishedDocs); - } - public static get ActiveDashboard() { - return DocCast(Doc.UserDoc().activeDashboard); - } - public static set ActiveDashboard(val: Doc | undefined) { - Doc.UserDoc().activeDashboard = val; - } - public static get ActivePresentation() { - return DocCast(Doc.UserDoc().activePresentation); - } - public static set ActivePresentation(val) { - Doc.UserDoc().activePresentation = val; - } - public static get ActivePage() { - return StrCast(Doc.UserDoc().activePage); - } - public static set ActivePage(val) { - Doc.UserDoc().activePage = val; - } - public static set ActiveTool(tool: InkTool) { - Doc.UserDoc().activeTool = tool; - } - public static get ActiveTool(): InkTool { - return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool; - } + public static get MyUserDocView() { return DocCast(Doc.UserDoc().myUserDocView); } + public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); } + public static get MySearcher() { return DocCast(Doc.UserDoc().mySearcher); } + public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); } + public static get MyHeaderBar() { return DocCast(Doc.UserDoc().myHeaderBar); } + public static get MyTools() { return DocCast(Doc.UserDoc().myTools); } + public static get MyDashboards() { return DocCast(Doc.UserDoc().myDashboards); } + public static get MyFileOrphans() { return DocCast(Doc.UserDoc().myFileOrphans); } + public static get MyTemplates() { return DocCast(Doc.UserDoc().myTemplates); } + public static get MyLeftSidebarMenu() { return DocCast(Doc.UserDoc().myLeftSidebarMenu); } + public static get MyLeftSidebarPanel() { return DocCast(Doc.UserDoc().myLeftSidebarPanel); } + public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); } + public static get MyTrails() { return DocCast(Doc.UserDoc().myTrails); } + public static get MyImports() { return DocCast(Doc.UserDoc().myImports); } + public static get MyContextMenuBtns() { return DocCast(Doc.UserDoc().myContextMenuBtns); } + public static get MyRecentlyClosed() { return DocCast(Doc.UserDoc().myRecentlyClosed); } + public static get MyOverlayDocs() { return DocCast(Doc.UserDoc().myOverlayDocs); } + public static get MyPublishedDocs() { return DocCast(Doc.UserDoc().myPublishedDocs); } + public static get ActiveDashboard() { return DocCast(Doc.UserDoc().activeDashboard); } + public static set ActiveDashboard(val:Doc|undefined) { Doc.UserDoc().activeDashboard = val; } + public static get ActivePresentation() { return DocCast(Doc.UserDoc().activePresentation); } + public static set ActivePresentation(val) { Doc.UserDoc().activePresentation = val; } + public static get ActivePage() { return StrCast(Doc.UserDoc().activePage); } + public static set ActivePage(val) { Doc.UserDoc().activePage = val; } + public static set ActiveTool(tool: InkTool) { Doc.UserDoc().activeTool = tool; } + public static get ActiveTool(): InkTool { return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool; } } -ScriptingGlobals.add(function MySharedDocs() { - return CurrentUserUtils.MySharedDocs; -}, 'document containing all shared Docs'); -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 snapshotDashboard() { - CurrentUserUtils.snapshotDashboard(); -}, 'creates a snapshot copy of a dashboard'); -ScriptingGlobals.add(function createNewDashboard() { - return CurrentUserUtils.createNewDashboard(); -}, 'creates a new dashboard when called'); -ScriptingGlobals.add(function createNewPresentation() { - return MainView.Instance.createNewPresentation(); -}, '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'); -ScriptingGlobals.add(function shareDashboard(dashboard: Doc) { - SharingManager.Instance.open(undefined, dashboard); -}, 'opens sharing dialog for Dashboard'); -ScriptingGlobals.add(function removeDashboard(dashboard: Doc) { - CurrentUserUtils.removeDashboard(dashboard); -}, 'Remove Dashboard from Dashboards'); -ScriptingGlobals.add(function addToDashboards(dashboard: Doc) { - CurrentUserUtils.openDashboard(Doc.MakeAlias(dashboard)); -}, 'adds Dashboard to set of Dashboards'); -ScriptingGlobals.add(function selectedDocumentType( - docType?: DocumentType, - colType?: CollectionViewType, - checkContext?: boolean -) { - let selected = ((sel) => (checkContext ? DocCast(sel?.context) : sel))( - SelectionManager.SelectedSchemaDoc() ?? - SelectionManager.Docs().lastElement() - ); - return docType - ? selected?.type === docType - : colType - ? selected?.viewType === colType - : true; +ScriptingGlobals.add(function MySharedDocs() { return CurrentUserUtils.MySharedDocs; }, "document containing all shared Docs"); +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 snapshotDashboard() { CurrentUserUtils.snapshotDashboard(); }, "creates a snapshot copy of a dashboard"); +ScriptingGlobals.add(function createNewDashboard() { return CurrentUserUtils.createNewDashboard(); }, "creates a new dashboard when called"); +ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance.createNewPresentation(); }, "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"); +ScriptingGlobals.add(function shareDashboard(dashboard: Doc) { SharingManager.Instance.open(undefined, dashboard); }, "opens sharing dialog for Dashboard"); +ScriptingGlobals.add(function removeDashboard(dashboard: Doc) { CurrentUserUtils.removeDashboard(dashboard); }, "Remove Dashboard from Dashboards"); +ScriptingGlobals.add(function addToDashboards(dashboard: Doc) { CurrentUserUtils.openDashboard( Doc.MakeAlias(dashboard)); }, "adds Dashboard to set of Dashboards"); +ScriptingGlobals.add(function selectedDocumentType(docType?: DocumentType, colType?: CollectionViewType, checkContext?: boolean) { + let selected = (sel => checkContext ? DocCast(sel?.context) : sel)(SelectionManager.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement()); + return docType ? selected?.type === docType : colType ? selected?.viewType === colType : true; }); ScriptingGlobals.add(function makeTopLevelFolder() { TreeView._editTitleOnLoad = { id: Utils.GenerateGuid(), parent: undefined }; - const opts = { - title: 'Untitled folder', - _stayInCollection: true, - isFolder: true, - }; - return Doc.AddDocToList( - CurrentUserUtils.MyFilesystem, - 'data', - Docs.Create.TreeDocument([], opts, TreeView._editTitleOnLoad.id) - ); -}); + const opts = { title: "Untitled folder", _stayInCollection: true, isFolder: true }; + return Doc.AddDocToList(CurrentUserUtils.MyFilesystem, "data", Docs.Create.TreeDocument([], opts, TreeView._editTitleOnLoad.id)); +});
\ No newline at end of file diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 076afd3a0..256ab5c44 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -20,7 +20,7 @@ export function MakeTemplate(doc: Doc, first: boolean = true, rename: Opt<string // the title of doc is used to determine which field is being templated, so // passing a value for 'rename' allows the doc to be given a meangingful name // after it has been converted to -export function makeTemplate(doc: Doc, first: boolean = true, rename: Opt<string> = undefined): boolean { +function makeTemplate(doc: Doc, first: boolean = true, rename: Opt<string> = undefined): boolean { const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc; if (layoutDoc.layout instanceof Doc) { // its already a template return true; diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 3e85edac8..b00017453 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -725,12 +725,12 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack /> {/* {this.renderDictation} */} - { /* check time to prevent weird div overflow */ this._hoverTime < this.clipDuration && <div + <div className="collectionStackedTimeline-hover" style={{ left: `${((this._hoverTime - this.clipStart) / this.clipDuration) * 100}%`, }} - />} + /> <div className="collectionStackedTimeline-current" @@ -775,7 +775,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack </div> </div> <div className="timeline-hoverUI" style={{ left: `calc(${((this._hoverTime - this.clipStart) / this.clipDuration) * 100}%` }}> - <div className="hoverTime">{formatTime(this._hoverTime)}</div> + <div className="hoverTime">{formatTime(this._hoverTime - this.clipStart)}</div> {this._thumbnail && <img className="videoBox-thumbnail" src={this._thumbnail} />} </div> </div >); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9ae604e9b..8e1698eba 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -29,7 +29,7 @@ import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; import { DictationManager } from '../../../util/DictationManager'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from "../../../util/DragManager"; -import { makeTemplate } from '../../../util/DropConverter'; +import { MakeTemplate } from '../../../util/DropConverter'; import { LinkManager } from '../../../util/LinkManager'; import { SelectionManager } from "../../../util/SelectionManager"; import { SnappingManager } from '../../../util/SnappingManager'; @@ -682,7 +682,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (!this.layoutDoc.isTemplateDoc) { const title = StrCast(this.rootDoc.title); this.rootDoc.title = "text"; - this.rootDoc.isTemplateDoc = makeTemplate(this.rootDoc, true, title); + MakeTemplate(this.rootDoc, true, title); } else if (!this.rootDoc.isTemplateDoc) { const title = StrCast(this.rootDoc.title); this.rootDoc.title = "text"; @@ -691,7 +691,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.rootDoc.isTemplateDoc = false; this.rootDoc.isTemplateForField = ""; this.rootDoc.layoutKey = "layout"; - this.rootDoc.isTemplateDoc = makeTemplate(this.rootDoc, true, title); + MakeTemplate(this.rootDoc, true, title); setTimeout(() => { this.rootDoc._autoHeight = this.layoutDoc._autoHeight; // autoHeight, width and height this.rootDoc._width = this.layoutDoc._width || 300; // are stored on the template, since we're getting rid of the old template |