aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionSubView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionSubView.tsx')
-rw-r--r--src/client/views/collections/CollectionSubView.tsx191
1 files changed, 94 insertions, 97 deletions
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 36e276d13..a7614b605 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,23 +1,25 @@
-import { action, runInAction } from "mobx";
-import React = require("react");
-import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { DragManager } from "../../util/DragManager";
-import { Docs, DocumentOptions } from "../../documents/Documents";
-import { RouteStore } from "../../../server/RouteStore";
+import { action, computed } from "mobx";
+import * as rp from 'request-promise';
+import CursorField from "../../../new_fields/CursorField";
+import { Doc, DocListCast, Opt } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/FieldSymbols";
+import { List } from "../../../new_fields/List";
+import { listSpec } from "../../../new_fields/Schema";
+import { BoolCast, Cast } from "../../../new_fields/Types";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
+import { RouteStore } from "../../../server/RouteStore";
+import { DocServer } from "../../DocServer";
+import { Docs, DocumentOptions } from "../../documents/Documents";
+import { DragManager } from "../../util/DragManager";
+import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { DocComponent } from "../DocComponent";
import { FieldViewProps } from "../nodes/FieldView";
-import * as rp from 'request-promise';
-import { CollectionView } from "./CollectionView";
+import { FormattedTextBox } from "../nodes/FormattedTextBox";
import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
-import { Doc, Opt, FieldResult, DocListCast } from "../../../new_fields/Doc";
-import { DocComponent } from "../DocComponent";
-import { listSpec } from "../../../new_fields/Schema";
-import { Cast, PromiseValue, FieldValue, ListSpec } from "../../../new_fields/Types";
-import { List } from "../../../new_fields/List";
-import { DocServer } from "../../DocServer";
-import CursorField from "../../../new_fields/CursorField";
-import { DocumentManager } from "../../util/DocumentManager";
+import { CollectionView } from "./CollectionView";
+import React = require("react");
+import { MainView } from "../MainView";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -35,9 +37,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
class CollectionSubView extends DocComponent<SubCollectionViewProps, T>(schemaCtor) {
private dropDisposer?: DragManager.DragDropDisposer;
protected createDropTarget = (ele: HTMLDivElement) => {
- if (this.dropDisposer) {
- this.dropDisposer();
- }
+ this.dropDisposer && this.dropDisposer();
if (ele) {
this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
}
@@ -46,10 +46,18 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
this.createDropTarget(ele);
}
+ @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); }
+
get childDocs() {
+ let self = this;
+ //TODO tfs: This might not be what we want?
+ //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue)
+ return DocListCast((BoolCast(this.props.Document.isTemplate) ? this.extensionDoc : this.props.Document)[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey]);
+ }
+ get childDocList() {
//TODO tfs: This might not be what we want?
//This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue)
- return DocListCast(this.props.Document[this.props.fieldKey]);
+ return Cast((BoolCast(this.props.Document.isTemplate) ? this.extensionDoc : this.props.Document)[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey], listSpec(Doc));
}
@action
@@ -60,10 +68,17 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
let email = CurrentUserUtils.email;
let pos = { x: position[0], y: position[1] };
if (id && email) {
- const proto = await doc.proto;
+ const proto = Doc.GetProto(doc);
if (!proto) {
return;
}
+ // The following conditional detects a recurring bug we've seen on the server
+ if (proto[Id] === "collectionProto") {
+ alert("COLLECTION PROTO CURSOR ISSUE DETECTED! Check console for more info...");
+ console.log(doc);
+ console.log(proto);
+ throw new Error(`AHA! You were trying to set a cursor on a collection's proto, which is the original collection proto! Look at the two previously printed lines for document values!`);
+ }
let cursors = Cast(proto.cursors, listSpec(CursorField));
if (!cursors) {
proto.cursors = cursors = new List<CursorField>();
@@ -81,79 +96,29 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
@action
protected drop(e: Event, de: DragManager.DropEvent): boolean {
if (de.data instanceof DragManager.DocumentDragData) {
- if (de.data.dropAction || de.data.userDropAction) {
- ["width", "height", "curPage"].map(key =>
- de.data.draggedDocuments.map((draggedDocument: Doc, i: number) =>
- PromiseValue(Cast(draggedDocument[key], "number")).then(f => f && (de.data.droppedDocuments[i][key] = f))));
- }
let added = false;
if (de.data.dropAction || de.data.userDropAction) {
- added = de.data.droppedDocuments.reduce((added: boolean, d) => {
- let moved = this.props.addDocument(d);
- return moved || added;
- }, false);
+ added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
} else if (de.data.moveDocument) {
- const move = de.data.moveDocument;
- added = de.data.droppedDocuments.reduce((added: boolean, d) => {
- let moved = move(d, this.props.Document, this.props.addDocument);
- return moved || added;
- }, false);
+ let movedDocs = de.data.options === this.props.Document[Id] ? de.data.draggedDocuments : de.data.droppedDocuments;
+ added = movedDocs.reduce((added: boolean, d) =>
+ de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false);
} else {
- added = de.data.droppedDocuments.reduce((added: boolean, d) => {
- let moved = this.props.addDocument(d);
- return moved || added;
- }, false);
+ added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
}
e.stopPropagation();
return added;
}
- return false;
- }
-
- protected async getDocumentFromType(type: string, path: string, options: DocumentOptions): Promise<Opt<Doc>> {
- let ctor: ((path: string, options: DocumentOptions) => (Doc | Promise<Doc | undefined>)) | undefined = undefined;
- if (type.indexOf("image") !== -1) {
- ctor = Docs.Create.ImageDocument;
- }
- if (type.indexOf("video") !== -1) {
- ctor = Docs.Create.VideoDocument;
- }
- if (type.indexOf("audio") !== -1) {
- ctor = Docs.Create.AudioDocument;
- }
- if (type.indexOf("pdf") !== -1) {
- ctor = Docs.Create.PdfDocument;
- options.nativeWidth = 1200;
- }
- if (type.indexOf("excel") !== -1) {
- ctor = Docs.Create.DBDocument;
- options.dropAction = "copy";
- }
- if (type.indexOf("html") !== -1) {
- if (path.includes(window.location.hostname)) {
- let s = path.split('/');
- let id = s[s.length - 1];
- DocServer.getRefField(id).then(field => {
- if (field instanceof Doc) {
- let alias = Doc.MakeAlias(field);
- alias.x = options.x || 0;
- alias.y = options.y || 0;
- alias.width = options.width || 300;
- alias.height = options.height || options.width || 300;
- this.props.addDocument(alias, false);
- }
- });
- return undefined;
- }
- ctor = Docs.Create.WebDocument;
- options = { height: options.width, ...options, title: path, nativeWidth: undefined };
+ else if (de.data instanceof DragManager.AnnotationDragData) {
+ e.stopPropagation();
+ return this.props.addDocument(de.data.dropDocument);
}
- return ctor ? ctor(path, options) : undefined;
+ return false;
}
@undoBatch
@action
- protected onDrop(e: React.DragEvent, options: DocumentOptions): void {
+ protected onDrop(e: React.DragEvent, options: DocumentOptions, completed?: () => void) {
if (e.ctrlKey) {
e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl
return;
@@ -167,17 +132,50 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
e.stopPropagation();
e.preventDefault();
- if (html && html.indexOf(document.location.origin)) { // prosemirror text containing link to dash document
- let start = html.indexOf(window.location.origin);
- let path = html.substr(start, html.length - start);
- let docid = path.substr(0, path.indexOf("\">")).replace(DocServer.Util.prepend("/doc/"), "").split("?")[0];
- DocServer.getRefField(docid).then(f => (f instanceof Doc) && this.props.addDocument(f, false));
+ if (html && FormattedTextBox.IsFragment(html)) {
+ let href = FormattedTextBox.GetHref(html);
+ if (href) {
+ let docid = FormattedTextBox.GetDocFromUrl(href);
+ if (docid) { // prosemirror text containing link to dash document
+ DocServer.GetRefField(docid).then(f => {
+ if (f instanceof Doc) {
+ if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
+ (f instanceof Doc) && this.props.addDocument(f, false);
+ }
+ });
+ } else {
+ this.props.addDocument && this.props.addDocument(Docs.Create.WebDocument(href, options));
+ }
+ } else if (text) {
+ this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text }), false);
+ }
return;
}
- if (html && html.indexOf("<img") !== 0 && !html.startsWith("<a")) {
- let htmlDoc = Docs.Create.HtmlDocument(html, { ...options, width: 300, height: 300, documentText: text });
- this.props.addDocument(htmlDoc, false);
- return;
+ if (html && !html.startsWith("<a")) {
+ let tags = html.split("<");
+ if (tags[0] === "") tags.splice(0, 1);
+ let img = tags[0].startsWith("img") ? tags[0] : tags.length > 1 && tags[1].startsWith("img") ? tags[1] : "";
+ if (img) {
+ let split = img.split("src=\"")[1].split("\"")[0];
+ let doc = Docs.Create.ImageDocument(split, { ...options, width: 300 });
+ this.props.addDocument(doc, false);
+ return;
+ } else {
+ let path = window.location.origin + "/doc/";
+ if (text.startsWith(path)) {
+ let docid = text.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+ DocServer.GetRefField(docid).then(f => {
+ if (f instanceof Doc) {
+ if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
+ (f instanceof Doc) && this.props.addDocument(f, false);
+ }
+ });
+ } else {
+ let htmlDoc = Docs.Create.HtmlDocument(html, { ...options, width: 300, height: 300, documentText: text });
+ this.props.addDocument(htmlDoc, false);
+ }
+ return;
+ }
}
if (text && text.indexOf("www.youtube.com/watch") !== -1) {
const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/");
@@ -194,11 +192,11 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
if (item.kind === "string" && item.type.indexOf("uri") !== -1) {
let str: string;
let prom = new Promise<string>(resolve => e.dataTransfer.items[i].getAsString(resolve))
- .then(action((s: string) => rp.head(DocServer.Util.prepend(RouteStore.corsProxy + "/" + (str = s)))))
+ .then(action((s: string) => rp.head(DocServer.prepend(RouteStore.corsProxy + "/" + (str = s)))))
.then(result => {
let type = result["content-type"];
if (type) {
- this.getDocumentFromType(type, str, { ...options, width: 300, nativeWidth: 300 })
+ Docs.Get.DocumentFromType(type, str, { ...options, width: 300, nativeWidth: 300 })
.then(doc => doc && this.props.addDocument(doc, false));
}
});
@@ -219,10 +217,9 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
body: formData
}).then(async (res: Response) => {
(await res.json()).map(action((file: any) => {
- let path = window.location.origin + file;
- let docPromise = this.getDocumentFromType(type, path, { ...options, nativeWidth: 300, width: 300, title: dropFileName });
-
- docPromise.then(doc => doc && this.props.addDocument(doc));
+ let full = { ...options, nativeWidth: 300, width: 300, title: dropFileName };
+ let path = DocServer.prepend(file);
+ Docs.Get.DocumentFromType(type, path, full).then(doc => doc && this.props.addDocument(doc));
}));
});
promises.push(prom);
@@ -230,7 +227,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
}
if (promises.length) {
- Promise.all(promises).finally(() => batch.end());
+ Promise.all(promises).finally(() => { completed && completed(); batch.end(); });
} else {
batch.end();
}