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.scss2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx16
-rw-r--r--src/client/views/nodes/DocumentView.scss1
-rw-r--r--src/client/views/nodes/DocumentView.tsx113
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx14
-rw-r--r--src/client/views/nodes/IconBox.tsx12
-rw-r--r--src/client/views/nodes/ImageBox.tsx57
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx3
-rw-r--r--src/client/views/nodes/LinkMenuItem.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx6
10 files changed, 134 insertions, 92 deletions
diff --git a/src/client/views/nodes/ButtonBox.scss b/src/client/views/nodes/ButtonBox.scss
index 97cc91128..92beafa15 100644
--- a/src/client/views/nodes/ButtonBox.scss
+++ b/src/client/views/nodes/ButtonBox.scss
@@ -2,9 +2,11 @@
width: 100%;
height: 100%;
pointer-events: all;
+ border-radius: inherit;
}
.buttonBox-mainButton {
width: 100%;
height: 100%;
+ border-radius: inherit;
} \ No newline at end of file
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 389b9f68b..7ffd760e0 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -35,21 +35,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@computed get zoom(): number { return 1 / FieldValue(this.Document.zoomBasis, 1); }
@computed get nativeWidth(): number { return FieldValue(this.Document.nativeWidth, 0); }
@computed get nativeHeight(): number { return FieldValue(this.Document.nativeHeight, 0); }
-
- set width(w: number) {
- this.Document.width = w;
- if (this.nativeWidth && this.nativeHeight) {
- this.Document.height = this.nativeHeight / this.nativeWidth * w;
- }
- }
- set height(h: number) {
- this.Document.height = h;
- if (this.nativeWidth && this.nativeHeight) {
- this.Document.width = this.nativeWidth / this.nativeHeight * h;
- }
- }
@computed get scaleToOverridingWidth() { return this.width / NumCast(this.props.Document.width, this.width); }
- contentScaling = () => this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
+
+ contentScaling = () => this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? this.width / this.nativeWidth : 1;
panelWidth = () => this.props.PanelWidth();
panelHeight = () => this.props.PanelHeight();
getTransform = (): Transform => this.props.ScreenToLocalTransform()
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 3a4b46b7e..7c72fb6e6 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -4,7 +4,6 @@
position: inherit;
top: 0;
left:0;
- pointer-events: all;
// background: $light-color; //overflow: hidden;
transform-origin: left top;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 16cfeba3f..99f073459 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -39,6 +39,8 @@ import { OverlayView } from '../OverlayView';
import { ScriptingRepl } from '../ScriptingRepl';
import { ClientUtils } from '../../util/ClientUtils';
import { EditableView } from '../EditableView';
+import { faHandPointer, faHandPointRight } from '@fortawesome/free-regular-svg-icons';
+import { DocumentDecorations } from '../DocumentDecorations';
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
library.add(fa.faTrash);
@@ -60,8 +62,7 @@ library.add(fa.faCrosshairs);
library.add(fa.faDesktop);
library.add(fa.faUnlock);
library.add(fa.faLock);
-library.add(fa.faLaptopCode);
-
+library.add(fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointRight, fa.faCompass, fa.faSnowflake);
// const linkSchema = createSchema({
// title: "string",
@@ -88,7 +89,7 @@ export interface DocumentViewProps {
ContentScaling: () => number;
PanelWidth: () => number;
PanelHeight: () => number;
- focus: (doc: Doc, willZoom: boolean) => void;
+ focus: (doc: Doc, willZoom: boolean, scale?: number) => void;
selectOnLoad: boolean;
parentActive: () => boolean;
whenActiveChanged: (isActive: boolean) => void;
@@ -275,7 +276,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let iconAnimating = Cast(maximizedDoc.isIconAnimating, List);
if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) {
if (isMinimized === undefined) {
- isMinimized = BoolCast(maximizedDoc.isMinimized, false);
+ isMinimized = BoolCast(maximizedDoc.isMinimized);
}
maximizedDoc.willMaximize = isMinimized;
maximizedDoc.isMinimized = false;
@@ -298,6 +299,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let fullScreenAlias = Doc.MakeAlias(this.props.Document);
fullScreenAlias.templates = new List<string>();
Doc.UseDetailLayout(fullScreenAlias);
+ fullScreenAlias.showCaption = true;
this.props.addDocTab(fullScreenAlias, this.dataDoc, "inTab");
SelectionManager.DeselectAll();
this.props.Document.libraryBrush = false;
@@ -307,7 +309,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
SelectionManager.SelectDoc(this, e.ctrlKey);
let isExpander = (e.target as any).id === "isExpander";
- if (BoolCast(this.props.Document.isButton, false) || isExpander) {
+ if (BoolCast(this.props.Document.isButton) || isExpander) {
SelectionManager.DeselectAll();
let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs);
let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs);
@@ -325,7 +327,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
maxLocation = this.props.Document.maximizeLocation = (ctrlKey ? maxLocation : (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"));
if (!maxLocation || maxLocation === "inPlace") {
let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);
- let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false);
+ let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized), false);
expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false);
let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);
if (!hasView) {
@@ -358,7 +360,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (!linkedFwdDocs.some(l => l instanceof Promise)) {
let maxLocation = StrCast(linkedFwdDocs[0].maximizeLocation, "inTab");
let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined;
- DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => this.props.addDocTab(document, undefined, maxLocation), linkedFwdPage[altKey ? 1 : 0], targetContext);
+ DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => {
+ this.props.focus(this.props.Document, true, 1);
+ setTimeout(() =>
+ this.props.addDocTab(document, undefined, maxLocation), 1000);
+ }
+ , linkedFwdPage[altKey ? 1 : 0], targetContext);
}
}
}
@@ -408,7 +415,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
makeBtnClicked = (): void => {
let doc = Doc.GetProto(this.props.Document);
- doc.isButton = !BoolCast(doc.isButton, false);
+ doc.isButton = !BoolCast(doc.isButton);
if (doc.isButton) {
if (!doc.nativeWidth) {
doc.nativeWidth = this.props.Document[WidthSym]();
@@ -506,12 +513,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@action
freezeNativeDimensions = (): void => {
let proto = this.props.Document.isTemplate ? this.props.Document : Doc.GetProto(this.props.Document);
- if (proto.ignoreAspect === undefined && !proto.nativeWidth) {
+ this.props.Document.autoHeight = proto.autoHeight = false;
+ proto.ignoreAspect = !BoolCast(proto.ignoreAspect);
+ if (!BoolCast(proto.ignoreAspect) && !proto.nativeWidth) {
proto.nativeWidth = this.props.PanelWidth();
proto.nativeHeight = this.props.PanelHeight();
- proto.ignoreAspect = true;
}
- proto.ignoreAspect = !BoolCast(proto.ignoreAspect, false);
+ }
+ @undoBatch
+ @action
+ makeBackground = (): void => {
+ this.props.Document.isBackground = true;
}
@undoBatch
@@ -540,21 +552,27 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
subitems.push({ description: "Open Right Alias", event: () => this.props.addDocTab && this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.dataDoc, "onRight"), icon: "caret-square-right" });
subitems.push({ description: "Open Fields", event: this.fieldsClicked, icon: "layer-group" });
cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" });
- cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "edit" });
- cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });
- cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Pos" : "Lock Pos", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
- cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
- cm.addItem({
+ cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" });
+ cm.addItem({ description: "Pin to Presentation", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });
+ cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
+ let makes: ContextMenuProps[] = [];
+ makes.push({ description: "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
+ makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
+ makes.push({
description: "Make Portal", event: () => {
let portal = Docs.Create.FreeformDocument([], { width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".portal" });
- Doc.GetProto(this.props.Document).subBulletDocs = new List<Doc>([portal]);
+ //Doc.GetProto(this.props.Document).subBulletDocs = new List<Doc>([portal]);
//summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
- Doc.GetProto(this.props.Document).templates = new List<string>([Templates.Bullet.Layout]);
- let coll = Docs.Create.StackingDocument([this.props.Document, portal], { x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y), width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".cont" });
- this.props.addDocument && this.props.addDocument(coll);
- this.props.removeDocument && this.props.removeDocument(this.props.Document);
+ //Doc.GetProto(this.props.Document).templates = new List<string>([Templates.Bullet.Layout]);
+ //let coll = Docs.Create.StackingDocument([this.props.Document, portal], { x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y), width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".cont" });
+ //this.props.addDocument && this.props.addDocument(coll);
+ //this.props.removeDocument && this.props.removeDocument(this.props.Document);
+ DocUtils.MakeLink(this.props.Document, portal, undefined, this.props.Document.title + ".portal");
+ this.makeBtnClicked();
+
}, icon: "window-restore"
});
+ cm.addItem({ description: "Make...", subitems: makes, icon: "hand-point-right" });
// cm.addItem({
// description: "Find aliases", event: async () => {
// const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document);
@@ -565,11 +583,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
cm.addItem({ description: "Toggle detail", event: () => Doc.ToggleDetailLayout(this.props.Document), icon: "image" });
}
cm.addItem({ description: "Add Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });
- cm.addItem({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
- cm.addItem({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" });
+ let existing = ContextMenu.Instance.findByDescription("Layout...");
+ let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : [];
+ layoutItems.push({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
+ layoutItems.push({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" });
+ !existing && cm.addItem({ description: "Layout...", subitems: layoutItems, icon: "compass" });
if (!ClientUtils.RELEASE) {
- cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" });
- cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+ let copies: ContextMenuProps[] = [];
+ copies.push({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" });
+ copies.push({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+ cm.addItem({ description: "Copy...", subitems: copies, icon: "copy" });
}
cm.addItem({ description: "Delete", event: this.deleteClicked, icon: "trash" });
type User = { email: string, userDocumentId: string };
@@ -593,7 +616,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
notifDoc.data = new List([sharedDoc]);
}
}
- }
+ }, icon: "male"
}));
} catch {
@@ -628,36 +651,46 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
DataDoc={this.dataDoc} />);
}
+ get layoutDoc() {
+ // if this document's layout field contains a document (ie, a rendering template), then we will use that
+ // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string.
+ return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document;
+ }
render() {
if (this.Document.hidden) {
return null;
}
let self = this;
- let backgroundColor = this.props.Document.layout instanceof Doc ? StrCast(this.props.Document.layout.backgroundColor) : this.Document.backgroundColor;
- let foregroundColor = StrCast(this.props.Document.layout instanceof Doc ? this.props.Document.layout.color : this.props.Document.color);
- var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";
+ let backgroundColor = StrCast(this.layoutDoc.backgroundColor);
+ let foregroundColor = StrCast(this.layoutDoc.color);
+ var nativeWidth = this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? `${this.nativeWidth}px` : "100%";
var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%";
- let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.props.Document) : undefined;
- let showTitle = showOverlays && showOverlays.title !== "undefined" ? showOverlays.title : StrCast(this.props.Document.showTitle);
- let showCaption = showOverlays && showOverlays.caption !== "undefined" ? showOverlays.caption : StrCast(this.props.Document.showCaption);
- let templates = Cast(this.props.Document.templates, listSpec("string"));
+ let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.layoutDoc) : undefined;
+ let showTitle = showOverlays && showOverlays.title !== "undefined" ? showOverlays.title : StrCast(this.layoutDoc.showTitle);
+ let showCaption = showOverlays && showOverlays.caption !== "undefined" ? showOverlays.caption : StrCast(this.layoutDoc.showCaption);
+ let templates = Cast(this.layoutDoc.templates, listSpec("string"));
if (!showOverlays && templates instanceof List) {
templates.map(str => {
if (str.indexOf("{props.Document.title}") !== -1) showTitle = "title";
if (str.indexOf("fieldKey={\"caption\"}") !== -1) showCaption = "caption";
});
}
- let showTextTitle = showTitle && StrCast(this.props.Document.layout).startsWith("<FormattedTextBox") || (this.props.Document.layout instanceof Doc && StrCast(this.props.Document.layout.layout).startsWith("<FormattedTextBox")) ? showTitle : undefined;
+ let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith("<FormattedTextBox") ? showTitle : undefined;
return (
<div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
ref={this._mainCont}
style={{
+ pointerEvents: this.layoutDoc.isBackground ? "none" : "all",
color: foregroundColor,
outlineColor: "maroon",
outlineStyle: "dashed",
- outlineWidth: BoolCast(this.props.Document.libraryBrush) && !StrCast(this.props.Document.borderRounding) ?
+ outlineWidth: BoolCast(this.layoutDoc.libraryBrush) && !StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
`${this.props.ScreenToLocalTransform().Scale}px` : "0px",
- border: BoolCast(this.props.Document.libraryBrush) && StrCast(this.props.Document.borderRounding) ?
+ marginLeft: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
+ `${-1 * this.props.ScreenToLocalTransform().Scale}px` : undefined,
+ marginTop: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
+ `${-1 * this.props.ScreenToLocalTransform().Scale}px` : undefined,
+ border: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
`dashed maroon ${this.props.ScreenToLocalTransform().Scale}px` : undefined,
borderRadius: "inherit",
background: backgroundColor,
@@ -678,17 +711,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
{!showTitle ? (null) :
<div style={{
position: showTextTitle ? "relative" : "absolute", top: 0, padding: "4px", textAlign: "center", textOverflow: "ellipsis", whiteSpace: "pre",
- pointerEvents: "all",
+ pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
overflow: "hidden", width: `${100 * this.props.ContentScaling()}%`, height: 25, background: "rgba(0, 0, 0, .4)", color: "white",
transformOrigin: "top left", transform: `scale(${1 / this.props.ContentScaling()})`
}}>
<EditableView
- contents={this.props.Document[showTitle]}
+ contents={(this.dataDoc || this.layoutDoc)[showTitle]}
display={"block"}
height={72}
fontSize={12}
- GetValue={() => StrCast(this.props.Document[showTitle!])}
- SetValue={(value: string) => (Doc.GetProto(this.props.Document)[showTitle!] = value) ? true : true}
+ GetValue={() => StrCast(this.layoutDoc[showTitle!])}
+ SetValue={(value: string) => (Doc.GetProto(this.layoutDoc)[showTitle!] = value) ? true : true}
/>
</div>
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0a79677e2..5ac4af0bb 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEdit, faSmile } from '@fortawesome/free-solid-svg-icons';
+import { faEdit, faSmile, faTextHeight } from '@fortawesome/free-solid-svg-icons';
import { action, IReactionDisposer, observable, reaction, runInAction, computed, trace } from "mobx";
import { observer } from "mobx-react";
import { baseKeymap } from "prosemirror-commands";
@@ -38,7 +38,7 @@ import { thisExpression } from 'babel-types';
import { Utils } from '../../../Utils';
library.add(faEdit);
-library.add(faSmile);
+library.add(faSmile, faTextHeight);
// FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document
//
@@ -139,7 +139,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()));
this._applyingChange = false;
let title = StrCast(this.dataDoc.title);
- if (title && title.startsWith("-") && this._editorView) {
+ if (title && title.startsWith("-") && this._editorView && !this.Document.customTitle) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
@@ -422,7 +422,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
// stop propagation doesn't seem to stop propagation of native keyboard events.
// so we set a flag on the native event that marks that the event's been handled.
(e.nativeEvent as any).DASHFormattedTextBoxHandled = true;
- if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView) {
+ if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.Document.customTitle) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
@@ -459,10 +459,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
specificContextMenu = (e: React.MouseEvent): void => {
let subitems: ContextMenuProps[] = [];
subitems.push({
- description: BoolCast(this.props.Document.autoHeight, false) ? "Manual Height" : "Auto Height",
- event: action(() => Doc.GetProto(this.props.Document).autoHeight = !BoolCast(this.props.Document.autoHeight, false)), icon: "expand-arrows-alt"
+ description: BoolCast(this.props.Document.autoHeight) ? "Manual Height" : "Auto Height",
+ event: action(() => Doc.GetProto(this.props.Document).autoHeight = !BoolCast(this.props.Document.autoHeight)), icon: "expand-arrows-alt"
});
- ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems });
+ ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems, icon: "text-height" });
}
render() {
let self = this;
diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx
index d6ab2a34a..7e78ec684 100644
--- a/src/client/views/nodes/IconBox.tsx
+++ b/src/client/views/nodes/IconBox.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons';
+import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTag, faTextHeight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
@@ -18,7 +18,7 @@ library.add(faCaretUp);
library.add(faObjectGroup);
library.add(faStickyNote);
library.add(faFilePdf);
-library.add(faFilm);
+library.add(faFilm, faTag, faTextHeight);
@observer
export class IconBox extends React.Component<FieldViewProps> {
@@ -47,13 +47,15 @@ export class IconBox extends React.Component<FieldViewProps> {
specificContextMenu = (): void => {
ContextMenu.Instance.addItem({
description: BoolCast(this.props.Document.hideLabel) ? "Show label with icon" : "Remove label from icon",
- event: this.setLabelField
+ event: this.setLabelField,
+ icon: "tag"
});
let maxDocs = DocListCast(this.props.Document.maximizedDocs);
if (maxDocs.length === 1 && !BoolCast(this.props.Document.hideLabel)) {
ContextMenu.Instance.addItem({
description: BoolCast(this.props.Document.useOwnTitle) ? "Use target title for label" : "Use own title label",
- event: this.setUseOwnTitleField
+ event: this.setUseOwnTitleField,
+ icon: "text-height"
});
}
}
@@ -64,7 +66,7 @@ export class IconBox extends React.Component<FieldViewProps> {
let hideLabel = BoolCast(this.props.Document.hideLabel);
let maxDocs = DocListCast(this.props.Document.maximizedDocs);
let firstDoc = maxDocs.length ? maxDocs[0] : undefined;
- let label = hideLabel ? "" : (firstDoc && labelField && !BoolCast(this.props.Document.useOwnTitle, false) ? firstDoc[labelField] : this.props.Document.title);
+ let label = hideLabel ? "" : (firstDoc && labelField && !BoolCast(this.props.Document.useOwnTitle) ? firstDoc[labelField] : this.props.Document.title);
return (
<div className="iconBox-container" onContextMenu={this.specificContextMenu}>
{this.minimizedIcon}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 6541007d0..29a76b0c8 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -21,7 +21,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import "./ImageBox.scss";
import React = require("react");
import { RouteStore } from '../../../server/RouteStore';
-import { Docs } from '../../documents/Documents';
+import { Docs, DocumentType } from '../../documents/Documents';
import { DocServer } from '../../DocServer';
import { Font } from '@react-pdf/renderer';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -30,7 +30,7 @@ import FaceRectangles from './FaceRectangles';
import { faEye } from '@fortawesome/free-regular-svg-icons';
var requestImageSize = require('../../util/request-image-size');
var path = require('path');
-const { Howl, Howler } = require('howler');
+const { Howl } = require('howler');
library.add(faImage, faEye, faPaintBrush);
@@ -85,10 +85,20 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
@computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "Alternates"); }
@undoBatch
+ @action
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.data instanceof DragManager.DocumentDragData) {
de.data.droppedDocuments.forEach(action((drop: Doc) => {
- if (de.mods === "AltKey" && /*this.dataDoc !== this.props.Document &&*/ drop.data instanceof ImageField) {
+ if (de.mods === "CtrlKey") {
+ let temp = Doc.MakeDelegate(drop);
+ this.props.Document.nativeWidth = Doc.GetProto(this.props.Document).nativeWidth = undefined;
+ this.props.Document.nativeHeight = Doc.GetProto(this.props.Document).nativeHeight = undefined;
+ this.props.Document.width = drop.width;
+ this.props.Document.height = drop.height;
+ Doc.GetProto(this.props.Document).type = DocumentType.TEMPLATE;
+ this.props.Document.layout = temp;
+ e.stopPropagation();
+ } else if (de.mods === "AltKey" && /*this.dataDoc !== this.props.Document &&*/ drop.data instanceof ImageField) {
Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new ImageField(drop.data.url);
e.stopPropagation();
} else if (de.mods === "CtrlKey") {
@@ -104,8 +114,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
e.stopPropagation();
}
}
- } else if (!this.props.isSelected()) {
- e.stopPropagation();
}
}));
// de.data.removeDocument() bcz: need to implement
@@ -194,6 +202,20 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
});
}
+ @undoBatch
+ rotate = action(() => {
+ let proto = Doc.GetProto(this.props.Document);
+ let nw = this.props.Document.nativeWidth;
+ let nh = this.props.Document.nativeHeight;
+ let w = this.props.Document.width;
+ let h = this.props.Document.height;
+ proto.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
+ proto.nativeWidth = nh;
+ proto.nativeHeight = nw;
+ this.props.Document.width = h;
+ this.props.Document.height = w;
+ });
+
specificContextMenu = (e: React.MouseEvent): void => {
let field = Cast(this.Document[this.props.fieldKey], ImageField);
if (field) {
@@ -201,20 +223,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
let funcs: ContextMenuProps[] = [];
funcs.push({ description: "Copy path", event: () => Utils.CopyText(url), icon: "expand-arrows-alt" });
funcs.push({ description: "Record 1sec audio", event: this.recordAudioAnnotation, icon: "expand-arrows-alt" });
- funcs.push({
- description: "Rotate", event: action(() => {
- let proto = Doc.GetProto(this.props.Document);
- let nw = this.props.Document.nativeWidth;
- let nh = this.props.Document.nativeHeight;
- let w = this.props.Document.width;
- let h = this.props.Document.height;
- proto.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
- proto.nativeWidth = nh;
- proto.nativeHeight = nw;
- this.props.Document.width = h;
- this.props.Document.height = w;
- }), icon: "expand-arrows-alt"
- });
+ funcs.push({ description: "Rotate", event: this.rotate, icon: "expand-arrows-alt" });
let modes: ContextMenuProps[] = [];
let dataDoc = Doc.GetProto(this.props.Document);
@@ -244,11 +253,15 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
choosePath(url: URL) {
const lower = url.href.toLowerCase();
- if (url.protocol === "data" || url.href.indexOf(window.location.origin) === -1 || !(lower.endsWith(".png") || lower.endsWith(".jpg") || lower.endsWith(".jpeg"))) {
+ if (url.protocol === "data") {
return url.href;
+ } else if (url.href.indexOf(window.location.origin) === -1) {
+ return Utils.CorsProxy(url.href);
+ } else if (!(lower.endsWith(".png") || lower.endsWith(".jpg") || lower.endsWith(".jpeg"))) {
+ return url.href;//Why is this here
}
let ext = path.extname(url.href);
- const suffix = this.props.renderDepth <= 1 ? "_o" : this._curSuffix;
+ const suffix = this.props.renderDepth < 1 ? "_o" : this._curSuffix;
return url.href.replace(ext, suffix + ext);
}
@@ -352,7 +365,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
if (field instanceof ImageField) paths = [this.choosePath(field.url)];
paths.push(...altpaths);
// }
- let interactive = InkingControl.Instance.selectedTool ? "" : "-interactive";
+ let interactive = InkingControl.Instance.selectedTool || this.props.Document.isBackground ? "" : "-interactive";
let rotation = NumCast(this.dataDoc.rotation, 0);
let aspect = (rotation % 180) ? this.dataDoc[HeightSym]() / this.dataDoc[WidthSym]() : 1;
let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 9fc0f2080..77824b4ff 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -46,6 +46,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
@action
onEnterKey = (e: React.KeyboardEvent): void => {
if (e.key === 'Enter') {
+ e.stopPropagation();
if (this._keyInput && this._valueInput && this.fieldDocToLayout) {
if (KeyValueBox.SetField(this.fieldDocToLayout, this._keyInput, this._valueInput)) {
this._keyInput = "";
@@ -153,7 +154,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
<input style={{ width: "100%" }} type="text" value={this._keyInput} placeholder="Key" onChange={this.keyChanged} />
</td>
<td className="keyValueBox-td-value" style={{ width: `${this.splitPercentage}%` }}>
- <input style={{ width: "100%" }} type="text" value={this._valueInput} placeholder="Value" onChange={this.valueChanged} onKeyPress={this.onEnterKey} />
+ <input style={{ width: "100%" }} type="text" value={this._valueInput} placeholder="Value" onChange={this.valueChanged} onKeyDown={this.onEnterKey} />
</td>
</tr>
)
diff --git a/src/client/views/nodes/LinkMenuItem.tsx b/src/client/views/nodes/LinkMenuItem.tsx
index a0c37a719..d4c92c9f2 100644
--- a/src/client/views/nodes/LinkMenuItem.tsx
+++ b/src/client/views/nodes/LinkMenuItem.tsx
@@ -7,7 +7,7 @@ import { undoBatch } from "../../util/UndoManager";
import './LinkMenu.scss';
import React = require("react");
import { Doc } from '../../../new_fields/Doc';
-import { StrCast, Cast, BoolCast, FieldValue, NumCast } from '../../../new_fields/Types';
+import { StrCast, Cast, FieldValue, NumCast } from '../../../new_fields/Types';
import { observable, action } from 'mobx';
import { LinkManager } from '../../util/LinkManager';
import { DragLinkAsDocument } from '../../util/DragManager';
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 30ad75000..34cb47b20 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -19,10 +19,14 @@ import { positionSchema } from "./DocumentView";
import { FieldView, FieldViewProps } from './FieldView';
import { pageSchema } from "./ImageBox";
import "./VideoBox.scss";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faVideo } from "@fortawesome/free-solid-svg-icons";
type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
const VideoDocument = makeInterface(positionSchema, pageSchema);
+library.add(faVideo);
+
@observer
export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoDocument) {
private _reactionDisposer?: IReactionDisposer;
@@ -179,7 +183,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
},
icon: "expand-arrows-alt"
});
- ContextMenu.Instance.addItem({ description: "Video Funcs...", subitems: subitems });
+ ContextMenu.Instance.addItem({ description: "Video Funcs...", subitems: subitems, icon: "video" });
}
}