aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/DocServer.ts34
-rw-r--r--src/client/views/MainView.tsx8
-rw-r--r--src/client/views/nodes/WebBox.tsx3
-rw-r--r--src/new_fields/Doc.ts38
-rw-r--r--src/new_fields/util.ts11
-rw-r--r--src/server/GarbageCollector.ts2
6 files changed, 84 insertions, 12 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 87a87be92..5af89cf49 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,6 +1,6 @@
import * as OpenSocket from 'socket.io-client';
import { MessageStore, Diff, YoutubeQueryTypes } from "./../server/Message";
-import { Opt } from '../new_fields/Doc';
+import { Opt, Doc } from '../new_fields/Doc';
import { Utils, emptyFunction } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
import { RefField } from '../new_fields/RefField';
@@ -26,6 +26,38 @@ export namespace DocServer {
let GUID: string;
// indicates whether or not a document is currently being udpated, and, if so, its id
+ export enum WriteMode {
+ Always = 0,
+ None = 1,
+ SameUser = 2,
+ }
+
+ const fieldWriteModes: { [field: string]: WriteMode } = {};
+ const docsWithUpdates: { [field: string]: Doc[] } = {};
+
+ export function setFieldWriteMode(field: string, writeMode: WriteMode) {
+ fieldWriteModes[field] = writeMode;
+ if (writeMode === WriteMode.Always) {
+ const docs = docsWithUpdates[field];
+ if (docs) {
+ docs.forEach(doc => Doc.RunCachedUpdate(doc, field));
+ delete docsWithUpdates[field];
+ }
+ }
+ }
+
+ export function getFieldWriteMode(field: string) {
+ return fieldWriteModes[field];
+ }
+
+ export function registerDocWithCachedUpdate(doc: Doc, field: string) {
+ let list = docsWithUpdates[field];
+ if (!list) {
+ list = docsWithUpdates[field] = [];
+ }
+ list.push(doc);
+ }
+
export function init(protocol: string, hostname: string, port: number, identifier: string) {
_cache = {};
GUID = identifier;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 53f589684..7bc31e961 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -422,6 +422,14 @@ export class MainView extends React.Component {
</button>
</div></li>)}
<li key="undoTest"><button className="add-button round-button" title="Click if undo isn't working" onClick={() => UndoManager.TraceOpenBatches()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li>
+ <li key="test"><button className="add-button round-button" title="asdf" onClick={(() => {
+ let state = DocServer.WriteMode.Always;
+ return () => {
+ state++;
+ state = state % 3;
+ DocServer.setFieldWriteMode("x", state);
+ };
+ })()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li>
<li key="color"><button className="add-button round-button" title="Select Color" style={{ zIndex: 1000 }} onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} >
<div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}>
<SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} />
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 162ac1d98..c8749b7cd 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -8,6 +8,7 @@ import "./WebBox.scss";
import React = require("react");
import { InkTool } from "../../../new_fields/InkField";
import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
+import { Utils } from "../../../Utils";
@observer
export class WebBox extends React.Component<FieldViewProps> {
@@ -52,7 +53,7 @@ export class WebBox extends React.Component<FieldViewProps> {
if (field instanceof HtmlField) {
view = <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
} else if (field instanceof WebField) {
- view = <iframe src={field.url.href} style={{ position: "absolute", width: "100%", height: "100%" }} />;
+ view = <iframe src={Utils.CorsProxy(field.url.href)} style={{ position: "absolute", width: "100%", height: "100%" }} />;
} else {
view = <iframe src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%" }} />;
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index c01f4e8cf..ebe3a5ba8 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -68,6 +68,7 @@ export function DocListCast(field: FieldResult): Doc[] {
export const WidthSym = Symbol("Width");
export const HeightSym = Symbol("Height");
+const CachedUpdates = Symbol("Cached updates");
function fetchProto(doc: Doc) {
const proto = doc.proto;
@@ -147,6 +148,8 @@ export class Doc extends RefField {
return "invalid";
}
+ private [CachedUpdates]: { [key: string]: () => Promise<any> } = {};
+
public async [HandleUpdate](diff: any) {
const set = diff.$set;
if (set) {
@@ -154,11 +157,18 @@ export class Doc extends RefField {
if (!key.startsWith("fields.")) {
continue;
}
- const value = await SerializationHelper.Deserialize(set[key]);
const fKey = key.substring(7);
- updatingFromServer = true;
- this[fKey] = value;
- updatingFromServer = false;
+ const fn = async () => {
+ const value = await SerializationHelper.Deserialize(set[key]);
+ updatingFromServer = true;
+ this[fKey] = value;
+ updatingFromServer = false;
+ };
+ if (DocServer.getFieldWriteMode(fKey)) {
+ this[CachedUpdates][fKey] = fn;
+ } else {
+ await fn();
+ }
}
}
const unset = diff.$unset;
@@ -168,9 +178,16 @@ export class Doc extends RefField {
continue;
}
const fKey = key.substring(7);
- updatingFromServer = true;
- delete this[fKey];
- updatingFromServer = false;
+ const fn = async () => {
+ updatingFromServer = true;
+ delete this[fKey];
+ updatingFromServer = false;
+ };
+ if (DocServer.getFieldWriteMode(fKey)) {
+ this[CachedUpdates][fKey] = fn;
+ } else {
+ await fn();
+ }
}
}
}
@@ -187,6 +204,13 @@ export namespace Doc {
// return Cast(field, ctor);
// });
// }
+ export function RunCachedUpdate(doc: Doc, field: string) {
+ const update = doc[CachedUpdates][field];
+ if (update) {
+ update();
+ delete doc[CachedUpdates][field];
+ }
+ }
export function MakeReadOnly(): { end(): void } {
makeReadOnly();
return {
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index c6f693f7f..245b844fb 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -7,6 +7,8 @@ import { ObjectField } from "./ObjectField";
import { action } from "mobx";
import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
import { ComputedField } from "./ScriptField";
+import { DocServer } from "../client/DocServer";
+import { CurrentUserUtils } from "../server/authentication/models/current_user_utils";
function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
@@ -63,9 +65,14 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
} else {
target.__fields[prop] = value;
}
- if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
+ const writeMode = DocServer.getFieldWriteMode(prop as string);
if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
- else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
+ if (!writeMode || (writeMode === DocServer.WriteMode.SameUser && receiver.author === CurrentUserUtils.email)) {
+ if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
+ else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
+ } else {
+ DocServer.registerDocWithCachedUpdate(receiver, prop as string);
+ }
UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts
index ea5388004..09b52eadf 100644
--- a/src/server/GarbageCollector.ts
+++ b/src/server/GarbageCollector.ts
@@ -13,7 +13,7 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
if (field === undefined || field === null) {
continue;
}
- if (field.__type === "proxy") {
+ if (field.__type === "proxy" || field.__type === "prefetch_proxy") {
ids.push(field.fieldId);
} else if (field.__type === "list") {
addDoc(field.fields, ids, files);