aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--src/Utils.ts3
-rw-r--r--src/client/util/Import & Export/ImageUtils.ts4
-rw-r--r--src/client/views/ContextMenu.scss4
-rw-r--r--src/client/views/MainView.scss40
-rw-r--r--src/client/views/MainView.tsx30
-rw-r--r--src/client/views/PropertiesView.scss8
-rw-r--r--src/client/views/PropertiesView.tsx18
-rw-r--r--src/client/views/collections/CollectionDockingView.scss2
-rw-r--r--src/client/views/collections/CollectionMenu.tsx2
-rw-r--r--src/client/views/collections/TabDocView.scss1
-rw-r--r--src/client/views/collections/TabDocView.tsx3
-rw-r--r--src/client/views/globalCssVariables.scss2
-rw-r--r--src/client/views/nodes/ColorBox.tsx4
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/PresBox.tsx27
-rw-r--r--src/client/views/nodes/VideoBox.tsx15
-rw-r--r--src/client/views/nodes/WebBox.tsx98
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx6
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx8
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx2
-rw-r--r--src/fields/Doc.ts8
-rw-r--r--src/fields/ScriptField.ts2
-rw-r--r--src/server/DashSession/Session/agents/server_worker.ts4
-rw-r--r--startup.sh4
27 files changed, 192 insertions, 111 deletions
diff --git a/package.json b/package.json
index ecbadcb92..13849c0f3 100644
--- a/package.json
+++ b/package.json
@@ -263,4 +263,4 @@
"xoauth2": "^1.2.0",
"xregexp": "^4.3.0"
}
-} \ No newline at end of file
+}
diff --git a/src/Utils.ts b/src/Utils.ts
index cc7ee9537..daacca51d 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -475,7 +475,7 @@ const easeInOutQuad = (currentTime: number, start: number, change: number, durat
return (-change / 2) * (newCurrentTime * (newCurrentTime - 2) - 1) + start;
};
-export function smoothScroll(duration: number, element: HTMLElement, to: number) {
+export function smoothScroll(duration: number, element: HTMLElement, to: number, finish?: () => void) {
const start = element.scrollTop;
const change = to - start;
const startDate = new Date().getTime();
@@ -489,6 +489,7 @@ export function smoothScroll(duration: number, element: HTMLElement, to: number)
requestAnimationFrame(animateScroll);
} else {
element.scrollTop = to;
+ finish?.();
}
};
animateScroll();
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index 0d12b39b8..9bd92a316 100644
--- a/src/client/util/Import & Export/ImageUtils.ts
+++ b/src/client/util/Import & Export/ImageUtils.ts
@@ -1,7 +1,6 @@
import { Doc } from "../../../fields/Doc";
import { ImageField } from "../../../fields/URLField";
-import { Cast, StrCast } from "../../../fields/Types";
-import { Docs } from "../../documents/Documents";
+import { Cast, StrCast, NumCast } from "../../../fields/Types";
import { Networking } from "../../Network";
import { Id } from "../../../fields/FieldSymbols";
import { Utils } from "../../../Utils";
@@ -22,6 +21,7 @@ export namespace ImageUtils {
} = await Networking.PostToServer("/inspectImage", { source });
document.exif = error || Doc.Get.FromJson({ data });
const proto = Doc.GetProto(document);
+ nativeWidth && (document._height = NumCast(document._width) * nativeHeight / nativeWidth);
proto["data-nativeWidth"] = nativeWidth;
proto["data-nativeHeight"] = nativeHeight;
proto["data-path"] = source;
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 7467bc043..b514de5f2 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -43,7 +43,6 @@
.contextMenu-item {
// width: 11vw; //10vw
height: 25px; //2vh
- background: whitesmoke;
display: flex; //comment out to allow search icon to be inline with search text
justify-content: left;
align-items: center;
@@ -58,7 +57,6 @@
// padding: 10px 0px 10px 0px;
white-space: nowrap;
font-size: 13px;
- color: grey;
letter-spacing: 2px;
text-transform: uppercase;
padding-right: 30px;
@@ -75,7 +73,6 @@
.contextMenu-description {
// width: 11vw; //10vw
- background: whitesmoke;
display: flex; //comment out to allow search icon to be inline with search text
justify-content: left;
-webkit-touch-callout: none;
@@ -89,7 +86,6 @@
// padding: 10px 0px 10px 0px;
white-space: nowrap;
font-size: 10px;
- color: grey;
letter-spacing: 1px;
text-transform: uppercase;
padding-right: 30px;
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index b608eceb1..b49990433 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -153,7 +153,7 @@
cursor: auto;
}
-.mainView-innerContent {
+.mainView-innerContent, .mainView-innerContent-dark {
display: contents;
flex-direction: row;
position: relative;
@@ -174,6 +174,43 @@
right: 0;
position: absolute;
z-index: 2;
+ background-color: rgb(159, 159, 159);
+ .editable-title {
+ background-color: lightgrey;
+ }
+ }
+
+}
+.mainView-innerContent-dark
+{
+ .propertiesView {
+ background-color: #252525;
+ input {
+ background-color: dimgrey;
+ }
+ .propertiesView-sharingTable
+ {
+ background-color: dimgrey;
+ }
+ .editable-title {
+ background-color: dimgrey;
+ }
+ .propertiesView-field {
+ background-color: dimgrey;
+ }
+ }
+ .mainView-propertiesDragger,
+ .mainView-libraryHandle {
+ background: #353535;
+ }
+}
+.mainView-container-dark {
+ .contextMenu-cont {
+ background: dimgrey;
+ color: white;
+ input::placeholder {
+ color:white;
+ }
}
}
@@ -334,7 +371,6 @@
position: relative;
z-index: 41; // lm_maximised has a z-index of 40 and this needs to be above that
touch-action: none;
- background-color: lightgrey;
cursor: grab;
display: flex;
align-items: center;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 1730007a5..3a3dbc68f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -229,25 +229,29 @@ export class MainView extends React.Component {
getContentsHeight = () => this._panelHeight - Number(SEARCH_PANEL_HEIGHT.replace("px", ""));
defaultBackgroundColors = (doc: Opt<Doc>, renderDepth: number) => {
- if (doc?.type === DocumentType.COL) {
- return Doc.IsSystem(doc) ? "lightgrey" : StrCast(renderDepth > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground);
- }
if (this.darkScheme) {
switch (doc?.type) {
- case DocumentType.FONTICON: return "white";
+ case DocumentType.PRESELEMENT: return "dimgrey";
+ case DocumentType.PRES: return "#3e3e3e";
+ case DocumentType.FONTICON: return "black";
case DocumentType.RTF || DocumentType.LABEL || DocumentType.BUTTON: return "#2d2d2d";
case DocumentType.LINK:
- case DocumentType.COL: if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)";
+ case DocumentType.COL:
+ return Doc.IsSystem(doc) ? "rgb(62,62,62)" : StrCast(renderDepth > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground);
+ //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)";
default: return "black";
}
} else {
switch (doc?.type) {
+ case DocumentType.PRESELEMENT: return "";
case DocumentType.FONTICON: return "black";
case DocumentType.RTF: return "#f1efeb";
case DocumentType.BUTTON:
case DocumentType.LABEL: return "lightgray";
case DocumentType.LINK:
- case DocumentType.COL: if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "lightgray";
+ case DocumentType.COL:
+ return Doc.IsSystem(doc) ? "lightgrey" : StrCast(renderDepth > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground);
+ //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "lightgray";
default: return "white";
}
}
@@ -345,7 +349,7 @@ export class MainView extends React.Component {
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
relative={true}
- forcedBackgroundColor={() => "lightgrey"}
+ forcedBackgroundColor={() => this.darkScheme ? "rgb(62,62,62)" : "lightgrey"}
/>
</div>
{this.docButtons}
@@ -411,18 +415,18 @@ export class MainView extends React.Component {
@computed get mainInnerContent() {
return <>
{this.menuPanel}
- <div className="mainView-innerContent" >
+ <div className={`mainView-innerContent${this.darkScheme ? "-dark" : ""}`}>
{this.flyout}
- <div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
- <FontAwesomeIcon icon="chevron-left" color="black" size="sm" />
+ < div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined, }} onPointerDown={this.onFlyoutPointerDown} >
+ <FontAwesomeIcon icon="chevron-left" color={this.darkScheme ? "white" : "black"} size="sm" />
</div>
{this.dockingContent}
<div className="mainView-propertiesDragger" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
- <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color="black" size="sm" />
+ <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? "white" : "black"} size="sm" />
</div>
- {this.propertiesWidth() < 10 ? (null) : <PropertiesView width={this.propertiesWidth()} height={this.getContentsHeight()} />}
+ {this.propertiesWidth() < 10 ? (null) : <PropertiesView backgroundColor={this.defaultBackgroundColors} width={this.propertiesWidth()} height={this.getContentsHeight()} />}
</div>
</>;
}
@@ -443,7 +447,7 @@ export class MainView extends React.Component {
expandFlyout = action((button: Doc) => {
this._flyoutWidth = (this._flyoutWidth || 250);
this._sidebarContent.proto = button.target as any;
- button._backgroundColor = "lightgrey";
+ button._backgroundColor = this.darkScheme ? "dimgrey" : "lightgrey";
button.color = "black";
this._lastButton = button;
});
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index ce2a87733..1365725cb 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -1,6 +1,4 @@
.propertiesView {
-
- background-color: rgb(205, 205, 205);
height: 100%;
font-family: "Noto Sans";
cursor: auto;
@@ -9,7 +7,6 @@
overflow-y: auto;
.propertiesView-title {
- background-color: rgb(159, 159, 159);
text-align: center;
padding-top: 12px;
padding-bottom: 12px;
@@ -335,7 +332,6 @@
}
}
}
-
.propertiesView-fields {
//border-bottom: 1px solid black;
//padding: 8.5px;
@@ -390,7 +386,7 @@
}
}
- .field {
+ .propertiesView-field {
display: flex;
font-size: 7px;
background-color: #e8e8e8;
@@ -400,7 +396,7 @@
padding-left: 3px;
}
- .uneditable-field {
+ .propertiesView-uneditable-field {
display: flex;
overflow-y: visible;
margin-bottom: 2px;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 9b77e2736..fad2f5284 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -5,7 +5,7 @@ import { intersection } from "lodash";
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
import { ColorState, SketchPicker } from "react-color";
-import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc";
+import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, WidthSym, Opt } from "../../fields/Doc";
import { Id } from "../../fields/FieldSymbols";
import { InkField } from "../../fields/InkField";
import { ComputedField } from "../../fields/ScriptField";
@@ -36,6 +36,7 @@ const _global = (window /* browser */ || global /* node */) as any;
interface PropertiesViewProps {
width: number;
height: number;
+ backgroundColor: (doc: Opt<Doc>, renderDepth: number) => Opt<string>;
}
@observer
@@ -61,7 +62,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openOptions: boolean = true;
@observable openSharing: boolean = true;
@observable openFields: boolean = true;
- @observable openLayout: boolean = true;
+ @observable openLayout: boolean = false;
@observable openContexts: boolean = true;
@observable openAppearance: boolean = true;
@observable openTransform: boolean = true;
@@ -144,7 +145,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>);
}
}
- rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+ rows.push(<div className="propertiesView-field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
<EditableView
key="editableView"
contents={"add key:value or #tags"}
@@ -172,14 +173,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
docs.forEach(doc => docvals.add(doc[key]));
const contents = Array.from(docvals.keys()).length > 1 ? "-multiple" : docs[0][key];
if (key[0] === "#") {
- rows.push(<div className="uneditable-field" key={key}>
+ rows.push(<div className="propertiesView-uneditable-field" key={key}>
<span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
&nbsp;
</div>);
} else if (contents !== undefined) {
const value = Field.toString(contents as Field);
if (noviceReqFields.includes(key) || key.indexOf("lastModified") !== -1) {
- rows.push(<div className="uneditable-field" key={key}>
+ rows.push(<div className="propertiesView-uneditable-field" key={key}>
<span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ": "}</span>
<div style={{ whiteSpace: "nowrap", overflowX: "hidden" }}>{value}</div>
</div>);
@@ -200,7 +201,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
}
}
- rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+ rows.push(<div className="propertiesView-field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
<EditableView
key="editableView"
contents={"add key:value or #tags"}
@@ -253,7 +254,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return !this.selectedDoc ? (null) : <PropertiesDocContextSelector Document={this.selectedDoc} hideTitle={true} addDocTab={(doc, where) => CollectionDockingView.AddSplit(doc, "right")} />;
}
- previewBackground = () => "lightgrey";
@computed get layoutPreview() {
if (SelectionManager.SelectedDocuments().length > 1) {
return "-- multiple selected --";
@@ -270,7 +270,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
renderDepth={1}
rootSelected={returnFalse}
treeViewDoc={undefined}
- backgroundColor={this.previewBackground}
+ backgroundColor={this.props.backgroundColor}
fitToBox={true}
FreezeDimensions={true}
dontCenter={true}
@@ -856,7 +856,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
if (this.selectedDoc && !this.isPres) {
return <div className="propertiesView" style={{
width: this.props.width,
- minWidth: this.props.width
+ minWidth: this.props.width,
//overflowY: this.scrolling ? "scroll" : "visible"
}} >
<div className="propertiesView-title" style={{ width: this.props.width }}>
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 8b1594b21..f4736eb29 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -4,7 +4,7 @@
.lm_title {
margin-top: 3px;
border-radius: 5px;
- border: solid 1px dimgray;
+ border: solid 0px dimgray;
border-width: 2px 2px 0px;
height: 20px;
transform: translate(0px, -3px);
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 38817a601..1dbafbd61 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1324,5 +1324,5 @@ Scripting.addGlobal(function gotoFrame(doc: any, newFrame: any) {
CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
}
CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
- doc._currentFrame = Math.max(0, newFrame);
+ doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
});
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index edf556c9f..9acbc4f85 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -43,7 +43,6 @@ input.lm_title {
right: 0;
width: 45px;
height: 45px;
- background: white;
transform: translate(20px, 20px) rotate(45deg);
border-radius: 30px;
padding: 2px;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 82530c26d..38b9b399d 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -336,7 +336,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
</div>
<Tooltip title={<div className="dash-tooltip">{"toggle minimap"}</div>}>
- <div className="miniMap-hidden" onPointerDown={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} >
+ <div className="miniMap-hidden" onPointerDown={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })}
+ style={{ background: CollectionDockingView.Instance.props.backgroundColor?.(this._document, 0) }} >
<FontAwesomeIcon icon={"globe-asia"} size="lg" />
</div>
</Tooltip>
diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss
index 1e0b023d7..b2ea87c06 100644
--- a/src/client/views/globalCssVariables.scss
+++ b/src/client/views/globalCssVariables.scss
@@ -33,7 +33,7 @@ $searchpanel-height: 32px;
$mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc
$docDecorations-zindex: 998; // then doc decorations appear over everything else
$remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right?
-$COLLECTION_BORDER_WIDTH: 1;
+$COLLECTION_BORDER_WIDTH: 0;
$SCHEMA_DIVIDER_WIDTH: 4;
$MINIMIZED_ICON_SIZE:25;
$MAX_ROW_HEIGHT: 44px;
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index fcc9e50f5..4fb350b55 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -69,11 +69,11 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument
SetActiveInkWidth(e.target.value);
SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value));
}} />
- <div> {ActiveInkBezierApprox() ?? 2}</div>
+ {/* <div> {ActiveInkBezierApprox() ?? 2}</div>
<input type="range" defaultValue={ActiveInkBezierApprox() ?? 2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
SetActiveBezierApprox(e.target.value);
SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value);
- }} />
+ }} /> */}
<br />
<br />
</div>
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index bc3ad5bce..0c52b9044 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -40,7 +40,7 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp
@computed get panelWidth() { return this.nativeWidth() && !this.props.Document._fitWidth ? this.nativeWidth() * this.contentScaling() : this.props.PanelWidth(); }
@computed get panelHeight() {
if (this.nativeHeight()) {
- if (!this.props.Document._fitWidth) return this.nativeHeight() * this.contentScaling()
+ if (!this.props.Document._fitWidth) return this.nativeHeight() * this.contentScaling();
else return this.panelWidth / Doc.NativeAspect(this.layoutDoc, this.props.DataDoc, this.freezeDimensions) || 1;
}
return this.props.PanelHeight();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0b27cd03c..a4da00578 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -839,8 +839,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onClicks.push({ description: "Select on Click", event: () => this.selectOnClick(), icon: "link" });
onClicks.push({ description: "Follow Link on Click", event: () => this.followLinkOnClick(undefined, false), icon: "link" });
onClicks.push({ description: "Toggle Link Target on Click", event: () => this.toggleTargetOnClick(), icon: "map-pin" });
+ !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
}
- !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
}
const funcs: ContextMenuProps[] = [];
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index a31e92807..518d365ed 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -91,7 +91,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const tagDocs: Doc[] = [];
for (const doc of this.childDocs) {
const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
- tagDocs.push(tagDoc)
+ tagDocs.push(tagDoc);
}
return tagDocs;
}
@@ -486,7 +486,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
//stops the presentaton.
resetPresentation = () => {
this.rootDoc._itemIndex = 0;
- for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1;
+ this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => {
+ try {
+ doc.opacity = 1;
+ } catch (e) {
+ console.log("REset presentation error: ", e);
+ }
+ });
+ ///for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1;
}
@action togglePath = (srcContext: Doc, off?: boolean) => {
@@ -638,9 +645,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => {
const curDoc = Cast(doc, Doc, null);
const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null);
- if (curDoc && curDoc === this.activeItem) return <div className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div>
- else if (tagDoc) return <div className="selectedList-items">{index + 1}. {curDoc.title}</div>;
- else if (curDoc) return <div className="selectedList-items">{index + 1}. {curDoc.title}</div>;
+ if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div>;
+ else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>;
+ else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>;
});
return list;
}
@@ -799,10 +806,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
getAllIndexes = (arr: Doc[], val: Doc): number[] => {
- var indexes = [], i;
- for (i = 0; i < arr.length; i++)
- if (arr[i] === val)
- indexes.push(i);
+ const indexes = [];
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] === val && indexes.push(i);
+ }
return indexes;
}
@@ -952,7 +959,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
doc.presMovement = PresMovement.None;
break;
}
- })
+ });
});
@undoBatch
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 250595db5..190193351 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -159,7 +159,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
@action
updateTimecode = () => {
this.player && (this.layoutDoc._currentTimecode = this.player.currentTime);
- this._youtubePlayer && (this.layoutDoc._currentTimecode = this._youtubePlayer.getCurrentTime());
+ this._youtubePlayer && (this.layoutDoc._currentTimecode = this._youtubePlayer.getCurrentTime?.());
}
componentDidMount() {
@@ -281,13 +281,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
() => !this.props.Document.isAnnotating && Doc.GetSelectedTool() === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting,
(interactive) => iframe.style.pointerEvents = interactive ? "all" : "none", { fireImmediately: true });
};
- this._youtubePlayer = new YT.Player(`${this.youtubeVideoId + this._youtubeIframeId}-player`, {
- events: {
- 'onReady': this.props.dontRegisterView ? undefined : onYoutubePlayerReady,
- 'onStateChange': this.props.dontRegisterView ? undefined : onYoutubePlayerStateChange,
- }
+ (YT as any)?.ready(() => {
+ this._youtubePlayer = new YT.Player(`${this.youtubeVideoId + this._youtubeIframeId}-player`, {
+ events: {
+ 'onReady': this.props.dontRegisterView ? undefined : onYoutubePlayerReady,
+ 'onStateChange': this.props.dontRegisterView ? undefined : onYoutubePlayerStateChange,
+ }
+ })
});
-
}
private get uIButtons() {
const curTime = (this.layoutDoc._currentTimecode || 0);
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index de5546fa9..8a8f46963 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,4 +1,3 @@
-import { faMousePointer, faPen, faStickyNote } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
@@ -47,6 +46,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _startX: number = 0;
private _startY: number = 0;
+ private _scrollTarget: any = undefined;
@observable private _marqueeX: number = 0;
@observable private _marqueeY: number = 0;
@observable private _marqueeWidth: number = 0;
@@ -61,8 +61,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
@observable private _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>();
private _selectionReactionDisposer?: IReactionDisposer;
private _scrollReactionDisposer?: IReactionDisposer;
+ private _scrollTopReactionDisposer?: IReactionDisposer;
private _moveReactionDisposer?: IReactionDisposer;
- private _keyInput = React.createRef<HTMLInputElement>();
private _longPressSecondsHack?: NodeJS.Timeout;
private _outerRef = React.createRef<HTMLDivElement>();
private _iframeRef = React.createRef<HTMLIFrameElement>();
@@ -83,14 +83,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
if (iframe && iframe.contentDocument) {
iframe.setAttribute("enable-annotation", "true");
iframe.contentDocument.addEventListener("click", undoBatch(action(e => {
- const href = e.target?.href;
+ let href = "";
+ for (let ele = e.target; ele; ele = ele.parentElement) {
+ href = (typeof (ele.href) === "string" ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href;
+ }
if (href) {
this._url = href.replace(Utils.prepend(""), Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.origin);
this.submitURL();
}
})));
- iframe.contentDocument.addEventListener('pointerdown', this.iframedown, false);
- iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false);
+ iframe.contentDocument.addEventListener('wheel', this.iframeWheel, false);
+ iframe.contentDocument.addEventListener('scroll', this.iframeScroll, false);
this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000;
iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc._scrollTop);
iframe.contentDocument.children[0].scrollLeft = NumCast(this.layoutDoc._scrollLeft);
@@ -102,17 +105,30 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/);
const duration = durationStr ? Number(durationStr[1]) : 1000;
if (scrollY !== undefined) {
- setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollY || 0)), delay);
- setTimeout(() => { this.layoutDoc._scrollTop = scrollY; this.layoutDoc._scrollY = undefined; }, duration + delay);
+ this._forceSmoothScrollUpdate = true;
+ this.layoutDoc._scrollY = undefined;
+ setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollY || 0), () => this.layoutDoc._scrollTop = scrollY), delay);
}
if (scrollX !== undefined) {
- setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollX || 0)), delay);
- setTimeout(() => { this.layoutDoc._scrollLeft = scrollX; this.layoutDoc._scrollX = undefined; }, duration + delay);
+ this._forceSmoothScrollUpdate = true;
+ this.layoutDoc._scrollX = undefined;
+ setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollX || 0), () => this.layoutDoc._scrollLeft = scrollX), delay);
}
},
{ fireImmediately: true }
);
+ this._scrollTopReactionDisposer = reaction(() => this.layoutDoc._scrollTop,
+ scrollTop => {
+ const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/);
+ const duration = durationStr ? Number(durationStr[1]) : 1000;
+ if (scrollTop !== undefined && this._forceSmoothScrollUpdate) {
+ this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollTop || 0), () => this._forceSmoothScrollUpdate = true);
+ } else this._forceSmoothScrollUpdate = true;
+ },
+ { fireImmediately: true }
+ );
});
+ _forceSmoothScrollUpdate = true;
updateScroll = (x: Opt<number>, y: Opt<number>) => {
if (y !== undefined) {
@@ -126,18 +142,28 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func;
- iframedown = (e: PointerEvent) => {
- this._setPreviewCursor?.(e.screenX, e.screenY, false);
- }
- iframeScrolled = (e: any) => {
- if (e.target?.children) {
- e.target.children[0].scrollLeft = 0;
- const scrollTop = e.target.children[0].scrollTop;
- const scrollLeft = e.target.children[0].scrollLeft;
- this.layoutDoc._scrollTop = this._outerRef.current!.scrollTop = scrollTop;
- this.layoutDoc._scrollLeft = this._outerRef.current!.scrollLeft = scrollLeft;
+ iframeWheel = (e: any) => {
+ if (this._forceSmoothScrollUpdate && e.target?.children) {
+ this._scrollTarget && setTimeout(action(() => {
+ this._scrollTarget.scrollLeft = 0;
+ const scrollTop = this._scrollTarget.scrollTop;
+ const scrollLeft = this._scrollTarget.scrollLeft;
+ this._outerRef.current!.scrollTop = scrollTop;
+ this._outerRef.current!.scrollLeft = scrollLeft;
+ if (this.layoutDoc._scrollTop !== scrollTop) {
+ this._forceSmoothScrollUpdate = false;
+ this.layoutDoc._scrollTop = scrollTop;
+ }
+ if (this.layoutDoc._scrollLeft !== scrollLeft) {
+ this._forceSmoothScrollUpdate = false;
+ this.layoutDoc._scrollLeft = scrollLeft;
+ }
+ }))
}
}
+ iframeScroll = (e: any) => {
+ this._scrollTarget = e.target.children[0];
+ }
async componentDidMount() {
const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField);
runInAction(() => this._url = urlField?.url.toString() || "");
@@ -180,11 +206,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
componentWillUnmount() {
this._moveReactionDisposer?.();
this._selectionReactionDisposer?.();
+ this._scrollTopReactionDisposer?.();
this._scrollReactionDisposer?.();
document.removeEventListener("pointerup", this.onLongPressUp);
document.removeEventListener("pointermove", this.onLongPressMove);
- this._iframeRef.current?.contentDocument?.removeEventListener('pointerdown', this.iframedown);
- this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScrolled);
+ this._iframeRef.current?.contentDocument?.removeEventListener('wheel', this.iframeWheel);
+ this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScroll);
}
onUrlDragover = (e: React.DragEvent) => {
@@ -468,7 +495,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
@computed get annotationLayer() {
TraceMobx();
- return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) }} ref={this._annotationLayer}>
+ return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
{this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
<Annotation {...this.props} showInfo={emptyFunction} focus={this.props.focus} dataDoc={this.dataDoc} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />)
}
@@ -542,10 +569,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
else if (this._mainCont.current) {
// set marquee x and y positions to the spatially transformed position
+ const nheight = Doc.NativeHeight(this.Document) || 1;
+ const nwidth = Doc.NativeWidth(this.Document) || 1;
const boundingRect = this._mainCont.current.getBoundingClientRect();
- const boundingHeight = (Doc.NativeHeight(this.Document) || 1) / (Doc.NativeWidth(this.Document) || 1) * boundingRect.width;
- this._startX = (e.clientX - boundingRect.left) / boundingRect.width * (Doc.NativeWidth(this.Document) || 1);
- this._startY = (e.clientY - boundingRect.top) / boundingHeight * (Doc.NativeHeight(this.Document) || 1);
+ const boundingHeight = nheight / nwidth * boundingRect.width;
+ this._startX = (e.clientX - boundingRect.left) / boundingRect.width * nwidth;
+ this._startY = (e.clientY - boundingRect.top) / boundingHeight * nheight;
this._marqueeHeight = this._marqueeWidth = 0;
this._marqueeing = true;
}
@@ -619,23 +648,24 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
marqueeX = () => this._marqueeX;
marqueeY = () => this._marqueeY;
marqueeing = () => this._marqueeing;
- visibleHeiht = () => {
+ visibleHeight = () => {
if (this._mainCont.current) {
const boundingRect = this._mainCont.current.getBoundingClientRect();
- const scalin = (Doc.NativeWidth(this.Document) || 0) / boundingRect.width;
- return Math.min(boundingRect.height * scalin, this.props.PanelHeight() * scalin);
+ const scaling = (Doc.NativeWidth(this.Document) || 0) / boundingRect.width;
+ return Math.min(boundingRect.height * scaling, this.props.PanelHeight() * scaling);
}
return this.props.PanelHeight();
}
scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
render() {
+ const scaling = Number.isFinite(this.props.ContentScaling()) ? this.props.ContentScaling() || 1 : 1;
return (<div className="webBox" ref={this._mainCont} >
<div className={`webBox-container`}
style={{
position: undefined,
- transform: `scale(${this.props.ContentScaling()})`,
- width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
- height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
+ transform: `scale(${scaling})`,
+ width: `${100 / scaling}% `,
+ height: `${100 / scaling}% `,
pointerEvents: this.layoutDoc._isBackground ? "none" : undefined
}}
onContextMenu={this.specificContextMenu}>
@@ -643,7 +673,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
{this.content}
<div className={"webBox-outerContent"} ref={this._outerRef}
style={{
- width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%",
+ width: `${Math.max(100, 100 / scaling)}% `,
pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc._isBackground ? "all" : "none"
}}
onWheel={e => e.stopPropagation()}
@@ -662,14 +692,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
//this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
}}>
<div className={"webBox-innerContent"} style={{
- height: NumCast(this.layoutDoc.scrollHeight),
+ height: NumCast(this.layoutDoc.scrollHeight, 50),
pointerEvents: this.layoutDoc._isBackground ? "none" : undefined
}}>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
PanelHeight={this.props.PanelHeight}
PanelWidth={this.props.PanelWidth}
annotationsKey={this.annotationKey}
- VisibleHeight={this.visibleHeiht}
+ VisibleHeight={this.visibleHeight}
focus={this.props.focus}
setPreviewCursor={this.setPreviewCursor}
isSelected={this.props.isSelected}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 9307f1649..b75cc230f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -22,7 +22,7 @@
border-style: solid;
overflow-y: auto;
overflow-x: hidden;
- color: initial;
+ color: inherit;
display: flex;
flex-direction: row;
transition: opacity 1s;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index d44f35a96..bc9e8e99d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -11,7 +11,7 @@ import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "
import { ReplaceStep } from 'prosemirror-transform';
import { EditorView } from "prosemirror-view";
import { DateField } from '../../../../fields/DateField';
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer } from "../../../../fields/Doc";
+import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer, ForceServerWrite } from "../../../../fields/Doc";
import { documentSchema } from '../../../../fields/documentSchemas';
import applyDevTools = require("prosemirror-dev-tools");
import { removeMarkWithAttrs } from "./prosemirrorPatches";
@@ -805,9 +805,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
tr = tr.addMark(pos, pos + node.nodeSize, link);
}
});
- this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents
+ this.dataDoc[ForceServerWrite] = this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents
this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter));
- this.dataDoc[UpdatingFromServer] = false;
+ this.dataDoc[UpdatingFromServer] = this.dataDoc[ForceServerWrite] = false;
}
}
componentDidMount() {
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 2700c508b..cf9b03308 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -31,6 +31,7 @@ const { toggleMark } = require("prosemirror-commands");
export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
static Instance: RichTextMenu;
public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
+ private _linkToRef = React.createRef<HTMLInputElement>();
@observable public view?: EditorView;
public editorProps: FieldViewProps & FormattedTextBoxProps | undefined;
@@ -154,6 +155,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@action
public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) {
+ if (this._linkToRef.current?.getBoundingClientRect().width) {
+ return;
+ }
this.view = view;
if (!view || !view.hasFocus()) {
return;
@@ -792,7 +796,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const self = this;
function onLinkChange(e: React.ChangeEvent<HTMLInputElement>) {
- self.TextView.endUndoTypingBatch();
+ self.TextView?.endUndoTypingBatch();
UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), "link change");
}
@@ -807,7 +811,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const dropdownContent =
<div className="dropdown link-menu">
<p>Linked to:</p>
- <input value={link} placeholder="Enter URL" onChange={onLinkChange} />
+ <input value={link} ref={this._linkToRef} placeholder="Enter URL" onChange={onLinkChange} />
<button className="make-button" onPointerDown={e => this.makeLinkToURL(link, "add:right")}>Apply hyperlink</button>
<div className="divider"></div>
<button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index c90395b82..b2acad86e 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -311,7 +311,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
<div className="presItem-number">
{`${this.indexInPres + 1}.`}
</div>}
- {miniView ? (null) : <div ref={miniView ? null : this._dragRef} className={`presItem-slide ${isSelected ? "active" : ""}`}>
+ {miniView ? (null) : <div ref={miniView ? null : this._dragRef} className={`presItem-slide ${isSelected ? "active" : ""}`} style={{ backgroundColor: this.props.backgroundColor?.(this.layoutDoc, this.props.renderDepth) }}>
<div className="presItem-name" style={{ maxWidth: showMore ? (toolbarWidth - 175) : toolbarWidth - 85, cursor: isSelected ? 'text' : 'grab' }}>
<EditableView
ref={this._titleRef}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index adda40621..4c3c45d92 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -92,6 +92,7 @@ export const AclAddonly = Symbol("AclAddonly");
export const AclEdit = Symbol("AclEdit");
export const AclAdmin = Symbol("AclAdmin");
export const UpdatingFromServer = Symbol("UpdatingFromServer");
+export const ForceServerWrite = Symbol("ForceServerWrite");
export const CachedUpdates = Symbol("Cached updates");
const AclMap = new Map<string, symbol>([
@@ -185,9 +186,10 @@ export class Doc extends RefField {
@observable public [AclSym]: { [key: string]: symbol };
private [UpdatingFromServer]: boolean = false;
+ private [ForceServerWrite]: boolean = false;
private [Update] = (diff: any) => {
- !this[UpdatingFromServer] && DocServer.UpdateField(this[Id], diff);
+ (!this[UpdatingFromServer] || this[ForceServerWrite]) && DocServer.UpdateField(this[Id], diff);
}
private [Self] = this;
@@ -680,7 +682,7 @@ export namespace Doc {
templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = Cast(templateLayoutDoc.proto, Doc, null) || templateLayoutDoc); // if the template has already been applied (ie, a nested template), then use the template's prototype
if (!targetDoc[expandedLayoutFieldKey]) {
_pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey + args, true);
- setTimeout(() => {
+ setTimeout(action(() => {
const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
// the template's arguments are stored in params which is derefenced to find
// the actual field key where the parameterized template data is stored.
@@ -694,7 +696,7 @@ export namespace Doc {
targetDoc[expandedLayoutFieldKey] = newLayoutDoc;
_pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey + args);
- });
+ }));
}
}
}
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 47efccc99..024017302 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -196,7 +196,7 @@ export class ComputedField extends ScriptField {
}
Scripting.addGlobal(function getIndexVal(list: any[], index: number) {
- return list.reduce((p, x, i) => (i <= index && x !== undefined) || p === undefined ? x : p, undefined as any);
+ return list?.reduce((p, x, i) => (i <= index && x !== undefined) || p === undefined ? x : p, undefined as any);
}, "returns the value at a given index of a list", "(list: any[], index: number)");
Scripting.addGlobal(function makeScript(script: string) {
diff --git a/src/server/DashSession/Session/agents/server_worker.ts b/src/server/DashSession/Session/agents/server_worker.ts
index afa5fc68d..6a19bfa5d 100644
--- a/src/server/DashSession/Session/agents/server_worker.ts
+++ b/src/server/DashSession/Session/agents/server_worker.ts
@@ -113,8 +113,8 @@ export class ServerWorker extends IPCMessageReceiver {
this.shouldServerBeResponsive = false;
// communicates via IPC to the master thread that it should dispatch a crash notification email
const { name, message, stack } = error;
- const deconstructed_error: ErrorLike = { name, message, stack };
- this.emit(Monitor.IntrinsicEvents.CrashDetected, { error: deconstructed_error });
+ const errorLike: ErrorLike = { name, message, stack };
+ this.emit(Monitor.IntrinsicEvents.CrashDetected, { error: errorLike });
await this.executeExitHandlers(error);
// notify master thread (which will log update in the console) of crash event via IPC
this.lifecycleNotification(red(`crash event detected @ ${new Date().toUTCString()}`));
diff --git a/startup.sh b/startup.sh
new file mode 100644
index 000000000..6554b5666
--- /dev/null
+++ b/startup.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+cd /c/Users/dash/Desktop/Dash-Web # cd /c/Users/dash/Documents/Dash-Web instead for dash-release
+npm run start-release
+# works for browndash \ No newline at end of file