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/DocumentView.tsx23
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx7
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx1
-rw-r--r--src/client/views/nodes/VideoBox.tsx2
-rw-r--r--src/client/views/nodes/WebBox.tsx47
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
7 files changed, 70 insertions, 28 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ee4df97ed..f07cbfbf5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -71,19 +71,18 @@ export interface DocFocusOptions {
scale?: number; // percent of containing frame to zoom into document
afterFocus?: DocAfterFocusFunc; // function to call after focusing on a document
docTransform?: Transform; // when a document can't be panned and zoomed within its own container (say a group), then we need to continue to move up the render hierarchy to find something that can pan and zoom. when this happens the docTransform must accumulate all the transforms of each level of the hierarchy
+ instant?: boolean; // whether focus should happen instantly (as opposed to smooth zoom)
}
export type DocAfterFocusFunc = (notFocused: boolean) => Promise<ViewAdjustment>;
export type DocFocusFunc = (doc: Doc, options?: DocFocusOptions) => void;
export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
export interface DocComponentView {
- getAnchor?: () => Doc;
+ getAnchor?: () => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
scrollFocus?: (doc: Doc, smooth: boolean) => Opt<number>; // returns the duration of the focus
- setViewSpec?: (anchor: Doc, preview: boolean) => void;
- back?: () => boolean;
- forward?: () => boolean;
- url?: () => string;
- submitURL?: (url: string) => boolean;
- freeformData?: (force?: boolean) => Opt<{ panX: number, panY: number, scale: number }>;
+ setViewSpec?: (anchor: Doc, preview: boolean) => void; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
+ reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling.
+ shrinkWrap?: () => void; // requests a document to display all of its contents with no white space. currently only implemented (needed?) for freeform views
+ menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected.
}
export interface DocumentViewSharedProps {
renderDepth: number;
@@ -380,8 +379,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
startDragging(x: number, y: number, dropAction: dropActionType) {
if (this._mainCont.current) {
- const ffview = this.props.CollectionFreeFormDocumentView;
- ffview && runInAction(() => (ffview().props.CollectionFreeFormView.ChildDrag = this.props.DocumentView()));
const dragData = new DragManager.DocumentDragData([this.props.Document]);
const [left, top] = this.props.ScreenToLocalTransform().scale(this.ContentScale).inverse().transformPoint(0, 0);
dragData.offset = this.props.ScreenToLocalTransform().scale(this.ContentScale).transformDirection(x - left, y - top);
@@ -389,8 +386,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
dragData.treeViewDoc = this.props.treeViewDoc;
dragData.removeDocument = this.props.removeDocument;
dragData.moveDocument = this.props.moveDocument;
+ const ffview = this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
+ ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));
DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.layoutDoc.onDragStart },
- () => setTimeout(action(() => ffview && (ffview().props.CollectionFreeFormView.ChildDrag = undefined)))); // this needs to happen after the drop event is processed.
+ () => setTimeout(action(() => ffview && (ffview.ChildDrag = undefined)))); // this needs to happen after the drop event is processed.
}
}
@@ -998,8 +997,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
@computed get docViewPath() { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; }
@computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); }
- @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); }
- @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); }
+ @computed get nativeWidth() { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); }
+ @computed get nativeHeight() { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); }
@computed get nativeScaling() {
if (this.nativeWidth && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / this.nativeHeight > this.props.PanelWidth() / this.nativeWidth)) {
return this.props.PanelWidth() / this.nativeWidth; // width-limited or fitWidth
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 728e5e02f..4c3031ae2 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -381,7 +381,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
addDocument={this.addDocument}
- forceScaling={true}
+ annotationLayerHostsContent={true}
focus={this.props.focus}
isSelected={this.props.isSelected}
select={emptyFunction}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index ce9d8bed5..ebb953dad 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -125,12 +125,9 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
contents={contents}
maxHeight={36}
height={"auto"}
- GetValue={() => {
- return Field.toKeyValueString(props.Document, props.fieldKey);
- }}
+ GetValue={() => Field.toKeyValueString(props.Document, props.fieldKey)}
SetValue={(value: string) =>
- KeyValueBox.SetField(props.Document, props.fieldKey, value)}>
- </EditableView>
+ KeyValueBox.SetField(props.Document, props.fieldKey, value)} />
</div>
</td>
</tr>
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 720af6c9d..30b272a9a 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -2,7 +2,6 @@ import React = require("react");
import { observer } from "mobx-react";
import "./LinkDescriptionPopup.scss";
import { observable, action } from "mobx";
-import { EditableView } from "../EditableView";
import { LinkManager } from "../../util/LinkManager";
import { TaskCompletionBox } from "./TaskCompletedBox";
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 435563255..ac67949f9 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -552,7 +552,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
fieldKey={this.annotationKey}
isAnnotationOverlay={true}
- forceScaling={true}
+ annotationLayerHostsContent={true}
select={emptyFunction}
active={this.annotationsActive}
scaling={returnOne}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 663a8b8e4..2cd6f5f33 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -46,6 +46,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
private _iframeIndicatorRef = React.createRef<HTMLDivElement>();
private _iframeDragRef = React.createRef<HTMLDivElement>();
+ private _keyInput = React.createRef<HTMLInputElement>();
private _ignoreScroll = false;
private _initialScroll: Opt<number>;
@observable private _marqueeing: number[] | undefined;
@@ -262,6 +263,52 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
return true;
}
+ menuControls = () => this.urlEditor;
+ onWebUrlDrop = (e: React.DragEvent) => {
+ const { dataTransfer } = e;
+ const html = dataTransfer.getData("text/html");
+ const uri = dataTransfer.getData("text/uri-list");
+ const url = uri || html || this._url || "";
+ const newurl = url.startsWith(window.location.origin) ?
+ url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url;
+ this.submitURL(newurl);
+ e.stopPropagation();
+ }
+ onWebUrlValueKeyDown = (e: React.KeyboardEvent) => {
+ e.key === "Enter" && this.submitURL(this._keyInput.current!.value);
+ e.stopPropagation();
+ }
+
+ @computed get urlEditor() {
+ return (
+ <div className="collectionMenu-webUrlButtons" onDrop={this.onWebUrlDrop} onDragOver={e => e.preventDefault()} >
+ <input className="collectionMenu-urlInput" key={this._url}
+ placeholder="ENTER URL"
+ defaultValue={this._url}
+ onDrop={this.onWebUrlDrop}
+ onDragOver={e => e.preventDefault()}
+ onKeyDown={this.onWebUrlValueKeyDown}
+ onClick={(e) => {
+ this._keyInput.current!.select();
+ e.stopPropagation();
+ }}
+ ref={this._keyInput}
+ />
+ <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", maxWidth: "250px", }}>
+ <button className="submitUrl" onClick={() => this.submitURL(this._keyInput.current!.value)} onDragOver={e => e.stopPropagation()} onDrop={this.onWebUrlDrop}>
+ GO
+ </button>
+ <button className="submitUrl" onClick={this.back}>
+ <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
+ </button>
+ <button className="submitUrl" onClick={this.forward}>
+ <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
+ </button>
+ </div>
+ </div>
+ );
+ }
+
editToggleBtn() {
return <Tooltip title={<div className="dash-tooltip" >{`${this.props.Document.isAnnotating ? "Exit" : "Enter"} annotation mode`}</div>}>
<div className="webBox-annotationToggle"
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index da7ed9ac7..b4fbda9f4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -105,13 +105,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
private _disposers: { [name: string]: IReactionDisposer } = {};
private _dropDisposer?: DragManager.DragDropDisposer;
private _recordingStart: number = 0;
- private _pause: boolean = false;
private _ignoreScroll = false;
@computed get _recording() { return this.dataDoc?.audioState === "recording"; }
- set _recording(value) {
- this.dataDoc.audioState = value ? "recording" : undefined;
- }
+ set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; }
public static FocusedBox: FormattedTextBox | undefined;
public static SelectOnLoad = "";
@@ -1651,6 +1648,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
fitToBox = () => this.props.Document._fitToBox;
+ sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.SidebarKey);
+ sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey);
+ sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey);
@computed get sidebarCollection() {
const collectionProps: SubCollectionViewProps & collectionFreeformViewProps = {
...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit,
@@ -1662,16 +1662,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
yMargin: 0,
chromeStatus: "enabled",
scaleField: this.SidebarKey + "-scale",
- isAnnotationOverlay: true,
+ isAnnotationOverlay: false,
fieldKey: this.SidebarKey,
fitContentsToDoc: this.fitToBox,
select: emptyFunction,
active: this.annotationsActive,
scaling: this.sidebarContentScaling,
whenActiveChanged: this.whenActiveChanged,
- removeDocument: this.removeDocument,
- moveDocument: this.moveDocument,
- addDocument: this.addDocument,
+ removeDocument: this.sidebarRemDocument,
+ moveDocument: this.sidebarMoveDocument,
+ addDocument: this.sidebarAddDocument,
CollectionView: undefined,
ScreenToLocalTransform: this.sidebarScreenToLocal,
renderDepth: this.props.renderDepth + 1,