aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts16
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/util/HypothesisUtils.ts2
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/InkingStroke.tsx8
-rw-r--r--src/client/views/PreviewCursor.tsx2
-rw-r--r--src/client/views/PropertiesButtons.tsx2
-rw-r--r--src/client/views/StyleProvider.scss2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx6
-rw-r--r--src/client/views/nodes/ImageBox.tsx1
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx1
-rw-r--r--src/client/views/nodes/WebBox.tsx1
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx80
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx2
-rw-r--r--src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts2
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx27
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx11
-rw-r--r--src/client/views/pdf/Annotation.tsx6
-rw-r--r--src/client/views/pdf/PDFViewer.tsx2
-rw-r--r--src/mobile/ImageUpload.tsx2
24 files changed, 98 insertions, 89 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b32cbd3d0..df08345f9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -280,7 +280,7 @@ export namespace Docs {
}],
[DocumentType.WEB, {
layout: { view: WebBox, dataField: defaultDataKey },
- options: { _height: 300 }
+ options: { _height: 300, scrollHeight: 100000, _fitWidth: true }
}],
[DocumentType.COL, {
layout: { view: CollectionView, dataField: defaultDataKey },
@@ -304,7 +304,7 @@ export namespace Docs {
}],
[DocumentType.PDF, {
layout: { view: PDFBox, dataField: defaultDataKey },
- options: { _curPage: 1 }
+ options: { _curPage: 1, _fitWidth: true }
}],
[DocumentType.IMPORT, {
layout: { view: DirectoryImportBox, dataField: defaultDataKey },
@@ -764,11 +764,16 @@ export namespace Docs {
}
export function PdfDocument(url: string, options: DocumentOptions = {}) {
- return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(new URL(url)), options);
+ const pdfProto = Prototypes.get(DocumentType.PDF);
+ pdfProto._fitWidth = true; // backward compatibility -- can be removed after db is reset
+ return InstanceFromProto(pdfProto, new PdfField(new URL(url)), options);
}
export function WebDocument(url: string, options: DocumentOptions = {}) {
- return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _fitWidth: true, _chromeStatus: url ? "disabled" : "enabled", isAnnotating: false, _lockedTransform: true, ...options });
+ const webProto = Prototypes.get(DocumentType.WEB);
+ webProto.scrollHeight = 100000; // backward compatibility -- can be removed after db is reset
+ webProto._fitWidth = true; // backward compatibility -- can be removed after db is reset
+ return InstanceFromProto(webProto, url ? new WebField(new URL(url)) : undefined, { _chromeStatus: url ? "disabled" : "enabled", isAnnotating: false, _lockedTransform: true, ...options });
}
export function HtmlDocument(html: string, options: DocumentOptions = {}) {
@@ -1110,7 +1115,6 @@ export namespace DocUtils {
}
if (type.indexOf("pdf") !== -1) {
ctor = Docs.Create.PdfDocument;
- if (!options._fitWidth) options._fitWidth = true;
if (!options._width) options._width = 400;
if (!options._height) options._height = options._width * 1200 / 927;
}
@@ -1131,7 +1135,7 @@ export namespace DocUtils {
});
}
ctor = Docs.Create.WebDocument;
- options = { ...options, _fitWidth: true, _width: 400, _height: 512, title: path, };
+ options = { ...options, _width: 400, _height: 512, title: path, };
}
return ctor ? ctor(path, options) : undefined;
}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index c4f7744ce..f3fec9ae6 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -444,7 +444,7 @@ export class CurrentUserUtils {
{ _width: 250, _height: 250, title: "container", system: true, cloneFieldFilter: new List<string>(["system"]) });
}
if (doc.emptyWebpage === undefined) {
- doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, _fitWidth: true, isTemplateDoc: true, _height: 512, _width: 400, useCors: true, system: true, cloneFieldFilter: new List<string>(["system"]) });
+ doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, isTemplateDoc: true, _height: 512, _width: 400, useCors: true, system: true, cloneFieldFilter: new List<string>(["system"]) });
}
if (doc.activeMobileMenu === undefined) {
this.setupActiveMobileMenu(doc);
diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts
index 7a449b882..8ddfce772 100644
--- a/src/client/util/HypothesisUtils.ts
+++ b/src/client/util/HypothesisUtils.ts
@@ -21,7 +21,7 @@ export namespace Hypothesis {
export const getSourceWebDoc = async (uri: string) => {
const result = await findWebDoc(uri);
console.log(result ? "existing doc found" : "existing doc NOT found");
- return result || Docs.Create.WebDocument(uri, { title: uri, _fitWidth: true, _nativeWidth: 850, _height: 512, _width: 400, useCors: true }); // create and return a new Web doc with given uri if no matching docs are found
+ return result || Docs.Create.WebDocument(uri, { title: uri, _nativeWidth: 850, _height: 512, _width: 400, useCors: true }); // create and return a new Web doc with given uri if no matching docs are found
};
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index a2bd0aad9..eeef94d74 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -155,7 +155,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
e.preventDefault();
let googleDoc = await Cast(dataDoc.googleDoc, Doc);
if (!googleDoc) {
- const options = { _width: 600, _fitWidth: true, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
+ const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
dataDoc.googleDoc = googleDoc;
}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 8df7f7eef..19b23af13 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -6,7 +6,7 @@ import { InkData, InkField, InkTool } from "../../fields/InkField";
import { makeInterface } from "../../fields/Schema";
import { Cast, StrCast } from "../../fields/Types";
import { TraceMobx } from "../../fields/util";
-import { setupMoveUpEvents } from "../../Utils";
+import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
import { InteractionUtils } from "../util/InteractionUtils";
import { Scripting } from "../util/Scripting";
@@ -87,6 +87,11 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
}
}
+ onPointerDown = (e: React.PointerEvent) => {
+ this.props.isSelected(true) && setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e: PointerEvent, doubleTap: boolean | undefined) => {
+ doubleTap && InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true);
+ }));
+ }
public static MaskDim = 50000;
render() {
@@ -196,6 +201,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? "multiply" : "unset",
overflow: "visible",
}}
+ onPointerDown={this.onPointerDown}
onContextMenu={() => {
const cm = ContextMenu.Instance;
if (cm) {
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index ac61dd1d8..5b57ad19f 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -49,7 +49,7 @@ export class PreviewCursor extends React.Component<{}> {
else if (re.test(plain)) {
const url = plain;
undoBatch(() => PreviewCursor._addDocument(Docs.Create.WebDocument(url, {
- title: url, _fitWidth: true, _width: 500, _height: 300, useCors: true, x: newPoint[0], y: newPoint[1]
+ title: url, _width: 500, _height: 300, useCors: true, x: newPoint[0], y: newPoint[1]
})))();
}
else if (plain.startsWith("__DashDocId(") || plain.startsWith("__DashCloneId(")) {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 4413d28f5..9a836313c 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -153,7 +153,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
e.preventDefault();
let googleDoc = await Cast(dataDoc.googleDoc, Doc);
if (!googleDoc) {
- const options = { _width: 600, _fitWidth: true, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
+ const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
dataDoc.googleDoc = googleDoc;
}
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss
index df63288f1..94001730c 100644
--- a/src/client/views/StyleProvider.scss
+++ b/src/client/views/StyleProvider.scss
@@ -3,7 +3,7 @@
width: 20;
height: 20;
position: absolute;
- right: -5;
+ right: -25;
top: -5;
background: transparent;
pointer-events: all;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 26cb4d156..287bc56c2 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -268,7 +268,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
}
});
} else {
- this.addDocument(Docs.Create.WebDocument(href, { ...options, _fitWidth: true, title: href }));
+ this.addDocument(Docs.Create.WebDocument(href, { ...options, title: href }));
}
} else if (text) {
this.addDocument(Docs.Create.TextDocument(text, { ...options, _showTitle: StrCast(Doc.UserDoc().showTitle), _width: 100, _height: 25 }));
@@ -385,7 +385,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
console.log("Adding ...");
const newDoc = Docs.Create.WebDocument(uriList.split("#annotations:")[0], {// clean hypothes.is URLs that reference a specific annotation (eg. https://en.wikipedia.org/wiki/Cartoon#annotations:t7qAeNbCEeqfG5972KR2Ig)
...options,
- _fitWidth: true,
title: uriList.split("#annotations:")[0],
_width: 400,
_height: 512,
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 258e839d0..9ef37ecc2 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -89,7 +89,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const [x, y] = this.Transform.transformPoint(this._downX, this._downY);
if (e.key === "?") {
cm.setDefaultItem("?", (str: string) => this.props.addDocTab(
- Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _fitWidth: true, _width: 400, x, y, _height: 512, _nativeWidth: 850, isAnnotating: false, title: "bing", useCors: true }), "add:right"));
+ Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, isAnnotating: false, title: "bing", useCors: true }), "add:right"));
cm.displayMenu(this._downX, this._downY);
e.stopPropagation();
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d6cefa5b0..19ef03a31 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -127,9 +127,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
@undoBatch
@action
- deleteLink = (): void => {
+ deleteLink = (e: React.PointerEvent): void => {
this.props.linkDoc.linksToAnnotation && Hypothesis.deleteLink(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
LinkManager.Instance.deleteLink(this.props.linkDoc);
+ e.stopPropagation();
runInAction(() => {
LinkDocPreview.LinkInfo = undefined;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 546eca427..c5c47b463 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -389,9 +389,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}, console.log);
undoBatch(func)();
} else if (!Doc.IsSystem(this.props.Document)) {
- if (this.props.Document.type === DocumentType.INK) {
- InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true);
- } else if (this.props.Document.type !== DocumentType.LABEL) {
+ if (this.props.Document.type !== DocumentType.LABEL) {
UndoManager.RunInBatch(() => {
const fullScreenDoc = Cast(this.props.Document._fullScreenView, Doc, null) || this.props.Document;
this.props.addDocTab(fullScreenDoc, "add");
@@ -897,7 +895,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
if (this.nativeHeight) {
return Math.min(this.props.PanelHeight(),
this.props.Document._fitWidth ?
- Math.max(NumCast(this.props.Document._height), NumCast((this.props.Document.scrollHeight as number) * this.props.PanelWidth() / this.nativeWidth, this.props.PanelHeight())) :
+ Math.max(NumCast(this.props.Document._height), NumCast(((this.props.Document.scrollHeight || 0) as number) * this.props.PanelWidth() / this.nativeWidth, this.props.PanelHeight())) :
this.nativeHeight * this.nativeScaling
);
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 47fa25951..649fe8f40 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -83,7 +83,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
if (!selected) {
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
this._savedAnnotations.clear();
- AnchorMenu.Instance.fadeOut(true);
}
},
{ fireImmediately: true });
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 07b2b6338..7934dba8e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -76,7 +76,7 @@ export class LinkDocPreview extends React.Component<Props> {
if (this.props.linkDoc && this.props.linkSrc) {
LinkManager.FollowLink(this.props.linkDoc, this.props.linkSrc, this.props.docprops, false);
} else if (this.props.href) {
- this.props.docprops?.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right");
+ this.props.docprops?.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right");
}
}
width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 55a9818ad..6354c677e 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -195,7 +195,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
if (!selected) {
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
this._savedAnnotations.clear();
- AnchorMenu.Instance.fadeOut(true);
}
},
{ fireImmediately: true });
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c9c4ed159..69f797880 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -161,7 +161,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
if (!selected) {
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
this._savedAnnotations.clear();
- AnchorMenu.Instance.fadeOut(true);
}
},
{ fireImmediately: true });
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f9982f747..ac5ea66ff 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -59,7 +59,7 @@ import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark }
import React = require("react");
import { LinkManager } from '../../../util/LinkManager';
import { CollectionStackingView } from '../../collections/CollectionStackingView';
-import { CollectionViewType, CollectionViewProps } from '../../collections/CollectionView';
+import { CollectionViewType } from '../../collections/CollectionView';
import { SnappingManager } from '../../../util/SnappingManager';
import { LinkDocPreview } from '../LinkDocPreview';
import { SubCollectionViewProps } from '../../collections/CollectionSubView';
@@ -85,6 +85,7 @@ type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, da
export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProps & FormattedTextBoxProps), RichTextDocument>(RichTextDocument) {
public static LayoutString(fieldStr: string) { return FieldView.LayoutString(FormattedTextBox, fieldStr); }
public static blankState = () => EditorState.create(FormattedTextBox.Instance.config);
+ public static CanAnnotate = true;
public static Instance: FormattedTextBox;
public ProseRef?: HTMLDivElement;
public get EditorView() { return this._editorView; }
@@ -211,6 +212,42 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this.linkOnDeselect.clear();
}
+ @action
+ setupAnchorMenu = () => {
+ AnchorMenu.Instance.Status = "marquee";
+ AnchorMenu.Instance.Highlight = action((color: string) => {
+ this._editorView?.state && RichTextMenu.Instance.insertHighlight(color, this._editorView.state, this._editorView?.dispatch);
+ return undefined;
+ });
+ /**
+ * This function is used by the PDFmenu to create an anchor highlight and a new linked text annotation.
+ * It also initiates a Drag/Drop interaction to place the text annotation.
+ */
+ AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => {
+ e.preventDefault();
+ e.stopPropagation();
+ const targetCreator = () => {
+ const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.rootDoc.title, 0, 0, 100, 100);
+ FormattedTextBox.SelectOnLoad = target[Id];
+ return target;
+ }
+
+ DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.rootDoc, () => this.rootDoc, targetCreator), e.pageX, e.pageY, {
+ dragComplete: e => {
+ if (!e.aborted && e.annoDragData && e.annoDragData.annotationDocument && e.annoDragData.dropDocument && !e.linkDocument) {
+ e.linkDocument = DocUtils.MakeLink({ doc: e.annoDragData.annotationDocument }, { doc: e.annoDragData.dropDocument }, "hyperlink", "link to note");
+ e.annoDragData.annotationDocument.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.rootDoc;
+ }
+ e.linkDocument && e.annoDragData?.dropDocument && this.makeLinkToSelection(e.linkDocument[Id], "a link", "add:right", e.annoDragData.dropDocument[Id]);
+ e.linkDocument && e.annoDragData?.linkDropCallback?.(e as { linkDocument: Doc });// bcz: typescript can't figure out that this is valid even though we tested e.linkDocument
+ }
+ });
+ });
+ const coordsT = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
+ const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
+ this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(Math.min(coordsT.left, coordsB.left), Math.max(coordsT.bottom, coordsB.bottom));
+ }
+
dispatchTransaction = (tx: Transaction) => {
let timeStamp;
clearTimeout(timeStamp);
@@ -254,42 +291,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
let unchanged = true;
const effectiveAcl = GetEffectiveAcl(this.dataDoc);
- if (!this._editorView.state.selection.empty) {
- runInAction(() => {
- AnchorMenu.Instance.Status = "marquee";
- AnchorMenu.Instance.Highlight = action((color: string) => {
- this._editorView?.state && RichTextMenu.Instance.insertHighlight(color, this._editorView?.state, this._editorView?.dispatch);
- return undefined;
- });
- /**
- * This function is used by the PDFmenu to create an anchor highlight and a new linked text annotation.
- * It also initiates a Drag/Drop interaction to place the text annotation.
- */
- AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => {
- e.preventDefault();
- e.stopPropagation();
- const targetCreator = () => {
- const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.rootDoc.title, 0, 0, 100, 100);
- FormattedTextBox.SelectOnLoad = target[Id];
- return target;
- }
-
- DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.rootDoc, () => this.rootDoc, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.annotationDocument && e.annoDragData.dropDocument && !e.linkDocument) {
- e.linkDocument = DocUtils.MakeLink({ doc: e.annoDragData.annotationDocument }, { doc: e.annoDragData.dropDocument }, "hyperlink", "link to note");
- e.annoDragData.annotationDocument.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.rootDoc;
- }
- e.linkDocument && e.annoDragData?.dropDocument && this.makeLinkToSelection(e.linkDocument[Id], "a link", "add:right", e.annoDragData.dropDocument[Id]);
- e.linkDocument && e.annoDragData?.linkDropCallback?.(e as { linkDocument: Doc });// bcz: typescript can't figure out that this is valid even though we tested e.linkDocument
- }
- });
- });
- });
- const coordsT = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
- const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
- AnchorMenu.Instance.jumpTo(Math.min(coordsT.left, coordsB.left), Math.max(coordsT.bottom, coordsB.bottom));
- }
+ if (!this._editorView.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu();
const removeSelection = (json: string | undefined) => {
return json?.indexOf("\"storedMarks\"") === -1 ? json?.replace(/"selection":.*/, "") : json?.replace(/"selection":"\"storedMarks\""/, "\"storedMarks\"");
@@ -658,6 +660,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const uicontrols: ContextMenuProps[] = [];
+ uicontrols.push({ description: `${FormattedTextBox.CanAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox.CanAnnotate = !FormattedTextBox.CanAnnotate, icon: "expand-arrows-alt" });
uicontrols.push({ description: `${this.layoutDoc._showAudio ? "Hide" : "Show"} Dictation Icon`, event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" });
uicontrols.push({ description: "Show Highlights...", noexpand: true, subitems: highlighting, icon: "hand-point-right" });
!Doc.UserDoc().noviceMode && uicontrols.push({ description: `Create TimeStamp When ${this.layoutDoc._timeStampOnEnter ? "Pause" : "Enter"}`, event: () => this.layoutDoc._timeStampOnEnter = !this.layoutDoc._timeStampOnEnter, icon: "expand-arrows-alt" });
@@ -999,7 +1002,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._disposers.selected = reaction(() => this.props.isSelected(),
action((selected) => {
this._recording = false;
- AnchorMenu.Instance.fadeOut(true);
if (RichTextMenu.Instance?.view === this._editorView && !selected) {
RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
}
@@ -1296,9 +1298,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
componentWillUnmount() {
+ Object.values(this._disposers).forEach(disposer => disposer?.());
this.endUndoTypingBatch();
this.unhighlightSearchTerms();
- Object.values(this._disposers).forEach(disposer => disposer?.());
this._editorView?.destroy();
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 8867595ff..5371bd10a 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -121,7 +121,7 @@ export class FormattedTextBoxComment {
}
}
} else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
- textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _fitWidth: true, _width: 200, _height: 400, useCors: true }), "add:right");
+ textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, useCors: true }), "add:right");
}
keep && textBox && FormattedTextBoxComment.start !== undefined && textBox.adoptAnnotation(
FormattedTextBoxComment.start, FormattedTextBoxComment.end, FormattedTextBoxComment.mark);
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index cb5823e86..8d9d36580 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -135,7 +135,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
//Command to create a new Tab with a PDF of all the command shortcuts
bind("Mod-/", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
- const newDoc = Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _fitWidth: true, _width: 300, _height: 300 });
+ const newDoc = Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 });
props.addDocTab(newDoc, "add:right");
});
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 07439825f..992194e2b 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -56,7 +56,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable private activeListType: string = "";
@observable private activeAlignment: string = "left";
- @observable private brushIsEmpty: boolean = true;
@observable private brushMarks: Set<Mark> = new Set();
@observable private showBrushDropdown: boolean = false;
@@ -600,7 +599,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
createBrushButton() {
const self = this;
- function onBrushClick(e: React.PointerEvent) {
+ const onBrushClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
self.TextView.endUndoTypingBatch();
@@ -622,8 +621,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
//onPointerDown={onBrushClick}
const button = <Tooltip title={<div className="dash-tooltip">style brush</div>} placement="bottom">
-
- <button className="antimodeMenu-button" style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}>
+ <button className="antimodeMenu-button" onClick={onBrushClick} style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}>
<FontAwesomeIcon icon="paint-roller" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.brushMarks?.size > 0 ? 45 : 0}deg)` }} />
</button>
</Tooltip>;
@@ -636,13 +634,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
</div>;
return (
- <ButtonDropdown view={this.view} key={"brush dropdown"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} />
+ <ButtonDropdown view={this.view} key={"brush dropdown"} button={button} openDropdownOnButton={false} dropdownContent={dropdownContent} />
);
}
@action
clearBrush() {
- RichTextMenu.Instance.brushIsEmpty = true;
RichTextMenu.Instance.brushMarks = new Set();
}
@@ -650,26 +647,22 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
fillBrush(state: EditorState<any>, dispatch: any) {
if (!this.view) return;
- if (this.brushIsEmpty) {
+ if (!Array.from(this.brushMarks.keys()).length) {
const selected_marks = this.getMarksInSelection(this.view.state);
if (selected_marks.size >= 0) {
this.brushMarks = selected_marks;
- this.brushIsEmpty = !this.brushIsEmpty;
}
}
else {
const { from, to, $from } = this.view.state.selection;
if (!this.view.state.selection.empty && $from && $from.nodeAfter) {
- if (this.brushMarks && to - from > 0) {
+ if (to - from > 0) {
this.view.dispatch(this.view.state.tr.removeMark(from, to));
Array.from(this.brushMarks).filter(m => m.type !== schema.marks.user_mark).forEach((mark: Mark) => {
this.setMark(mark, this.view!.state, this.view!.dispatch);
});
}
}
- else {
- this.brushIsEmpty = !this.brushIsEmpty;
- }
}
}
@@ -817,8 +810,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
<button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button>
</div>;
- return <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent}
- openDropdownOnButton={true} link={true} />;
+ return <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} link={true} />;
}
async getTextLinkTargetTitle() {
@@ -1027,6 +1019,7 @@ interface ButtonDropdownProps {
openDropdownOnButton?: boolean;
link?: boolean;
pdf?: boolean;
+
}
@observer
@@ -1071,9 +1064,11 @@ export class ButtonDropdown extends React.Component<ButtonDropdownProps> {
return (
<div className="button-dropdown-wrapper" ref={node => this.ref = node}>
{!this.props.pdf ?
- <div className="antimodeMenu-button dropdown-button-combined" onPointerDown={this.onDropdownClick}>
+ <div className="antimodeMenu-button dropdown-button-combined" onPointerDown={this.props.openDropdownOnButton ? this.onDropdownClick : undefined}>
{this.props.button}
- <div style={{ marginTop: "-8.5" }}><FontAwesomeIcon icon="caret-down" size="sm" /></div>
+ <div style={{ marginTop: "-8.5", position: "relative" }} onPointerDown={!this.props.openDropdownOnButton ? this.onDropdownClick : undefined}>
+ <FontAwesomeIcon icon="caret-down" size="sm" />
+ </div>
</div>
:
<>
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index e2bd5a73d..d1fdc6c44 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -1,7 +1,7 @@
import React = require("react");
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@material-ui/core";
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
import { ColorState } from "react-color";
import { Doc, Opt } from "../../../fields/Doc";
@@ -9,6 +9,7 @@ import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from "..
import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu";
import { ButtonDropdown } from "../nodes/formattedText/RichTextMenu";
import "./AnchorMenu.scss";
+import { SelectionManager } from "../../util/SelectionManager";
@observer
export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -58,6 +59,14 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
AnchorMenu.Instance._canFade = false;
}
+ _disposer: IReactionDisposer | undefined;
+ componentDidMount() {
+ this._disposer = reaction(() => SelectionManager.Views(),
+ selected => {
+ AnchorMenu.Instance.fadeOut(true);
+ });
+ }
+
pointerDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, (e: PointerEvent) => {
this.StartDrag(e, this._commentCont.current!);
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 85dd65901..cd32c2c3a 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -67,8 +67,8 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
}
componentWillUnmount() {
- this._brushDisposer && this._brushDisposer();
- this._reactionDisposer && this._reactionDisposer();
+ this._brushDisposer?.();
+ this._reactionDisposer?.();
}
@undoBatch
@@ -83,8 +83,8 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
DocListCast(group.annotations).forEach(anno => anno.delete = true);
}
-
AnchorMenu.Instance.fadeOut(true);
+ this.props.select(false);
}
@undoBatch
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index f2052d454..fa97bde3f 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -137,7 +137,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
if (!selected) {
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
this._savedAnnotations.keys().forEach(k => this._savedAnnotations.setValue(k, []));
- AnchorMenu.Instance.fadeOut(true);
}
(SelectionManager.Views().length === 1) && this.setupPdfJsViewer();
},
@@ -389,7 +388,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
} else {
// clear out old marquees and initialize menu for new selection
AnchorMenu.Instance.Status = "marquee";
- AnchorMenu.Instance.fadeOut(true);
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));
this._savedAnnotations.clear();
this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, "pdfAnnotation", { "pointer-events": "none" });
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 65f9e40ff..2183d2172 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -57,7 +57,7 @@ export class Uploader extends React.Component<ImageUploadProps> {
doc = Docs.Create.VideoDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
// Case 2: File is a PDF document
} else if (file.type === "application/pdf") {
- doc = Docs.Create.PdfDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, _fitWidth: true, title: name });
+ doc = Docs.Create.PdfDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });
// Case 3: File is another document type (most likely Image)
} else {
doc = Docs.Create.ImageDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name });