aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/ButtonBox.tsx16
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DocumentBox.scss7
-rw-r--r--src/client/views/nodes/DocumentBox.tsx89
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx28
-rw-r--r--src/client/views/nodes/DocumentView.tsx148
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx29
-rw-r--r--src/client/views/nodes/ImageBox.tsx5
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx2
-rw-r--r--src/client/views/nodes/RadialMenuItem.tsx30
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx2
-rw-r--r--src/client/views/nodes/WebBox.tsx2
12 files changed, 209 insertions, 151 deletions
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index de0b509eb..1b70ff824 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -42,9 +42,7 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
protected createDropTarget = (ele: HTMLDivElement) => {
- if (this.dropDisposer) {
- this.dropDisposer();
- }
+ this.dropDisposer?.();
if (ele) {
this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
}
@@ -55,7 +53,7 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
funcs.push({
description: "Clear Script Params", event: () => {
const params = FieldValue(this.Document.buttonParams);
- params && params.map(p => this.props.Document[p] = undefined);
+ params?.map(p => this.props.Document[p] = undefined);
}, icon: "trash"
});
@@ -66,7 +64,9 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
@action
drop = (e: Event, de: DragManager.DropEvent) => {
const docDragData = de.complete.docDragData;
- if (docDragData && e.target) {
+ const params = this.Document.buttonParams;
+ const missingParams = params?.filter(p => this.props.Document[p] === undefined);
+ if (docDragData && missingParams?.includes((e.target as any).textContent)) {
this.props.Document[(e.target as any).textContent] = new List<Doc>(docDragData.droppedDocuments.map((d, i) =>
d.onDragStart ? docDragData.draggedDocuments[i] : d));
e.stopPropagation();
@@ -75,14 +75,14 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
// (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")")
render() {
const params = this.Document.buttonParams;
- const missingParams = params && params.filter(p => this.props.Document[p] === undefined);
- params && params.map(p => DocListCast(this.props.Document[p])); // bcz: really hacky form of prefetching ...
+ const missingParams = params?.filter(p => this.props.Document[p] === undefined);
+ params?.map(p => DocListCast(this.props.Document[p])); // bcz: really hacky form of prefetching ...
return (
<div className="buttonBox-outerDiv" ref={this.createDropTarget} onContextMenu={this.specificContextMenu}
style={{ boxShadow: this.Document.opacity === 0 ? undefined : StrCast(this.Document.boxShadow, "") }}>
<div className="buttonBox-mainButton" style={{
background: this.Document.backgroundColor, color: this.Document.color || "inherit",
- fontSize: this.Document.fontSize, letterSpacing: this.Document.letterSpacing || "", textTransform: this.Document.textTransform || ""
+ fontSize: this.Document.fontSize, letterSpacing: this.Document.letterSpacing || "", textTransform: (this.Document.textTransform as any) || ""
}} >
<div className="buttonBox-mainButtonCenter">
{(this.Document.text || this.Document.title)}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 8632f9c9a..9494a4bc4 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -22,6 +22,7 @@ interface ContentFittingDocumentViewProps {
childDocs?: Doc[];
renderDepth: number;
fitToBox?: boolean;
+ layoutKey?: string;
dropAction?: dropActionType;
PanelWidth: () => number;
PanelHeight: () => number;
@@ -88,6 +89,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
LayoutDoc={this.props.LayoutDoc}
LibraryPath={this.props.LibraryPath}
fitToBox={this.props.fitToBox}
+ layoutKey={this.props.layoutKey}
dropAction={this.props.dropAction}
onClick={this.props.onClick}
backgroundColor={this.props.backgroundColor}
diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss
index b7d06b364..ce21391ce 100644
--- a/src/client/views/nodes/DocumentBox.scss
+++ b/src/client/views/nodes/DocumentBox.scss
@@ -3,13 +3,12 @@
height: 100%;
pointer-events: all;
background: gray;
- border: #00000021 solid 15px;
- border-top: #0000005e inset 15px;
- border-bottom: #0000005e outset 15px;
.documentBox-lock {
margin: auto;
color: white;
- margin-top: -15px;
+ position: absolute;
+ }
+ .contentFittingDocumentView {
position: absolute;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index 978480142..debe104d7 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -5,7 +5,7 @@ import { Doc, Field } from "../../../new_fields/Doc";
import { documentSchema } from "../../../new_fields/documentSchemas";
import { makeInterface } from "../../../new_fields/Schema";
import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
+import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
import { emptyPath } from "../../../Utils";
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
@@ -15,6 +15,8 @@ import "./DocumentBox.scss";
import { FieldView, FieldViewProps } from "./FieldView";
import React = require("react");
import { TraceMobx } from "../../../new_fields/util";
+import { DocumentView } from "./DocumentView";
+import { Docs } from "../../documents/Documents";
type DocBoxSchema = makeInterface<[typeof documentSchema]>;
const DocBoxDocument = makeInterface(documentSchema);
@@ -35,12 +37,12 @@ export class DocumentBox extends DocAnnotatableComponent<FieldViewProps, DocBoxS
});
}
componentWillUnmount() {
- this._prevSelectionDisposer && this._prevSelectionDisposer();
+ this._prevSelectionDisposer?.();
}
specificContextMenu = (e: React.MouseEvent): void => {
const funcs: ContextMenuProps[] = [];
funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" });
- funcs.push({ description: (this.props.Document.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.props.Document.excludeCollections = !this.props.Document.excludeCollections, icon: "expand-arrows-alt" });
+ funcs.push({ description: (this.props.Document.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => Doc.GetProto(this.props.Document).excludeCollections = !this.props.Document.excludeCollections, icon: "expand-arrows-alt" });
funcs.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" });
@@ -85,13 +87,15 @@ export class DocumentBox extends DocAnnotatableComponent<FieldViewProps, DocBoxS
(e.nativeEvent as any).formattedHandled = true;
e.stopPropagation();
}
+ get xPad() { return NumCast(this.props.Document._xPadding); }
+ get yPad() { return NumCast(this.props.Document._yPadding); }
onClick = (e: React.MouseEvent) => {
let hitWidget: boolean | undefined = false;
- if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
- else if (this._contRef.current!.getBoundingClientRect().bottom - 15 < e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
+ if (this._contRef.current!.getBoundingClientRect().top + this.yPad > e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
+ else if (this._contRef.current!.getBoundingClientRect().bottom - this.yPad < e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
else {
- if (this._contRef.current!.getBoundingClientRect().left + 15 > e.clientX) hitWidget = this.prevSelection();
- if (this._contRef.current!.getBoundingClientRect().right - 15 < e.clientX) hitWidget = this.nextSelection();
+ if (this._contRef.current!.getBoundingClientRect().left + this.xPad > e.clientX) hitWidget = this.prevSelection();
+ if (this._contRef.current!.getBoundingClientRect().right - this.xPad < e.clientX) hitWidget = this.nextSelection();
}
if (hitWidget) {
(e.nativeEvent as any).formattedHandled = true;
@@ -99,38 +103,57 @@ export class DocumentBox extends DocAnnotatableComponent<FieldViewProps, DocBoxS
}
}
_contRef = React.createRef<HTMLDivElement>();
- pwidth = () => this.props.PanelWidth() - 30;
- pheight = () => this.props.PanelHeight() - 30;
- getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15);
+ pwidth = () => this.props.PanelWidth() - 2 * this.xPad;
+ pheight = () => this.props.PanelHeight() - 2 * this.yPad;
+ getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad);
+ get renderContents() {
+ const containedDoc = Cast(this.contentDoc[this.props.fieldKey], Doc, null);
+ const childTemplateName = StrCast(this.props.Document.childTemplateName);
+ if (containedDoc && childTemplateName && !containedDoc["layout_" + childTemplateName]) {
+ setTimeout(() => {
+ DocumentView.createCustomView(containedDoc, Docs.Create.StackingDocument, childTemplateName);
+ Doc.expandTemplateLayout(Cast(containedDoc["layout_" + childTemplateName], Doc, null)!, containedDoc, undefined);
+ }, 0);
+ }
+ const contents = !(containedDoc instanceof Doc) ? (null) : <ContentFittingDocumentView
+ Document={containedDoc}
+ DataDocument={undefined}
+ LibraryPath={emptyPath}
+ CollectionView={this as any} // bcz: hack! need to pass a prop that can be used to select the container (ie, 'this') when the up selector in document decorations is clicked. currently, the up selector allows only a containing collection to be selected
+ fitToBox={this.props.fitToBox}
+ layoutKey={"layout_" + childTemplateName}
+ addDocument={this.props.addDocument}
+ moveDocument={this.props.moveDocument}
+ removeDocument={this.props.removeDocument}
+ addDocTab={this.props.addDocTab}
+ pinToPres={this.props.pinToPres}
+ getTransform={this.getTransform}
+ renderDepth={this.props.renderDepth + 1}
+ PanelWidth={this.pwidth}
+ PanelHeight={this.pheight}
+ focus={this.props.focus}
+ active={this.props.active}
+ dontRegisterView={!this.isSelectionLocked()}
+ whenActiveChanged={this.props.whenActiveChanged}
+ />;
+ return contents;
+ }
render() {
TraceMobx();
- const containedDoc = this.contentDoc[this.props.fieldKey];
return <div className="documentBox-container" ref={this._contRef}
onContextMenu={this.specificContextMenu}
onPointerDown={this.onPointerDown} onClick={this.onClick}
- style={{ background: StrCast(this.props.Document.backgroundColor) }}>
- <div className="documentBox-lock" onClick={this.onLockClick}>
+ style={{
+ background: StrCast(this.props.Document.backgroundColor),
+ border: `#00000021 solid ${this.xPad}px`,
+ borderTop: `#0000005e solid ${this.yPad}px`,
+ borderBottom: `#0000005e solid ${this.yPad}px`,
+ }}>
+ {this.renderContents}
+ <div className="documentBox-lock" onClick={this.onLockClick}
+ style={{ marginTop: - this.yPad }}>
<FontAwesomeIcon icon={this.isSelectionLocked() ? "lock" : "unlock"} size="sm" />
</div>
- {!(containedDoc instanceof Doc) ? (null) : <ContentFittingDocumentView
- Document={containedDoc}
- DataDocument={undefined}
- LibraryPath={emptyPath}
- fitToBox={this.props.fitToBox}
- addDocument={this.props.addDocument}
- moveDocument={this.props.moveDocument}
- removeDocument={this.props.removeDocument}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- getTransform={this.getTransform}
- renderDepth={this.props.renderDepth + 1} // bcz: need a forceActive prop here ... not the same as renderDepth = 0
- PanelWidth={this.pwidth}
- PanelHeight={this.pheight}
- focus={this.props.focus}
- active={this.props.active}
- dontRegisterView={!this.isSelectionLocked()}
- whenActiveChanged={this.props.whenActiveChanged}
- />}
- </div>;
+ </div >;
}
}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 8be6ab151..68501fca2 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -58,21 +58,26 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
select: (ctrl: boolean) => void,
layoutKey: string,
forceLayout?: string,
- forceFieldKey?: string
+ forceFieldKey?: string,
+ hideOnLeave?: boolean,
+ makeLink?: () => Opt<Doc>;
}> {
@computed get layout(): string {
TraceMobx();
if (!this.layoutDoc) return "<p>awaiting layout</p>";
const layout = Cast(this.layoutDoc[StrCast(this.layoutDoc.layoutKey, this.layoutDoc === this.props.Document ? this.props.layoutKey : "layout")], "string");
- if (layout === undefined) {
- return this.props.Document.data ?
- "<FieldView {...props} fieldKey='data' />" :
- KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
- } else if (typeof layout === "string") {
- return layout;
- } else {
- return "<p>Loading layout</p>";
- }
+ if (this.props.layoutKey === "layout_keyValue") {
+ return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
+ } else
+ if (layout === undefined) {
+ return this.props.Document.data ?
+ "<FieldView {...props} fieldKey='data' />" :
+ KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
+ } else if (typeof layout === "string") {
+ return layout;
+ } else {
+ return "<p>Loading layout</p>";
+ }
}
get dataDoc() {
@@ -81,7 +86,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
}
get layoutDoc() {
const params = StrCast(this.props.Document.PARAMS);
- return Doc.expandTemplateLayout(this.props.LayoutDoc?.() || Doc.Layout(this.props.Document), this.props.Document, params ? "(" + params + ")" : this.props.layoutKey);
+ const template: Doc = this.props.LayoutDoc?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
+ return Doc.expandTemplateLayout(template, this.props.Document, params ? "(" + params + ")" : this.props.layoutKey);
}
CreateBindings(): JsxBindings {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1dee25c51..02a1ac527 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -40,7 +40,6 @@ import { ScriptBox } from '../ScriptBox';
import { ScriptingRepl } from '../ScriptingRepl';
import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
-import { FormattedTextBox } from './FormattedTextBox';
import React = require("react");
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField';
@@ -509,58 +508,49 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
deleteClicked = (): void => { SelectionManager.DeselectAll(); this.props.removeDocument?.(this.props.Document); }
- static makeNativeViewClicked = (doc: Doc) => {
- undoBatch(() => Doc.setNativeView(doc))();
- }
-
- static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => {
- const userDoc = Doc.UserDoc();
- const imgView = Cast(userDoc.iconView, Doc, null);
- const iconImgView = Cast(userDoc.iconImageView, Doc, null);
- const iconColView = Cast(userDoc.iconColView, Doc, null);
- const iconViews = [imgView, iconImgView, iconColView];
- const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data);
- const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data);
- const allTemplates = iconViews.concat(templateButtons).concat(noteTypes);
- const templateName = templateSignature.replace(/\(.*\)/, "");
- !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => {
- if (StrCast(tempDoc.title) === doc.type + "_" + templateName) {
- docLayoutTemplate = tempDoc;
- }
- });
- !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => {
- if (StrCast(tempDoc.title) === templateName) {
- docLayoutTemplate = tempDoc;
+ // applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView)
+ static makeCustomViewClicked = (doc: Doc, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => {
+ const batch = UndoManager.StartBatch("makeCustomViewClicked");
+ runInAction(() => {
+ doc.layoutKey = "layout_" + templateSignature;
+ if (doc[doc.layoutKey] === undefined) {
+ DocumentView.createCustomView(doc, creator, templateSignature, docLayoutTemplate);
}
});
+ batch.end();
+ }
+ static createCustomView = (doc: Doc, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => {
+ const iconViews = DocListCast(Cast(Doc.UserDoc().iconViews, Doc, null)?.data);
+ const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data);
+ const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data);
+ const allTemplates = iconViews.concat(templBtns).concat(noteTypes).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc);
+ const templateName = templateSignature.replace(/\(.*\)/, "");
+ // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized
+ // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName>
+ !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === doc.type + "_" + templateName && (docLayoutTemplate = tempDoc));
+ !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc));
- const batch = UndoManager.StartBatch("CustomViewClicked");
const customName = "layout_" + templateSignature;
- if (doc[customName] === undefined) {
- const _width = NumCast(doc._width);
- const _height = NumCast(doc._height);
- const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
-
- let fieldTemplate: Opt<Doc>;
- if (doc.data instanceof RichTextField || typeof (doc.data) === "string") {
- fieldTemplate = Docs.Create.TextDocument("", options);
- } else if (doc.data instanceof PdfField) {
- fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
- } else if (doc.data instanceof VideoField) {
- fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
- } else if (doc.data instanceof AudioField) {
- fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
- } else if (doc.data instanceof ImageField) {
- fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
- }
- 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));
- Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
- } else {
- doc.layoutKey = customName;
+ const _width = NumCast(doc._width);
+ const _height = NumCast(doc._height);
+ const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
+
+ let fieldTemplate: Opt<Doc>;
+ if (doc.data instanceof RichTextField || typeof (doc.data) === "string") {
+ fieldTemplate = Docs.Create.TextDocument("", options);
+ } else if (doc.data instanceof PdfField) {
+ fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
+ } else if (doc.data instanceof VideoField) {
+ fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
+ } else if (doc.data instanceof AudioField) {
+ fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
+ } else if (doc.data instanceof ImageField) {
+ fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
}
- batch.end();
+ 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));
+ Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
}
@undoBatch
@@ -584,29 +574,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "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(":")) {
- const loc = text.indexOf(":");
- const key = text.slice(1, loc);
- const 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();
// const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
@@ -647,9 +614,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
@action
setCustomView = (custom: boolean, layout: string): void => {
- DocumentView.makeNativeViewClicked(this.props.Document);
+ Doc.setNativeView(this.props.Document);
if (custom) {
- DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, Docs.Create.StackingDocument, layout, undefined);
+ DocumentView.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined);
}
}
@@ -962,7 +929,30 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
@computed get contents() {
TraceMobx();
- return (<DocumentContentsView {...OmitKeys(this.props, ['children']).omit}
+ return (<DocumentContentsView ContainingCollectionView={this.props.ContainingCollectionView}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+ Document={this.props.Document}
+ DataDoc={this.props.DataDoc}
+ LayoutDoc={this.props.LayoutDoc}
+ makeLink={this.makeLink}
+ fitToBox={this.props.fitToBox}
+ LibraryPath={this.props.LibraryPath}
+ addDocument={this.props.addDocument}
+ removeDocument={this.props.removeDocument}
+ moveDocument={this.props.moveDocument}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ renderDepth={this.props.renderDepth}
+ PanelWidth={this.props.PanelWidth}
+ PanelHeight={this.props.PanelHeight}
+ focus={this.props.focus}
+ parentActive={this.props.parentActive}
+ whenActiveChanged={this.props.whenActiveChanged}
+ bringToFront={this.props.bringToFront}
+ addDocTab={this.props.addDocTab}
+ pinToPres={this.props.pinToPres}
+ zoomToScale={this.props.zoomToScale}
+ backgroundColor={this.props.backgroundColor}
+ getScale={this.props.getScale}
ContentScaling={this.childScaling}
ChromeHeight={this.chromeHeight}
isSelected={this.isSelected}
@@ -981,6 +971,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return anchor.type === DocumentType.AUDIO && NumCast(ept) ? false : true;
}
+ @observable _link: Opt<Doc>;
+ makeLink = () => {
+ return this._link;
+ }
+
@computed get innards() {
TraceMobx();
if (!this.props.PanelWidth()) {
@@ -988,8 +983,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
{StrCast(this.props.Document.title)}
{this.Document.links && DocListCast(this.Document.links).filter(d => !d.hidden).filter(this.isNonTemporalLink).map((d, i) =>
<div className="documentView-docuLinkWrapper" style={{ position: "absolute", top: 0, left: 0 }} key={`${d[Id]}`}>
- <DocumentView {...this.props} ContentScaling={returnOne} ContainingCollectionDoc={this.props.Document}
- PanelWidth={returnOne} PanelHeight={returnOne} Document={d} layoutKey={this.linkEndpoint(d)} backgroundColor={returnTransparent} removeDocument={undoBatch(doc => doc.hidden = true)} />
+ <DocumentView {...this.props} Document={d} ContainingCollectionDoc={this.props.Document}
+ PanelWidth={returnOne} PanelHeight={returnOne} layoutKey={this.linkEndpoint(d)} ContentScaling={returnOne}
+ backgroundColor={returnTransparent} removeDocument={undoBatch(doc => doc.hidden = true)} />
</div>)}
</div>;
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index bc43beab9..241345f3e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -54,6 +54,7 @@ library.add(faSmile, faTextHeight, faUpload);
export interface FormattedTextBoxProps {
hideOnLeave?: boolean;
+ makeLink?: () => Opt<Doc>;
}
const richTextSchema = createSchema({
@@ -91,6 +92,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
private _pullReactionDisposer: Opt<IReactionDisposer>;
private _pushReactionDisposer: Opt<IReactionDisposer>;
private _buttonBarReactionDisposer: Opt<IReactionDisposer>;
+ private _linkMakerDisposer: Opt<IReactionDisposer>;
private _scrollDisposer: Opt<IReactionDisposer>;
private dropDisposer?: DragManager.DragDropDisposer;
@@ -282,8 +284,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
e.stopPropagation();
// }
} // otherwise, fall through to outer collection to handle drop
+ } else if (de.complete.linkDragData) {
+ de.complete.linkDragData.linkDropCallback = this.linkDrop;
}
}
+ linkDrop = (data: DragManager.LinkDragData) => {
+ const linkDoc = data.linkDocument!;
+ const anchor1Title = linkDoc.anchor1 instanceof Doc ? StrCast(linkDoc.anchor1.title) : "-untitled-";
+ const anchor1Id = linkDoc.anchor1 instanceof Doc ? linkDoc.anchor1[Id] : "";
+ this.makeLinkToSelection(linkDoc[Id], anchor1Title, "onRight", anchor1Id)
+ }
getNodeEndpoints(context: Node, node: Node): { from: number, to: number } | null {
let offset = 0;
@@ -513,6 +523,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
};
}
+ makeLinkToSelection(linkDocId: string, title: string, location: string, targetDocId: string) {
+ if (this._editorView) {
+ const link = this._editorView.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, linkId: linkDocId, targetId: targetDocId });
+ this._editorView.dispatch(this._editorView.state.tr.removeMark(this._editorView.state.selection.from, this._editorView.state.selection.to, this._editorView.state.schema.marks.link).
+ addMark(this._editorView.state.selection.from, this._editorView.state.selection.to, link));
+ }
+ }
componentDidMount() {
this._buttonBarReactionDisposer = reaction(
() => DocumentButtonBar.Instance,
@@ -523,6 +540,17 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
}
}
);
+ this._linkMakerDisposer = reaction(
+ () => this.props.makeLink?.(),
+ (linkDoc: Opt<Doc>) => {
+ if (linkDoc) {
+ const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast(linkDoc.anchor2.title) : "-untitled-";
+ const anchor2Id = linkDoc.anchor2 instanceof Doc ? linkDoc.anchor2[Id] : "";
+ this.makeLinkToSelection(linkDoc[Id], anchor2Title, "onRight", anchor2Id);
+ }
+ },
+ { fireImmediately: true }
+ );
this._reactionDisposer = reaction(
() => {
@@ -858,6 +886,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
this._searchReactionDisposer?.();
this._recordReactionDisposer?.();
this._buttonBarReactionDisposer?.();
+ this._linkMakerDisposer?.();
this._editorView?.destroy();
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 68eb4493a..00057055f 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -225,7 +225,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
return url.href;
} else if (url.href.indexOf(window.location.origin) === -1) {
return Utils.CorsProxy(url.href);
- } else if (!/\.(png|jpg|jpeg|gif)$/.test(lower)) {
+ } else if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower)) {
return url.href;//Why is this here
}
const ext = path.extname(url.href);
@@ -439,7 +439,8 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
transform: `scale(${this.props.ContentScaling()})`,
width: `${100 / this.props.ContentScaling()}%`,
height: `${100 / this.props.ContentScaling()}%`,
- pointerEvents: this.props.Document.isBackground ? "none" : undefined
+ pointerEvents: this.props.Document.isBackground ? "none" : undefined,
+ borderRadius: `${Number(StrCast(this.layoutDoc.borderRounding).replace("px", "")) / this.props.ContentScaling()}px`
}} >
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 93bda6d02..3d59ea61a 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -61,6 +61,8 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
fieldKey: this.props.keyName,
isSelected: returnFalse,
select: emptyFunction,
+ dropAction:"alias",
+ bringToFront:emptyFunction,
renderDepth: 1,
active: returnFalse,
whenActiveChanged: emptyFunction,
diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx
index fdc732d3f..bd5b3bff4 100644
--- a/src/client/views/nodes/RadialMenuItem.tsx
+++ b/src/client/views/nodes/RadialMenuItem.tsx
@@ -44,12 +44,12 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
setcircle() {
let circlemin = 0;
- let circlemax = 1
+ let circlemax = 1;
this.props.min ? circlemin = this.props.min : null;
this.props.max ? circlemax = this.props.max : null;
if (document.getElementById("myCanvas") !== null) {
- var c: any = document.getElementById("myCanvas");
- let color = "white"
+ const c: any = document.getElementById("myCanvas");
+ let color = "white";
switch (circlemin % 3) {
case 1:
color = "#c2c2c5";
@@ -70,38 +70,38 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
}
if (c.getContext) {
- var ctx = c.getContext("2d");
+ const ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(150, 150, 150, (circlemin / circlemax) * 2 * Math.PI, ((circlemin + 1) / circlemax) * 2 * Math.PI);
ctx.arc(150, 150, 50, ((circlemin + 1) / circlemax) * 2 * Math.PI, (circlemin / circlemax) * 2 * Math.PI, true);
ctx.fillStyle = color;
- ctx.fill()
+ ctx.fill();
}
}
}
calculatorx() {
let circlemin = 0;
- let circlemax = 1
+ let circlemax = 1;
this.props.min ? circlemin = this.props.min : null;
this.props.max ? circlemax = this.props.max : null;
- let avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
- let degrees = 360 * avg;
- let x = 100 * Math.cos(degrees * Math.PI / 180);
- let y = -125 * Math.sin(degrees * Math.PI / 180);
+ const avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
+ const degrees = 360 * avg;
+ const x = 100 * Math.cos(degrees * Math.PI / 180);
+ const y = -125 * Math.sin(degrees * Math.PI / 180);
return x;
}
calculatory() {
let circlemin = 0;
- let circlemax = 1
+ let circlemax = 1;
this.props.min ? circlemin = this.props.min : null;
this.props.max ? circlemax = this.props.max : null;
- let avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
- let degrees = 360 * avg;
- let x = 125 * Math.cos(degrees * Math.PI / 180);
- let y = -100 * Math.sin(degrees * Math.PI / 180);
+ const avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2;
+ const degrees = 360 * avg;
+ const x = 125 * Math.cos(degrees * Math.PI / 180);
+ const y = -100 * Math.sin(degrees * Math.PI / 180);
return y;
}
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 548066f1c..7c58a5148 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -142,7 +142,7 @@ export class ScreenshotBox extends DocAnnotatableComponent<FieldViewProps, Scree
toggleRecording = action(async () => {
this._screenCapture = !this._screenCapture;
this._videoRef!.srcObject = !this._screenCapture ? undefined : await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
- })
+ });
private get uIButtons() {
return (<div className="screenshotBox-uiButtons">
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 591864f2c..838fbefb1 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -63,7 +63,7 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect;
}
} else if (field?.url) {
- var result = await WebRequest.get(Utils.CorsProxy(field.url.href));
+ const result = await WebRequest.get(Utils.CorsProxy(field.url.href));
this.dataDoc.text = htmlToText.fromString(result.content);
}