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.tsx6
-rw-r--r--src/client/views/nodes/ImageBox.tsx25
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx3
-rw-r--r--src/client/views/nodes/VideoBox.tsx19
-rw-r--r--src/client/views/nodes/WebBox.tsx40
5 files changed, 44 insertions, 49 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 678be0500..121d2d556 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -777,7 +777,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
onClickFunc = () => this.onClickHandler;
setHeight = (height: number) => this.layoutDoc._height = height;
setContentView = (view: { getAnchor?: () => Doc, forward?: () => boolean, back?: () => boolean }) => this._componentView = view;
- isContentActive = (outsideReaction?: boolean) => this.props.isContentActive() ? true : false;
+ isContentActive = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || this.props.isContentActive() ? true : false;
@computed get contents() {
TraceMobx();
const audioView = !this.layoutDoc._showAudio ? (null) :
@@ -792,7 +792,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>;
return <div className="documentView-contentsView"
style={{
- pointerEvents: this.props.contentPointerEvents as any,
+ pointerEvents: (this.props.contentPointerEvents as any) || (CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() || this.isContentActive() ? "all" : "none"),
height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
}}>
<DocumentContentsView key={1} {...this.props}
@@ -809,7 +809,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
layoutKey={this.finalLayoutKey} />
{this.layoutDoc.hideAllLinks ? (null) : this.allLinkEndpoints}
{this.hideLinkButton ? (null) :
- <div style={{ transformOrigin: "top left", transform: `scale(${Math.min(1, this.props.ScreenToLocalTransform().Scale)})` }}>
+ <div style={{ transformOrigin: "top left", transform: `scale(${Math.min(1, this.props.ScreenToLocalTransform().scale(this.props.ContentScaling?.() || 1).Scale)})` }}>
<DocumentLinksButton View={this.props.DocumentView()} Offset={[this.topMost ? 0 : -15, undefined, undefined, this.topMost ? 10 : -20]} />
</div>}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2c0106960..c4e74ebd2 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,19 +1,21 @@
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
import { observer } from "mobx-react";
import { DataSym, Doc, DocListCast, WidthSym } from '../../../fields/Doc';
import { documentSchema } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
+import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { createSchema, makeInterface } from '../../../fields/Schema';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, NumCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, OmitKeys, returnOne, Utils, returnFalse } from '../../../Utils';
+import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils';
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices';
import { Networking } from '../../Network';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from "../../views/ContextMenu";
@@ -21,15 +23,13 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
+import { AnchorMenu } from '../pdf/AnchorMenu';
import { StyleProp } from '../StyleProvider';
import { FaceRectangles } from './FaceRectangles';
import { FieldView, FieldViewProps } from './FieldView';
import "./ImageBox.scss";
import React = require("react");
-import { InkTool } from '../../../fields/InkField';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
-import { AnchorMenu } from '../pdf/AnchorMenu';
-import { Docs } from '../../documents/Documents';
+import { SnappingManager } from '../../util/SnappingManager';
const path = require('path');
export const pageSchema = createSchema({
@@ -294,7 +294,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<div className="imageBox-fader" >
<img key="paths" ref={this._imgRef}
src={srcpath}
- style={{ transform, transformOrigin }} draggable={false}
+ style={{ transform, transformOrigin }}
+ draggable={false}
width={nativeWidth} />
{fadepath === srcpath ? (null) : <div className="imageBox-fadeBlocker">
<img className="imageBox-fadeaway" key={"fadeaway"} ref={this._imgRef}
@@ -330,11 +331,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
TraceMobx();
return <div className="imageBox-annotationLayer" style={{ height: this.props.PanelHeight() }} ref={this._annotationLayer} />;
}
- @action
marqueeDown = (e: React.PointerEvent) => {
if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
- this._marqueeing = [e.clientX, e.clientY];
- e.stopPropagation();
+ setupMoveUpEvents(this, e, action(e => {
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations)
+ this._marqueeing = [e.clientX, e.clientY];
+ return true;
+ }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
}
}
@action
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index f0db0b594..7ad96bf05 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -175,8 +175,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
@computed get content() {
if (this.rootDoc.videoWall) return (null);
- const interactive = CurrentUserUtils.SelectedTool !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
- return <video className={"videoBox-content" + interactive} key="video"
+ return <video className={"videoBox-content"} key="video"
ref={r => {
this._videoRef = r;
setTimeout(() => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index fc97a6f4d..d4df30b48 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -9,7 +9,7 @@ import { InkTool } from "../../../fields/InkField";
import { makeInterface } from "../../../fields/Schema";
import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { AudioField, nullAudio, VideoField } from "../../../fields/URLField";
-import { emptyFunction, formatTime, OmitKeys, returnOne, setupMoveUpEvents, Utils } from "../../../Utils";
+import { emptyFunction, formatTime, OmitKeys, returnOne, setupMoveUpEvents, Utils, returnFalse } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { Networking } from "../../Network";
import { CurrentUserUtils } from "../../util/CurrentUserUtils";
@@ -209,11 +209,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
componentDidMount() {
this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
- this._disposers.selection = reaction(() => this.props.isSelected(),
- selected => !selected && setTimeout(() => {
- Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
- this._savedAnnotations.clear();
- }));
this._disposers.triggerVideo = reaction(
() => !LinkDocPreview.LinkInfo && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerVideo, null) : undefined,
time => time !== undefined && setTimeout(() => {
@@ -550,9 +545,15 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return <div className="imageBox-annotationLayer" style={{ transition: this.transition, height: `${this.heightPercent}%` }} ref={this._annotationLayer} />;
}
- marqueeDown = action((e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) this._marqueeing = [e.clientX, e.clientY];
- });
+ marqueeDown = (e: React.PointerEvent) => {
+ if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+ setupMoveUpEvents(this, e, action(e => {
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
+ this._marqueeing = [e.clientX, e.clientY];
+ return true;
+ }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
+ }
+ }
finishMarquee = action(() => {
this._marqueeing = undefined;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 2ff41c73a..0c32a30db 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -44,7 +44,7 @@ const WebDocument = makeInterface(documentSchema);
export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps, WebDocument>(WebDocument) {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); }
public static openSidebarWidth = 250;
- private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void);
+ private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _outerRef: React.RefObject<HTMLDivElement> = React.createRef();
private _disposers: { [name: string]: IReactionDisposer } = {};
@@ -52,16 +52,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
private _keyInput = React.createRef<HTMLInputElement>();
private _initialScroll: Opt<number>;
private _sidebarRef = React.createRef<SidebarAnnos>();
- @observable private _urlHash: string = "";
@observable private _scrollTimer: any;
@observable private _overlayAnnoInfo: Opt<Doc>;
@observable private _marqueeing: number[] | undefined;
- @observable private _url: string = "hello";
@observable private _isAnnotating = false;
@observable private _iframeClick: HTMLIFrameElement | undefined = undefined;
@observable private _iframe: HTMLIFrameElement | null = null;
@observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
@observable private _scrollHeight = 1500;
+ @computed get _url() { return this.webField?.toString() || ""; }
+ @computed get _urlHash() { return this._url ? WebBox.urlHash(this._url) + "" : ""; }
@computed get scrollHeight() { return this._scrollHeight; }
@computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); }
@computed get inlineTextAnnotations() { return this.allAnnotations.filter(a => a.textInlineAnnotations); }
@@ -82,9 +82,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
runInAction(() => {
- this._url = this.webField?.toString() || "";
- this._urlHash = WebBox.urlHash(this._url) + "";
- this._annotationKey = this._urlHash + "-annotations";
+ this._annotationKeySuffix = () => this._urlHash + "-annotations";
// bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be when the doc is created)
this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"`);
this.dataDoc[this.fieldKey + "-sidebar"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"`);
@@ -214,6 +212,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
const scale = (this.props.scaling?.() || 1) * mainContBounds.scale;
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
+ this._setPreviewCursor?.(e.clientX, e.clientY, false, true);
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX * scale + mainContBounds.translateX,
e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale];
if (word) {
@@ -306,9 +306,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), []);
if (future.length) {
this.dataDoc[this.fieldKey + "-history"] = new List<string>([...history, this._url]);
- this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = future.pop()!));
- this._urlHash = WebBox.urlHash(this._url) + "";
- this._annotationKey = this._urlHash + "-annotations";
+ this.dataDoc[this.fieldKey] = new WebField(new URL(future.pop()!));
return true;
}
return false;
@@ -321,9 +319,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (history.length) {
if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]);
else this.dataDoc[this.fieldKey + "-future"] = new List<string>([...future, this._url]);
- this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = history.pop()!));
- this._urlHash = WebBox.urlHash(this._url) + "";
- this._annotationKey = this._urlHash + "-annotations";
+ this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!));
return true;
}
return false;
@@ -342,17 +338,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"));
const url = this.webField?.toString();
if (url && !preview) {
- if (history === undefined) {
- this.dataDoc[this.fieldKey + "-history"] = new List<string>([url]);
- } else {
- this.dataDoc[this.fieldKey + "-history"] = new List<string>([...history, url]);
- }
+ this.dataDoc[this.fieldKey + "-history"] = new List<string>([...(history || []), url]);
this.layoutDoc._scrollTop = 0;
future && (future.length = 0);
}
- this._url = newUrl;
- this._urlHash = WebBox.urlHash(this._url) + "";
- this._annotationKey = this._urlHash + "-annotations";
if (!preview) this.dataDoc[this.fieldKey] = new WebField(new URL(newUrl));
} catch (e) {
console.log("WebBox URL error:" + this._url);
@@ -413,15 +402,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
onMarqueeDown = (e: React.PointerEvent) => {
if (!e.altKey && e.button === 0 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
- this._marqueeing = [e.clientX, e.clientY];
- this.props.select(false);
+ setupMoveUpEvents(this, e, action(e => {
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
+ this._marqueeing = [e.clientX, e.clientY];
+ return true;
+ }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
}
}
@action finishMarquee = (x?: number, y?: number) => {
this._marqueeing = undefined;
this._isAnnotating = false;
this._iframeClick = undefined;
- x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false);
+ x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false);
}
@computed
@@ -511,7 +503,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get SidebarShown() { return this._showSidebar || this.layoutDoc._showSidebar ? true : false; }
showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno);
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func;
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => this._setPreviewCursor = func;
panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0);
panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));