aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/CaptureManager.tsx2
-rw-r--r--src/client/util/CurrentUserUtils.ts94
-rw-r--r--src/client/util/DocumentManager.ts4
-rw-r--r--src/client/util/DropConverter.ts45
-rw-r--r--src/client/util/LinkFollower.ts24
-rw-r--r--src/client/util/LinkManager.ts42
-rw-r--r--src/client/util/RTFMarkup.tsx34
-rw-r--r--src/client/util/Scripting.ts11
-rw-r--r--src/client/util/SettingsManager.tsx3
-rw-r--r--src/client/util/SnappingManager.ts5
-rw-r--r--src/client/util/UndoManager.ts21
11 files changed, 155 insertions, 130 deletions
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 2e13aff2f..8451357ef 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -2,9 +2,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { addStyleSheet } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { DocCast, StrCast } from '../../fields/Types';
-import { addStyleSheet } from '../../Utils';
import { LightboxView } from '../views/LightboxView';
import { MainViewModal } from '../views/MainViewModal';
import './CaptureManager.scss';
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 18b37ffd1..21b74e30c 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -74,7 +74,7 @@ export class CurrentUserUtils {
};
const reqdScripts = { dropConverter : "convertToButtons(dragData)" };
const reqdFuncs = { /* hidden: "IsNoviceMode()" */ };
- return DocUtils.AssignScripts(DocUtils.AssignOpts(userDocTemplates, reqdOpts, userTemplates) ?? Docs.Create.MasonryDocument(userTemplates, reqdOpts), reqdScripts, reqdFuncs);
+ return DocUtils.AssignScripts(userDocTemplates ?? Docs.Create.MasonryDocument(userTemplates, reqdOpts), reqdScripts, reqdFuncs);
}
/// Initializes templates for editing click funcs of a document
@@ -122,9 +122,9 @@ export class CurrentUserUtils {
static setupNoteTemplates(doc: Doc, field="template_notes") {
const tempNotes = DocCast(doc[field]);
const reqdTempOpts:DocumentOptions[] = [
- { title: "Postit", backgroundColor: "yellow", icon: "sticky-note"},
- { title: "Idea", backgroundColor: "pink", icon: "lightbulb" },
- { title: "Topic", backgroundColor: "lightblue", icon: "book-open" }];
+ { title: "Postit", backgroundColor: "yellow", icon: "sticky-note", _layout_showTitle: "title", layout_borderRounding: "5px"},
+ { title: "Idea", backgroundColor: "pink", icon: "lightbulb" , _layout_showTitle: "title"},
+ { title: "Topic", backgroundColor: "lightblue", icon: "book-open" , _layout_showTitle: "title"}];
const reqdNoteList = [...reqdTempOpts.map(opts => {
const reqdOpts = {...opts, isSystem:true, width:200, layout_autoHeight: true, layout_fitWidth: true};
const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.title === opts.title): undefined;
@@ -134,11 +134,19 @@ export class CurrentUserUtils {
const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, isSystem: true };
return DocUtils.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts));
}
+ static setupUserTemplates(doc: Doc, field="template_user") {
+ const tempUsers = DocCast(doc[field]);
+ const reqdUserList = DocListCast(tempUsers?.data);
+
+ const reqdOpts:DocumentOptions = { title: "User Layouts", _height: 75, isSystem: true };
+ return DocUtils.AssignOpts(tempUsers, reqdOpts, reqdUserList) ?? (doc[field] = Docs.Create.TreeDocument(reqdUserList, reqdOpts));
+ }
/// Initializes collection of templates for notes and click functions
static setupDocTemplates(doc: Doc, field="myTemplates") {
const templates = [
CurrentUserUtils.setupNoteTemplates(doc),
+ CurrentUserUtils.setupUserTemplates(doc),
CurrentUserUtils.setupClickEditorTemplates(doc)
];
CurrentUserUtils.setupChildClickEditors(doc)
@@ -213,34 +221,26 @@ export class CurrentUserUtils {
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: "Untitled Header",
- 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' backgroundColor='{this._headerColor || MySharedDocs().userColor||`lightGray`}' />" +
- ` <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' backgroundColor='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(0,this._height-30),this._headerHeight===0?50:0)) + (this._layout_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)'/>" +
+ // " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._header_pointerEvents||`none`}' fontSize='{this._header_fontSize}px' height='{this._header_height}px' background='{this._header_color}' />" +
+ // " <FormattedTextBox {...props} fieldKey={'text'} position='absolute' top='{(this._header_height)*scale}px' height='calc({100/scale}% - {this._header_height}px)'/>" +
// "</div>";
- MakeTemplate(Doc.GetProto(header));
- return header;
- }
- const slideView = (opts:DocumentOptions) => {
- const slide = Docs.Create.MultirowDocument(
+ const headerBtnHgt = 10;
+ const headerTemplate = (opts:DocumentOptions) =>
+ MakeTemplate(Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { ...opts, title: "Header Template",
+ 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._header_height||0}px)' />
+ <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._header_fontSize||9}px' height='{(this._header_height||0)}px' backgroundColor='{this._header_color || "lightGray"}' />
+ <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' backgroundColor='yellow' onClick={‘(this._header_height=Math.min(Math.max(0,this._height-30),this._header_height===0?50:0)) + (this._layout_autoHeightMargins=this._header_height ? this._header_height+${headerBtnHgt}:0)’} > Metadata</HTMLdiv>
+ </HTMLdiv>`
+ }, "header"));
+ const slideView = (opts:DocumentOptions) =>
+ MakeTemplate(Docs.Create.MultirowDocument(
[
Docs.Create.MulticolumnDocument([], { title: "hero", _height: 200, isSystem: true }),
Docs.Create.TextDocument("", { title: "text", _layout_fitWidth:true, _height: 100, isSystem: true, _text_fontFamily: StrCast(Doc.UserDoc().fontFamily), _text_fontSize: StrCast(Doc.UserDoc().fontSize) })
- ], {...opts, title: "Untitled Slide View"});
-
- MakeTemplate(Doc.GetProto(slide));
- return slide;
- }
+ ], {...opts, title: "Slide View Template"}));
const plotlyApi = () => {
var plotly = Doc.MyPublishedDocs.find(doc => doc.title === "@plotly");
if (!plotly) {
@@ -277,7 +277,7 @@ export class CurrentUserUtils {
slide[DocData].text = rtfield;
slide[DocData].layout_textPainted = `<CollectionView {...props} fieldKey={'text'}/>`;
slide[DocData]._type_collection = CollectionViewType.Freeform;
- slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted", "")`, {documentView:"any"});
+ slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"});
return slide;
}
const mermaidsApi = () => {
@@ -314,9 +314,9 @@ export class CurrentUserUtils {
{type:"text",text:" "},
{type:"text",text:"Minerals in my tap water"},
{type:"text",text:"\n \"Calcium\" : "},
- {type:"dashField",attrs:{fieldKey:"calcium",docId:"","hideKey":false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"calcium",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Potassium\" : "},
- {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Magnesium\" : 10.01"}
]}
]},
@@ -331,7 +331,7 @@ pie title Minerals in my tap water
slide[DocData].text = rtfield;
slide[DocData].layout_textPainted = `<CollectionView {...props} fieldKey={'text'}/>`;
slide[DocData]._type_collection = CollectionViewType.Freeform;
- slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted", "")`, {documentView:"any"});
+ slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"});
return slide;
}
const apis = [plotlyApi(), mermaidsApi()]
@@ -342,6 +342,7 @@ pie title Minerals in my tap water
creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist
}[] = [
{key: "Note", creator: opts => Docs.Create.TextDocument("", opts), opts: { _width: 200, _layout_autoHeight: true }},
+ {key: "Image", creator: opts => Docs.Create.ImageDocument("", opts), opts: { _width: 400, _height:400 }},
{key: "Flashcard", creator: opts => Docs.Create.TextDocument("", opts), opts: { _width: 200, _layout_autoHeight: true, _layout_enableAltContentUI: true}},
{key: "Equation", creator: opts => Docs.Create.EquationDocument("",opts), opts: { _width: 300, _height: 35, }},
{key: "Noteboard", creator: opts => Docs.Create.NoteTakingDocument([], opts), opts: { _width: 250, _height: 200, _layout_fitWidth: true}},
@@ -351,13 +352,14 @@ pie title Minerals in my tap water
{key: "Comparison", creator: Docs.Create.ComparisonDocument, opts: { _width: 300, _height: 300 }},
{key: "Diagram", creator: Docs.Create.DiagramDocument, opts: { _width: 300, _height: 300, _type_collection: CollectionViewType.Freeform, layout_diagramEditor: CollectionView.LayoutString("data") }, scripts: { onPaint: `toggleDetail(documentView, "diagramEditor","")`}},
{key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, }},
+ {key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, _layout_fitWidth: true, }},
{key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, }},
{key: "Screengrab", creator: Docs.Create.ScreenshotDocument, opts: { _width: 400, _height: 200 }},
{key: "WebCam", creator: opts => Docs.Create.WebCamDocument("", opts), opts: { _width: 400, _height: 200, recording:true, isSystem: true, cloneFieldFilter: new List<string>(["isSystem"]) }},
{key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, title_custom: true, waitForDoubleClickToClick: 'never'}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}},
{key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
{key: "DataViz", creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts), opts: { _width: 300, _height: 300 }},
- {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _layout_autoHeight: true, treeView_HideUnrendered: true}},
+ {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}},
{key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}},
{key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }},
{key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _layout_fitWidth: true, _freeform_backgroundGrid: true, }},
@@ -380,9 +382,10 @@ pie title Minerals in my tap water
{ toolTip: "Tap or drag to create a flashcard", title: "Flashcard", icon: "id-card", dragFactory: doc.emptyFlashcard as Doc, clickFactory: DocCast(doc.emptyFlashcard)},
{ toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, clickFactory: DocCast(doc.emptyEquation)},
{ toolTip: "Tap or drag to create a mermaid node", title: "Mermaids", icon: "rocket", dragFactory: doc.emptyMermaids as Doc, clickFactory: DocCast(doc.emptyMermaids)},
- { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)},
+ { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)},
{ toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}},
- { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "folder", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
+ { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
+ { toolTip: "Tap or drag to create an iamge", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)},
{ toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)},
{ toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)},
{ toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)},
@@ -391,10 +394,10 @@ pie title Minerals in my tap water
{ toolTip: "Tap or drag to create a map", title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, clickFactory: DocCast(doc.emptyMap)},
{ toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, clickFactory: DocCast(doc.emptyWebCam), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
- { toolTip: "Tap or drag to create a button", title: "Button", icon: "circle", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)},
+ { toolTip: "Tap or drag to create a button", title: "Button", icon: "circle", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)},
{ toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
- { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "file", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
+ { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "person-chalkboard", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc,clickFactory: DocCast(doc.emptyViewSlide),openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} },
{ toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '<ScriptingRepl />' as any, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
@@ -721,8 +724,6 @@ pie title Minerals in my tap water
{ title: "Grid", icon: "border-all", toolTip: "Show Grid", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"grid", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
{ title: "Fit All", icon: "object-group", toolTip: "Fit Docs to View (double click to make sticky)",btnType: ButtonType.ToggleButton, ignoreClick:true, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}', onDoubleClick: '{ return showFreeform(this.toolType, _readOnly_, true);}'}}, // Only when floating document is selected in freeform
{ title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
- { title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
- { title: "Arrange", icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
]
}
static textTools():Button[] {
@@ -731,7 +732,7 @@ pie title Minerals in my tap water
btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) },
{ title: "Font Size",toolTip: "Font size (%size)", btnType: ButtonType.NumberDropdownButton, toolType:"fontSize", ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 6 },
{ title: "Color", toolTip: "Font color (%color)", btnType: ButtonType.ColorButton, icon: "font", toolType:"fontColor",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}},
- { title: "Highlight",toolTip: "Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} },
+ { title: "Highlight",toolTip: "Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}},
{ title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", toolType:"bold", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", toolType:"italics", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", toolType:"underline",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
@@ -744,6 +745,7 @@ pie title Minerals in my tap water
{ title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
]},
+ { title: "Elide", toolTip: "Elide selection", btnType: ButtonType.ToggleButton, icon: "eye", toolType:"elide", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}},
{ title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}},
{ title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink", expertMode:true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
// { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
@@ -761,6 +763,7 @@ pie title Minerals in my tap water
{ title: "Square", toolTip: "Square (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "square", toolType:GestureUtils.Gestures.Rectangle, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
{ title: "Line", toolTip: "Line (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "minus", toolType:GestureUtils.Gestures.Line, scripts: {onClick:`{ return setActiveTool(this.toolType, false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool(this.toolType, true, _readOnly_);}`} },
{ title: "Mask", toolTip: "Mask", btnType: ButtonType.ToggleButton, icon: "user-circle",toolType: "inkMask", scripts: {onClick:'{ return setInkProperty(this.toolType, value, _readOnly_);}'}, funcs: {hidden:"IsNoviceMode()" } },
+ { title: "Labels", toolTip: "Lab els", btnType: ButtonType.ToggleButton, icon: "text-width", toolType: "labels", scripts: {onClick:'{ return setInkProperty(this.toolType, value, _readOnly_);}'}, },
{ title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberSliderButton, toolType: "strokeWidth", ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'}, numBtnMin: 1},
{ title: "Ink", toolTip: "Stroke color", btnType: ButtonType.ColorButton, icon: "pen", toolType: "strokeColor", ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'} },
];
@@ -769,7 +772,7 @@ pie title Minerals in my tap water
static schemaTools():Button[] {
return [
{title: "Preview", toolTip: "Show selection preview", btnType: ButtonType.ToggleButton, icon: "portrait", scripts:{ onClick: '{ return toggleSchemaPreview(_readOnly_); }'} },
- {title: "1 Line", toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} },
+ {title: "1 Line", toolTip: "Single Line Rows", btnType: ButtonType.ToggleButton, icon: "eye", scripts:{ onClick: '{ return toggleSingleLineSchema(_readOnly_); }'} },
{title: "DataViz", toolTip: "Turn Schema Table into Data Visualization Doc", btnType: ButtonType.ClickButton, icon: "chart-bar", scripts:{ onClick: '{ datavizFromSchema()'} }, ];
}
@@ -777,12 +780,18 @@ pie title Minerals in my tap water
return [
{ title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", scripts: { onClick: '{ return webBack(); }' }},
{ title: "Forward", toolTip: "Go forward", btnType: ButtonType.ClickButton, icon: "arrow-right", scripts: { onClick: '{ return webForward(); }'}},
- { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, scripts: { script: '{ return webSetURL(value, _readOnly_); }'} },
+ { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, scripts: { script: '{ return webSetURL(value, _readOnly_); }'} },
];
}
static videoTools() {
return [
- { title: "Snapshot",toolTip: "Take snapshot of current frame", btnType: ButtonType.ClickButton, icon: "camera", scripts: { onClick: '{ return videoSnapshot(); }' }},
+ { title: "Snapshot",toolTip: "Take snapshot of current frame", btnType: ButtonType.ClickButton, icon: "camera", scripts: { onClick: '{ return videoSnapshot(); }' }},
+ ];
+ }
+ static imageTools() {
+ return [
+ { title: "Pixels",toolTip: "Set Native Pixel Sizze", btnType: ButtonType.ClickButton, icon: "portrait", scripts: { onClick: 'imageSetPixelSize();' }},
+ { title: "Rotate",toolTip: "Rotate 90", btnType: ButtonType.ClickButton, icon: "redo-alt", scripts: { onClick: 'imageRotate90();' }},
];
}
static contextMenuTools():Button[] {
@@ -807,7 +816,8 @@ pie title Minerals in my tap water
{ title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
- { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
+ { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when video is selected
+ { title: "Image", icon: "Image", toolTip: "Image functions", subMenu: CurrentUserUtils.imageTools(), expertMode: false, toolType:DocumentType.IMG, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when image is selected
{ title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Schema is selected
];
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index a38a330da..40d28c690 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -59,7 +59,7 @@ export class DocumentManager {
private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => any }[] = [];
public AddViewRenderedCb = (doc: Opt<Doc>, func: (dv: DocumentView) => any) => {
if (doc) {
- const dv = this.getDocumentView(doc);
+ const dv = LightboxView.LightboxDoc ? this.getLightboxDocumentView(doc) : this.getDocumentView(doc);
this._viewRenderedCbs.push({ doc, func });
if (dv) {
this.callAddViewFuncs(dv);
@@ -262,7 +262,7 @@ export class DocumentManager {
return res(this.getDocumentView(docContextPath[0])!);
}
options.didMove = true;
- docContextPath.some(doc => TabDocView.Activate(doc)) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
+ (!LightboxView.LightboxDoc && docContextPath.some(doc => TabDocView.Activate(doc))) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
this.AddViewRenderedCb(docContextPath[0], dv => res(dv));
}));
if (options.openLocation === OpenWhere.lightbox) {
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 3df3e36c6..ed5749d06 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -28,6 +28,7 @@ export function MakeTemplate(doc: Doc) {
}
/**
+ *
* Recursively converts 'doc' into a template that can be used to render other documents.
*
* For recurive Docs in the template, their target fieldKey is defined by their title,
@@ -75,32 +76,36 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
remProps.map(prop => (dbox[prop] = undefined));
}
} else if (!doc.onDragStart && !doc.isButtonBar) {
- const layoutDoc = doc; // doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
- if (layoutDoc.type !== DocumentType.FONTICON) {
- !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
- }
- layoutDoc.isTemplateDoc = true;
- dbox = Docs.Create.FontIconDocument({
- _nativeWidth: 100,
- _nativeHeight: 100,
- _width: 100,
- _height: 100,
- backgroundColor: StrCast(doc.backgroundColor),
- title: StrCast(layoutDoc.title),
- btnType: ButtonType.ClickButton,
- icon: 'bolt',
- isSystem: false,
- });
- dbox.title = ComputedField.MakeFunction('this.dragFactory.title');
- dbox.dragFactory = layoutDoc;
- dbox.dropPropertiesToRemove = doc.dropPropertiesToRemove instanceof ObjectField ? ObjectField.MakeCopy(doc.dropPropertiesToRemove) : undefined;
- dbox.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory)');
+ dbox = makeUserTemplateButton(doc);
} else if (doc.isButtonBar) {
dbox.ignoreClick = true;
}
data.droppedDocuments[i] = dbox;
});
}
+export function makeUserTemplateButton(doc: Doc) {
+ const layoutDoc = doc; // doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
+ if (layoutDoc.type !== DocumentType.FONTICON) {
+ !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
+ }
+ layoutDoc.isTemplateDoc = true;
+ const dbox = Docs.Create.FontIconDocument({
+ _nativeWidth: 100,
+ _nativeHeight: 100,
+ _width: 100,
+ _height: 100,
+ backgroundColor: StrCast(doc.backgroundColor),
+ title: StrCast(layoutDoc.title),
+ btnType: ButtonType.ClickButton,
+ icon: 'bolt',
+ isSystem: false,
+ });
+ dbox.title = ComputedField.MakeFunction('this.dragFactory.title');
+ dbox.dragFactory = layoutDoc;
+ dbox.dropPropertiesToRemove = doc.dropPropertiesToRemove instanceof ObjectField ? ObjectField.MakeCopy(doc.dropPropertiesToRemove) : undefined;
+ dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory)');
+ return dbox;
+}
ScriptingGlobals.add(
function convertToButtons(dragData: any) {
convertDropDataToButtons(dragData as DragManager.DocumentDragData);
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 20261859c..6c0bf3242 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -110,18 +110,18 @@ export class LinkFollower {
movedTarget = true;
}
Doc.SetContainer(target, sourceDocParent);
- const moveTo = [NumCast(sourceDoc.x) + NumCast(sourceDoc.followLinkXoffset), NumCast(sourceDoc.y) + NumCast(sourceDoc.followLinkYoffset)];
- if (srcAnchor.followLinkXoffset !== undefined && moveTo[0] !== target.x) {
- target.x = moveTo[0];
- movedTarget = true;
- }
- if (srcAnchor.followLinkYoffset !== undefined && moveTo[1] !== target.y) {
- target.y = moveTo[1];
- movedTarget = true;
- }
- if (movedTarget) setTimeout(doFollow);
- else doFollow(true);
- } else doFollow(true);
+ }
+ const moveTo = [NumCast(sourceDoc.x) + NumCast(sourceDoc.followLinkXoffset), NumCast(sourceDoc.y) + NumCast(sourceDoc.followLinkYoffset)];
+ if (srcAnchor.followLinkXoffset !== undefined && moveTo[0] !== target.x) {
+ target.x = moveTo[0];
+ movedTarget = true;
+ }
+ if (srcAnchor.followLinkYoffset !== undefined && moveTo[1] !== target.y) {
+ target.y = moveTo[1];
+ movedTarget = true;
+ }
+ if (movedTarget) setTimeout(doFollow);
+ else doFollow(true);
} else {
allFinished();
}
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index dd3b9bd07..8972bf705 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -58,8 +58,8 @@ export class LinkManager {
link &&
action(lAnchProtoProtos => {
Doc.AddDocToList(Doc.UserDoc(), 'links', link);
- lAnchs[0] && lAnchs[0][DocData][DirectLinks].add(link);
- lAnchs[1] && lAnchs[1][DocData][DirectLinks].add(link);
+ lAnchs[0]?.[DocData][DirectLinks].add(link);
+ lAnchs[1]?.[DocData][DirectLinks].add(link);
})
)
)
@@ -152,28 +152,44 @@ export class LinkManager {
}
}
public deleteLink(linkDoc: Doc) {
- return Doc.RemoveDocFromList(Doc.LinkDBDoc(), 'data', linkDoc);
+ const ret = Doc.RemoveDocFromList(Doc.LinkDBDoc(), 'data', linkDoc);
+ linkDoc[DocData].link_anchor_1 = linkDoc[DocData].link_anchor_2 = undefined;
+ return ret;
}
public deleteAllLinksOnAnchor(anchor: Doc) {
- LinkManager.Instance.relatedLinker(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc));
+ LinkManager.Instance.relatedLinker(anchor).forEach(LinkManager.Instance.deleteLink);
}
public getAllRelatedLinks(anchor: Doc) {
return this.relatedLinker(anchor);
} // finds all links that contain the given anchor
public getAllDirectLinks(anchor?: Doc): Doc[] {
- return anchor ? Array.from(anchor[DirectLinks]) : [];
+ return anchor ? Array.from(anchor[DocData][DirectLinks]) : [];
} // finds all links that contain the given anchor
- relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] {
+ computedRelatedLinks = (anchor: Doc, processed: Doc[]): Doc[] => {
+ if (Doc.IsSystem(anchor)) return [];
if (!anchor || anchor instanceof Promise || Doc.GetProto(anchor) instanceof Promise) {
console.log('WAITING FOR DOC/PROTO IN LINKMANAGER');
return [];
}
- const dirLinks = Doc.GetProto(anchor)[DirectLinks];
- const annos = DocListCast(anchor[Doc.LayoutFieldKey(anchor) + '_annotations']);
- if (!annos) debugger;
- return annos.reduce((list, anno) => [...list, ...LinkManager.Instance.relatedLinker(anno)], Array.from(dirLinks).slice());
+
+ const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as any));
+ const anchorRoot = DocCast(anchor.rootDocument, anchor); // template Doc fields store annotations on the topmost root of a template (not on themselves since the template layout items are only for layout)
+ const annos = DocListCast(anchorRoot[Doc.LayoutFieldKey(anchor) + '_annotations']);
+ return Array.from(
+ annos.reduce((set, anno) => {
+ if (!processed.includes(anno)) {
+ processed.push(anno);
+ this.computedRelatedLinks(anno, processed).forEach(link => set.add(link));
+ }
+ return set;
+ }, new Set<Doc>(dirLinks))
+ );
+ };
+
+ relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] {
+ return this.computedRelatedLinks(anchor, [anchor]);
}, true);
// returns map of group type to anchor's links in that group type
@@ -208,10 +224,10 @@ export class LinkManager {
const a1 = DocCast(linkDoc.link_anchor_1);
const a2 = DocCast(linkDoc.link_anchor_2);
if (linkDoc.link_matchEmbeddings) {
- return [a2, a2.annotationOn].includes(anchor) ? '2' : '1';
+ return [a2, a2?.annotationOn].includes(anchor) ? '2' : '1';
}
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return '1';
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return '2';
+ if (Doc.AreProtosEqual(DocCast(anchor?.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return '1';
+ if (Doc.AreProtosEqual(DocCast(anchor?.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return '2';
if (Doc.AreProtosEqual(anchor, linkDoc)) return '0';
// const a1 = DocCast(linkDoc.link_anchor_1);
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index f96d8a5df..35b1579df 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -3,18 +3,12 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { MainViewModal } from '../views/MainViewModal';
import { SettingsManager } from './SettingsManager';
-import { Doc } from '../../fields/Doc';
-import { StrCast } from '../../fields/Types';
@observer
export class RTFMarkup extends React.Component<{}> {
static Instance: RTFMarkup;
@observable private isOpen = false; // whether the SharingManager modal is open or not
- // private get linkVisible() {
- // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
- // }
-
@action
public open = () => (this.isOpen = true);
@@ -36,10 +30,14 @@ export class RTFMarkup extends React.Component<{}> {
return (
<div style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, textAlign: 'initial', height: '100%' }}>
<p>
- <b style={{ fontSize: 'larger' }}>{`wiki:phrase`}</b>
+ <b style={{ fontSize: 'larger' }}>{`(@wiki:phrase)`}</b>
{` display wikipedia page for entered text (terminate with carriage return)`}
</p>
<p>
+ <b style={{ fontSize: 'larger' }}>{`(( any text ))`}</b>
+ {` submit text to Chat GPT to have results appended afterward`}
+ </p>
+ <p>
<b style={{ fontSize: 'larger' }}>{`#tag `}</b>
{` add hashtag metadata to document. e.g, #idea`}
</p>
@@ -48,10 +46,6 @@ export class RTFMarkup extends React.Component<{}> {
{` set heading style based on number of '#'s between 1 and 6`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`#tag `}</b>
- {` add hashtag metadata to document. e.g, #idea`}
- </p>
- <p>
<b style={{ fontSize: 'larger' }}>{`>> `}</b>
{` add a sidebar text document inline`}
</p>
@@ -61,7 +55,7 @@ export class RTFMarkup extends React.Component<{}> {
</p>
<p>
<b style={{ fontSize: 'larger' }}>{`cmd-f `}</b>
- {` collapse to an inline footnote)`}
+ {` collapse to an inline footnote`}
</p>
<p>
<b style={{ fontSize: 'larger' }}>{`cmd-e `}</b>
@@ -116,20 +110,20 @@ export class RTFMarkup extends React.Component<{}> {
{` start a block of text that begins with a hanging indent`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[:doctitle]] `}</b>
+ <b style={{ fontSize: 'larger' }}>{`@(doctitle) `}</b>
{` hyperlink to document specified by it’s title`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname]] `}</b>
- {` display value of fieldname`}
+ <b style={{ fontSize: 'larger' }}>{`[@(doctitle.)fieldname] `}</b>
+ {` display value of fieldname of text document (unless (doctitle.) is used to indicate another document by it's title)`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname=value]] `}</b>
- {` assign value to fieldname of document and display it`}
+ <b style={{ fontSize: 'larger' }}>{`[@fieldname:value] `}</b>
+ {` assign value to fieldname to data document and display it (if '=' is used instead of ':' the value is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the response will replace the value)`}
</p>
<p>
- <b style={{ fontSize: 'larger' }}>{`[[fieldname:doctitle]] `}</b>
- {` show value of fieldname from doc specified by it’s title`}
+ <b style={{ fontSize: 'larger' }}>{`[@fieldname:=expression] `}</b>
+ {` assign a computed expression to fieldname to data document and display it (if '=:=' is used instead of ':=' the expression is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the prompt/response will replace the value)`}
</p>
</div>
);
@@ -138,7 +132,7 @@ export class RTFMarkup extends React.Component<{}> {
render() {
return (
<MainViewModal
- dialogueBoxStyle={{ backgroundColor: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, padding: '16px' }}
+ dialogueBoxStyle={{ backgroundColor: SettingsManager.userBackgroundColor, alignContent: 'normal', color: SettingsManager.userColor, padding: '16px' }}
contents={this.cheatSheet}
isDisplayed={this.isOpen}
interactive={true}
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index f5e162d16..422e708bc 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -88,15 +88,10 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
}
const result = compiledFunction.apply(thisParam, params).apply(thisParam, argsArray);
- if (batch) {
- batch.end();
- }
-
+ batch?.end();
return { success: true, result };
} catch (error) {
- if (batch) {
- batch.end();
- }
+ batch?.end();
onError?.(script + ' ' + error);
return { success: false, error, result: errorVal };
}
@@ -255,7 +250,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const outputText = host.readFile('file.js');
const diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics);
-
+ if (script.startsWith('@')) options.typecheck = true; // need the compilation to fail so that the script will return itself as a string (instead of nothing)
const result = Run(outputText, paramNames, diagnostics, script, options);
if (options.globals) {
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 682704770..8594a1c92 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -483,7 +483,8 @@ export class SettingsManager extends React.Component<{}> {
toggleStatus={BoolCast(Doc.defaultAclPrivate)}
onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}
/>
- <Toggle toggleType={ToggleType.SWITCH} formLabel={'Enable Sharing UI'} color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.IsSharingEnabled)} onClick={action(() => (Doc.IsSharingEnabled = !Doc.IsSharingEnabled))} />
+ <Toggle toggleType={ToggleType.SWITCH} formLabel="Enable Sharing UI" color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.IsSharingEnabled)} onClick={action(() => (Doc.IsSharingEnabled = !Doc.IsSharingEnabled))} />
+ <Toggle toggleType={ToggleType.SWITCH} formLabel="Disable Info UI" color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.IsInfoUIDisabled)} onClick={action(() => (Doc.IsInfoUIDisabled = !Doc.IsInfoUIDisabled))} />
</div>
</div>
</div>
diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts
index 40c3f76fb..359140732 100644
--- a/src/client/util/SnappingManager.ts
+++ b/src/client/util/SnappingManager.ts
@@ -9,6 +9,7 @@ export class SnappingManager {
@observable _shiftKey = false;
@observable _ctrlKey = false;
+ @observable _metaKey = false;
@observable _isLinkFollowing = false;
@observable _isDragging: boolean = false;
@observable _isResizing: Doc | undefined = undefined;
@@ -32,6 +33,7 @@ export class SnappingManager {
public static get VertSnapLines() { return this.Instance._vertSnapLines; } // prettier-ignore
public static get ShiftKey() { return this.Instance._shiftKey; } // prettier-ignore
public static get CtrlKey() { return this.Instance._ctrlKey; } // prettier-ignore
+ public static get MetaKey() { return this.Instance._metaKey; } // prettier-ignore
public static get IsLinkFollowing(){ return this.Instance._isLinkFollowing; } // prettier-ignore
public static get IsDragging() { return this.Instance._isDragging; } // prettier-ignore
public static get IsResizing() { return this.Instance._isResizing; } // prettier-ignore
@@ -39,7 +41,8 @@ export class SnappingManager {
public static get ExploreMode() { return this.Instance._exploreMode; } // prettier-ignore
public static SetShiftKey = (down: boolean) => runInAction(() => (this.Instance._shiftKey = down)); // prettier-ignore
public static SetCtrlKey = (down: boolean) => runInAction(() => (this.Instance._ctrlKey = down)); // prettier-ignore
- public static SetIsLinkFollowing= (follow: boolean) => runInAction(() => (this.Instance._isLinkFollowing = follow)); // prettier-ignore
+ public static SetMetaKey = (down: boolean) => runInAction(() => (this.Instance._metaKey = down)); // prettier-ignore
+ public static SetIsLinkFollowing= (follow:boolean)=> runInAction(() => (this.Instance._isLinkFollowing = follow)); // prettier-ignore
public static SetIsDragging = (drag: boolean) => runInAction(() => (this.Instance._isDragging = drag)); // prettier-ignore
public static SetIsResizing = (doc: Opt<Doc>) => runInAction(() => (this.Instance._isResizing = doc)); // prettier-ignore
public static SetCanEmbed = (embed:boolean) => runInAction(() => (this.Instance._canEmbed = embed)); // prettier-ignore
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index 421855bf3..857ca852f 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -1,5 +1,5 @@
import { observable, action, runInAction } from 'mobx';
-import { Field } from '../../fields/Doc';
+import { Doc, Field } from '../../fields/Doc';
import { RichTextField } from '../../fields/RichTextField';
import { Without } from '../../Utils';
@@ -97,13 +97,14 @@ export namespace UndoManager {
export function AddEvent(event: UndoEvent, value?: any): void {
if (currentBatch && batchCounter.get() && !undoing) {
- console.log(
- ' '.slice(0, batchCounter.get()) +
- 'UndoEvent : ' +
- event.prop +
- ' = ' +
- (value instanceof RichTextField ? value.Text : value instanceof Array ? value.map(val => Field.toJavascriptString(val)).join(',') : Field.toJavascriptString(value))
- );
+ Doc.MyDockedBtns.linearView_IsOpen &&
+ console.log(
+ ' '.slice(0, batchCounter.get()) +
+ 'UndoEvent : ' +
+ event.prop +
+ ' = ' +
+ (value instanceof RichTextField ? value.Text : value instanceof Array ? value.map(val => Field.toJavascriptString(val)).join(',') : Field.toJavascriptString(value))
+ );
currentBatch.push(event);
tempEvents?.push(event);
}
@@ -171,7 +172,7 @@ export namespace UndoManager {
}
export function StartBatch(batchName: string): Batch {
- console.log(' '.slice(0, batchCounter.get()) + 'Start ' + batchCounter + ' ' + batchName);
+ Doc.MyDockedBtns.linearView_IsOpen && console.log(' '.slice(0, batchCounter.get()) + 'Start ' + batchCounter + ' ' + batchName);
runInAction(() => batchCounter.set(batchCounter.get() + 1));
if (currentBatch === undefined) {
currentBatch = [];
@@ -181,7 +182,7 @@ export namespace UndoManager {
const EndBatch = action((batchName: string, cancel: boolean = false) => {
runInAction(() => batchCounter.set(batchCounter.get() - 1));
- console.log(' '.slice(0, batchCounter.get()) + 'End ' + batchName + ' (' + currentBatch?.length + ')');
+ Doc.MyDockedBtns.linearView_IsOpen && console.log(' '.slice(0, batchCounter.get()) + 'End ' + batchName + ' (' + currentBatch?.length + ')');
if (batchCounter.get() === 0 && currentBatch?.length) {
if (!cancel) {
undoStack.push(currentBatch);