diff options
| author | mehekj <mehek.jethani@gmail.com> | 2022-10-12 13:21:07 -0400 |
|---|---|---|
| committer | mehekj <mehek.jethani@gmail.com> | 2022-10-12 13:21:07 -0400 |
| commit | 0b3a83acd4f75b7f6ff4b9bb7daf4377dede51a1 (patch) | |
| tree | 438789f7e7f50e5eb9829e1f301b4d043d8d4906 /src/client/util | |
| parent | 69ca9baca6ff1da272a5191187542351bd242ccc (diff) | |
| parent | eb5f75785fd28acb50f1b30434e89223fff00185 (diff) | |
Merge branch 'master' into schema-mehek
Diffstat (limited to 'src/client/util')
| -rw-r--r-- | src/client/util/CurrentUserUtils.ts | 99 | ||||
| -rw-r--r-- | src/client/util/DocumentManager.ts | 24 | ||||
| -rw-r--r-- | src/client/util/DragManager.ts | 44 | ||||
| -rw-r--r-- | src/client/util/InteractionUtils.tsx | 53 | ||||
| -rw-r--r-- | src/client/util/ReportManager.tsx | 33 | ||||
| -rw-r--r-- | src/client/util/Scripting.ts | 8 | ||||
| -rw-r--r-- | src/client/util/SelectionManager.ts | 2 | ||||
| -rw-r--r-- | src/client/util/SettingsManager.tsx | 2 | ||||
| -rw-r--r-- | src/client/util/SharingManager.scss | 3 | ||||
| -rw-r--r-- | src/client/util/SharingManager.tsx | 2 | ||||
| -rw-r--r-- | src/client/util/request-image-size.js | 26 |
11 files changed, 154 insertions, 142 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 99a8c895f..cd2ea4c87 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1,12 +1,14 @@ +import { forOwn } from "lodash"; import { reaction } from "mobx"; import * as rp from 'request-promise'; import { 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 { ScriptField } from "../../fields/ScriptField"; +import { ComputedField, ScriptField } from "../../fields/ScriptField"; import { Cast, DateCast, DocCast, PromiseValue, StrCast } from "../../fields/Types"; import { nullAudio } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; @@ -143,7 +145,7 @@ export class CurrentUserUtils { { noteType: "Idea", backgroundColor: "pink", icon: "lightbulb" }, { noteType: "Topic", backgroundColor: "lightblue", icon: "book-open" }]; const reqdNoteList = reqdTempOpts.map(opts => { - const reqdOpts = {...opts, title: "text", width:200, system: true}; + const reqdOpts = {...opts, title: "text", width:200, autoHeight: true, fitWidth: true, system: true}; const noteType = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.noteType === opts.noteType): undefined; return DocUtils.AssignOpts(noteType, reqdOpts) ?? MakeTemplate(Docs.Create.TextDocument("",reqdOpts), true, opts.noteType??"Note"); }); @@ -154,7 +156,7 @@ export class CurrentUserUtils { /// Initializes collection of templates for notes and click functions static setupDocTemplates(doc: Doc, field="myTemplates") { - DocUtils.AssignDocField(doc, "presElement", opts => Docs.Create.PresElementBoxDocument(opts), { title: "pres element template", type: DocumentType.PRESELEMENT, _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"}); + DocUtils.AssignDocField(doc, "presElement", opts => Docs.Create.PresElementBoxDocument(), { }); const templates = [ CurrentUserUtils.setupNoteTemplates(doc), CurrentUserUtils.setupClickEditorTemplates(doc) @@ -196,6 +198,7 @@ export class CurrentUserUtils { makeIconTemplate(DocumentType.RTF, "text", { iconTemplate:DocumentType.LABEL, _showTitle: "creationDate"}), makeIconTemplate(DocumentType.IMG, "data", { iconTemplate:DocumentType.IMG, _height: undefined}), makeIconTemplate(DocumentType.COL, "icon", { iconTemplate:DocumentType.IMG}), + makeIconTemplate(DocumentType.COL, "icon", { iconTemplate:DocumentType.IMG}), makeIconTemplate(DocumentType.VID, "icon", { iconTemplate:DocumentType.IMG}), makeIconTemplate(DocumentType.BUTTON,"data", { iconTemplate:DocumentType.FONTICON}), //nasty hack .. templates are looked up exclusively by type -- but we want a template for a document with a certain field (transcription) .. so this hack and the companion hack in createCustomView does this for now @@ -205,7 +208,7 @@ export class CurrentUserUtils { DocUtils.AssignOpts(DocCast(doc[field]), {}, iconTemplates); } - /// initalizes the set of "empty<DocType>" versions of each document type with default fields. e.g.,. emptyNote, emptyPresentation + /// initalizes the set of "empty<DocType>" versions of each document type with default fields. e.g.,. emptyNote, emptyTrail 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}, @@ -267,7 +270,7 @@ export class CurrentUserUtils { {key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }}, // {key: "DataViz", creator: opts => Docs.Create.DataVizDocument(opts), opts: { _width: 300, _height: 300 }}, {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true,}}, - {key: "Presentation",creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 500, _viewType: CollectionViewType.Stacking, targetDropAction: "alias" as any, treeViewHideTitle: true, _chromeHidden: true, boxShadow: "0 0" }}, + {key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _viewType: CollectionViewType.Stacking, targetDropAction: "alias" as any, treeViewHideTitle: true, _chromeHidden: true, boxShadow: "0 0" }}, {key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _backgroundGridShow: true, }}, {key: "Slide", creator: opts => Docs.Create.TreeDocument([], opts), opts: { _width: 300, _height: 200, _viewType: CollectionViewType.Tree, treeViewHasOverlay: true, _fontSize: "20px", _autoHeight: true, @@ -321,16 +324,17 @@ export class CurrentUserUtils { /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] { - const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())"; + const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())"; + const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails"; return [ - { title: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", }, + { title: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", funcs: {hidden: "IsNoviceMode()"} }, { title: "Search", target: this.setupSearcher(doc, "mySearcher"), icon: "search", }, { title: "Files", target: this.setupFilesystem(doc, "myFilesystem"), icon: "folder-open", }, { title: "Tools", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", funcs: {hidden: "IsNoviceMode()"} }, { title: "Imports", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", }, { title: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", }, { title: "Shared Docs", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}}, - { title: "Trails", target: this.setupTrails(doc, "myTrails"), icon: "pres-trail", }, + { title: "Trails", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}}, { title: "User Doc View", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}})); } @@ -458,28 +462,33 @@ export class CurrentUserUtils { static setupDashboards(doc: Doc, field:string) { var myDashboards = DocCast(doc[field]); + const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`; const newDashboard = `createNewDashboard()`; + const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _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 = DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(myDashboards?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript); + const contextMenuScripts = [/*newDashboard*/] as string[]; + const contextMenuLabels = [/*"Create New Dashboard"*/] as string[]; + const contextMenuIcons = [/*"plus"*/] as string[]; + const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + const childContextMenuLabels = ["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters + const childContextMenuIcons = ["chalkboard", "tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { 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 + contextMenuLabels:new List<string>(contextMenuLabels), + contextMenuIcons:new List<string>(contextMenuIcons), + childContextMenuLabels:new List<string>(childContextMenuLabels), + childContextMenuIcons:new List<string>(childContextMenuIcons), 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 = DocUtils.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)!)); } @@ -492,31 +501,6 @@ export class CurrentUserUtils { return myDashboards; } - /// initializes the left sidebar Trails pane - static setupTrails(doc: Doc, field:string) { - var myTrails = DocCast(doc[field]); - const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, - title: "New trail", toolTip: "Create new trail", btnType: ButtonType.ClickButton, buttonText: "New trail", icon: "plus", system: true }; - const reqdBtnScript = {onClick: `createNewPresentation()`}; - const newTrailButton = DocUtils.AssignScripts(DocUtils.AssignOpts(DocCast(myTrails?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript); - - const reqdOpts:DocumentOptions = { - title: "My Trails", _showTitle: "title", _height: 100, - treeViewHideTitle: true, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias", - treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newTrailButton, - contextMenuIcons: new List<string>(["plus"]), - contextMenuLabels: new List<string>(["Create New Trail"]), - _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true, - explainer: "All of the trails that you have created will appear here." - }; - myTrails = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), reqdOpts); - const contextMenuScripts = [reqdBtnScript.onClick]; - if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { - myTrails.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); - } - return myTrails; - } - /// initializes the left sidebar File system pane static setupFilesystem(doc: Doc, field:string) { var myFilesystem = DocCast(doc[field]); @@ -597,14 +581,17 @@ export class CurrentUserUtils { /// initializes the required buttons in the expanding button menu at the bottom of the Dash window static setupDockedButtons(doc: Doc, field="myDockedBtns") { const dockedBtns = DocCast(doc[field]); - const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string}) => + const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string}, funcs?: {[key:string]:string}) => DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? - CurrentUserUtils.createToolButton(opts), scripts); + CurrentUserUtils.createToolButton(opts), scripts, funcs); const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet { 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" }} - ]; + { scripts: { onClick: "redo()"}, opts: { title: "redo", icon: "redo-alt", toolTip: "Click to redo" }}, + // { scripts: { onClick: 'prevKeyFrame(_readOnly_)'}, opts: { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, width: 20}}, + // { scripts: { onClick:""}, opts: { title: "Num", icon: "", toolTip: "Frame Number", btnType: ButtonType.TextButton, width: 20}, funcs: { buttonText: 'selectedDocs()?.lastElement()?.currentFrame.toString()'}}, + // { scripts: { onClick: 'nextKeyFrame(_readOnly_)'}, opts:{title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, width: 20,} }, + ]; 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, @@ -619,8 +606,8 @@ export class CurrentUserUtils { return [ { title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true, scripts: {script: 'setFont(value, _readOnly_)'}, btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) }, - { title: "Size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, ignoreClick: true, scripts: {script: '{ return setFontSize(value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions }, - { title: "Color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, scripts: {script: '{ return setFontColor(value, _readOnly_); }'}}, + { title: "Size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, ignoreClick: true, scripts: {script: '{ return setFontSize(value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions }, + { 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_);}'} }, @@ -677,15 +664,15 @@ export class CurrentUserUtils { title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "tab")'}, width: 20, scripts: { onClick: 'pinWithView(_readOnly_)'}}, { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()'}, width: 20, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, - { title: "Num", icon: "", toolTip: "Frame Number", btnType: ButtonType.TextButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()', buttonText: 'selectedDocs()?.lastElement()?.currentFrame.toString()'}, width: 20, scripts: {}}, + { title: "Num", icon: "", toolTip: "Frame Number", btnType: ButtonType.TextButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: {}}, { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()'}, width: 20, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, funcs: {hidden: '!SelectionManager_selectedDocType()'}, ignoreClick: true, width: 20, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, funcs: {hidden: '!SelectionManager_selectedDocType()'}, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}}, { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform", true)'}, scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform - { title: "Text", icon: "text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), funcs: {hidden: 'false', linearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.RTF}")`} }, // Always available - { title: "Ink", icon: "ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), funcs: {hidden: 'false', inearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.INK}")`} }, // Always available - { title: "Web", icon: "web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), funcs: {hidden: `!SelectionManager_selectedDocType("${DocumentType.WEB}")`, linearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.WEB}")`, } }, // Only when Web is selected - { title: "Schema", icon: "schema", toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), funcs: {hidden: `!SelectionManager_selectedDocType(undefined, "${CollectionViewType.Schema}")`, linearViewIsExpanded: `SelectionManager_selectedDocType(undefined, "${CollectionViewType.Schema}")`} } // Only when Schema is selected + { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), funcs: {hidden: 'false', linearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.RTF}")`} }, // Always available + { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), funcs: {hidden: 'false', linearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.INK}")`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available + { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), funcs: {hidden: `!SelectionManager_selectedDocType("${DocumentType.WEB}")`, linearViewIsExpanded: `SelectionManager_selectedDocType("${DocumentType.WEB}")`, } }, // Only when Web is selected + { title: "Schema", icon: "Schema", toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), funcs: {hidden: `!SelectionManager_selectedDocType(undefined, "${CollectionViewType.Schema}")`, linearViewIsExpanded: `SelectionManager_selectedDocType(undefined, "${CollectionViewType.Schema}")`} } // Only when Schema is selected ]; } @@ -717,13 +704,13 @@ export class CurrentUserUtils { return this.setupContextMenuButton(params, menuBtnDoc); } else { const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, - childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: true, + childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: params.scripts?.onClick ? false : true, linearViewSubMenu: true, linearViewExpandable: true, }; const items = params.subMenu?.map(sub => this.setupContextMenuButton(sub, DocListCast(menuBtnDoc?.data).find(doc => doc.title === sub.title)) ); return DocUtils.AssignScripts( - DocUtils.AssignDocField(ctxtMenuBtnsDoc, StrCast(params.title), (opts) => this.linearButtonList(opts, items??[]), reqdSubMenuOpts, items), undefined, params.funcs); + DocUtils.AssignDocField(ctxtMenuBtnsDoc, StrCast(params.title), (opts) => this.linearButtonList(opts, items??[]), reqdSubMenuOpts, items), params.scripts, params.funcs); } }); return DocUtils.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts, ctxtMenuBtns); @@ -768,7 +755,7 @@ export class CurrentUserUtils { 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, + childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 0, _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'" @@ -952,6 +939,8 @@ ScriptingGlobals.add(function MySharedDocs() { return Doc.MySharedDocs; }, "docu ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode"); ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering"); ScriptingGlobals.add(function createNewPresentation() { return MainView.Instance.createNewPresentation(); }, "creates a new presentation when called"); +ScriptingGlobals.add(function openPresentation(pres:Doc) { return MainView.Instance.openPresentation(pres); }, "creates a new presentation when called"); ScriptingGlobals.add(function createNewFolder() { return MainView.Instance.createNewFolder(); }, "creates a new folder in myFiles when called"); ScriptingGlobals.add(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, "returns all the links to the document or its annotations", "(doc: any)"); ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); +ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; });
\ No newline at end of file diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 52b643c04..50190061a 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -154,7 +154,7 @@ export class DocumentManager { CollectionDockingView.AddSplit(doc, 'right'); finished?.(); }; - public jumpToDocument = async ( + public jumpToDocument = ( targetDoc: Doc, // document to display willZoom: boolean, // whether to zoom doc to take up most of screen createViewFunc = DocumentManager.addView, // how to create a view of the doc if it doesn't exist @@ -165,13 +165,13 @@ export class DocumentManager { finished?: () => void, originalTarget?: Doc, noSelect?: boolean, - presZoom?: number - ): Promise<void> => { + presZoomScale?: number + ): void => { originalTarget = originalTarget ?? targetDoc; const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView; const docView = getFirstDocView(targetDoc, originatingDoc); const annotatedDoc = Cast(targetDoc.annotationOn, Doc, null); - const resolvedTarget = targetDoc.type === DocumentType.MARKER ? annotatedDoc ?? targetDoc : targetDoc; // if target is a marker, then focus toggling should apply to the document it's on since the marker itself doesn't have a hidden field + const resolvedTarget = targetDoc.type === DocumentType.MARKER ? annotatedDoc ?? docView?.rootDoc ?? targetDoc : docView?.rootDoc ?? targetDoc; // if target is a marker, then focus toggling should apply to the document it's on since the marker itself doesn't have a hidden field var wasHidden = resolvedTarget.hidden; if (wasHidden) { runInAction(() => { @@ -207,7 +207,7 @@ export class DocumentManager { finished?.(); }; const annoContainerView = (!wasHidden || resolvedTarget !== annotatedDoc) && annotatedDoc && getFirstDocView(annotatedDoc); - const contextDocs = docContext.length ? await DocListCastAsync(docContext[0].data) : undefined; + const contextDocs = docContext.length ? DocListCast(docContext[0].data) : undefined; const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext.lastElement() : undefined; const targetDocContext = contextDoc || annotatedDoc; const targetDocContextView = (targetDocContext && getFirstDocView(targetDocContext)) || (wasHidden && annoContainerView); // if we have an annotation container and the target was hidden, then try again because we just un-hid the document above @@ -218,7 +218,7 @@ export class DocumentManager { annoContainerView.focus(targetDoc, { originalTarget, willZoom, - scale: presZoom, + scale: presZoomScale, afterFocus: (didFocus: boolean) => new Promise<ViewAdjustment>(res => { focusAndFinish(true); @@ -228,7 +228,7 @@ export class DocumentManager { ); return; } else if (!docView && targetDoc.type !== DocumentType.MARKER) { - annoContainerView.focus(targetDoc); // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below + annoContainerView.focus(targetDoc, {}); // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below } } if (focusView) { @@ -237,7 +237,7 @@ export class DocumentManager { focusView.focus(originalTarget ?? targetDoc, { originalTarget, willZoom, - scale: presZoom, + scale: presZoomScale, afterFocus: (didFocus: boolean) => new Promise<ViewAdjustment>(res => { focusAndFinish(forceDidFocus || didFocus); @@ -265,7 +265,9 @@ export class DocumentManager { afterFocus: async () => { targetDocContext._viewTransition = undefined; if (targetDocContext.layoutKey === 'layout_icon') { - targetDocContextView.iconify(() => this.jumpToDocument(resolvedTarget ?? targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, finished, originalTarget, noSelect, presZoom)); + targetDocContextView.iconify(() => + this.jumpToDocument(resolvedTarget ?? targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, finished, originalTarget, noSelect, presZoomScale) + ); } return ViewAdjustment.doNothing; }, @@ -309,7 +311,7 @@ export class DocumentManager { const docContextView = this.getFirstDocumentView(docContext[0]); if (docContextView) { return docContextView.iconify(() => - this.jumpToDocument(targetDoc, willZoom, createViewFunc, docContext.slice(1, docContext.length), linkDoc, closeContextIfNotFound, originatingDoc, finished, originalTarget, noSelect, presZoom) + this.jumpToDocument(targetDoc, willZoom, createViewFunc, docContext.slice(1, docContext.length), linkDoc, closeContextIfNotFound, originatingDoc, finished, originalTarget, noSelect, presZoomScale) ); } } @@ -335,7 +337,7 @@ export function DocFocusOrOpen(doc: Doc, collectionDoc?: Doc) { const showDoc = context || doc; const bestAlias = showDoc === Doc.GetProto(showDoc) ? DocListCast(showDoc.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail) : showDoc; - CollectionDockingView.AddSplit(bestAlias ? bestAlias : Doc.MakeAlias(showDoc), 'right') && context && setTimeout(() => DocumentManager.Instance.getDocumentView(Doc.GetProto(doc))?.focus(doc)); + CollectionDockingView.AddSplit(bestAlias ? bestAlias : Doc.MakeAlias(showDoc), 'right') && context && setTimeout(() => DocumentManager.Instance.getDocumentView(Doc.GetProto(doc))?.focus(doc, {})); } } ScriptingGlobals.add(DocFocusOrOpen); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6386c87a0..664933de0 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -344,8 +344,7 @@ export namespace DragManager { } Object.assign(dragDiv.style, { width: '', height: '', overflow: '' }); dragDiv.hidden = false; - const scaleXs: number[] = [], - scaleYs: number[] = [], + const scalings: number[] = [], xs: number[] = [], ys: number[] = []; @@ -355,8 +354,18 @@ export namespace DragManager { top: Number.MAX_SAFE_INTEGER, bottom: Number.MIN_SAFE_INTEGER, }; + let rot = 0; const docsToDrag = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : []; const dragElements = eles.map(ele => { + let useDim = false; + if (ele?.parentElement?.parentElement?.parentElement?.className === 'collectionFreeFormDocumentView-container') { + ele = ele.parentElement.parentElement.parentElement; + const rotStr = ele.style.transform.replace(/.*rotate\(([-0-9.]*)deg\).*/, '$1'); + if (rotStr) rot = Number(rotStr); + } else { + useDim = true; + } + if (rot < 0) rot += 360; if (!ele.parentNode) dragDiv.appendChild(ele); const dragElement = ele.parentNode === dragDiv ? ele : (ele.cloneNode(true) as HTMLElement); const children = Array.from(dragElement.children); @@ -376,17 +385,28 @@ export namespace DragManager { } } const rect = ele.getBoundingClientRect(); - const scaleX = rect.width / (ele.offsetWidth || rect.width); - const scaleY = scaleX; //ele.offsetHeight ? rect.height / (ele.offsetHeight || rect.height) : scaleX; + const w = ele.offsetWidth || rect.width; + const h = ele.offsetHeight || rect.height; + const rotR = -(rot / 180) * Math.PI; + const tl = [0, 0]; + const tr = [Math.cos(rotR) * w, Math.sin(-rotR) * w]; + const bl = [Math.sin(rotR) * h, Math.cos(-rotR) * h]; + const br = [Math.cos(rotR) * w + Math.sin(rotR) * h, Math.cos(-rotR) * h - Math.sin(rotR) * w]; + const minx = Math.min(tl[0], tr[0], br[0], bl[0]); + const maxx = Math.max(tl[0], tr[0], br[0], bl[0]); + const miny = Math.min(tl[1], tr[1], br[1], bl[1]); + const maxy = Math.max(tl[1], tr[1], br[1], bl[1]); + const scaling = rect.width / (Math.abs(maxx - minx) || 1); elesCont.left = Math.min(rect.left, elesCont.left); elesCont.top = Math.min(rect.top, elesCont.top); elesCont.right = Math.max(rect.right, elesCont.right); elesCont.bottom = Math.max(rect.bottom, elesCont.bottom); - xs.push(rect.left + (options?.offsetX || 0)); - ys.push(rect.top + (options?.offsetY || 0)); - scaleXs.push(scaleX); - scaleYs.push(scaleY); + xs.push(((0 - minx) / (maxx - minx)) * rect.width + rect.left); + ys.push(((0 - miny) / (maxy - miny)) * rect.height + rect.top); + scalings.push(scaling); + const width = useDim ? getComputedStyle(ele).width : ''; + const height = useDim ? getComputedStyle(ele).height : ''; Object.assign(dragElement.style, { opacity: '0.7', position: 'absolute', @@ -399,9 +419,9 @@ export namespace DragManager { borderRadius: getComputedStyle(ele).borderRadius, zIndex: globalCssVariables.contextMenuZindex, transformOrigin: '0 0', - width: `${rect.width / scaleX}px`, - height: `${rect.height / scaleY}px`, - transform: `translate(${xs[0]}px, ${ys[0]}px) scale(${scaleX}, ${scaleY})`, + width, + height, + transform: `translate(${xs[0]}px, ${ys[0]}px) rotate(${rot}deg) scale(${scaling})`, }); dragLabel.style.transform = `translate(${xs[0]}px, ${ys[0] - 20}px)`; @@ -542,7 +562,7 @@ export namespace DragManager { const moveVec = { x: x - lastPt.x, y: y - lastPt.y }; lastPt = { x, y }; - dragElements.map((dragElement, i) => (dragElement.style.transform = `translate(${(xs[i] += moveVec.x)}px, ${(ys[i] += moveVec.y)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)); + dragElements.map((dragElement, i) => (dragElement.style.transform = `translate(${(xs[i] += moveVec.x)}px, ${(ys[i] += moveVec.y)}px) rotate(${rot}deg) scale(${scalings[i]})`)); dragLabel.style.transform = `translate(${xs[0]}px, ${ys[0] - 20}px)`; }; const upHandler = (e: PointerEvent) => { diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 4af51b9a0..85700da37 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -230,58 +230,33 @@ export namespace InteractionUtils { points.push({ X: right, Y: bottom }); points.push({ X: left, Y: bottom }); points.push({ X: left, Y: top }); + break; case 'triangle': - // points.push({ X: left, Y: bottom }); - // points.push({ X: right, Y: bottom }); - // points.push({ X: (right + left) / 2, Y: top }); - // points.push({ X: left, Y: bottom }); - - points.push({ X: left, Y: bottom }); points.push({ X: left, Y: bottom }); - - points.push({ X: right, Y: bottom }); - points.push({ X: right, Y: bottom }); points.push({ X: right, Y: bottom }); - points.push({ X: right, Y: bottom }); - - points.push({ X: (right + left) / 2, Y: top }); - points.push({ X: (right + left) / 2, Y: top }); points.push({ X: (right + left) / 2, Y: top }); - points.push({ X: (right + left) / 2, Y: top }); - - points.push({ X: left, Y: bottom }); points.push({ X: left, Y: bottom }); + break; case 'circle': const centerX = (Math.max(left, right) + Math.min(left, right)) / 2; const centerY = (Math.max(top, bottom) + Math.min(top, bottom)) / 2; const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom)); - if (centerX - Math.min(left, right) < centerY - Math.min(top, bottom)) { - for (var y = Math.min(top, bottom); y < Math.max(top, bottom); y++) { - const x = Math.sqrt(Math.pow(radius, 2) - Math.pow(y - centerY, 2)) + centerX; - points.push({ X: x, Y: y }); - } - for (var y = Math.max(top, bottom); y > Math.min(top, bottom); y--) { - const x = Math.sqrt(Math.pow(radius, 2) - Math.pow(y - centerY, 2)) + centerX; - const newX = centerX - (x - centerX); - points.push({ X: newX, Y: y }); - } - points.push({ X: Math.sqrt(Math.pow(radius, 2) - Math.pow(Math.min(top, bottom) - centerY, 2)) + centerX, Y: Math.min(top, bottom) }); - } else { - for (var x = Math.min(left, right); x < Math.max(left, right); x++) { - const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY; - points.push({ X: x, Y: y }); - } - for (var x = Math.max(left, right); x > Math.min(left, right); x--) { - const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY; - const newY = centerY - (y - centerY); - points.push({ X: x, Y: newY }); - } - points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - Math.pow(Math.min(left, right) - centerX, 2)) + centerY }); + for (var x = Math.min(left, right); x < Math.max(left, right); x++) { + const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY; + points.push({ X: x, Y: y }); } + for (var x = Math.max(left, right); x > Math.min(left, right); x--) { + const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x - centerX, 2)) + centerY; + const newY = centerY - (y - centerY); + points.push({ X: x, Y: newY }); + } + points.push({ X: Math.min(left, right), Y: Math.sqrt(Math.pow(radius, 2) - Math.pow(Math.min(left, right) - centerX, 2)) + centerY }); + break; + case 'line': points.push({ X: left, Y: top }); points.push({ X: right, Y: bottom }); - return points; + break; } return points; } diff --git a/src/client/util/ReportManager.tsx b/src/client/util/ReportManager.tsx index 55c5ca87f..51742d455 100644 --- a/src/client/util/ReportManager.tsx +++ b/src/client/util/ReportManager.tsx @@ -57,7 +57,7 @@ export class ReportManager extends React.Component<{}> { ReportManager.Instance = this; this.octokit = new Octokit({ - auth: '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' + auth: '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' }); } @@ -104,6 +104,20 @@ export class ReportManager extends React.Component<{}> { } } + // turns an upload link into a servable link + // ex: + // C: /Users/dash/Documents/GitHub/Dash-Web/src/server/public/files/images/upload_8008dbc4b6424fbff14da7345bb32eb2.png + // -> http://localhost:1050/files/images/upload_8008dbc4b6424fbff14da7345bb32eb2_l.png + private fileLinktoServerLink = (fileLink: string) => { + const serverUrl = 'https://browndash.com/'; + + const regex = 'public' + const publicIndex = fileLink.indexOf(regex) + regex.length; + + const finalUrl = `${serverUrl}${fileLink.substring(publicIndex + 1).replace('.', '_l.')}`; + return finalUrl; + } + public async reportIssue() { if (this.bugTitle === '' || this.bugDescription === '' || this.bugType === '' || this.bugPriority === '') { @@ -111,14 +125,15 @@ export class ReportManager extends React.Component<{}> { return; } - if (this.toGithub) { + const formattedLinks = (this.fileLinks ?? []).map(this.fileLinktoServerLink) + const req = await this.octokit.request('POST /repos/{owner}/{repo}/issues', { owner: 'brown-dash', repo: 'Dash-Web', title: this.formatTitle(this.bugTitle, Doc.CurrentUserEmail), - body: `${this.bugDescription} \n\nfiles:\n${(this.fileLinks ?? []).join('\n')}`, + body: `${this.bugDescription} \n\nfiles:\n${formattedLinks.join('\n')}`, labels: [ 'from-dash-app', this.bugType, @@ -140,7 +155,7 @@ export class ReportManager extends React.Component<{}> { // if we're down here, then we're good to go. reset the fields. this.setBugTitle(''); this.setBugDescription(''); - this.toGithub = false; + // this.toGithub = false; this.setFileLinks([]); this.setBugType(''); this.setBugPriority(''); @@ -176,10 +191,10 @@ export class ReportManager extends React.Component<{}> { (<div className="settings-content"> <h3 style={{ 'textDecoration': 'underline'}}>Report an Issue</h3> <label>Please leave a title for the bug.</label><br /> - <input type="text" placeholder='title' onChange={(e) => this.bugTitle = e.target.value} required/> + <input type="text" placeholder='title' onChange={(e) => this.setBugTitle(e.target.value)} required/> <br /> <label>Please leave a description for the bug and how it can be recreated.</label> - <textarea placeholder='description' onChange={(e) => this.bugDescription = e.target.value} required/> + <textarea placeholder='description' onChange={(e) => this.setBugDescription(e.target.value)} required/> <br /> {/* {<label>Send to github issues? </label> <input type="checkbox" onChange={(e) => this.toGithub = e.target.checked} /> @@ -187,14 +202,14 @@ export class ReportManager extends React.Component<{}> { <label>Please label the issue</label> <div className='flex-select'> - <select name="bugType"> + <select name="bugType" onChange={e => this.bugType = e.target.value}> <option value="" disabled selected>Type</option> <option value="bug">Bug</option> <option value="cosmetic">Poor Design or Cosmetic</option> <option value="documentation">Poor Documentation</option> </select> - <select name="bigPriority"> + <select name="bigPriority" onChange={e => this.bugPriority = e.target.value}> <option value="" disabled selected>Priority</option> <option value="priority-low">Low</option> <option value="priority-medium">Medium</option> @@ -205,7 +220,7 @@ export class ReportManager extends React.Component<{}> { <div> <label>Upload media that shows the bug (optional)</label> - <input type="file" name="file" multiple accept='audio/*, video/*' onChange={e => this.uploadFiles(e.target)}/> + <input type="file" name="file" multiple accept='audio/*, video/*, image/*' onChange={e => this.uploadFiles(e.target)}/> </div> <br /> diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index ea2bf6551..6dcdcb71b 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -7,6 +7,8 @@ import * as typescriptlib from '!!raw-loader!./type_decls.d'; import * as ts from 'typescript'; import { Doc, Field } from '../../fields/Doc'; +import { ObjectField } from '../../fields/ObjectField'; +import { ScriptField } from '../../fields/ScriptField'; import { scriptingGlobals, ScriptingGlobals } from './ScriptingGlobals'; export { ts }; @@ -177,6 +179,10 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde } export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult { + const captured = options.capturedVariables ?? {}; + const signature = Object.keys(captured).reduce((p, v) => p + `${v}=${captured[v] instanceof ObjectField ? 'XXX' : captured[v].toString()}`, ''); + const found = ScriptField.GetScriptFieldCache(script + ':' + signature); + if (found) return found as CompiledScript; const { requiredType = '', addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options; if (options.params && !options.params.this) options.params.this = Doc.name; if (options.params && !options.params.self) options.params.self = Doc.name; @@ -241,6 +247,8 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp if (options.globals) { ScriptingGlobals.resetScriptingGlobals(); } + !signature.includes('XXX') && ScriptField._scriptFieldCache.set(script + ':' + signature, result as CompiledScript); + //console.log('COMPILED: ' + script + ':' + signature); return result; } diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 7a555d5f8..a3d6f5227 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -91,7 +91,7 @@ export namespace SelectionManager { } export function Views(): Array<DocumentView> { - return Array.from(manager.SelectedViews.keys()).filter(dv => manager.SelectedViews.get(dv)?._viewType !== CollectionViewType.Docking); + return Array.from(manager.SelectedViews.keys()); //.filter(dv => manager.SelectedViews.get(dv)?._viewType !== CollectionViewType.Docking); } export function SelectedSchemaDoc(): Doc | undefined { return manager.SelectedSchemaDocument; diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index cf143c5e8..a185c8936 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -30,7 +30,7 @@ export enum ColorScheme { export class SettingsManager extends React.Component<{}> { public static Instance: SettingsManager; static _settingsStyle = addStyleSheet(); - @observable private isOpen = false; + @observable public isOpen = false; @observable private passwordResultText = ''; @observable private playgroundMode = false; diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss index 2de636f21..932e94664 100644 --- a/src/client/util/SharingManager.scss +++ b/src/client/util/SharingManager.scss @@ -107,7 +107,7 @@ .user-sort { text-align: left; margin-left: 10; - width: 100px; + width: 100%; cursor: pointer; } @@ -122,6 +122,7 @@ background: #e8e8e8; padding-left: 10px; padding-right: 10px; + width: 100%; overflow-y: scroll; overflow-x: hidden; text-align: left; diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 895bd3374..4b0310e76 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -374,7 +374,7 @@ export class SharingManager extends React.Component<{}> { if (!uniform) dropdownValues.unshift('-multiple-'); if (override) dropdownValues.unshift('None'); return dropdownValues - .filter(permission => !Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)) + .filter(permission => !Doc.noviceMode || ![SharingPermissions.SelfEdit].includes(permission as any)) .map(permission => ( <option key={permission} value={permission}> {permission} diff --git a/src/client/util/request-image-size.js b/src/client/util/request-image-size.js index beb030635..502e0fbac 100644 --- a/src/client/util/request-image-size.js +++ b/src/client/util/request-image-size.js @@ -15,15 +15,18 @@ const HttpError = require('standard-http-error'); module.exports = function requestImageSize(options) { let opts = { - encoding: null + encoding: null, }; if (options && typeof options === 'object') { opts = Object.assign(options, opts); } else if (options && typeof options === 'string') { - opts = Object.assign({ - uri: options - }, opts); + opts = Object.assign( + { + uri: options, + }, + opts + ); } else { return Promise.reject(new Error('You should provide an URI string or a "request" options object.')); } @@ -38,9 +41,8 @@ module.exports = function requestImageSize(options) { return reject(new HttpError(res.statusCode, res.statusMessage)); } - let buffer = new Buffer.from([]); + let buffer = Buffer.from([]); let size; - let imageSizeError; res.on('data', chunk => { buffer = Buffer.concat([buffer, chunk]); @@ -48,8 +50,8 @@ module.exports = function requestImageSize(options) { try { size = imageSize(buffer); } catch (err) { - imageSizeError = err; - return; + reject(err); + return req.abort(); } if (size) { @@ -58,11 +60,11 @@ module.exports = function requestImageSize(options) { } }); - res.on('error', err => reject(err)); + res.on('error', reject); res.on('end', () => { if (!size) { - return reject(imageSizeError); + return reject(new Error('Image has no size')); } size.downloaded = buffer.length; @@ -70,6 +72,6 @@ module.exports = function requestImageSize(options) { }); }); - req.on('error', err => reject(err)); + req.on('error', reject); }); -};
\ No newline at end of file +}; |
