aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf')
-rw-r--r--src/client/views/pdf/AnchorMenu.scss29
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx19
-rw-r--r--src/client/views/pdf/Annotation.scss3
-rw-r--r--src/client/views/pdf/Annotation.tsx5
-rw-r--r--src/client/views/pdf/PDFViewer.tsx46
5 files changed, 74 insertions, 28 deletions
diff --git a/src/client/views/pdf/AnchorMenu.scss b/src/client/views/pdf/AnchorMenu.scss
index b7afb26a5..6990bdcf1 100644
--- a/src/client/views/pdf/AnchorMenu.scss
+++ b/src/client/views/pdf/AnchorMenu.scss
@@ -4,6 +4,35 @@
padding: 5px;
grid-template-columns: 90px 20px 90px;
}
+.anchorMenu-highlighter {
+ padding-right: 5px;
+ .antimodeMenu-button {
+ padding: 0;
+ padding: 0;
+ padding-right: 0px;
+ padding-left: 0px;
+ width: 5px;
+ }
+}
+.anchor-color-preview-button {
+ width: 25px !important;
+ .anchor-color-preview {
+ display: flex;
+ flex-direction: column;
+ padding-right: 3px;
+ width: unset !important;
+ .color-preview {
+ width: 60%;
+ top: 80%;
+ height: 4px;
+ position: relative;
+ top: unset;
+ width: 15px;
+ margin-top: 5px;
+ display: block;
+ }
+ }
+}
.color-wrapper {
display: flex;
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 17979ef4b..ad3afb775 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -41,7 +41,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable private highlightColor: string = "rgba(245, 230, 95, 0.616)";
@observable private _showLinkPopup: boolean = false;
- @observable public _colorBtn = false;
@observable public Highlighting: boolean = false;
@observable public Status: "marquee" | "annotation" | "" = "";
@@ -85,6 +84,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
if (!this.Highlight(this.highlightColor, false) && this.Pinned) {
this.Highlighting = !this.Highlighting;
}
+ AnchorMenu.Instance.fadeOut(true);
}
@action
@@ -96,9 +96,11 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@computed get highlighter() {
const button =
- <button className="antimodeMenu-button color-preview-button" title="" key="highlighter-button" onClick={this.highlightClicked}>
- <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
- <div className="color-preview" style={{ backgroundColor: this.highlightColor }}></div>
+ <button className="antimodeMenu-button anchor-color-preview-button" title="" key="highlighter-button" onClick={this.highlightClicked}>
+ <div className="anchor-color-preview" >
+ <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
+ <div className="color-preview" style={{ backgroundColor: this.highlightColor }}></div>
+ </div>
</button>;
const dropdownContent =
@@ -116,7 +118,9 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
</div>;
return (
<Tooltip key="highlighter" title={<div className="dash-tooltip">{"Click to Highlight"}</div>}>
- <ButtonDropdown key={"highlighter"} button={button} dropdownContent={dropdownContent} pdf={true} />
+ <div className="anchorMenu-highlighter">
+ <ButtonDropdown key={"highlighter"} button={button} dropdownContent={dropdownContent} pdf={true} />
+ </div>
</Tooltip>
);
}
@@ -151,9 +155,10 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
</button>
</Tooltip>,
//NOTE: link popup is currently in progress
- <Tooltip key="link" title={<div className="dash-tooltip">{"Link selected text to document"}</div>}>
+ <Tooltip key="link" title={<div className="dash-tooltip">{"Find document to link to selected text"}</div>}>
<button className="antimodeMenu-button link" onPointerDown={this.toggleLinkPopup} style={{}}>
- <FontAwesomeIcon icon="link" size="lg" />
+ <FontAwesomeIcon style={{ position: "absolute", transform: "scale(1.5)" }} icon={"search"} size="lg" />
+ <FontAwesomeIcon style={{ position: "absolute", transform: "scale(0.5)", transformOrigin: "top left", top: 12, left: 12 }} icon={"link"} size="lg" />
</button>
</Tooltip>,
<LinkPopup key="popup" showPopup={this._showLinkPopup} linkFrom={this.onMakeAnchor} />
diff --git a/src/client/views/pdf/Annotation.scss b/src/client/views/pdf/Annotation.scss
index e98f071c3..1de60ffed 100644
--- a/src/client/views/pdf/Annotation.scss
+++ b/src/client/views/pdf/Annotation.scss
@@ -4,4 +4,7 @@
position: absolute;
background-color: rgba(146, 245, 95, 0.467);
transition: opacity 0.5s;
+ &:hover {
+ cursor: pointer;
+ }
} \ No newline at end of file
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 07b734405..b1d1d8293 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -16,17 +16,19 @@ interface IAnnotationProps extends FieldViewProps {
dataDoc: Doc;
fieldKey: string;
showInfo: (anno: Opt<Doc>) => void;
+ pointerEvents?: string;
}
@observer
export
class Annotation extends React.Component<IAnnotationProps> {
render() {
- return DocListCast(this.props.anno.textInlineAnnotations).map(a => <RegionAnnotation {...this.props} document={a} key={a[Id]} />);
+ return DocListCast(this.props.anno.textInlineAnnotations).map(a => <RegionAnnotation pointerEvents={this.props.pointerEvents} {...this.props} document={a} key={a[Id]} />);
}
}
interface IRegionAnnotationProps extends IAnnotationProps {
document: Doc;
+ pointerEvents?: string;
}
@observer
class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
@@ -96,6 +98,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
width: NumCast(this.props.document._width),
height: NumCast(this.props.document._height),
opacity: this._brushed ? 0.5 : undefined,
+ pointerEvents: this.props.pointerEvents as any,
backgroundColor: this._brushed ? "orange" : StrCast(this.props.document.backgroundColor),
}} >
</div>);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 02010e123..3f7f38bdf 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -2,14 +2,13 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
-import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
-import { createSchema } from "../../../fields/Schema";
import { Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
import { PdfField } from "../../../fields/URLField";
import { TraceMobx } from "../../../fields/util";
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils, returnFalse, returnEmptyString, returnEmptyFilter } from "../../../Utils";
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils } from "../../../Utils";
import { DocUtils } from "../../documents/Documents";
import { Networking } from "../../Network";
import { CurrentUserUtils } from "../../util/CurrentUserUtils";
@@ -17,10 +16,13 @@ import { CompiledScript, CompileScript } from "../../util/Scripting";
import { SelectionManager } from "../../util/SelectionManager";
import { SharingManager } from "../../util/SharingManager";
import { SnappingManager } from "../../util/SnappingManager";
+import { MarqueeOptionsMenu } from "../collections/collectionFreeForm";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
import { MarqueeAnnotator } from "../MarqueeAnnotator";
+import { DocumentViewProps } from "../nodes/DocumentView";
import { FieldViewProps } from "../nodes/FieldView";
import { LinkDocPreview } from "../nodes/LinkDocPreview";
+import { StyleProp } from "../StyleProvider";
import { AnchorMenu } from "./AnchorMenu";
import { Annotation } from "./Annotation";
import "./PDFViewer.scss";
@@ -126,12 +128,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
});
- this._disposers.searchMatch = reaction(() => Doc.IsSearchMatch(this.props.rootDoc),
- m => {
- if (m) (this._lastSearch = true) && this.search(Doc.SearchQuery(), m.searchMatch > 0);
- else !(this._lastSearch = false) && setTimeout(() => !this._lastSearch && this.search("", false, true), 200);
- }, { fireImmediately: true });
-
this._disposers.selected = reaction(() => this.props.isSelected(),
selected => {
// if (!selected) {
@@ -186,7 +182,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
let focusSpeed: Opt<number>;
if (doc !== this.props.rootDoc && mainCont) {
const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight);
+ const scrollTo = doc.unrendered ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight);
if (scrollTo !== undefined) {
focusSpeed = 500;
@@ -338,10 +334,10 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
@action
- search = (searchString: string, fwd: boolean, clear: boolean = false) => {
+ search = (searchString: string, bwd?: boolean, clear: boolean = false) => {
const findOpts = {
caseSensitive: false,
- findPrevious: !fwd,
+ findPrevious: bwd,
highlightAll: true,
phraseSearch: true,
query: searchString
@@ -349,7 +345,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (clear) {
this._pdfViewer?.findController.executeCommand('reset', { query: "" });
} else if (!searchString) {
- fwd ? this.nextAnnotation() : this.prevAnnotation();
+ bwd ? this.prevAnnotation() : this.nextAnnotation();
} else if (this._pdfViewer?.pageViewsReady) {
this._pdfViewer.findController.executeCommand('findagain', findOpts);
}
@@ -358,6 +354,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
this._mainCont.current.addEventListener("pagesloaded", executeFind);
this._mainCont.current.addEventListener("pagerendered", executeFind);
}
+ return true;
}
@action
@@ -487,11 +484,12 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
}
+ pointerEvents = () => this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none";
@computed get annotationLayer() {
+ const pe = this.pointerEvents();
return <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this.props.Document), transform: `scale(${this._zoomed})` }} ref={this._annotationLayer}>
{this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
- <Annotation {...this.props} fieldKey={this.props.fieldKey + "-annotations"} showInfo={this.showInfo} dataDoc={this.props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)
- }
+ <Annotation {...this.props} fieldKey={this.props.fieldKey + "-annotations"} pointerEvents={pe} showInfo={this.showInfo} dataDoc={this.props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)}
</div>;
}
@@ -508,8 +506,16 @@ export class PDFViewer extends React.Component<IViewerProps> {
overlayTransform = () => this.scrollXf().scale(1 / this._zoomed);
panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1); // (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);
+ basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")];
transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
+ childStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => {
+ if (doc instanceof Doc && property === StyleProp.PointerEvents) {
+ if (doc.textInlineAnnotations) return "none";
+ return "all";
+ }
+ return this.props.styleProvider?.(doc, props, property);
+ }
@computed get overlayLayer() {
const renderAnnotations = (docFilters?: () => string[]) =>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
@@ -522,12 +528,12 @@ export class PDFViewer extends React.Component<IViewerProps> {
select={emptyFunction}
ContentScaling={this.contentZoom}
bringToFront={emptyFunction}
- docFilters={docFilters || this.props.docFilters}
+ docFilters={docFilters || this.basicFilter}
+ styleProvider={this.childStyleProvider}
dontRenderDocuments={docFilters ? false : true}
CollectionView={undefined}
ScreenToLocalTransform={this.overlayTransform}
- renderDepth={this.props.renderDepth + 1}
- childPointerEvents={true} />;
+ renderDepth={this.props.renderDepth + 1} />;
return <div>
<div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
style={{
@@ -549,7 +555,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
</div>;
}
@computed get pdfViewerDiv() {
- return <div className={"pdfViewerDash-text" + (this._textSelecting && (this.props.isSelected() || this.props.isContentActive()) ? "-selected" : "")} ref={this._viewer} />;
+ return <div className={"pdfViewerDash-text" + (this.props.pointerEvents !== "none" && this._textSelecting && (this.props.isSelected() || this.props.isContentActive()) ? "-selected" : "")} ref={this._viewer} />;
}
@computed get contentScaling() { return this.props.ContentScaling?.() || 1; }
@computed get standinViews() {
@@ -562,7 +568,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
render() {
TraceMobx();
return <div className="pdfViewer-content">
- <div className={`pdfViewerDash${this.props.isContentActive() ? "-interactive" : ""}`} ref={this._mainCont}
+ <div className={`pdfViewerDash${this.props.isContentActive() && this.props.pointerEvents !== "none" ? "-interactive" : ""}`} ref={this._mainCont}
onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
style={{
overflowX: this._zoomed !== 1 ? "scroll" : undefined,