aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentView.tsx
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-03-05 22:20:52 -0500
committerBob Zeleznik <zzzman@gmail.com>2020-03-05 22:20:52 -0500
commitb667ac18c58cd022219bec091e59977107b5bd7d (patch)
treebf79b3ad5fa5c3ebd89383b1c7cc50e846697900 /src/client/views/nodes/DocumentView.tsx
parent45643918180f32f070f8d9f770c446b70c08548d (diff)
parent288e4d24b61d281819b7f0b5bb697edbcc9ed173 (diff)
Merge branch 'master' into audio_refactor
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
-rw-r--r--src/client/views/nodes/DocumentView.tsx358
1 files changed, 271 insertions, 87 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index fb97c18c3..7d2940df5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import * as fa from '@fortawesome/free-solid-svg-icons';
-import { action, computed, observable, runInAction } from "mobx";
+import { action, computed, runInAction, trace, observable } from "mobx";
import { observer } from "mobx-react";
import * as rp from "request-promise";
import { Doc, DocListCast, Opt } from "../../../new_fields/Doc";
@@ -45,6 +45,12 @@ import { FormattedTextBox } from './FormattedTextBox';
import React = require("react");
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { CollectionStackingView } from '../collections/CollectionStackingView';
+import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField';
+import { ClientRecommender } from '../../ClientRecommender';
+import { SearchUtil } from '../../util/SearchUtil';
+import { RadialMenu } from './RadialMenu';
+import { KeyphraseQueryView } from '../KeyphraseQueryView';
library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -59,6 +65,8 @@ export interface DocumentViewProps {
LibraryPath: Doc[];
fitToBox?: boolean;
onClick?: ScriptField;
+ onPointerDown?: ScriptField;
+ onPointerUp?: ScriptField;
dragDivName?: string;
addDocument?: (doc: Doc) => boolean;
removeDocument?: (doc: Doc) => boolean;
@@ -92,10 +100,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
private _doubleTap = false;
private _mainCont = React.createRef<HTMLDivElement>();
private _dropDisposer?: DragManager.DragDropDisposer;
+ private _showKPQuery: boolean = false;
+ private _queries: string = "";
private _gestureEventDisposer?: GestureUtils.GestureEventDisposer;
private _titleRef = React.createRef<EditableView>();
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ private holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
public get ContentDiv() { return this._mainCont.current; }
@@ -104,72 +115,85 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get nativeWidth() { return this.layoutDoc._nativeWidth || 0; }
@computed get nativeHeight() { return this.layoutDoc._nativeHeight || 0; }
@computed get onClickHandler() { return this.props.onClick || this.layoutDoc.onClick || this.Document.onClick; }
+ @computed get onPointerDownHandler() { return this.props.onPointerDown ? this.props.onPointerDown : this.Document.onPointerDown; }
+ @computed get onPointerUpHandler() { return this.props.onPointerUp ? this.props.onPointerUp : this.Document.onPointerUp; }
- private _firstX: number = 0;
- private _firstY: number = 0;
-
-
- // handle1PointerHoldStart = (e: React.TouchEvent): any => {
- // this.onRadialMenu(e);
- // const pt = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true)[0];
- // this._firstX = pt.pageX;
- // this._firstY = pt.pageY;
- // e.stopPropagation();
- // e.preventDefault();
-
- // document.removeEventListener("touchmove", this.onTouch);
- // document.removeEventListener("touchmove", this.handle1PointerHoldMove);
- // document.addEventListener("touchmove", this.handle1PointerHoldMove);
- // document.removeEventListener("touchend", this.handle1PointerHoldEnd);
- // document.addEventListener("touchend", this.handle1PointerHoldEnd);
- // }
-
- // handle1PointerHoldMove = (e: TouchEvent): void => {
- // const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
- // if (Math.abs(pt.pageX - this._firstX) > 150 || Math.abs(pt.pageY - this._firstY) > 150) {
- // this.handleRelease();
- // }
- // document.removeEventListener("touchmove", this.handle1PointerHoldMove);
- // document.addEventListener("touchmove", this.handle1PointerHoldMove);
- // document.removeEventListener("touchend", this.handle1PointerHoldEnd);
- // document.addEventListener("touchend", this.handle1PointerHoldEnd);
- // }
-
- // handleRelease() {
- // RadialMenu.Instance.closeMenu();
- // document.removeEventListener("touchmove", this.handle1PointerHoldMove);
- // document.removeEventListener("touchend", this.handle1PointerHoldEnd);
- // }
-
- // handle1PointerHoldEnd = (e: TouchEvent): void => {
- // RadialMenu.Instance.closeMenu();
- // document.removeEventListener("touchmove", this.handle1PointerHoldMove);
- // document.removeEventListener("touchend", this.handle1PointerHoldEnd);
- // }
-
- // @action
- // onRadialMenu = (e: React.TouchEvent): void => {
- // const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
-
- // RadialMenu.Instance.openMenu();
-
- // RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight"), icon: "layer-group", selected: -1 });
- // RadialMenu.Instance.addItem({ description: "Delete this document", event: () => this.props.ContainingCollectionView?.removeDocument(this.props.Document), icon: "trash", selected: -1 });
- // RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "folder", selected: -1 });
- // RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin", selected: -1 });
-
- // RadialMenu.Instance.displayMenu(pt.pageX - 15, pt.pageY - 15);
- // if (!SelectionManager.IsSelected(this, true)) {
- // SelectionManager.SelectDoc(this, false);
- // }
- // e.stopPropagation();
- // }
+ private _firstX: number = -1;
+ private _firstY: number = -1;
+
+
+
+ handle1PointerHoldStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): any => {
+ this.removeMoveListeners();
+ this.removeEndListeners();
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ console.log(SelectionManager.SelectedDocuments());
+ console.log("START");
+ if (RadialMenu.Instance._display === false) {
+ this.addHoldMoveListeners();
+ this.addHoldEndListeners();
+ this.onRadialMenu(e, me);
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+ this._firstX = pt.pageX;
+ this._firstY = pt.pageY;
+ }
+
+ }
+
+ handle1PointerHoldMove = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
+
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+
+ if (this._firstX === -1 || this._firstY === -1) {
+ return;
+ }
+ if (Math.abs(pt.pageX - this._firstX) > 150 || Math.abs(pt.pageY - this._firstY) > 150) {
+ this.handle1PointerHoldEnd(e, me);
+ }
+ }
+
+ handle1PointerHoldEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
+ this.removeHoldMoveListeners();
+ this.removeHoldEndListeners();
+ RadialMenu.Instance.closeMenu();
+ this._firstX = -1;
+ this._firstY = -1;
+ SelectionManager.DeselectAll();
+ me.touchEvent.stopPropagation();
+ me.touchEvent.preventDefault();
+ e.stopPropagation();
+ if (RadialMenu.Instance.used) {
+ this.onContextMenu(me.touches[0]);
+ }
+ }
+
+ @action
+ onRadialMenu = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): void => {
+ // console.log(InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true));
+ // const pt = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1];
+ RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15);
+
+ RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Delete this document", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "layer-group", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
+ RadialMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "folder", selected: -1 });
+
+ // if (SelectionManager.IsSelected(this, true)) {
+ // SelectionManager.SelectDoc(this, false);
+ // }
+ SelectionManager.DeselectAll();
+
+
+ }
@action
componentDidMount() {
this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
+ // this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)));
!this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.push(this);
}
@@ -179,16 +203,24 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._dropDisposer && this._dropDisposer();
this._gestureEventDisposer && this._gestureEventDisposer();
this.multiTouchDisposer && this.multiTouchDisposer();
+ this.holdDisposer && this.holdDisposer();
this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
+ this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)));
}
@action
componentWillUnmount() {
this._dropDisposer && this._dropDisposer();
+ this._gestureEventDisposer && this._gestureEventDisposer();
+ this.multiTouchDisposer && this.multiTouchDisposer();
+ this.holdDisposer && this.holdDisposer();
Doc.UnBrushDoc(this.props.Document);
- !this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1);
+ if (!this.props.dontRegisterView) {
+ const index = DocumentManager.Instance.DocumentViews.indexOf(this);
+ index !== -1 && DocumentManager.Instance.DocumentViews.splice(index, 1);
+ }
}
startDragging(x: number, y: number, dropAction: dropActionType) {
@@ -284,9 +316,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => {
+ SelectionManager.DeselectAll();
if (this.Document.onPointerDown) return;
- const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
- console.log("down");
+ const touch = me.touchEvent.changedTouches.item(0);
if (touch) {
this._downX = touch.clientX;
this._downY = touch.clientY;
@@ -307,8 +339,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this.removeMoveListeners();
}
else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.Document.onDragStart || this.Document.onClick) && !this.Document.lockedPosition && !this.Document.inOverlay) {
- const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
- if (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3) {
+
+ const touch = me.touchEvent.changedTouches.item(0);
+ if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) {
if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick)) {
this.cleanUpInteractions();
this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined);
@@ -404,6 +437,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
e.stopPropagation();
+ // TODO: check here for panning/inking
}
return;
}
@@ -447,6 +481,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
onPointerUp = (e: PointerEvent): void => {
+ this.cleanUpInteractions();
+
+ if (this.onPointerUpHandler && this.onPointerUpHandler.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
+ this.onPointerUpHandler.script.run({ this: this.Document.isTemplateForField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ return;
+ }
+
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
@@ -476,28 +518,20 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (doc[customName] === undefined) {
const _width = NumCast(doc._width);
const _height = NumCast(doc._height);
- const options = { title: "data", _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
+ const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
- const field = doc.data;
let fieldTemplate: Opt<Doc>;
- if (field instanceof RichTextField || typeof (field) === "string") {
+ if (doc.data instanceof RichTextField || typeof (doc.data) === "string") {
fieldTemplate = Docs.Create.TextDocument("", options);
- } else if (field instanceof PdfField) {
+ } else if (doc.data instanceof PdfField) {
fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
- } else if (field instanceof VideoField) {
+ } else if (doc.data instanceof VideoField) {
fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
- } else if (field instanceof AudioField) {
+ } else if (doc.data instanceof AudioField) {
fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
- } else if (field instanceof ImageField) {
+ } else if (doc.data instanceof ImageField) {
fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
}
-
- if (fieldTemplate) {
- fieldTemplate.backgroundColor = doc.backgroundColor;
- fieldTemplate.heading = 1;
- fieldTemplate._autoHeight = true;
- }
-
const docTemplate = docLayoutTemplate || creator(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate));
@@ -527,8 +561,30 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
e.stopPropagation();
de.complete.annoDragData.linkedToDoc = true;
- DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc },
- `Link from ${StrCast(de.complete.annoDragData.annotationDocument.title)}`);
+ DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "link");
+ }
+ if (de.complete.docDragData) {
+ if (de.complete.docDragData.applyAsTemplate) {
+ Doc.ApplyTemplateTo(de.complete.docDragData.draggedDocuments[0], this.props.Document, "layout_custom", undefined);
+ e.stopPropagation();
+ }
+ else if (de.complete.docDragData.draggedDocuments[0].type === "text") {
+ const text = Cast(de.complete.docDragData.draggedDocuments[0].data, RichTextField)?.Text;
+ if (text && text[0] === "{" && text[text.length - 1] === "}" && text.includes(":")) {
+ let loc = text.indexOf(":");
+ let key = text.slice(1, loc);
+ let value = text.slice(loc + 1, text.length - 1);
+ console.log(key);
+ console.log(value);
+ console.log(this.props.Document);
+ this.props.Document[key] = value;
+ console.log(de.complete.docDragData.draggedDocuments[0].x);
+ console.log(de.complete.docDragData.draggedDocuments[0].x);
+ e.preventDefault();
+ e.stopPropagation();
+ de.complete.aborted = true;
+ }
+ }
}
if (de.complete.linkDragData) {
e.stopPropagation();
@@ -536,7 +592,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
// const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
(de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
- { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `link from ${de.complete.linkDragData.linkSourceDocument.title} to ${this.props.Document.title}`)); // TODODO this is where in text links get passed
+ { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `link`)); // TODODO this is where in text links get passed
}
}
@@ -562,7 +618,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const portalLink = DocListCast(this.Document.links).find(d => d.anchor1 === this.props.Document);
if (!portalLink) {
const portal = Docs.Create.FreeformDocument([], { _width: (this.layoutDoc._width || 0) + 10, _height: this.layoutDoc._height || 0, title: StrCast(this.props.Document.title) + ".portal" });
- DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, "portal link", "portal link");
+ DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, "portal to");
}
this.Document.isButton = true;
}
@@ -618,7 +674,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return;
}
e.persist();
- e.stopPropagation();
+ e?.stopPropagation();
if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3 ||
e.isDefaultPrevented()) {
e.preventDefault();
@@ -700,6 +756,35 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
// a.download = `DocExport-${this.props.Document[Id]}.zip`;
// a.click();
});
+ let recommender_subitems: ContextMenuProps[] = [];
+
+ recommender_subitems.push({
+ description: "Internal recommendations",
+ event: () => this.recommender(e),
+ icon: "brain"
+ });
+
+ let ext_recommender_subitems: ContextMenuProps[] = [];
+
+ ext_recommender_subitems.push({
+ description: "arXiv",
+ event: () => this.externalRecommendation("arxiv"),
+ icon: "brain"
+ });
+ ext_recommender_subitems.push({
+ description: "Bing",
+ event: () => this.externalRecommendation("bing"),
+ icon: "brain"
+ });
+
+ recommender_subitems.push({
+ description: "External recommendations",
+ subitems: ext_recommender_subitems,
+ icon: "brain"
+ });
+
+ cm.addItem({ description: "Recommender System", subitems: recommender_subitems, icon: "brain" });
+
moreItems.push({ description: "Publish", event: () => DocUtils.Publish(this.props.Document, this.Document.title || "", this.props.addDocument, this.props.removeDocument), icon: "file" });
moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
@@ -754,6 +839,104 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
});
}
+ recommender = async (e: React.MouseEvent) => {
+ if (!ClientRecommender.Instance) new ClientRecommender({ title: "Client Recommender" });
+ const documents: Doc[] = [];
+ const allDocs = await SearchUtil.GetAllDocs();
+ // allDocs.forEach(doc => console.log(doc.title));
+ // clears internal representation of documents as vectors
+ ClientRecommender.Instance.reset_docs();
+ //ClientRecommender.Instance.arxivrequest("electrons");
+ await Promise.all(allDocs.map((doc: Doc) => {
+ let isMainDoc: boolean = false;
+ const dataDoc = Doc.GetProto(doc);
+ if (doc.type === DocumentType.TEXT) {
+ if (dataDoc === Doc.GetProto(this.props.Document)) {
+ isMainDoc = true;
+ }
+ if (!documents.includes(dataDoc)) {
+ documents.push(dataDoc);
+ const extdoc = doc.data_ext as Doc;
+ return ClientRecommender.Instance.extractText(doc, extdoc ? extdoc : doc, true, "", isMainDoc);
+ }
+ }
+ if (doc.type === DocumentType.IMG) {
+ if (dataDoc === Doc.GetProto(this.props.Document)) {
+ isMainDoc = true;
+ }
+ if (!documents.includes(dataDoc)) {
+ documents.push(dataDoc);
+ const extdoc = doc.data_ext as Doc;
+ return ClientRecommender.Instance.extractText(doc, extdoc ? extdoc : doc, true, "", isMainDoc, true);
+ }
+ }
+ }));
+ const doclist = ClientRecommender.Instance.computeSimilarities("cosine");
+ let recDocs: { preview: Doc, score: number }[] = [];
+ // tslint:disable-next-line: prefer-for-of
+ for (let i = 0; i < doclist.length; i++) {
+ recDocs.push({ preview: doclist[i].actualDoc, score: doclist[i].score });
+ }
+
+ const data = recDocs.map(unit => {
+ unit.preview.score = unit.score;
+ return unit.preview;
+ });
+
+ console.log(recDocs.map(doc => doc.score));
+
+ const title = `Showing ${data.length} recommendations for "${StrCast(this.props.Document.title)}"`;
+ const recommendations = Docs.Create.RecommendationsDocument(data, { title });
+ recommendations.documentIconHeight = 150;
+ recommendations.sourceDoc = this.props.Document;
+ recommendations.sourceDocContext = this.props.ContainingCollectionView!.props.Document;
+ CollectionDockingView.AddRightSplit(recommendations, undefined);
+
+ // RecommendationsBox.Instance.displayRecommendations(e.pageX + 100, e.pageY);
+ }
+
+ @action
+ externalRecommendation = async (api: string) => {
+ if (!ClientRecommender.Instance) new ClientRecommender({ title: "Client Recommender" });
+ ClientRecommender.Instance.reset_docs();
+ const doc = Doc.GetDataDoc(this.props.Document);
+ const extdoc = doc.data_ext as Doc;
+ const recs_and_kps = await ClientRecommender.Instance.extractText(doc, extdoc ? extdoc : doc, false, api);
+ let recs: any;
+ let kps: any;
+ if (recs_and_kps) {
+ recs = recs_and_kps.recs;
+ kps = recs_and_kps.keyterms;
+ }
+ else {
+ console.log("recommender system failed :(");
+ return;
+ }
+ console.log("ibm keyterms: ", kps.toString());
+ const headers = [new SchemaHeaderField("title"), new SchemaHeaderField("href")];
+ const bodies: Doc[] = [];
+ const titles = recs.title_vals;
+ const urls = recs.url_vals;
+ for (let i = 0; i < 5; i++) {
+ const body = Docs.Create.FreeformDocument([], { title: titles[i] });
+ body.href = urls[i];
+ bodies.push(body);
+ }
+ CollectionDockingView.AddRightSplit(Docs.Create.SchemaDocument(headers, bodies, { title: `Showing External Recommendations for "${StrCast(doc.title)}"` }), undefined);
+ this._showKPQuery = true;
+ this._queries = kps.toString();
+ }
+
+ onPointerEnter = (e: React.PointerEvent): void => { Doc.BrushDoc(this.props.Document); };
+ onPointerLeave = (e: React.PointerEvent): void => { Doc.UnBrushDoc(this.props.Document); };
+
+ // does Document set a layout prop
+ // does Document set a layout prop
+ setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)] && this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)];
+ // get the a layout prop by first choosing the prop from Document, then falling back to the layout doc otherwise.
+ getLayoutPropStr = (prop: string) => StrCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
+ getLayoutPropNum = (prop: string) => NumCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
+
isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction);
select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); };
@@ -920,7 +1103,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear;
highlighting = highlighting && this.props.focus !== emptyFunction; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way
- return <div id={this.props.Document[Id]} className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont} onKeyDown={this.onKeyDown}
+ return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont} onKeyDown={this.onKeyDown}
onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
onPointerEnter={e => Doc.BrushDoc(this.props.Document)} onPointerLeave={e => Doc.UnBrushDoc(this.props.Document)}
style={{
@@ -944,11 +1127,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
</> :
this.innards}
</div>;
+ { this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined }
}
}
-Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string) {
+Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string="layout") {
const dv = DocumentManager.Instance.getDocumentView(doc);
- if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(false, "");
+ if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", ""));
else dv?.switchViews(true, layoutKey.replace("layout_", ""));
}); \ No newline at end of file