aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts46
-rw-r--r--src/client/util/CurrentUserUtils.ts8
-rw-r--r--src/client/util/DocumentManager.ts5
-rw-r--r--src/client/util/LinkManager.ts32
-rw-r--r--src/client/util/SettingsManager.tsx10
-rw-r--r--src/client/views/DashboardView.tsx5
-rw-r--r--src/client/views/DocumentDecorations.tsx10
-rw-r--r--src/client/views/GestureOverlay.tsx11
-rw-r--r--src/client/views/InkTranscription.tsx9
-rw-r--r--src/client/views/InkingStroke.tsx9
-rw-r--r--src/client/views/MainView.tsx5
-rw-r--r--src/client/views/OverlayView.tsx128
-rw-r--r--src/client/views/PropertiesView.tsx12
-rw-r--r--src/client/views/StyleProvider.tsx4
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx10
-rw-r--r--src/client/views/collections/CollectionPileView.tsx17
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx12
-rw-r--r--src/client/views/collections/CollectionSubView.tsx5
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx6
-rw-r--r--src/client/views/collections/TabDocView.tsx4
-rw-r--r--src/client/views/collections/TreeView.tsx18
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx9
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx31
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx2
-rw-r--r--src/client/views/global/globalScripts.ts25
-rw-r--r--src/client/views/nodes/ColorBox.tsx19
-rw-r--r--src/client/views/nodes/DataVizBox/components/TableBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx14
-rw-r--r--src/client/views/nodes/EquationBox.tsx3
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx11
-rw-r--r--src/client/views/nodes/ImageBox.tsx6
-rw-r--r--src/client/views/nodes/LinkBox.tsx11
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx30
-rw-r--r--src/client/views/nodes/LoadingBox.tsx21
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx4
-rw-r--r--src/client/views/nodes/MapBox/MapBox2.tsx3
-rw-r--r--src/client/views/nodes/PDFBox.tsx25
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx9
-rw-r--r--src/client/views/nodes/VideoBox.tsx5
-rw-r--r--src/client/views/nodes/WebBox.tsx21
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx21
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts2
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx17
-rw-r--r--src/client/views/pdf/Annotation.tsx6
-rw-r--r--src/fields/Doc.ts464
-rw-r--r--src/fields/RichTextUtils.ts2
-rw-r--r--src/fields/util.ts2
-rw-r--r--src/mobile/MobileInterface.tsx11
48 files changed, 482 insertions, 660 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c5a42aadc..edf72e45b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { action, reaction, runInAction } from 'mobx';
import { basename } from 'path';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, LinkedTo, Opt, updateCachedAcls } from '../../fields/Doc';
+import { Doc, DocListCast, Field, LinkedTo, Opt, StrListCast, updateCachedAcls } from '../../fields/Doc';
import { Initializing } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { HtmlField } from '../../fields/HtmlField';
@@ -1253,6 +1253,40 @@ export namespace Docs {
}
export namespace DocUtils {
+ function matchFieldValue(doc: Doc, key: string, value: any): boolean {
+ const hasFunctionFilter = Utils.HasFunctionFilter(value);
+ if (hasFunctionFilter) {
+ return hasFunctionFilter(StrCast(doc[key]));
+ }
+ if (key === LinkedTo) {
+ // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
+ const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
+ const matchLink = (value: string, anchor: Doc) => {
+ const linkedToExp = value?.split('=');
+ if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
+ return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
+ };
+ // prettier-ignore
+ return (value === Doc.FilterNone && !allLinks.length) ||
+ (value === Doc.FilterAny && !!allLinks.length) ||
+ (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) ||
+ matchLink(value,DocCast(link.link_anchor_2)) ));
+ }
+ if (typeof value === 'string') {
+ value = value.replace(`,${Utils.noRecursionHack}`, '');
+ }
+ const fieldVal = doc[key];
+ // prettier-ignore
+ if ((value === Doc.FilterAny && fieldVal !== undefined) ||
+ (value === Doc.FilterNone && fieldVal === undefined)) {
+ return true;
+ }
+ const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings
+ if (vals.length) {
+ return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+ }
+ return Field.toString(fieldVal as Field).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+ }
/**
* @param docs
* @param childFilters
@@ -1303,8 +1337,8 @@ export namespace DocUtils {
const xs = Object.keys(facet).filter(value => facet[value] === 'x');
if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
- const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value));
- const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value));
+ const failsNotEqualFacets = !xs.length ? false : xs.some(value => matchFieldValue(d, facetKey, value));
+ const satisfiesCheckFacets = !checks.length ? true : checks.some(value => matchFieldValue(d, facetKey, value));
const satisfiesExistsFacets = !exists.length ? true : exists.some(value => (facetKey !== LinkedTo ? d[facetKey] !== undefined : LinkManager.Instance.getAllRelatedLinks(d).length));
const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined);
const satisfiesMatchFacets = !matches.length
@@ -1802,7 +1836,7 @@ export namespace DocUtils {
proto.data_duration = result.duration;
}
if (overwriteDoc) {
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
generatedDocuments.push(doc);
}
@@ -1844,7 +1878,7 @@ export namespace DocUtils {
if (overwriteDoc) {
overwriteDoc.isLoading = false;
overwriteDoc.loadingError = (result as any).message;
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
} else name && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc);
});
@@ -1885,7 +1919,7 @@ export namespace DocUtils {
if ((result as any).message) {
if (overwriteDoc) {
overwriteDoc.loadingError = (result as any).message;
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
} else name && type && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc);
});
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index ba3c26b42..cd19daee5 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -110,7 +110,7 @@ export class CurrentUserUtils {
const tempClicks = DocCast(doc[field]);
const reqdClickOpts:DocumentOptions = {_width: 300, _height:200, isSystem: true};
const reqdTempOpts:{opts:DocumentOptions, script: string}[] = [
- { opts: { title: "Open In Target", targetScriptKey: "onChildClick"}, script: "docCast(documentView?.props.docViewPath().lastElement()?.rootDoc.target).then((target) => target && (target.proto.data = new List([self])))"},
+ { opts: { title: "Open In Target", targetScriptKey: "onChildClick"}, script: "docCastAsync(documentView?.props.docViewPath().lastElement()?.rootDoc.target).then((target) => target && (target.proto.data = new List([self])))"},
{ opts: { title: "Open Detail On Right", targetScriptKey: "onChildDoubleClick"}, script: `openDoc(self.doubleClickView.${OpenWhere.addRight})`}];
const reqdClickList = reqdTempOpts.map(opts => {
const allOpts = {...reqdClickOpts, ...opts.opts};
@@ -793,11 +793,6 @@ export class CurrentUserUtils {
return DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), dockBtnsReqdOpts, btns);
}
- /// collection of documents rendered in the overlay layer above all tabs and other UI
- static setupOverlays(doc: Doc, field = "myOverlayDocs") {
- return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.FreeformDocument([], opts), { title: "overlay documents", backgroundColor: "#aca3a6", isSystem: true });
- }
-
static setupPublished(doc:Doc, field = "myPublishedDocs") {
return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), { title: "published docs", backgroundColor: "#aca3a6", isSystem: true });
}
@@ -901,7 +896,6 @@ export class CurrentUserUtils {
this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
- this.setupOverlays(doc); // sets up the overlay panel where documents and other widgets can be added to float over the rest of the dashboard
this.setupPublished(doc); // sets up the list doc of all docs that have been published (meaning that they can be auto-linked by typing their title into another text box)
this.setupContextMenuButtons(doc); // set up the row of buttons at the top of the dashboard that change depending on what is selected
this.setupTopbarButtons(doc);
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 7cc8afaa6..f05c41fa7 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -13,6 +13,7 @@ import { LightboxView } from '../views/LightboxView';
import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from '../views/nodes/DocumentView';
import { KeyValueBox } from '../views/nodes/KeyValueBox';
import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox';
+import { LoadingBox } from '../views/nodes/LoadingBox';
import { PresBox } from '../views/nodes/trails';
import { ScriptingGlobals } from './ScriptingGlobals';
import { SelectionManager } from './SelectionManager';
@@ -40,8 +41,8 @@ export class DocumentManager {
//private constructor so no other class can create a nodemanager
private constructor() {
- if (!Doc.CurrentlyLoading) Doc.CurrentlyLoading = [];
- observe(Doc.CurrentlyLoading, change => {
+ if (!LoadingBox.CurrentlyLoading) LoadingBox.CurrentlyLoading = [];
+ observe(LoadingBox.CurrentlyLoading, change => {
// watch CurrentlyLoading-- when something is loaded, it's removed from the list and we have to update its icon if it were iconified since LoadingBox icons are different than the media they become
switch (change.type as any) {
case 'update':
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index ba53a760f..608184596 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -197,14 +197,32 @@ export class LinkManager {
}
// finds the opposite anchor of a given anchor in a link
- //TODO This should probably return undefined if there isn't an opposite anchor
- //TODO This should also await the return value of the anchor so we don't filter out promises
public static getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined {
- const a1 = Cast(linkDoc.link_anchor_1, Doc, null);
- const a2 = Cast(linkDoc.link_anchor_2, Doc, null);
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return a2;
- if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return a1;
- if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
+ const id = LinkManager.anchorIndex(linkDoc, anchor);
+ const a1 = DocCast(linkDoc.link_anchor_1);
+ const a2 = DocCast(linkDoc.link_anchor_2);
+ return id === '1' ? a2 : id === '2' ? a1 : id === '0' ? linkDoc : undefined;
+ // if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a1?.annotationOn, a1))) return a2;
+ // if (Doc.AreProtosEqual(DocCast(anchor.annotationOn, anchor), DocCast(a2?.annotationOn, a2))) return a1;
+ // if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
+ }
+ public static anchorIndex(linkDoc: Doc, anchor: Doc) {
+ 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';
+ }
+ 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);
+ // const a2 = DocCast(linkDoc.link_anchor_2);
+ // if (linkDoc.link_matchEmbeddings) {
+ // return [a2, a2.annotationOn].includes(anchor) ? '2' : '1';
+ // }
+ // if (Doc.AreProtosEqual(a2, anchor) || Doc.AreProtosEqual(a2.annotationOn as Doc, anchor)) return '2';
+ // return Doc.AreProtosEqual(a1, anchor) || Doc.AreProtosEqual(a1.annotationOn as Doc, anchor) ? '1' : '2';
}
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index f75322905..e58c2687c 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -12,7 +12,9 @@ import { addStyleSheet, addStyleSheetRule, Utils } from '../../Utils';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
+import { GestureOverlay } from '../views/GestureOverlay';
import { MainViewModal } from '../views/MainViewModal';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
import { undoBatch } from './UndoManager';
@@ -228,8 +230,8 @@ export class SettingsManager extends React.Component<{}> {
formLabel={'Show Button Labels'}
formLabelPlacement={'right'}
toggleType={ToggleType.SWITCH}
- onClick={e => Doc.SetShowIconLabels(!Doc.GetShowIconLabels())}
- toggleStatus={Doc.GetShowIconLabels()}
+ onClick={e => (FontIconBox.ShowIconLabels = !FontIconBox.ShowIconLabels)}
+ toggleStatus={FontIconBox.ShowIconLabels}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
@@ -237,8 +239,8 @@ export class SettingsManager extends React.Component<{}> {
formLabel={'Recognize Ink Gestures'}
formLabelPlacement={'right'}
toggleType={ToggleType.SWITCH}
- onClick={e => Doc.SetRecognizeGestures(!Doc.GetRecognizeGestures())}
- toggleStatus={Doc.GetRecognizeGestures()}
+ onClick={e => (GestureOverlay.RecognizeGestures = !GestureOverlay.RecognizeGestures)}
+ toggleStatus={GestureOverlay.RecognizeGestures}
size={Size.XSMALL}
color={SettingsManager.userColor}
/>
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 014a6358f..9e2ed7822 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -12,6 +12,7 @@ import { PrefetchProxy } from '../../fields/Proxy';
import { listSpec } from '../../fields/Schema';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, ImageCast, StrCast } from '../../fields/Types';
+import { normalizeEmail } from '../../fields/util';
import { DocServer } from '../DocServer';
import { Docs, DocumentOptions, DocUtils } from '../documents/Documents';
import { HistoryUtil } from '../util/History';
@@ -149,7 +150,7 @@ export class DashboardView extends React.Component {
: this.getDashboards(this.selectedDashboardGroup).map(dashboard => {
const href = ImageCast(dashboard.thumb)?.url?.href;
const shared = Object.keys(dashboard[DocAcl])
- .filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key))
+ .filter(key => key !== `acl-${normalizeEmail(Doc.CurrentUserEmail)}` && !['acl-Me', 'acl-Guest'].includes(key))
.some(key => dashboard[DocAcl][key] !== AclPrivate);
return (
<div
@@ -372,6 +373,8 @@ export class DashboardView extends React.Component {
Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc);
dashboardDoc['pane-count'] = 1;
freeformDoc.embedContainer = dashboardDoc;
+ dashboardDoc.myOverlayDocs = new List<Doc>();
+ dashboardDoc.myPublishedDocs = new List<Doc>();
Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 5a145e94a..6c55895ef 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -7,7 +7,7 @@ import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
-import { AclAdmin, AclAugment, AclEdit, DocData, Height, Width } from '../../fields/DocSymbols';
+import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
import { InkField } from '../../fields/InkField';
import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
@@ -126,10 +126,10 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
if (titleFieldKey === 'title') {
d.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
if (StrCast(d.rootDoc.title).startsWith('@') && !this._accumulatedTitle.startsWith('@')) {
- Doc.RemoveDocFromList(Doc.MyPublishedDocs, undefined, d.rootDoc);
+ Doc.RemFromMyPublished(d.rootDoc);
}
if (!StrCast(d.rootDoc.title).startsWith('@') && this._accumulatedTitle.startsWith('@')) {
- Doc.AddDocToList(Doc.MyPublishedDocs, undefined, d.rootDoc);
+ Doc.AddToMyPublished(d.rootDoc);
}
}
//@ts-ignore
@@ -295,8 +295,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
// open centered in a new workspace with Shift Key
const embedding = Doc.MakeEmbedding(selectedDocs[0].rootDoc);
embedding.embedContainer = undefined;
- embedding.x = -embedding[Width]() / 2;
- embedding.y = -embedding[Height]() / 2;
+ embedding.x = -NumCast(embedding._width) / 2;
+ embedding.y = -NumCast(embedding._height) / 2;
CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([embedding], { title: 'Tab for ' + embedding.title }), OpenWhereMod.right);
} else if (e.altKey) {
// open same document in new tab
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 35d6d73e4..caabdb09b 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
import { Doc, Opt } from '../../fields/Doc';
import { InkData, InkTool } from '../../fields/InkField';
-import { NumCast } from '../../fields/Types';
+import { BoolCast, NumCast } from '../../fields/Types';
import MobileInkOverlay from '../../mobile/MobileInkOverlay';
import { GestureUtils } from '../../pen-gestures/GestureUtils';
import { MobileInkOverlayContent } from '../../server/Message';
@@ -44,6 +44,13 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
static Instance: GestureOverlay;
static Instances: GestureOverlay[] = [];
+ public static set RecognizeGestures(active) {
+ Doc.UserDoc().recognizeGestures = active;
+ }
+ public static get RecognizeGestures() {
+ return BoolCast(Doc.UserDoc().recognizeGestures);
+ }
+
@observable public InkShape: Opt<GestureUtils.Gestures>;
@observable public SavedColor?: string;
@observable public SavedWidth?: number;
@@ -590,7 +597,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
// need to decide when to turn gestures back on
const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize(new Array(points));
let actionPerformed = false;
- if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) {
+ if (GestureOverlay.RecognizeGestures && result && result.Score > 0.7) {
switch (result.Name) {
case GestureUtils.Gestures.Line:
case GestureUtils.Gestures.Triangle:
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index 258bfad66..17136a737 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -2,7 +2,6 @@ import * as iink from 'iink-js';
import { action, observable } from 'mobx';
import * as React from 'react';
import { Doc, DocListCast } from '../../fields/Doc';
-import { Height, Width } from '../../fields/DocSymbols';
import { InkData, InkField, InkTool } from '../../fields/InkField';
import { Cast, DateCast, NumCast } from '../../fields/Types';
import { aggregateBounds } from '../../Utils';
@@ -287,8 +286,8 @@ export class InkTranscription extends React.Component {
action(d => {
const x = NumCast(d.x);
const y = NumCast(d.y);
- const width = d[Width]();
- const height = d[Height]();
+ const width = NumCast(d._width);
+ const height = NumCast(d._height);
bounds.push({ x, y, width, height });
})
);
@@ -327,8 +326,8 @@ export class InkTranscription extends React.Component {
// Gets a collection based on the selected nodes using a marquee view ref
const newCollection = marqViewRef?.getCollection(selected, undefined, true);
if (newCollection) {
- newCollection.height = newCollection[Height]();
- newCollection.width = newCollection[Width]();
+ newCollection.width = NumCast(newCollection._width);
+ newCollection.height = NumCast(newCollection._height);
// if the grouping we are creating is an individual word
if (word) {
newCollection.title = word;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index d26c7761e..513061e79 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -24,7 +24,6 @@ import React = require('react');
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc } from '../../fields/Doc';
-import { Height, Width } from '../../fields/DocSymbols';
import { InkData, InkField } from '../../fields/InkField';
import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
@@ -382,10 +381,10 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
const fillColor = this.fillColor;
// bcz: Hack!! Not really sure why, but having fractional values for width/height of mask ink strokes causes the dragging clone (see DragManager) to be offset from where it should be.
- if (isInkMask && (this.layoutDoc[Width]() !== Math.round(this.layoutDoc[Width]()) || this.layoutDoc[Height]() !== Math.round(this.layoutDoc[Height]()))) {
+ if (isInkMask && (this.layoutDoc._width !== Math.round(NumCast(this.layoutDoc._width)) || this.layoutDoc._height !== Math.round(NumCast(this.layoutDoc._height)))) {
setTimeout(() => {
- this.layoutDoc._width = Math.round(NumCast(this.layoutDoc[Width]()));
- this.layoutDoc._height = Math.round(NumCast(this.layoutDoc[Height]()));
+ this.layoutDoc._width = Math.round(NumCast(this.layoutDoc._width));
+ this.layoutDoc._height = Math.round(NumCast(this.layoutDoc._height));
});
}
const highlight = !this.controlUndo && this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Highlighting);
@@ -481,7 +480,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
style={{
color: StrCast(this.layoutDoc.textColor, 'black'),
pointerEvents: this.props.isDocumentActive?.() ? 'all' : undefined,
- width: this.layoutDoc[Width](),
+ width: NumCast(this.layoutDoc._width),
transform: `scale(${this.props.NativeDimScaling?.() || 1})`,
transformOrigin: 'top left',
//top: (this.props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this.props.NativeDimScaling?.() || 1)) / 2,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index da5e4f966..ccb46d7ec 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -261,6 +261,8 @@ export class MainView extends React.Component {
fa.faWindowRestore,
fa.faFolder,
fa.faFolderOpen,
+ fa.faFolderPlus,
+ fa.faFolderClosed,
fa.faMapPin,
fa.faMapMarker,
fa.faFingerprint,
@@ -450,6 +452,7 @@ export class MainView extends React.Component {
fa.faSortUp,
fa.faSortDown,
fa.faTable,
+ fa.faTableCells,
fa.faTableColumns,
fa.faTh,
fa.faThList,
@@ -475,11 +478,11 @@ export class MainView extends React.Component {
fa.faBookmark,
fa.faList,
fa.faListOl,
- fa.faFolderPlus,
fa.faLightbulb,
fa.faBookOpen,
fa.faMapMarkerAlt,
fa.faSearchPlus,
+ fa.faSolarPanel,
fa.faVolumeUp,
fa.faVolumeDown,
fa.faSquareRootAlt,
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index c174befc0..c7b59a8e2 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
import ReactLoading from 'react-loading';
-import { Doc, DocListCast } from '../../fields/Doc';
+import { Doc } from '../../fields/Doc';
import { Height, Width } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { NumCast } from '../../fields/Types';
@@ -119,7 +119,7 @@ export class OverlayView extends React.Component {
new _global.ResizeObserver(
action((entries: any) => {
for (const entry of entries) {
- DocListCast(Doc.MyOverlayDocs?.data).forEach(doc => {
+ Doc.MyOverlayDocs.forEach(doc => {
if (NumCast(doc.overlayX) > entry.contentRect.width - 10) {
doc.overlayX = entry.contentRect.width - 10;
}
@@ -184,70 +184,68 @@ export class OverlayView extends React.Component {
);
@computed get overlayDocs() {
- return DocListCast(Doc.MyOverlayDocs?.data)
- .filter(d => !LightboxView.LightboxDoc || d.type === DocumentType.PRES)
- .map(d => {
- let offsetx = 0,
- offsety = 0;
- const dref = React.createRef<HTMLDivElement>();
- const onPointerMove = action((e: PointerEvent, down: number[]) => {
- if (e.cancelBubble) return false; // if the overlay doc processed the move event (e.g., to pan its contents), then the event should be marked as canceled since propagation can't be stopped
- if (e.buttons === 1) {
- d.overlayX = e.clientX + offsetx;
- d.overlayY = e.clientY + offsety;
- }
- if (e.metaKey) {
- const dragData = new DragManager.DocumentDragData([d]);
- dragData.offset = [-offsetx, -offsety];
- dragData.dropAction = 'move';
- dragData.removeDocument = this.removeOverlayDoc;
- dragData.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
- return dragData.removeDocument!(doc) ? addDocument(doc) : false;
- };
- DragManager.StartDocumentDrag([dref.current!], dragData, down[0], down[1]);
- return true;
- }
- return false;
- });
-
- const onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, onPointerMove, emptyFunction, emptyFunction, false);
- offsetx = NumCast(d.overlayX) - e.clientX;
- offsety = NumCast(d.overlayY) - e.clientY;
- };
- return (
- <div
- className="overlayView-doc"
- ref={dref}
- key={d[Id]}
- onPointerDown={onPointerDown}
- style={{ top: d.type === DocumentType.PRES ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.overlayX}px, ${d.overlayY}px)` }}>
- <DocumentView
- Document={d}
- rootSelected={returnTrue}
- bringToFront={emptyFunction}
- addDocument={undefined}
- removeDocument={this.removeOverlayDoc}
- PanelWidth={d[Width]}
- PanelHeight={d[Height]}
- ScreenToLocalTransform={this.docScreenToLocalXf(d)}
- renderDepth={1}
- hideDecorations={true}
- isDocumentActive={returnTrue}
- isContentActive={returnTrue}
- whenChildContentsActiveChanged={emptyFunction}
- focus={emptyFunction}
- styleProvider={DefaultStyleProvider}
- docViewPath={returnEmptyDoclist}
- addDocTab={DocumentViewInternal.addDocTabFunc}
- pinToPres={emptyFunction}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
- </div>
- );
+ return Doc.MyOverlayDocs.filter(d => !LightboxView.LightboxDoc || d.type === DocumentType.PRES).map(d => {
+ let offsetx = 0,
+ offsety = 0;
+ const dref = React.createRef<HTMLDivElement>();
+ const onPointerMove = action((e: PointerEvent, down: number[]) => {
+ if (e.cancelBubble) return false; // if the overlay doc processed the move event (e.g., to pan its contents), then the event should be marked as canceled since propagation can't be stopped
+ if (e.buttons === 1) {
+ d.overlayX = e.clientX + offsetx;
+ d.overlayY = e.clientY + offsety;
+ }
+ if (e.metaKey) {
+ const dragData = new DragManager.DocumentDragData([d]);
+ dragData.offset = [-offsetx, -offsety];
+ dragData.dropAction = 'move';
+ dragData.removeDocument = this.removeOverlayDoc;
+ dragData.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => {
+ return dragData.removeDocument!(doc) ? addDocument(doc) : false;
+ };
+ DragManager.StartDocumentDrag([dref.current!], dragData, down[0], down[1]);
+ return true;
+ }
+ return false;
});
+
+ const onPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e, onPointerMove, emptyFunction, emptyFunction, false);
+ offsetx = NumCast(d.overlayX) - e.clientX;
+ offsety = NumCast(d.overlayY) - e.clientY;
+ };
+ return (
+ <div
+ className="overlayView-doc"
+ ref={dref}
+ key={d[Id]}
+ onPointerDown={onPointerDown}
+ style={{ top: d.type === DocumentType.PRES ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.overlayX}px, ${d.overlayY}px)` }}>
+ <DocumentView
+ Document={d}
+ rootSelected={returnTrue}
+ bringToFront={emptyFunction}
+ addDocument={undefined}
+ removeDocument={this.removeOverlayDoc}
+ PanelWidth={d[Width]}
+ PanelHeight={d[Height]}
+ ScreenToLocalTransform={this.docScreenToLocalXf(d)}
+ renderDepth={1}
+ hideDecorations={true}
+ isDocumentActive={returnTrue}
+ isContentActive={returnTrue}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ styleProvider={DefaultStyleProvider}
+ docViewPath={returnEmptyDoclist}
+ addDocTab={DocumentViewInternal.addDocTabFunc}
+ pinToPres={emptyFunction}
+ childFilters={returnEmptyFilter}
+ childFiltersByRanges={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ />
+ </div>
+ );
+ });
}
public static ShowSpinner() {
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index d37971517..49bf982ec 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -5,12 +5,12 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Checkbox, Tooltip } from '@material-ui/core';
import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components';
import { concat } from 'lodash';
-import { action, computed, IReactionDisposer, observable, reaction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState, SketchPicker } from 'react-color';
import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs"
import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
-import { AclAdmin, DocAcl, DocData, Height, Width } from '../../fields/DocSymbols';
+import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
import { List } from '../../fields/List';
@@ -123,16 +123,16 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return [CollectionViewType.Stacking, CollectionViewType.NoteTaking].includes(this.selectedDoc?.type_collection as any);
}
- rtfWidth = () => (!this.selectedDoc ? 0 : Math.min(this.selectedDoc?.[Width](), this.props.width - 20));
- rtfHeight = () => (!this.selectedDoc ? 0 : this.rtfWidth() <= this.selectedDoc?.[Width]() ? Math.min(this.selectedDoc?.[Height](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT);
+ rtfWidth = () => (!this.selectedDoc ? 0 : Math.min(NumCast(this.selectedDoc?._width), this.props.width - 20));
+ rtfHeight = () => (!this.selectedDoc ? 0 : this.rtfWidth() <= NumCast(this.selectedDoc?._width) ? Math.min(NumCast(this.selectedDoc?._height), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT);
@action
docWidth = () => {
if (this.selectedDoc) {
const layoutDoc = this.selectedDoc;
const aspect = Doc.NativeAspect(layoutDoc, undefined, !layoutDoc._layout_fitWidth);
- if (aspect) return Math.min(layoutDoc[Width](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.width - 20));
- return Doc.NativeWidth(layoutDoc) ? Math.min(layoutDoc[Width](), this.props.width - 20) : this.props.width - 20;
+ if (aspect) return Math.min(NumCast(layoutDoc._width), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.width - 20));
+ return Doc.NativeWidth(layoutDoc) ? Math.min(NumCast(layoutDoc._width), this.props.width - 20) : this.props.width - 20;
}
return 0;
};
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 72d7cd1c5..2162d8878 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -105,7 +105,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
const url = doc?.icon ? img.url.href : img.url.href.replace(ext, '_s' + ext);
return <img src={url} width={20} height={15} style={{ margin: 'auto', display: 'block', objectFit: 'contain' }} />;
}
- return Doc.toIcon(doc, isEmpty ? undefined : isOpen);
+ return Doc.toIcon(doc, isOpen);
case StyleProp.TreeViewSortings:
const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
@@ -117,7 +117,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;
if (doc && !doc.layout_disableBrushing && !props?.disableBrushing) {
const selected = Array.from(doc?.[DocViews]??[]).filter(dv => dv.SELECTED).length;
- const highlightIndex = Doc.isBrushedHighlightedDegree(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
+ const highlightIndex = Doc.GetBrushHighlightStatus(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
const highlightStyle = ['solid', 'dashed', 'solid', 'solid', 'solid'][highlightIndex];
if (highlightIndex) {
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index afeef5a8f..bb6d94590 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,9 +1,9 @@
import React = require('react');
import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, Field, Opt } from '../../../fields/Doc';
-import { DocData, Height, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Copy, Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
@@ -289,7 +289,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const existingHeader = this.colHeaderData.find(sh => sh.heading === heading);
const existingWidth = existingHeader?.width ? existingHeader.width : 0;
const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
- const width = d.layout_fitWidth ? maxWidth : d[Width]();
+ const width = d.layout_fitWidth ? maxWidth : NumCast(d._width);
return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
}
@@ -299,8 +299,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.DataDoc;
const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
- const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? d[Width]() : 0);
- const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? d[Height]() : 0);
+ const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._width) : 0);
+ const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._height) : 0);
if (nw && nh) {
const docWid = this.getDocWidth(d);
return Math.min(maxHeight, (docWid * nh) / nw);
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 91701b213..abb12a8ab 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,7 +1,6 @@
import { action, computed, IReactionDisposer } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, DocListCast } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { ScriptField } from '../../../fields/ScriptField';
import { NumCast, StrCast } from '../../../fields/Types';
import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
@@ -79,12 +78,12 @@ export class CollectionPileView extends CollectionSubView() {
toggleStarburst = action(() => {
this.layoutDoc._freeform_scale = undefined;
if (this.layoutEngine() === computeStarburstLayout.name) {
- if (this.rootDoc[Width]() !== NumCast(this.rootDoc._starburstDiameter, 500)) {
- this.rootDoc._starburstDiameter = this.rootDoc[Width]();
+ if (NumCast(this.rootDoc._width) !== NumCast(this.rootDoc._starburstDiameter, 500)) {
+ this.rootDoc._starburstDiameter = NumCast(this.rootDoc._width);
}
const defaultSize = 110;
- this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[Width]() / 2 - NumCast(this.layoutDoc._freeform_pileWidth, defaultSize) / 2;
- this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[Height]() / 2 - NumCast(this.layoutDoc._freeform_pileHeight, defaultSize) / 2;
+ this.rootDoc.x = NumCast(this.rootDoc.x) + NumCast(this.layoutDoc._width) / 2 - NumCast(this.layoutDoc._freeform_pileWidth, defaultSize) / 2;
+ this.rootDoc.y = NumCast(this.rootDoc.y) + NumCast(this.layoutDoc._height) / 2 - NumCast(this.layoutDoc._freeform_pileHeight, defaultSize) / 2;
this.layoutDoc._width = NumCast(this.layoutDoc._freeform_pileWidth, defaultSize);
this.layoutDoc._height = NumCast(this.layoutDoc._freeform_pileHeight, defaultSize);
DocUtils.pileup(this.childDocs, undefined, undefined, NumCast(this.layoutDoc._width) / 2, false);
@@ -93,10 +92,10 @@ export class CollectionPileView extends CollectionSubView() {
this.props.Document._freeform_pileEngine = computePassLayout.name;
} else {
const defaultSize = NumCast(this.rootDoc._starburstDiameter, 400);
- this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[Width]() / 2 - defaultSize / 2;
- this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[Height]() / 2 - defaultSize / 2;
- this.layoutDoc._freeform_pileWidth = this.layoutDoc[Width]();
- this.layoutDoc._freeform_pileHeight = this.layoutDoc[Height]();
+ this.rootDoc.x = NumCast(this.rootDoc.x) + NumCast(this.layoutDoc._width) / 2 - defaultSize / 2;
+ this.rootDoc.y = NumCast(this.rootDoc.y) + NumCast(this.layoutDoc._height) / 2 - defaultSize / 2;
+ this.layoutDoc._freeform_pileWidth = NumCast(this.layoutDoc._width);
+ this.layoutDoc._freeform_pileHeight = NumCast(this.layoutDoc._height);
this.layoutDoc._freeform_panX = this.layoutDoc._freeform_panY = 0;
this.layoutDoc._width = this.layoutDoc._height = defaultSize;
this.layoutDoc.background;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0b29e7286..e5695f63b 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,17 +4,18 @@ import { CursorProperty } from 'csstype';
import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, Opt } from '../../../fields/Doc';
-import { DocData, Height, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { CollectionViewType } from '../../documents/DocumentTypes';
import { DragManager, dropActionType } from '../../util/DragManager';
+import { SettingsManager } from '../../util/SettingsManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -31,7 +32,6 @@ import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
import './CollectionStackingView.scss';
import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn';
import { CollectionSubView } from './CollectionSubView';
-import { SettingsManager } from '../../util/SettingsManager';
const _global = (window /* browser */ || global) /* node */ as any;
export type collectionStackingViewProps = {
@@ -378,7 +378,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
const maxWidth = this.columnWidth / this.numGroupColumns;
if (!this.layoutDoc._columnsFill && !(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d))) {
- return Math.min(d[Width](), maxWidth);
+ return Math.min(NumCast(d._width), maxWidth);
}
return maxWidth;
}
@@ -387,8 +387,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this.props.DataDoc;
const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
- const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? d[Width]() : 0);
- const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? d[Height]() : 0);
+ const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._width) : 0);
+ const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._height) : 0);
if (nw && nh) {
const colWid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
const docWid = this.layoutDoc._columnsFill ? colWid : Math.min(this.getDocWidth(d), colWid);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index e9192ebbe..7c8b2f195 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -25,6 +25,7 @@ import { DocComponent } from '../DocComponent';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { CollectionView, CollectionViewProps } from './CollectionView';
import React = require('react');
+import { LoadingBox } from '../nodes/LoadingBox';
export interface SubCollectionViewProps extends CollectionViewProps {
isAnyChildContentActive: () => boolean;
@@ -450,13 +451,13 @@ export function CollectionSubView<X>(moreProps?: X) {
if (typeof files === 'string') {
const loading = Docs.Create.LoadingDocument(files, options);
generatedDocuments.push(loading);
- Doc.addCurrentlyLoading(loading);
+ LoadingBox.addCurrentlyLoading(loading);
DocUtils.uploadYoutubeVideoLoading(files, {}, loading);
} else {
generatedDocuments.push(
...files.map(file => {
const loading = Docs.Create.LoadingDocument(file, options);
- Doc.addCurrentlyLoading(loading);
+ LoadingBox.addCurrentlyLoading(loading);
DocUtils.uploadFileToDoc(file, {}, loading);
return loading;
})
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index e408c193a..761192a22 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
-import { DocData, Height, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
@@ -371,8 +371,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
marginX = () => NumCast(this.doc._xMargin);
marginTop = () => NumCast(this.doc._yMargin);
marginBot = () => NumCast(this.doc._yMargin);
- documentTitleWidth = () => Math.min(this.layoutDoc?.[Width](), this.panelWidth());
- documentTitleHeight = () => (this.layoutDoc?.[Height]() || 0) - NumCast(this.layoutDoc.layout_autoHeightMargins);
+ documentTitleWidth = () => Math.min(NumCast(this.layoutDoc?._width), this.panelWidth());
+ documentTitleHeight = () => NumCast(this.layoutDoc?._height) - NumCast(this.layoutDoc.layout_autoHeightMargins);
truncateTitleWidth = () => this.treeViewtruncateTitleWidth;
onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
panelWidth = () => Math.max(0, this.props.PanelWidth() - 2 * this.marginX() * (this.props.NativeDimScaling?.() || 1));
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 41f3b2603..180578a36 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -6,7 +6,7 @@ import { action, computed, IReactionDisposer, observable, ObservableSet, reactio
import { observer } from 'mobx-react';
import * as ReactDOM from 'react-dom/client';
import { Doc, Opt } from '../../../fields/Doc';
-import { DocData, Height, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { FieldId } from '../../../fields/RefField';
@@ -539,7 +539,7 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
default: return 'gray';
}
})(doc.type as DocumentType);
- return !background ? undefined : <div style={{ width: doc[Width](), height: doc[Height](), position: 'absolute', display: 'block', background }} />;
+ return !background ? undefined : <div style={{ width: NumCast(doc._width), height: NumCast(doc._height), position: 'absolute', display: 'block', background }} />;
}
}
};
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 193c70add..dbce45fda 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,9 +1,10 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconButton, Size } from 'browndash-components';
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../fields/Doc';
-import { DocData, Height, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { RichTextField } from '../../../fields/RichTextField';
@@ -19,6 +20,7 @@ import { DragManager, dropActionType } from '../../util/DragManager';
import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
+import { SettingsManager } from '../../util/SettingsManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoable, undoBatch, UndoManager } from '../../util/UndoManager';
@@ -32,11 +34,9 @@ import { KeyValueBox } from '../nodes/KeyValueBox';
import { StyleProp } from '../StyleProvider';
import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
import { CollectionView } from './CollectionView';
+import { TreeSort } from './TreeSort';
import './TreeView.scss';
import React = require('react');
-import { IconButton, Size } from 'browndash-components';
-import { TreeSort } from './TreeSort';
-import { SettingsManager } from '../../util/SettingsManager';
export interface TreeViewProps {
treeView: CollectionTreeView;
@@ -455,7 +455,7 @@ export class TreeView extends React.Component<TreeViewProps> {
embeddedPanelHeight = () => {
const layoutDoc = (temp => temp && Doc.expandTemplateLayout(temp, this.props.document))(this.props.treeView.props.childLayoutTemplate?.()) || this.layoutDoc;
return Math.min(
- layoutDoc[Height](),
+ NumCast(layoutDoc._height),
this.MAX_EMBED_HEIGHT,
(() => {
const aspect = Doc.NativeAspect(layoutDoc);
@@ -464,7 +464,7 @@ export class TreeView extends React.Component<TreeViewProps> {
? !Doc.NativeHeight(layoutDoc)
? NumCast(layoutDoc._height)
: Math.min((this.embeddedPanelWidth() * NumCast(layoutDoc.scrollHeight, Doc.NativeHeight(layoutDoc))) / (Doc.NativeWidth(layoutDoc) || NumCast(this.props.treeViewParent._height)))
- : (this.embeddedPanelWidth() * layoutDoc[Height]()) / layoutDoc[Width]();
+ : (this.embeddedPanelWidth() * NumCast(layoutDoc._height)) / NumCast(layoutDoc._width);
})()
);
};
@@ -741,7 +741,7 @@ export class TreeView extends React.Component<TreeViewProps> {
<div
className={`bullet${this.props.treeView.outlineMode ? '-outline' : ''}`}
key="bullet"
- title={this.childDocs?.length ? `click to see ${this.childDocs?.length} items` : 'view fields'}
+ title={this.childDocs?.length ? `click to see ${this.childDocs?.length} items` : `view ${this.props.document.type} content`}
onClick={this.bulletClick}
style={
this.props.treeView.outlineMode
@@ -872,7 +872,7 @@ export class TreeView extends React.Component<TreeViewProps> {
case StyleProp.Highlighting: if (this.props.treeView.outlineMode) return undefined;
case StyleProp.BoxShadow: return undefined;
case StyleProp.DocContents:
- const highlightIndex = this.props.treeView.outlineMode ? Doc.DocBrushStatus.unbrushed : Doc.isBrushedHighlightedDegree(doc);
+ const highlightIndex = this.props.treeView.outlineMode ? Doc.DocBrushStatus.unbrushed : Doc.GetBrushHighlightStatus(doc);
const highlightColor = ['transparent', 'rgb(68, 118, 247)', 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
return treeView.outlineMode ? null : (
<div
@@ -1265,7 +1265,7 @@ export class TreeView extends React.Component<TreeViewProps> {
const childLayout = Doc.Layout(pair.layout);
const rowHeight = () => {
const aspect = Doc.NativeAspect(childLayout);
- return aspect ? Math.min(childLayout[Width](), rowWidth()) / aspect : childLayout[Height]();
+ return aspect ? Math.min(NumCast(childLayout._width), rowWidth()) / aspect : NumCast(childLayout._height);
};
return (
<TreeView
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index d93e44ab7..f9f9b5637 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -1,5 +1,4 @@
import { Doc, Field, FieldResult } from '../../../../fields/Doc';
-import { Height, Width } from '../../../../fields/DocSymbols';
import { Id, ToString } from '../../../../fields/FieldSymbols';
import { ObjectField } from '../../../../fields/ObjectField';
import { RefField } from '../../../../fields/RefField';
@@ -91,8 +90,8 @@ export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc
docMap.set(layout[Id], {
x: NumCast(layout.x),
y: NumCast(layout.y),
- width: layout[Width](),
- height: layout[Height](),
+ width: NumCast(layout._width),
+ height: NumCast(layout._height),
pair: { layout, data },
transition: 'all .3s',
replica: '',
@@ -106,8 +105,8 @@ export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc
const burstDiam = [NumCast(pivotDoc._width), NumCast(pivotDoc._height)];
const burstScale = NumCast(pivotDoc._starburstDocScale, 1);
childPairs.forEach(({ layout, data }, i) => {
- const aspect = layout[Height]() / layout[Width]();
- const docSize = Math.min(Math.min(400, layout[Width]()), Math.min(400, layout[Width]()) / aspect) * burstScale;
+ const aspect = NumCast(layout._height) / NumCast(layout._width);
+ const docSize = Math.min(Math.min(400, NumCast(layout._width)), Math.min(400, NumCast(layout._width)) / aspect) * burstScale;
const deg = (i / childPairs.length) * Math.PI * 2;
docMap.set(layout[Id], {
x: Math.min(burstDiam[0] / 2 - docSize, Math.max(-burstDiam[0] / 2, (Math.cos(deg) * burstDiam[0]) / 2 - docSize / 2)),
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index da0f7c893..ee3dcca11 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -460,6 +460,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onExternalDrop = (e: React.DragEvent) => (([x, y]) => super.onExternalDrop(e, { x, y }))(this.getTransform().transformPoint(e.pageX, e.pageY));
+ static overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
+ const doc2Layout = Doc.Layout(doc2);
+ const doc1Layout = Doc.Layout(doc1);
+ const x2 = NumCast(doc2.x) - clusterDistance;
+ const y2 = NumCast(doc2.y) - clusterDistance;
+ const w2 = NumCast(doc2Layout._width) + clusterDistance;
+ const h2 = NumCast(doc2Layout._height) + clusterDistance;
+ const x = NumCast(doc1.x) - clusterDistance;
+ const y = NumCast(doc1.y) - clusterDistance;
+ const w = NumCast(doc1Layout._width) + clusterDistance;
+ const h = NumCast(doc1Layout._height) + clusterDistance;
+ return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
+ }
pickCluster(probe: number[]) {
return this.childLayoutPairs
.map(pair => pair.layout)
@@ -519,7 +532,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
docs.map(doc =>
this._clusterSets.map((set, i) =>
set.map(member => {
- if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) {
+ if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) {
docFirst.layout_cluster = i;
}
})
@@ -560,7 +573,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
doc.layout_cluster = -1;
this._clusterSets.forEach((set, i) =>
set.forEach(member => {
- if (doc.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) {
+ if (doc.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) {
doc.layout_cluster = i;
}
})
@@ -737,9 +750,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const inks = this.getActiveDocuments().filter(doc => {
if (doc.type === 'ink') {
const l = NumCast(doc.x);
- const r = l + doc[Width]();
+ const r = l + NumCast(doc._width);
const t = NumCast(doc.y);
- const b = t + doc[Height]();
+ const b = t + NumCast(doc._height);
const pass = !(this._inkToTextStartX! > r || end[0] < l || this._inkToTextStartY! > b || end[1] < t);
return pass;
}
@@ -1217,7 +1230,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
calculatePanIntoView = (doc: Doc, xf: Transform, scale?: number) => {
const layoutdoc = Doc.Layout(doc);
const pt = xf.transformPoint(NumCast(doc.x), NumCast(doc.y));
- const pt2 = xf.transformPoint(NumCast(doc.x) + layoutdoc[Width](), NumCast(doc.y) + layoutdoc[Height]());
+ const pt2 = xf.transformPoint(NumCast(doc.x) + NumCast(layoutdoc._width), NumCast(doc.y) + NumCast(layoutdoc._height));
const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1], width: pt2[0] - pt[0], height: pt2[1] - pt[1] };
if (scale !== undefined) {
@@ -1586,14 +1599,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._disposers.groupBounds = reaction(
() => {
if (this.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
- const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[Width](), height: cd[Height]() }));
+ const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: NumCast(cd._width), height: NumCast(cd._height) }));
return aggregateBounds(clist, NumCast(this.layoutDoc._xPadding), NumCast(this.layoutDoc._yPadding));
}
return undefined;
},
cbounds => {
if (cbounds) {
- const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[Width]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[Height]() / 2];
+ const c = [NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width) / 2, NumCast(this.layoutDoc.y) + NumCast(this.layoutDoc._height) / 2];
const p = [NumCast(this.layoutDoc[this.panXFieldKey]), NumCast(this.layoutDoc[this.panYFieldKey])];
const pbounds = {
x: cbounds.x - p[0] + c[0],
@@ -1680,8 +1693,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
CollectionFreeFormView.UpdateIcon(
this.layoutDoc[Id] + '-icon' + new Date().getTime(),
this.props.docViewPath().lastElement().ContentDiv!,
- this.layoutDoc[Width](),
- this.layoutDoc[Height](),
+ NumCast(this.layoutDoc._width),
+ NumCast(this.layoutDoc._height),
this.props.PanelWidth(),
this.props.PanelHeight(),
0,
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 9a2c79a22..4267a9059 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -48,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView() {
componentDidMount() {
this._widthDisposer = reaction(
- () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsOpen ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[Width]() || this.dimension()) + tot + 4, 0) : 0),
+ () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsOpen ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (NumCast(doc._width) || this.dimension()) + tot + 4, 0) : 0),
width => this.childDocs.length && (this.layoutDoc._width = width),
{ fireImmediately: true }
);
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 894afebfd..b529991cb 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -1,25 +1,24 @@
import { Colors } from 'browndash-components';
-import { runInAction, action } from 'mobx';
-import { aggregateBounds } from '../../../Utils';
+import { action, runInAction } from 'mobx';
import { Doc } from '../../../fields/Doc';
-import { Width, Height } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
-import { Cast, StrCast, NumCast, BoolCast } from '../../../fields/Types';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
+import { aggregateBounds } from '../../../Utils';
+import { DocumentType } from '../../documents/DocumentTypes';
import { LinkManager } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { undoable, UndoManager } from '../../util/UndoManager';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { GestureOverlay } from '../GestureOverlay';
+import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, SetActiveIsInkMask } from '../InkingStroke';
import { InkTranscription } from '../InkTranscription';
-import { ActiveFillColor, SetActiveFillColor, ActiveIsInkMask, SetActiveIsInkMask, ActiveInkWidth, SetActiveInkWidth, ActiveInkColor, SetActiveInkColor, InkingStroke } from '../InkingStroke';
-import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
-import { WebBox } from '../nodes/WebBox';
-import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
-import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentView } from '../nodes/DocumentView';
+import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
+import { WebBox } from '../nodes/WebBox';
ScriptingGlobals.add(function IsNoneSelected() {
return SelectionManager.Views().length <= 0;
@@ -239,8 +238,8 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
action(d => {
const x = NumCast(d.x);
const y = NumCast(d.y);
- const width = d[Width]();
- const height = d[Height]();
+ const width = NumCast(d._width);
+ const height = NumCast(d._height);
bounds.push({ x, y, width, height });
})
);
@@ -277,8 +276,8 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
// TODO: nda - this is the code to actually get a new grouped collection
const newCollection = marqViewRef?.getCollection(selected, undefined, true);
if (newCollection) {
- newCollection.height = newCollection[Height]();
- newCollection.width = newCollection[Width]();
+ newCollection.height = NumCast(newCollection._height);
+ newCollection.width = NumCast(newCollection._width);
}
// nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 1b6fe5748..23ffd1080 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -3,10 +3,12 @@ import { action } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState, SketchPicker } from 'react-color';
import { Doc } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
+import { Height } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
-import { StrCast } from '../../../fields/Types';
+import { NumCast, StrCast } from '../../../fields/Types';
+import { DashColor } from '../../../Utils';
import { DocumentType } from '../../documents/DocumentTypes';
+import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
@@ -14,8 +16,6 @@ import { ActiveInkColor, ActiveInkWidth, SetActiveInkColor, SetActiveInkWidth }
import './ColorBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
import { RichTextMenu } from './formattedText/RichTextMenu';
-import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { DashColor } from '../../../Utils';
@observer
export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -51,7 +51,7 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
render() {
- const scaling = Math.min(this.layoutDoc.layout_fitWidth ? 10000 : this.props.PanelHeight() / this.rootDoc[Height](), this.props.PanelWidth() / this.rootDoc[Width]());
+ const scaling = Math.min(this.layoutDoc.layout_fitWidth ? 10000 : this.props.PanelHeight() / NumCast(this.rootDoc._height), this.props.PanelWidth() / NumCast(this.rootDoc._width));
return (
<div
className={`colorBox-container${this.props.isContentActive() ? '-interactive' : ''}`}
@@ -84,9 +84,6 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
-
-ScriptingGlobals.add(
- function interpColors(c1:string, c2:string, weight=0.5) {
- return DashColor(c1).mix(DashColor(c2),weight)
- }
-) \ No newline at end of file
+ScriptingGlobals.add(function interpColors(c1: string, c2: string, weight = 0.5) {
+ return DashColor(c1).mix(DashColor(c2), weight);
+});
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index b88389de6..147dfb182 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -219,7 +219,7 @@ export class TableBox extends React.Component<TableBoxProps> {
</thead>
<tbody>
{this._tableDataIds
- .filter(rowId => this.startID <= rowId && rowId <= this.endID)
+ .filter((rowId, i) => this.startID <= i && i <= this.endID)
?.map(rowId => (
<tr
key={rowId}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d87efb7b1..943408010 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,11 +1,11 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { Dropdown, DropdownType, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate, Animation, AudioPlay, DocData, DocViews, Width } from '../../../fields/DocSymbols';
+import { AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
@@ -141,7 +141,7 @@ export interface DocComponentView {
annotationKey?: string;
getTitle?: () => string;
getCenter?: (xf: Transform) => { X: number; Y: number };
- screenBounds?: () => { left: number; top: number; right: number; bottom: number; center?: { X: number; Y: number } };
+ screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; center?: { X: number; Y: number } }>;
ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
snapPt?: (pt: { X: number; Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number; Y: number }; distance: number };
@@ -1016,7 +1016,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
removeDocument={this.hideLink(link)}
styleProvider={this.anchorStyleProvider}
LayoutTemplate={undefined}
- LayoutTemplateString={LinkAnchorBox.LayoutString(`link_anchor_${Doc.LinkEndpoint(link, this.rootDoc)}`)}
+ LayoutTemplateString={LinkAnchorBox.LayoutString(`link_anchor_${LinkManager.anchorIndex(link, this.rootDoc)}`)}
/>
</div>
));
@@ -1520,7 +1520,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
if (!this.docView?.ContentDiv || this.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
return undefined;
}
- if (this.docView._componentView?.screenBounds) {
+ if (this.docView._componentView?.screenBounds?.()) {
return this.docView._componentView.screenBounds();
}
const xf = this.docView.props
@@ -1712,7 +1712,7 @@ ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuff
ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc, linkSource: Doc) {
const collectedLinks = DocListCast(Doc.GetProto(linkCollection).data);
- let wid = linkSource[Width]();
+ let wid = NumCast(linkSource._width);
let embedding: Doc | undefined;
const links = LinkManager.Links(linkSource);
links.forEach(link => {
@@ -1723,7 +1723,7 @@ ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc, linkSour
embedding.x = wid;
embedding.y = 0;
embedding._lockedPosition = false;
- wid += otherdoc[Width]();
+ wid += NumCast(otherdoc._width);
Doc.AddDocToList(Doc.GetProto(linkCollection), 'data', embedding);
}
});
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index a77e4bdd1..d8b8bcb27 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -2,7 +2,6 @@ import EquationEditor from 'equation-editor-react';
import { action, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
@@ -68,7 +67,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
if (e.key === 'Tab') {
const graph = Docs.Create.FunctionPlotDocument([this.rootDoc], {
- x: NumCast(this.layoutDoc.x) + this.layoutDoc[Width](),
+ x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width),
y: NumCast(this.layoutDoc.y),
_width: 400,
_height: 300,
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index d2e1293da..de5ad1631 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -46,6 +46,15 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(FontIconBox, fieldKey);
}
+ //
+ // This controls whether fontIconButtons will display labels under their icons or not
+ //
+ public static get ShowIconLabels() {
+ return BoolCast(Doc.UserDoc()._showLabel);
+ }
+ public static set ShowIconLabels(show: boolean) {
+ Doc.UserDoc()._showLabel = show;
+ }
@observable noTooltip = false;
showTemplate = (): void => {
const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
@@ -161,7 +170,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
Doc.UnBrushAllDocs();
})}>
{this.Icon(color)}
- {!this.label || !Doc.GetShowIconLabels() ? null : (
+ {!this.label || !FontIconBox.ShowIconLabels ? null : (
<div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
{' '}
{this.label}{' '}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2f4f788d4..f7dee1cc1 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -4,7 +4,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from 'mobx-react';
import { extname } from 'path';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { DocData, Width } from '../../../fields/DocSymbols';
+import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
@@ -116,7 +116,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
);
const layoutDoc = this.layoutDoc;
this._disposers.path = reaction(
- () => ({ nativeSize: this.nativeSize, width: this.layoutDoc[Width]() }),
+ () => ({ nativeSize: this.nativeSize, width: NumCast(this.layoutDoc._width) }),
({ nativeSize, width }) => {
if (layoutDoc === this.layoutDoc || !this.layoutDoc._height) {
this.layoutDoc._height = (width * nativeSize.nativeHeight) / nativeSize.nativeWidth;
@@ -240,7 +240,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
croppingProto.freeform_panY_max = anchh / viewScale;
if (addCrop) {
DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' });
- cropping.x = NumCast(this.rootDoc.x) + this.rootDoc[Width]();
+ cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width);
cropping.y = NumCast(this.rootDoc.y);
this.props.addDocTab(cropping, OpenWhere.inParent);
}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index e66fed84b..a4dd5e7ef 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -2,7 +2,6 @@ import React = require('react');
import { Bezier } from 'bezier-js';
import { computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
-import { Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { DocCast, NumCast, StrCast } from '../../../fields/Types';
import { aggregateBounds, emptyFunction, returnAlways, returnFalse, Utils } from '../../../Utils';
@@ -36,8 +35,8 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView) {
const a_invXf = this.anchor1.props.ScreenToLocalTransform().inverse();
const b_invXf = this.anchor2.props.ScreenToLocalTransform().inverse();
- const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(this.anchor1.rootDoc[Width](), this.anchor1.rootDoc[Height]()) };
- const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(this.anchor2.rootDoc[Width](), this.anchor2.rootDoc[Height]()) };
+ const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(NumCast(this.anchor1.rootDoc._width), NumCast(this.anchor1.rootDoc._height)) };
+ const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(NumCast(this.anchor2.rootDoc._width), NumCast(this.anchor2.rootDoc._height)) };
const pts = [] as number[][];
pts.push([(a_scrBds.tl[0] + a_scrBds.br[0]) / 2, (a_scrBds.tl[1] + a_scrBds.br[1]) / 2]);
@@ -51,7 +50,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
return { left: agg.x, top: agg.y, right: agg.r, bottom: agg.b, center: undefined };
}
- return { left: 0, top: 0, right: 0, bottom: 0, center: undefined };
+ return undefined;
};
disposer: IReactionDisposer | undefined;
componentDidMount() {
@@ -66,8 +65,8 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
const this_xf = parxf?.getTransform() ?? Transform.Identity; //this.props.ScreenToLocalTransform();
const a_invXf = a.props.ScreenToLocalTransform().inverse();
const b_invXf = b.props.ScreenToLocalTransform().inverse();
- const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(a.rootDoc[Width](), a.rootDoc[Height]()) };
- const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(b.rootDoc[Width](), b.rootDoc[Height]()) };
+ const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(NumCast(a.rootDoc._width), NumCast(a.rootDoc._height)) };
+ const b_scrBds = { tl: b_invXf.transformPoint(0, 0), br: b_invXf.transformPoint(NumCast(b.rootDoc._width), NumCast(b.rootDoc._height)) };
const a_bds = { tl: this_xf.transformPoint(a_scrBds.tl[0], a_scrBds.tl[1]), br: this_xf.transformPoint(a_scrBds.br[0], a_scrBds.br[1]) };
const b_bds = { tl: this_xf.transformPoint(b_scrBds.tl[0], b_scrBds.tl[1]), br: this_xf.transformPoint(b_scrBds.br[0], b_scrBds.br[1]) };
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 198cbe851..7e4f1da8e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -3,13 +3,13 @@ import { Tooltip } from '@material-ui/core';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import wiki from 'wikijs';
-import { Doc, DocCastAsync, Opt } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
+import { Doc, Opt } from '../../../fields/Doc';
import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
import { DocServer } from '../../DocServer';
import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
+import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
import { LinkFollower } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
@@ -19,7 +19,6 @@ import { Transform } from '../../util/Transform';
import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
import './LinkDocPreview.scss';
import React = require('react');
-import { DocumentManager } from '../../util/DocumentManager';
interface LinkDocPreviewProps {
linkDoc?: Doc;
@@ -56,21 +55,20 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
LinkDocPreview._instance = this;
}
- @action init() {
+ @action
+ init() {
var linkTarget = this.props.linkDoc;
this._linkSrc = this.props.linkSrc;
this._linkDoc = this.props.linkDoc;
- const link_anchor_1 = this._linkDoc?.link_anchor_1 as Doc;
- const link_anchor_2 = this._linkDoc?.link_anchor_2 as Doc;
+ const link_anchor_1 = DocCast(this._linkDoc?.link_anchor_1);
+ const link_anchor_2 = DocCast(this._linkDoc?.link_anchor_2);
if (link_anchor_1 && link_anchor_2) {
linkTarget = Doc.AreProtosEqual(link_anchor_1, this._linkSrc) || Doc.AreProtosEqual(link_anchor_1?.annotationOn as Doc, this._linkSrc) ? link_anchor_2 : link_anchor_1;
}
if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) {
- // want to show annotation embedContainer document if annotation is not text
- linkTarget && DocCastAsync(linkTarget.annotationOn).then(action(anno => (this._markerTargetDoc = this._targetDoc = anno)));
- } else {
- this._markerTargetDoc = this._targetDoc = linkTarget;
+ linkTarget = DocCast(linkTarget.annotationOn); // want to show annotation embedContainer document if annotation is not text
}
+ this._markerTargetDoc = this._targetDoc = linkTarget;
this._toolTipText = '';
this.updateHref();
}
@@ -190,17 +188,17 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
width = () => {
if (!this._targetDoc) return 225;
- if (this._targetDoc[Width]() < this._targetDoc?.[Height]()) {
- return (Math.min(225, this._targetDoc[Height]()) * this._targetDoc[Width]()) / this._targetDoc[Height]();
+ if (NumCast(this._targetDoc._width) < NumCast(this._targetDoc._height)) {
+ return (Math.min(225, NumCast(this._targetDoc._height)) * NumCast(this._targetDoc._width)) / NumCast(this._targetDoc._height);
}
- return Math.min(225, NumCast(this._targetDoc?.[Width](), 225));
+ return Math.min(225, NumCast(this._targetDoc._width, 225));
};
height = () => {
if (!this._targetDoc) return 225;
- if (this._targetDoc[Width]() > this._targetDoc?.[Height]()) {
- return (Math.min(225, this._targetDoc[Width]()) * this._targetDoc[Height]()) / this._targetDoc[Width]();
+ if (NumCast(this._targetDoc._width) > NumCast(this._targetDoc._height)) {
+ return (Math.min(225, NumCast(this._targetDoc._width)) * NumCast(this._targetDoc._height)) / NumCast(this._targetDoc._width);
}
- return Math.min(225, NumCast(this._targetDoc?.[Height](), 225));
+ return Math.min(225, NumCast(this._targetDoc._height, 225));
};
@computed get previewHeader() {
return !this._linkDoc || !this._markerTargetDoc || !this._targetDoc || !this._linkSrc ? null : (
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index bdc074e0c..4bb0f14d2 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -1,4 +1,4 @@
-import { observable, runInAction } from 'mobx';
+import { action, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import ReactLoading from 'react-loading';
@@ -36,11 +36,28 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(LoadingBox, fieldKey);
}
+ @observable public static CurrentlyLoading: Doc[] = []; // this assignment doesn't work. the actual assignment happens in DocumentManager's constructor
+ // removes from currently loading display
+ @action
+ public static removeCurrentlyLoading(doc: Doc) {
+ if (LoadingBox.CurrentlyLoading) {
+ const index = LoadingBox.CurrentlyLoading.indexOf(doc);
+ index !== -1 && LoadingBox.CurrentlyLoading.splice(index, 1);
+ }
+ }
+
+ // adds doc to currently loading display
+ @action
+ public static addCurrentlyLoading(doc: Doc) {
+ if (LoadingBox.CurrentlyLoading.indexOf(doc) === -1) {
+ LoadingBox.CurrentlyLoading.push(doc);
+ }
+ }
_timer: any;
@observable progress = '';
componentDidMount() {
- if (!Doc.CurrentlyLoading?.includes(this.rootDoc)) {
+ if (!LoadingBox.CurrentlyLoading?.includes(this.rootDoc)) {
this.rootDoc.loadingError = 'Upload interrupted, please try again';
} else {
const updateFunc = async () => {
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 08dda2e1f..37935c513 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
-import { DocCss, Highlight, Width } from '../../../../fields/DocSymbols';
+import { DocCss, Highlight } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
@@ -170,7 +170,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
.ScreenToLocalTransform()
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const fullWidth = this.layoutDoc[Width]();
+ const fullWidth = NumCast(this.layoutDoc._width);
const mapWidth = fullWidth - this.sidebarWidth();
if (this.sidebarWidth() + localDelta[0] > 0) {
this.layoutDoc._layout_showSidebar = true;
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx
index d38857d90..c42664abe 100644
--- a/src/client/views/nodes/MapBox/MapBox2.tsx
+++ b/src/client/views/nodes/MapBox/MapBox2.tsx
@@ -4,7 +4,6 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, runInAc
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt } from '../../../../fields/Doc';
-import { Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { NumCast, StrCast } from '../../../../fields/Types';
@@ -368,7 +367,7 @@ export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
.ScreenToLocalTransform()
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const fullWidth = this.layoutDoc[Width]();
+ const fullWidth = NumCast(this.layoutDoc._width);
const mapWidth = fullWidth - this.sidebarWidth();
if (this.sidebarWidth() + localDelta[0] > 0) {
this._showSidebar = true;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index c068d9dd7..bde1d5fa4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -4,7 +4,6 @@ import { observer } from 'mobx-react';
import * as Pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/web/pdf_viewer.css';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { ComputedField } from '../../../fields/ScriptField';
@@ -63,7 +62,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
super(props);
const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927;
const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
- !this.Document._layout_fitWidth && (this.Document._height = this.Document[Width]() * (nh / nw));
+ !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
if (this.pdfUrl) {
if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href)));
else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf)));
@@ -104,15 +103,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const docViewContent = this.props.docViewPath().lastElement().ContentDiv!;
const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
- newDiv.style.width = this.layoutDoc[Width]().toString();
- newDiv.style.height = this.layoutDoc[Height]().toString();
+ newDiv.style.width = NumCast(this.layoutDoc._width).toString();
+ newDiv.style.height = NumCast(this.layoutDoc._height).toString();
this.replaceCanvases(docViewContent, newDiv);
const htmlString = this._pdfViewer?._mainCont.current && new XMLSerializer().serializeToString(newDiv);
const anchx = NumCast(cropping.x);
const anchy = NumCast(cropping.y);
- const anchw = cropping[Width]() * (this.props.NativeDimScaling?.() || 1);
- const anchh = cropping[Height]() * (this.props.NativeDimScaling?.() || 1);
+ const anchw = NumCast(cropping._width) * (this.props.NativeDimScaling?.() || 1);
+ const anchh = NumCast(cropping._height) * (this.props.NativeDimScaling?.() || 1);
const viewScale = 1;
cropping.title = 'crop: ' + this.rootDoc.title;
cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width);
@@ -169,8 +168,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
CollectionFreeFormView.UpdateIcon(
filename,
docViewContent,
- this.layoutDoc[Width](),
- this.layoutDoc[Height](),
+ NumCast(this.layoutDoc._width),
+ NumCast(this.layoutDoc._height),
this.props.PanelWidth(),
this.props.PanelHeight(),
NumCast(this.layoutDoc._layout_scrollTop),
@@ -255,8 +254,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.dataDoc[this.props.fieldKey + '_numPages'] = np;
Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), (nw * 96) / 72));
Doc.SetNativeHeight(this.dataDoc, (nh * 96) / 72);
- this.layoutDoc._height = this.layoutDoc[Width]() / (Doc.NativeAspect(this.dataDoc) || 1);
- !this.Document._layout_fitWidth && (this.Document._height = this.Document[Width]() * (nh / nw));
+ this.layoutDoc._height = NumCast(this.layoutDoc._width) / (Doc.NativeAspect(this.dataDoc) || 1);
+ !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
};
public search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
@@ -331,7 +330,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this.props.NativeDimScaling?.() || 1)) / nativeWidth;
if (ratio >= 1) {
this.layoutDoc.nativeWidth = nativeWidth * ratio;
- onButton && (this.layoutDoc._width = this.layoutDoc[Width]() + localDelta[0]);
+ onButton && (this.layoutDoc._width = NumCast(this.layoutDoc._width) + localDelta[0]);
this.layoutDoc._show_sidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
return false;
@@ -352,11 +351,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
if (preview) {
this._previewNativeWidth = nativeWidth * sideratio;
- this._previewWidth = (this.layoutDoc[Width]() * nativeWidth * sideratio) / curNativeWidth;
+ this._previewWidth = (NumCast(this.layoutDoc._width) * nativeWidth * sideratio) / curNativeWidth;
this._showSidebar = true;
} else {
this.layoutDoc.nativeWidth = nativeWidth * pdfratio;
- this.layoutDoc._width = (this.layoutDoc[Width]() * nativeWidth * pdfratio) / curNativeWidth;
+ this.layoutDoc._width = (NumCast(this.layoutDoc._width) * nativeWidth * pdfratio) / curNativeWidth;
this.layoutDoc._show_sidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
});
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index ebb8a3374..b2512a0e5 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -6,7 +6,6 @@ import { observer } from 'mobx-react';
// import { BufferAttribute, Camera, Vector2, Vector3 } from 'three';
import { DateField } from '../../../fields/DateField';
import { Doc } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { ComputedField } from '../../../fields/ScriptField';
import { Cast, DocCast, NumCast } from '../../../fields/Types';
@@ -18,16 +17,16 @@ import { DocumentType } from '../../documents/DocumentTypes';
import { Networking } from '../../Network';
import { CaptureManager } from '../../util/CaptureManager';
import { SettingsManager } from '../../util/SettingsManager';
+import { TrackMovements } from '../../util/TrackMovements';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
+import { media_state } from './AudioBox';
import { FieldView, FieldViewProps } from './FieldView';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import './ScreenshotBox.scss';
import { VideoBox } from './VideoBox';
-import { TrackMovements } from '../../util/TrackMovements';
-import { media_state } from './AudioBox';
declare class MediaRecorder {
constructor(e: any, options?: any); // whatever MediaRecorder has
@@ -145,7 +144,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
if (!nativeWidth || !nativeHeight) {
if (!nativeWidth) Doc.SetNativeWidth(this.dataDoc, 1200);
Doc.SetNativeHeight(this.dataDoc, (nativeWidth || 1200) / aspect);
- this.layoutDoc._height = (this.layoutDoc[Width]() || 0) / aspect;
+ this.layoutDoc._height = NumCast(this.layoutDoc._width) / aspect;
}
};
@@ -295,7 +294,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
dictationTextProto.mediaState = ComputedField.MakeFunction(`self.${textField}_recordingSource.mediaState`);
this.dataDoc[this.fieldKey + '_dictation'] = dictationText;
};
- videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], this.layoutDoc[Height]()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], this.layoutDoc[Width]())) * this.props.PanelWidth();
+ videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc._height)) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc._width))) * this.props.PanelWidth();
formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
render() {
TraceMobx();
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index d7f7c9b73..81749c98b 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -4,7 +4,6 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from 'mobx-react';
import { basename } from 'path';
import { Doc, StrListCast } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
@@ -355,8 +354,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
updateIcon = () => {
const makeIcon = (returnedfilename: string) => {
this.dataDoc.icon = new ImageField(returnedfilename);
- this.dataDoc.icon_nativeWidth = this.layoutDoc[Width]();
- this.dataDoc.icon_nativeHeight = this.layoutDoc[Height]();
+ this.dataDoc.icon_nativeWidth = NumCast(this.layoutDoc._width);
+ this.dataDoc.icon_nativeHeight = NumCast(this.layoutDoc._height);
};
this.Snapshot(undefined, undefined, makeIcon);
};
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 5c526fe38..a452b1cdd 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -3,7 +3,6 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from 'mobx-react';
import * as WebRequest from 'web-request';
import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { HtmlField } from '../../../fields/HtmlField';
import { InkTool } from '../../../fields/InkField';
@@ -81,7 +80,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return this._url ? WebBox.urlHash(this._url) + '' : '';
}
@computed get scrollHeight() {
- return Math.max(this.layoutDoc[Height](), this._scrollHeight);
+ return Math.max(NumCast(this.layoutDoc._height), this._scrollHeight);
}
@computed get allAnnotations() {
return DocListCast(this.dataDoc[this.annotationKey]);
@@ -209,7 +208,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
if (!nativeWidth) Doc.SetNativeWidth(this.layoutDoc, 600);
Doc.SetNativeHeight(this.layoutDoc, (nativeWidth || 600) / youtubeaspect);
- this.layoutDoc._height = this.layoutDoc[Width]() / youtubeaspect;
+ this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect;
}
} // else it's an HTMLfield
} else if (this.webField && !this.dataDoc.text) {
@@ -276,7 +275,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
focus = (anchor: Doc, options: DocFocusOptions) => {
if (anchor !== this.rootDoc && this._outerRef.current) {
const windowHeight = this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), anchor[Height](), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + anchor[Height](), this._scrollHeight));
+ const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), NumCast(anchor._height), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight));
if (scrollTo !== undefined) {
if (this._initialScroll === undefined) {
const focusTime = options.zoomTime ?? 500;
@@ -490,7 +489,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this._scrollHeight = Math.max(this._scrollHeight, iframeContent.body.scrollHeight || 0);
if (this._scrollHeight) {
this.rootDoc.nativeHeight = Math.min(NumCast(this.rootDoc.nativeHeight), this._scrollHeight);
- this.layoutDoc.height = Math.min(this.layoutDoc[Height](), (this.layoutDoc[Width]() * NumCast(this.rootDoc.nativeHeight)) / NumCast(this.rootDoc.nativeWidth));
+ this.layoutDoc.height = Math.min(NumCast(this.layoutDoc._height), (NumCast(this.layoutDoc._width) * NumCast(this.rootDoc.nativeHeight)) / NumCast(this.rootDoc.nativeWidth));
}
};
const swidth = Math.max(NumCast(this.layoutDoc.nativeWidth), iframeContent.body.scrollWidth || 0);
@@ -498,7 +497,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const aspectResize = swidth / NumCast(this.rootDoc.nativeWidth);
this.rootDoc.nativeWidth = swidth;
this.rootDoc.nativeHeight = NumCast(this.rootDoc.nativeHeight) * aspectResize;
- this.layoutDoc.height = this.layoutDoc[Height]() * aspectResize;
+ this.layoutDoc.height = NumCast(this.layoutDoc._height) * aspectResize;
}
initHeights();
this._iframetimeout && clearTimeout(this._iframetimeout);
@@ -838,7 +837,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (ratio >= 1) {
this.layoutDoc.nativeWidth = nativeWidth * ratio;
this.layoutDoc.nativeHeight = nativeHeight * (1 + ratio);
- onButton && (this.layoutDoc._width = this.layoutDoc[Width]() + localDelta[0]);
+ onButton && (this.layoutDoc._width = NumCast(this.layoutDoc._width) + localDelta[0]);
this.layoutDoc._layout_showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
return false;
@@ -873,9 +872,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = action((preview: boolean = false) => {
var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
if (!nativeWidth) {
- const defaultNativeWidth = this.rootDoc[this.fieldKey] instanceof WebField ? 850 : this.Document[Width]();
+ const defaultNativeWidth = this.rootDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width);
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
- Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (this.Document[Height]() / this.Document[Width]()) * defaultNativeWidth);
+ Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (NumCast(this.Document._height) / NumCast(this.Document._width)) * defaultNativeWidth);
nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
}
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
@@ -883,11 +882,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
if (preview) {
this._previewNativeWidth = nativeWidth * sideratio;
- this._previewWidth = (this.layoutDoc[Width]() * nativeWidth * sideratio) / curNativeWidth;
+ this._previewWidth = (NumCast(this.layoutDoc._width) * nativeWidth * sideratio) / curNativeWidth;
this._showSidebar = true;
} else {
this.layoutDoc._layout_showSidebar = !this.layoutDoc._layout_showSidebar;
- this.layoutDoc._width = (this.layoutDoc[Width]() * nativeWidth * pdfratio) / curNativeWidth;
+ this.layoutDoc._width = (NumCast(this.layoutDoc._width) * nativeWidth * pdfratio) / curNativeWidth;
if (!this.layoutDoc._layout_showSidebar && !(this.dataDoc[this.fieldKey] instanceof WebField)) {
this.layoutDoc.nativeWidth = this.dataDoc[this.fieldKey + '_nativeWidth'] = undefined;
} else {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 41b1c59b0..515952ae4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1,6 +1,7 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
+import { setCORS } from 'google-translate-api-browser';
import { isEqual } from 'lodash';
import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
@@ -14,7 +15,7 @@ import { EditorView } from 'prosemirror-view';
import { BsMarkdownFill } from 'react-icons/bs';
import { DateField } from '../../../../fields/DateField';
import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc';
-import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, Height, UpdatingFromServer, Width } from '../../../../fields/DocSymbols';
+import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
@@ -52,6 +53,7 @@ import { AnchorMenu } from '../../pdf/AnchorMenu';
import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup';
import { SidebarAnnos } from '../../SidebarAnnos';
import { StyleProp } from '../../StyleProvider';
+import { media_state } from '../AudioBox';
import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
import { LinkDocPreview } from '../LinkDocPreview';
@@ -71,8 +73,6 @@ import { schema } from './schema_rts';
import { SummaryView } from './SummaryView';
import applyDevTools = require('prosemirror-dev-tools');
import React = require('react');
-import { media_state } from '../AudioBox';
-import { setCORS } from 'google-translate-api-browser';
// setting up cors-anywhere server address
const translate = setCORS('http://cors-anywhere.herokuapp.com/');
export const GoogleRef = 'googleDocId';
@@ -434,10 +434,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
var tr = this._editorView.state.tr as any;
const autoAnch = this._editorView.state.schema.marks.autoLinkAnchor;
tr = tr.removeMark(0, tr.doc.content.size, autoAnch);
- DocListCast(Doc.MyPublishedDocs.data).forEach(term => (tr = this.hyperlinkTerm(tr, term, newAutoLinks)));
+ Doc.MyPublishedDocs.forEach(term => (tr = this.hyperlinkTerm(tr, term, newAutoLinks)));
tr = tr.setSelection(isNodeSel && false ? new NodeSelection(tr.doc.resolve(f)) : new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t)));
this._editorView?.dispatch(tr);
- // this.prepareForTyping();
}
oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink);
};
@@ -460,7 +459,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (!(cfield instanceof ComputedField)) {
this.dataDoc.title = (prefix + str.substring(0, Math.min(40, str.length)) + (str.length > 40 ? '...' : '')).trim();
if (str.startsWith('@') && str.length > 1) {
- Doc.AddDocToList(Doc.MyPublishedDocs, undefined, this.rootDoc);
+ Doc.AddToMyPublished(this.rootDoc);
}
}
}
@@ -487,9 +486,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
) ||
DocUtils.MakeLink(this.rootDoc, target, { link_relationship: LinkManager.AutoKeywords })!);
newAutoLinks.add(alink);
+ // DocCast(alink.link_anchor_1).followLinkLocation = 'add:right';
const allAnchors = [{ href: Doc.localServerPath(target), title: 'a link', anchorId: this.props.Document[Id] }];
allAnchors.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.autoLinkAnchor.name)?.attrs.allAnchors ?? []));
- const link = editorView.state.schema.marks.autoLinkAnchor.create({ allAnchors, title: 'auto term', location: 'add:right' });
+ const link = editorView.state.schema.marks.autoLinkAnchor.create({ allAnchors, title: 'auto term' });
tr = tr.addMark(pos, pos + node.nodeSize, link);
}
});
@@ -579,8 +579,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
// embed document when drag marked as embed
} else if (de.embedKey) {
const node = schema.nodes.dashDoc.create({
- width: draggedDoc[Width](),
- height: draggedDoc[Height](),
+ width: NumCast(draggedDoc._width),
+ height: NumCast(draggedDoc._height),
title: 'dashDoc',
docId: draggedDoc[Id],
float: 'unset',
@@ -733,7 +733,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.layout_sidebarWidthPercent.replace('%', ''))) / 100;
- const width = this.layoutDoc[Width]() + localDelta[0];
+ const width = NumCast(this.layoutDoc._width) + localDelta[0];
this.layoutDoc._layout_sidebarWidthPercent = Math.max(0, (sidebarWidth + localDelta[0]) / width) * 100 + '%';
this.layoutDoc.width = width;
this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
@@ -1407,7 +1407,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
view.state.schema.nodes.dashField.create({ fieldKey: 'text', docId: pdfAnchor[Id], hideKey: true, editable: false }, undefined, [
view.state.schema.marks.linkAnchor.create({
allAnchors: [{ href: `/doc/${this.rootDoc[Id]}`, title: this.rootDoc.title, anchorId: `${this.rootDoc[Id]}` }],
- location: 'add:right',
title: `from: ${DocCast(pdfAnchor.embedContainer).title}`,
noPreview: true,
docref: false,
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 6f07588b3..c565c4294 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -46,7 +46,7 @@ export const marks: { [index: string]: MarkSpec } = {
toDOM(node: any) {
const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), '');
const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), '');
- return ['a', { class: anchorids, 'data-targethrefs': targethrefs, 'data-noPreview': 'true', 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, location: node.attrs.location, style: `background: lightBlue` }, 0];
+ return ['a', { class: anchorids, 'data-targethrefs': targethrefs, /*'data-noPreview': 'true', */ 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, location: node.attrs.location, style: `background: lightBlue` }, 0];
},
},
noAutoLinkAnchor: {
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 82ed9e8d5..0402516a2 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -3,7 +3,6 @@ import { Tooltip } from '@material-ui/core';
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, DocListCast, Opt } from '../../../../fields/Doc';
-import { Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
@@ -15,6 +14,7 @@ import { DragManager } from '../../../util/DragManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { Transform } from '../../../util/Transform';
import { undoable, undoBatch } from '../../../util/UndoManager';
+import { TreeView } from '../../collections/TreeView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
@@ -25,9 +25,6 @@ import { PresBox } from './PresBox';
import './PresElementBox.scss';
import { PresMovement } from './PresEnums';
import React = require('react');
-import { TreeView } from '../../collections/TreeView';
-import { BranchingTrailManager } from '../../../util/BranchingTrailManager';
-import { MultiToggle, Type } from 'browndash-components';
/**
* This class models the view a document added to presentation will have in the presentation.
* It involves some functionality for its buttons and options.
@@ -331,7 +328,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@computed get recordingIsInOverlay() {
- return DocListCast(Doc.MyOverlayDocs.data).some(doc => doc.slides === this.rootDoc);
+ return Doc.MyOverlayDocs.some(doc => doc.slides === this.rootDoc);
}
// a previously recorded video will have timecode defined
@@ -341,14 +338,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
removeAllRecordingInOverlay = () => {
- DocListCast(Doc.MyOverlayDocs.data)
- .filter(doc => doc.slides === this.rootDoc)
- .forEach(Doc.RemFromMyOverlay);
+ Doc.MyOverlayDocs.filter(doc => doc.slides === this.rootDoc).forEach(Doc.RemFromMyOverlay);
};
static removeEveryExistingRecordingInOverlay = () => {
// Remove every recording that already exists in overlay view
- DocListCast(Doc.MyOverlayDocs.data).forEach(doc => {
+ Doc.MyOverlayDocs.forEach(doc => {
if (doc.slides !== null) {
// if it's a recording video, don't remove from overlay (user can lose data)
if (PresElementBox.videoIsRecorded(DocCast(doc.slides))) {
@@ -407,8 +402,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
activeItem.recording = recording;
// make recording box appear in the bottom right corner of the screen
- recording.overlayX = window.innerWidth - recording[Width]() - 20;
- recording.overlayY = window.innerHeight - recording[Height]() - 20;
+ recording.overlayX = window.innerWidth - NumCast(recording._width) - 20;
+ recording.overlayY = window.innerHeight - NumCast(recording._height) - 20;
Doc.AddToMyOverlay(recording);
}
};
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 17a8048e9..38e4f65b6 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -24,7 +24,7 @@ interface IAnnotationProps extends FieldViewProps {
export class Annotation extends React.Component<IAnnotationProps> {
render() {
return (
- <div style={{ display: this.props.anno.textCopied && !Doc.isBrushedHighlightedDegree(this.props.anno) ? 'none' : undefined }}>
+ <div style={{ display: this.props.anno.textCopied && !Doc.GetBrushHighlightStatus(this.props.anno) ? 'none' : undefined }}>
{DocListCast(this.props.anno.text_inlineAnnotations).map(a => (
<RegionAnnotation pointerEvents={this.props.pointerEvents} {...this.props} document={a} key={a[Id]} />
))}
@@ -90,12 +90,12 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
@computed get linkHighlighted() {
for (const link of LinkManager.Instance.getAllDirectLinks(this.props.document)) {
const a1 = LinkManager.getOppositeAnchor(link, this.props.document);
- if (a1 && Doc.IsBrushedDegree(DocCast(a1.annotationOn, this.props.document))) return true;
+ if (a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, this.props.document))) return true;
}
}
render() {
- const brushed = this.annoTextRegion && Doc.isBrushedHighlightedDegree(this.annoTextRegion);
+ const brushed = this.annoTextRegion && Doc.GetBrushHighlightStatus(this.annoTextRegion);
return (
<div
className="htmlAnnotation"
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 2f9eea492..6dece87b5 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1,46 +1,23 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { saveAs } from 'file-saver';
import { action, computed, observable, ObservableMap, ObservableSet, runInAction } from 'mobx';
import { computedFn } from 'mobx-utils';
import { alias, map, serializable } from 'serializr';
import { DocServer } from '../client/DocServer';
-import { DocumentType } from '../client/documents/DocumentTypes';
+import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
import { LinkManager } from '../client/util/LinkManager';
import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from '../client/util/SerializationHelper';
import { undoable } from '../client/util/UndoManager';
+import { DocumentView } from '../client/views/nodes/DocumentView';
import { decycle } from '../decycler/decycler';
import * as JSZipUtils from '../JSZipUtils';
-import { incrementTitleCopy, intersectRect, Utils } from '../Utils';
+import { incrementTitleCopy, Utils } from '../Utils';
import { DateField } from './DateField';
import {
- AclAdmin,
- AclAugment,
- AclEdit,
- AclPrivate,
- AclReadonly,
- Animation,
- AudioPlay,
- Brushed,
- CachedUpdates,
- DirectLinks,
- DocAcl,
- DocCss,
- DocData,
- DocFields,
- DocLayout,
- DocViews,
- FieldKeys,
- FieldTuples,
- ForceServerWrite,
- Height,
- Highlight,
- Initializing,
- Self,
- SelfProxy,
- UpdatingFromServer,
- Width,
-} from './DocSymbols';
+ AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, Animation, AudioPlay, Brushed, CachedUpdates, DirectLinks,
+ DocAcl, DocCss, DocData, DocFields, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight,
+ Initializing, Self, SelfProxy, UpdatingFromServer, Width
+} from './DocSymbols'; // prettier-ignore
import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToScriptString, ToString } from './FieldSymbols';
import { InkField, InkTool } from './InkField';
import { List, ListFieldName } from './List';
@@ -52,9 +29,8 @@ import { listSpec } from './Schema';
import { ComputedField, ScriptField } from './ScriptField';
import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor } from './Types';
import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from './URLField';
-import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, TraceMobx } from './util';
+import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, setter, SharingPermissions } from './util';
import JSZip = require('jszip');
-import { DocumentView } from '../client/views/nodes/DocumentView';
export const LinkedTo = '-linkedTo';
export namespace Field {
export function toKeyValueString(doc: Doc, key: string): string {
@@ -66,25 +42,23 @@ export namespace Field {
: ''
: (onDelegate ? '=' : '') + (field instanceof ComputedField ? `:=${field.script.originalScript}` : field instanceof ScriptField ? `$=${field.script.originalScript}` : Field.toScriptString(field));
}
- export function toScriptString(field: Field): string {
+ export function toScriptString(field: Field) {
switch (typeof field) {
- case 'string':
- if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
- return !field.includes('`') ? `\`${field}\`` : `"${field}"`;
+ case 'string': if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
+ return !field.includes('`') ? `\`${field}\`` : `"${field}"`;
case 'number':
- case 'boolean':
- return String(field);
- }
- return field?.[ToScriptString]?.() ?? 'null';
+ case 'boolean':return String(field);
+ default: return field?.[ToScriptString]?.() ?? 'null';
+ } // prettier-ignore
}
- export function toString(field: Field): string {
+ export function toString(field: Field) {
if (typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean') return String(field);
return field?.[ToString]?.() || '';
}
export function IsField(field: any): field is Field;
export function IsField(field: any, includeUndefined: true): field is Field | undefined;
export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
- return typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean' || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined);
+ return ['string', 'number', 'boolean'].includes(typeof field) || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined);
}
export function Copy(field: any) {
return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field;
@@ -107,11 +81,6 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
const list = Cast(field, listSpec(Doc));
return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
}
-
-export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
- return Cast(field, Doc);
-}
-
export function NumListCast(field: FieldResult, defaultVal: number[] = []) {
return Cast(field, listSpec('number'), defaultVal);
}
@@ -162,140 +131,51 @@ export function updateCachedAcls(doc: Doc) {
@Deserializable('Doc', updateCachedAcls, ['id'])
export class Doc extends RefField {
@observable public static RecordingEvent = 0;
-
- // this isn't really used at the moment, but is intended to indicate whether ink stroke are passed through a gesture recognizer
- static GetRecognizeGestures() {
- return BoolCast(Doc.UserDoc()._recognizeGestures);
- }
- static SetRecognizeGestures(show: boolean) {
- Doc.UserDoc()._recognizeGestures = show;
- }
-
- //
- // This controls whether fontIconButtons will display labels under their icons or not
- //
- static GetShowIconLabels() {
- return BoolCast(Doc.UserDoc()._showLabel);
- }
- static SetShowIconLabels(show: boolean) {
- Doc.UserDoc()._showLabel = show;
- }
- @observable public static CurrentlyLoading: Doc[] = []; // this assignment doesn't work. the actual assignment happens in DocumentManager's constructor
- // removes from currently loading display
- @action
- public static removeCurrentlyLoading(doc: Doc) {
- if (Doc.CurrentlyLoading) {
- const index = Doc.CurrentlyLoading.indexOf(doc);
- index !== -1 && Doc.CurrentlyLoading.splice(index, 1);
- }
- }
-
- // adds doc to currently loading display
- @action
- public static addCurrentlyLoading(doc: Doc) {
- if (Doc.CurrentlyLoading.indexOf(doc) === -1) {
- Doc.CurrentlyLoading.push(doc);
- }
- }
-
@observable public static GuestDashboard: Doc | undefined;
@observable public static GuestTarget: Doc | undefined;
@observable public static GuestMobile: Doc | undefined;
- public static get MySharedDocs() {
- return DocCast(Doc.UserDoc().mySharedDocs);
- }
- public static get MyUserDocView() {
- return DocCast(Doc.UserDoc().myUserDocView);
- }
- public static get MyDockedBtns() {
- return DocCast(Doc.UserDoc().myDockedBtns);
- }
- public static get MySearcher() {
- return DocCast(Doc.UserDoc().mySearcher);
- }
- public static get MyHeaderBar() {
- return DocCast(Doc.UserDoc().myHeaderBar);
- }
- public static get MyLeftSidebarMenu() {
- return DocCast(Doc.UserDoc().myLeftSidebarMenu);
- }
- public static get MyLeftSidebarPanel() {
- return DocCast(Doc.UserDoc().myLeftSidebarPanel);
- }
- public static get MyContextMenuBtns() {
- return DocCast(Doc.UserDoc().myContextMenuBtns);
- }
- public static get MyTopBarBtns() {
- return DocCast(Doc.UserDoc().myTopBarBtns);
- }
- public static get MyRecentlyClosed() {
- return DocCast(Doc.UserDoc().myRecentlyClosed);
- }
- public static get MyTrails() {
- return DocCast(Doc.ActiveDashboard?.myTrails);
- }
- public static IsInMyOverlay(doc: Doc) {
- return DocListCast(Doc.MyOverlayDocs?.data).includes(doc);
- }
- public static AddToMyOverlay(doc: Doc) {
- Doc.AddDocToList(Doc.MyOverlayDocs, undefined, doc);
- }
- public static RemFromMyOverlay(doc: Doc) {
- Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, doc);
- }
- public static get MyOverlayDocs() {
- return DocCast(Doc.UserDoc().myOverlayDocs);
- }
- public static get MyPublishedDocs() {
- return DocCast(Doc.UserDoc().myPublishedDocs);
- }
- public static get MyDashboards() {
- return DocCast(Doc.UserDoc().myDashboards);
- }
- public static get MyTemplates() {
- return DocCast(Doc.UserDoc().myTemplates);
- }
- public static get MyImports() {
- return DocCast(Doc.UserDoc().myImports);
- }
- public static get MyFilesystem() {
- return DocCast(Doc.UserDoc().myFilesystem);
- }
- public static get MyTools() {
- return DocCast(Doc.UserDoc().myTools);
- }
- public static get ActivePage() {
- return StrCast(Doc.UserDoc().activePage);
- }
- public static set ActivePage(val) {
- Doc.UserDoc().activePage = val;
- DocServer.UPDATE_SERVER_CACHE();
- }
- public static IsComicStyle(doc?: Doc) {
- return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic';
- }
- public static get ActiveDashboard() {
- return DocCast(Doc.UserDoc().activeDashboard);
- }
- public static set ActiveDashboard(val: Doc | undefined) {
- const overlays = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), null);
- overlays && (overlays.length = 0);
- Doc.UserDoc().activeDashboard = val;
- }
- public static set ActiveTool(tool: InkTool) {
- Doc.UserDoc().activeTool = tool;
- }
- public static get ActiveTool(): InkTool {
- return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool;
- }
- public static get ActivePresentation(): Opt<Doc> {
- return DocCast(Doc.ActiveDashboard?.activePresentation);
- }
- public static set ActivePresentation(val) {
- if (Doc.ActiveDashboard) {
- Doc.ActiveDashboard.activePresentation = val;
- }
- }
+ public static CurrentUserEmail: string = '';
+
+ public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); } // prettier-ignore
+ public static get MyUserDocView() { return DocCast(Doc.UserDoc().myUserDocView); } // prettier-ignore
+ public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); } // prettier-ignore
+ public static get MySearcher() { return DocCast(Doc.UserDoc().mySearcher); } // prettier-ignore
+ public static get MyHeaderBar() { return DocCast(Doc.UserDoc().myHeaderBar); } // prettier-ignore
+ public static get MyLeftSidebarMenu() { return DocCast(Doc.UserDoc().myLeftSidebarMenu); } // prettier-ignore
+ public static get MyLeftSidebarPanel() { return DocCast(Doc.UserDoc().myLeftSidebarPanel); } // prettier-ignore
+ public static get MyContextMenuBtns() { return DocCast(Doc.UserDoc().myContextMenuBtns); } // prettier-ignore
+ public static get MyTopBarBtns() { return DocCast(Doc.UserDoc().myTopBarBtns); } // prettier-ignore
+ public static get MyRecentlyClosed() { return DocCast(Doc.UserDoc().myRecentlyClosed); } // prettier-ignore
+ public static get MyTrails() { return DocCast(Doc.ActiveDashboard?.myTrails); } // prettier-ignore
+ public static get MyOverlayDocs() { return DocListCast(Doc.ActiveDashboard?.myOverlayDocs ?? DocCast(Doc.UserDoc().myOverlayDocs).data); } // prettier-ignore
+ public static get MyPublishedDocs() { return DocListCast(Doc.ActiveDashboard?.myPublishedDocs ?? DocCast(Doc.UserDoc().myPublishedDocs).data); } // prettier-ignore
+ public static get MyDashboards() { return DocCast(Doc.UserDoc().myDashboards); } // prettier-ignore
+ public static get MyTemplates() { return DocCast(Doc.UserDoc().myTemplates); } // prettier-ignore
+ public static get MyImports() { return DocCast(Doc.UserDoc().myImports); } // prettier-ignore
+ public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); } // prettier-ignore
+ public static get MyTools() { return DocCast(Doc.UserDoc().myTools); } // prettier-ignore
+ public static get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode); } // prettier-ignore
+ public static set noviceMode(val) { Doc.UserDoc().noviceMode = val; } // prettier-ignore
+ public static get IsSharingEnabled() { return BoolCast(Doc.UserDoc().isSharingEnabled); } // prettier-ignore
+ public static set IsSharingEnabled(val) { Doc.UserDoc().isSharingEnabled = val; } // prettier-ignore
+ public static get defaultAclPrivate() { return Doc.UserDoc().defaultAclPrivate; } // prettier-ignore
+ public static set defaultAclPrivate(val) { Doc.UserDoc().defaultAclPrivate = val; } // prettier-ignore
+ public static get ActivePage() { return StrCast(Doc.UserDoc().activePage); } // prettier-ignore
+ public static set ActivePage(val) { Doc.UserDoc().activePage = val; } // prettier-ignore
+ public static get ActiveTool(): InkTool { return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool; } // prettier-ignore
+ public static set ActiveTool(tool:InkTool){ Doc.UserDoc().activeTool = tool; } // prettier-ignore
+ public static get ActivePresentation() { return DocCast(Doc.ActiveDashboard?.activePresentation) as Opt<Doc>; } // prettier-ignore
+ public static set ActivePresentation(val) { Doc.ActiveDashboard && (Doc.ActiveDashboard.activePresentation = val) } // prettier-ignore
+ public static get ActiveDashboard() { return DocCast(Doc.UserDoc().activeDashboard); } // prettier-ignore
+ public static set ActiveDashboard(val: Opt<Doc>) { Doc.UserDoc().activeDashboard = val; } // prettier-ignore
+
+ public static IsInMyOverlay(doc: Doc) { return Doc.MyOverlayDocs.includes(doc); } // prettier-ignore
+ public static AddToMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static AddToMyPublished(doc: Doc) { Doc.ActiveDashboard?.myPublishedDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyPublished(doc: Doc){ Doc.ActiveDashboard?.myPublishedDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static IsComicStyle(doc?: Doc) { return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic' ; } // prettier-ignore
+
constructor(id?: FieldId, forceSave?: boolean) {
super(id);
const docProxy = new Proxy<this>(this, {
@@ -359,17 +239,14 @@ export class Doc extends RefField {
@observable public [Highlight]: boolean = false;
@observable public [Brushed]: boolean = false;
@observable public [DocViews] = new ObservableSet<DocumentView>();
- static __Anim(Doc: Doc) {
- // for debugging to print AnimationSym field easily.
- return Doc[Animation];
- }
+ private [Self] = this;
+ private [SelfProxy]: any;
private [UpdatingFromServer]: boolean = false;
private [ForceServerWrite]: boolean = false;
- public [Initializing]: boolean = false;
+ private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
- private [Self] = this;
- private [SelfProxy]: any;
+ public [Initializing]: boolean = false;
public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: Field[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => {
if (!this[UpdatingFromServer] || this[ForceServerWrite]) {
DocServer.UpdateField(this[Id], serverOp);
@@ -380,9 +257,7 @@ export class Doc extends RefField {
public [Height] = () => NumCast(this[SelfProxy]._height);
public [ToScriptString] = () => `idToDoc("${this[Self][Id]}")`;
public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? '-inaccessible-' : this[SelfProxy].title})`;
- public get [DocLayout]() {
- return this[SelfProxy].__LAYOUT__;
- }
+ public get [DocLayout]() { return this[SelfProxy].__LAYOUT__; } // prettier-ignore
public get [DocData](): Doc {
const self = this[SelfProxy];
return self.resolvedDataDoc && !self.isTemplateForField ? self : Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
@@ -403,29 +278,6 @@ export class Doc extends RefField {
return undefined;
}
- private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
- public static get noviceMode() {
- return Doc.UserDoc().noviceMode as boolean;
- }
- public static set noviceMode(val) {
- Doc.UserDoc().noviceMode = val;
- }
- public static get IsSharingEnabled() {
- return Doc.UserDoc().isSharingEnabled as boolean;
- }
- public static set IsSharingEnabled(val) {
- Doc.UserDoc().isSharingEnabled = val;
- }
- public static get defaultAclPrivate() {
- return Doc.UserDoc().defaultAclPrivate;
- }
- public static set defaultAclPrivate(val) {
- Doc.UserDoc().defaultAclPrivate = val;
- }
- public static CurrentUserEmail: string = '';
- public static get CurrentUserEmailNormalized() {
- return normalizeEmail(Doc.CurrentUserEmail);
- }
public async [HandleUpdate](diff: any) {
const set = diff.$set;
const sameAuthor = this.author === Doc.CurrentUserEmail;
@@ -482,17 +334,6 @@ export class Doc extends RefField {
}
export namespace Doc {
- // export function GetAsync(doc: Doc, key: string, ignoreProto: boolean = false): Promise<Field | undefined> {
- // const self = doc[Self];
- // return new Promise(res => getField(self, key, ignoreProto, res));
- // }
- // export function GetTAsync<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): Promise<T | undefined> {
- // return new Promise(async res => {
- // const field = await GetAsync(doc, key, ignoreProto);
- // return Cast(field, ctor);
- // });
- // }
-
export function SetContainer(doc: Doc, container: Doc) {
doc.embedContainer = container;
}
@@ -626,10 +467,9 @@ export namespace Doc {
/**
* @returns the index of doc toFind in list of docs, -1 otherwise
*/
- export function IndexOf(toFind: Doc, list: Doc[], allowProtos: boolean = true) {
- let index = list.reduce((p, v, i) => (v instanceof Doc && v === toFind ? i : p), -1);
- index = allowProtos && index !== -1 ? index : list.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, toFind) ? i : p), -1);
- return index; // list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind));
+ export function IndexOf(toFind: Doc, list: Doc[]) {
+ const index = list.indexOf(toFind);
+ return index !== -1 ? index : list.findIndex(doc => Doc.AreProtosEqual(doc, toFind));
}
/**
@@ -663,11 +503,10 @@ export namespace Doc {
}
const list = Cast(listDoc[key], listSpec(Doc));
if (list) {
- if (allowDuplicates !== true) {
- const pind = list.reduce((l, d, i) => (d instanceof Doc && d[Id] === doc[Id] ? i : l), -1);
+ if (!allowDuplicates) {
+ const pind = list.findIndex(d => d instanceof Doc && d[Id] === doc[Id]);
if (pind !== -1) {
return true;
- //list.splice(pind, 1); // bcz: this causes schemaView docs in the Catalog to move to the bottom of the schema view when they are dragged even though they haven't left the collection
}
}
if (first) {
@@ -687,22 +526,6 @@ export namespace Doc {
return false;
}
- /**
- * Computes the bounds of the contents of a set of documents.
- */
- export function ComputeContentBounds(docList: Doc[]) {
- const bounds = docList.reduce(
- (bounds, doc) => ({
- x: Math.min(NumCast(doc.x), bounds.x),
- y: Math.min(NumCast(doc.y), bounds.y),
- r: Math.max(NumCast(doc.x) + doc[Width](), bounds.r),
- b: Math.max(NumCast(doc.y) + doc[Height](), bounds.b),
- }),
- { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE }
- );
- return bounds;
- }
-
export function MakeEmbedding(doc: Doc, id?: string) {
const embedding = !GetT(doc, 'isDataDoc', 'boolean', true) && doc.proto ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
const layout = Doc.LayoutField(embedding);
@@ -779,7 +602,7 @@ export namespace Doc {
} else if (field instanceof RefField) {
assignKey(field);
} else if (cfield instanceof ComputedField) {
- assignKey(cfield[Copy]()); // ComputedField.MakeFunction(cfield.script.originalScript));
+ assignKey(cfield[Copy]());
} else if (field instanceof ObjectField) {
await copyObjectField(field);
} else if (field instanceof Promise) {
@@ -990,29 +813,6 @@ export namespace Doc {
return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
}
- export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
- Object.keys(doc).forEach(key => {
- const field = ProxyField.WithoutProxy(() => doc[key]);
- if (key === 'proto' && copyProto) {
- if (doc.proto instanceof Doc && overwrite.proto instanceof Doc) {
- overwrite[key] = Doc.Overwrite(doc.proto, overwrite.proto);
- }
- } else {
- if (field instanceof RefField) {
- overwrite[key] = field;
- } else if (field instanceof ObjectField) {
- overwrite[key] = ObjectField.MakeCopy(field);
- } else if (field instanceof Promise) {
- debugger; //This shouldn't happend...
- } else {
- overwrite[key] = field;
- }
- }
- });
-
- return overwrite;
- }
-
export function FindReferences(infield: Doc | List<any>, references: Set<Doc>, system: boolean | undefined) {
if (infield instanceof List<any>) {
infield.forEach(val => (val instanceof Doc || val instanceof List) && FindReferences(val, references, system));
@@ -1217,22 +1017,8 @@ export namespace Doc {
return '/doc/' + (doc ? doc[Id] : '');
}
- export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
- const doc2Layout = Doc.Layout(doc2);
- const doc1Layout = Doc.Layout(doc1);
- const x2 = NumCast(doc2.x) - clusterDistance;
- const y2 = NumCast(doc2.y) - clusterDistance;
- const w2 = NumCast(doc2Layout._width) + clusterDistance;
- const h2 = NumCast(doc2Layout._height) + clusterDistance;
- const x = NumCast(doc1.x) - clusterDistance;
- const y = NumCast(doc1.y) - clusterDistance;
- const w = NumCast(doc1Layout._width) + clusterDistance;
- const h = NumCast(doc1Layout._height) + clusterDistance;
- return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
- }
-
- export function isBrushedHighlightedDegree(doc: Doc) {
- return Doc.IsHighlighted(doc) ? DocBrushStatus.highlighted : Doc.IsBrushedDegree(doc);
+ export function GetBrushHighlightStatus(doc: Doc) {
+ return Doc.IsHighlighted(doc) ? DocBrushStatus.highlighted : Doc.GetBrushStatus(doc);
}
export class DocBrush {
BrushedDoc = new Set<Doc>();
@@ -1269,12 +1055,12 @@ export namespace Doc {
return Doc.NativeWidth(doc, dataDoc, useDim) / (Doc.NativeHeight(doc, dataDoc, useDim) || 1);
}
export function NativeWidth(doc?: Doc, dataDoc?: Doc, useWidth?: boolean) {
- return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeWidth'], useWidth ? doc[Width]() : 0));
+ return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeWidth'], useWidth ? NumCast(doc._width) : 0));
}
export function NativeHeight(doc?: Doc, dataDoc?: Doc, useHeight?: boolean) {
if (!doc) return 0;
- const nheight = (Doc.NativeWidth(doc, dataDoc, useHeight) * doc[Height]()) / doc[Width]();
- const dheight = NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeHeight'], useHeight ? doc[Height]() : 0);
+ const nheight = (Doc.NativeWidth(doc, dataDoc, useHeight) * NumCast(doc._height)) / NumCast(doc._width);
+ const dheight = NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeHeight'], useHeight ? NumCast(doc._height) : 0);
return NumCast(doc._nativeHeight, nheight || dheight);
}
export function SetNativeWidth(doc: Doc, width: number | undefined, fieldKey?: string) {
@@ -1337,36 +1123,22 @@ export namespace Doc {
highlighted = 3,
}
// returns 'how' a Doc has been brushed over - whether the document itself was brushed, it's prototype, or neither
- export function IsBrushedDegree(doc: Doc) {
+ export function GetBrushStatus(doc: Doc) {
if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate || doc.opacity === 0) return DocBrushStatus.unbrushed;
return doc[Brushed] ? DocBrushStatus.selfBrushed : Doc.GetProto(doc)[Brushed] ? DocBrushStatus.protoBrushed : DocBrushStatus.unbrushed;
}
export function BrushDoc(doc: Doc, unbrush = false) {
- if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return doc;
- brushManager.brushDoc(doc, unbrush);
- brushManager.brushDoc(Doc.GetProto(doc), unbrush);
+ if (doc && GetEffectiveAcl(doc) !== AclPrivate && GetEffectiveAcl(Doc.GetProto(doc)) !== AclPrivate) {
+ brushManager.brushDoc(doc, unbrush);
+ brushManager.brushDoc(Doc.GetProto(doc), unbrush);
+ }
return doc;
}
export function UnBrushDoc(doc: Doc) {
return BrushDoc(doc, true);
}
-
- export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) {
- const linkAnchor2 = DocCast(linkDoc.link_anchor_2);
- const linkAnchor1 = DocCast(linkDoc.link_anchor_1);
- if (linkDoc.link_matchEmbeddings) {
- return [linkAnchor2, linkAnchor2.annotationOn].includes(anchorDoc) ? '2' : '1';
- }
- if (Doc.AreProtosEqual(linkAnchor2, anchorDoc) || Doc.AreProtosEqual(linkAnchor2.annotationOn as Doc, anchorDoc)) return '2';
- return Doc.AreProtosEqual(linkAnchor1, anchorDoc) || Doc.AreProtosEqual(linkAnchor1.annotationOn as Doc, anchorDoc) ? '1' : '2';
- }
-
- export function linkFollowUnhighlight() {
- clearTimeout(UnhighlightTimer);
- UnhighlightWatchers.forEach(watcher => watcher());
- UnhighlightWatchers.length = 0;
- highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
- document.removeEventListener('pointerdown', linkFollowUnhighlight);
+ export function UnBrushAllDocs() {
+ Array.from(brushManager.BrushedDoc).forEach(action(doc => (doc[Brushed] = false)));
}
let UnhighlightWatchers: (() => void)[] = [];
@@ -1376,6 +1148,13 @@ export namespace Doc {
UnhighlightWatchers.push(watcher);
} else watcher();
}
+ export function linkFollowUnhighlight() {
+ clearTimeout(UnhighlightTimer);
+ UnhighlightWatchers.forEach(watcher => watcher());
+ UnhighlightWatchers.length = 0;
+ highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
+ document.removeEventListener('pointerdown', linkFollowUnhighlight);
+ }
export function linkFollowHighlight(destDoc: Doc | Doc[], dataAndDisplayDocs = true, presentation_effect?: Doc) {
linkFollowUnhighlight();
(destDoc instanceof Doc ? [destDoc] : destDoc).forEach(doc => Doc.HighlightDoc(doc, dataAndDisplayDocs, presentation_effect));
@@ -1415,9 +1194,6 @@ export namespace Doc {
});
});
}
- export function UnBrushAllDocs() {
- Array.from(brushManager.BrushedDoc).forEach(action(doc => (doc[Brushed] = false)));
- }
export function getDocTemplate(doc?: Doc) {
return !doc
@@ -1433,41 +1209,6 @@ export namespace Doc {
: undefined;
}
- export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
- const hasFunctionFilter = Utils.HasFunctionFilter(value);
- if (hasFunctionFilter) {
- return hasFunctionFilter(StrCast(doc[key]));
- }
- if (key === LinkedTo) {
- // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
- const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
- const matchLink = (value: string, anchor: Doc) => {
- const linkedToExp = value?.split('=');
- if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
- return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
- };
- // prettier-ignore
- return (value === Doc.FilterNone && !allLinks.length) ||
- (value === Doc.FilterAny && !!allLinks.length) ||
- (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) ||
- matchLink(value,DocCast(link.link_anchor_2)) ));
- }
- if (typeof value === 'string') {
- value = value.replace(`,${Utils.noRecursionHack}`, '');
- }
- const fieldVal = doc[key];
- // prettier-ignore
- if ((value === Doc.FilterAny && fieldVal !== undefined) ||
- (value === Doc.FilterNone && fieldVal === undefined)) {
- return true;
- }
- const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings
- if (vals.length) {
- return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
- }
- return Field.toString(fieldVal as Field).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
- }
-
export function deiconifyView(doc: Doc) {
StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc);
}
@@ -1603,15 +1344,25 @@ export namespace Doc {
}
// prettier-ignore
- export function toIcon(doc?: Doc, isOpen?: boolean) {
- switch (isOpen !== undefined ? DocumentType.COL: StrCast(doc?.type)) {
+ export function toIcon(doc?: Doc, isOpen?: Opt<boolean>) {
+ if (isOpen) return doc?.isFolder ? 'chevron-down' : 'folder-open';
+ switch (StrCast(doc?.type)) {
case DocumentType.IMG: return 'image';
case DocumentType.COMPARISON: return 'columns';
case DocumentType.RTF: return 'sticky-note';
case DocumentType.COL:
- const folder: IconProp = isOpen === true ? 'folder-open' : isOpen === false ? 'folder' : doc?.title==='Untitled Collection'? 'object-group': 'chalkboard';
- const chevron: IconProp = isOpen === true ? 'chevron-down' : isOpen === false ? 'chevron-right' : 'question';
- return !doc?.isFolder ? folder : chevron;
+ if (doc?.isFolder) {
+ switch (doc.type_collection) {
+ default: return isOpen === false ? 'chevron-right' : 'question';
+ } // prettier-ignore
+ }
+ switch (doc?.type_collection) {
+ case CollectionViewType.Freeform : return 'object-group';
+ case CollectionViewType.NoteTaking : return 'chalkboard';
+ case CollectionViewType.Schema : return 'table-cells';
+ case CollectionViewType.Docking: return 'solar-panel';
+ default: return 'folder';
+ } // prettier-ignore
case DocumentType.WEB: return 'globe-asia';
case DocumentType.SCREENSHOT: return 'photo-video';
case DocumentType.WEBCAM: return 'video';
@@ -1628,9 +1379,9 @@ export namespace Doc {
case DocumentType.DATAVIZ: return 'chart-bar';
case DocumentType.EQUATION: return 'calculator';
case DocumentType.SIMULATION: return 'rocket';
- case DocumentType.CONFIG: return 'question-circle';
- default: return 'question';
+ case DocumentType.CONFIG: return 'folder-closed';
}
+ return 'question';
}
///
@@ -1839,14 +1590,13 @@ ScriptingGlobals.add(function sameDocs(doc1: any, doc2: any) {
ScriptingGlobals.add(function assignDoc(doc: Doc, field: string, id: string) {
return Doc.assignDocToField(doc, field, id);
});
-ScriptingGlobals.add(function docCast(doc: FieldResult): any {
- return DocCastAsync(doc);
+ScriptingGlobals.add(function docCastAsync(doc: FieldResult): any {
+ return Cast(doc, Doc);
});
ScriptingGlobals.add(function activePresentationItem() {
const curPres = Doc.ActivePresentation;
return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
});
-
ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: any, modifiers: 'match' | 'check' | 'x' | 'remove') {
Doc.setDocFilter(container, key, value, modifiers);
});
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts
index 5ecf25e08..dfd02dbc0 100644
--- a/src/fields/RichTextUtils.ts
+++ b/src/fields/RichTextUtils.ts
@@ -275,7 +275,7 @@ export namespace RichTextUtils {
} else {
docId = backingDocId;
}
- return schema.node('image', { src, agnostic, width, docId, float: null, location: 'add:right' });
+ return schema.node('image', { src, agnostic, width, docId, float: null });
};
const textNode = (schema: any, run: docs_v1.Schema$TextRun) => {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 28db77c65..ca02284da 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -234,7 +234,7 @@ function getEffectiveAcl(target: any, user?: string): symbol {
* @param layoutOnly just sets the layout doc's ACL (unless the data doc has no entry for the ACL, in which case it will be set as well)
*/
export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, visited?: Doc[], allowUpgrade?: boolean, layoutOnly = false) {
- const selfKey = `acl-${Doc.CurrentUserEmailNormalized}`;
+ const selfKey = `acl-${normalizeEmail(Doc.CurrentUserEmail)}`;
if (!visited) visited = [] as Doc[];
if (!target || visited.includes(target) || key === selfKey) return;
visited.push(target);
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 498bec6ed..e24bcd733 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -658,7 +658,7 @@ export class MobileInterface extends React.Component {
// DocButton for switching into ink mode
@computed get drawInk() {
return !this.mainContainer || this._activeDoc._type_collection !== CollectionViewType.Docking ? null : (
- <div className="docButton" id="inkButton" title={Doc.isDocPinned(this._activeDoc) ? 'Pen on' : 'Pen off'} onClick={this.onSwitchInking}>
+ <div className="docButton" id="inkButton" onClick={this.onSwitchInking}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="pen-nib" />
</div>
);
@@ -668,7 +668,7 @@ export class MobileInterface extends React.Component {
@computed get uploadImageButton() {
if (this._activeDoc.type === DocumentType.COL && this._activeDoc !== this._homeDoc && this._activeDoc._type_collection !== CollectionViewType.Docking && this._activeDoc.title !== 'WORKSPACES') {
return (
- <div className="docButton" id="imageButton" title={Doc.isDocPinned(this._activeDoc) ? 'Pen on' : 'Pen off'} onClick={this.toggleUpload}>
+ <div className="docButton" id="imageButton" onClick={this.toggleUpload}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="upload" />
</div>
);
@@ -692,13 +692,8 @@ export class MobileInterface extends React.Component {
@computed get pinToPresentation() {
// Only making button available if it is an image
if (!(this._activeDoc.type === 'collection' || this._activeDoc.type === 'presentation')) {
- const isPinned = this._activeDoc && Doc.isDocPinned(this._activeDoc);
return (
- <div
- className="docButton"
- title={Doc.isDocPinned(this._activeDoc) ? 'Unpin from presentation' : 'Pin to presentation'}
- style={{ backgroundColor: isPinned ? 'black' : 'white', color: isPinned ? 'white' : 'black' }}
- onClick={e => TabDocView.PinDoc(this._activeDoc, {})}>
+ <div className="docButton" title={'Pin to presentation'} style={{ backgroundColor: 'white', color: 'black' }} onClick={e => TabDocView.PinDoc(this._activeDoc, {})}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
</div>
);