From 9aa10d201610cc2da7a28f720a7963dbe50e0069 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 28 Sep 2020 22:15:34 -0400 Subject: fixed inking on pdfs --- src/client/views/pdf/PDFViewer.scss | 1 + src/client/views/pdf/PDFViewer.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 8a38c439d..0ecb4dba4 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -59,6 +59,7 @@ left: 0px; display: inline-block; width:100%; + pointer-events: all; } .pdfViewerDash-overlay { pointer-events: none; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 8da3d2026..c9219b3f2 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -709,7 +709,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent (this.Document.scrollHeight || this.Document._nativeHeight || 0); panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document._nativeWidth || 0); @computed get overlayLayer() { - return
Date: Mon, 28 Sep 2020 22:42:35 -0400 Subject: made pdf annotations default to selected & editable on drop --- src/client/views/pdf/PDFViewer.tsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index c9219b3f2..e54464b77 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -35,6 +35,7 @@ import { LinkDocPreview } from "../nodes/LinkDocPreview"; import { FormattedTextBoxComment } from "../nodes/formattedText/FormattedTextBoxComment"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { SharingManager } from "../../util/SharingManager"; +import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); const _global = (window /* browser */ || global /* node */) as any; @@ -624,6 +625,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent([clipDoc]); clipDoc.rootDocument = targetDoc; // DocUtils.makeCustomViewClicked(targetDoc, Docs.Create.StackingDocument, "slideView", undefined); -- cgit v1.2.3-70-g09d2 From 1e28cf6d5398c22ad4ba3b7f0825d9d06899869e Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 28 Sep 2020 22:44:33 -0400 Subject: from last --- src/client/views/nodes/WebBox.tsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2517943d7..61f01cc95 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -33,6 +33,7 @@ import "../pdf/PDFViewer.scss"; import React = require("react"); import { Tooltip } from '@material-ui/core'; import { CurrentUserUtils } from '../../util/CurrentUserUtils'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; const htmlToText = require("html-to-text"); type WebDocument = makeInterface<[typeof documentSchema]>; @@ -499,6 +500,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Tue, 29 Sep 2020 02:46:28 -0400 Subject: changed sidebar functionality for textboxes to open outward and make handle blue when there are contents. added a fitToBox capability for contents of sidebar. --- src/client/views/DocumentButtonBar.tsx | 4 +-- src/client/views/PropertiesButtons.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 36 ++++++++++++---------- src/client/views/nodes/WebBox.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 13 +++++--- src/client/views/pdf/Annotation.tsx | 8 ++--- src/client/views/pdf/PDFViewer.tsx | 4 +-- 9 files changed, 40 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index c5fd3c777..5ec43319b 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -363,9 +363,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV {![DocumentType.VID, DocumentType.WEB].includes(StrCast(this.view0.props.Document.type) as DocumentType) ? (null) :
{this.annotateButton}
} -
+ {!Doc.UserDoc()["documentLinksButton-fullMenu"] ? (null) :
{this.considerGoogleDocsPush} -
+
}
{this.considerGoogleDocsPull}
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 462091f63..9de4f9c67 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -529,7 +529,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.clustersButton}
-
+
{this.fitContentButton}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 4ee00e0f4..423d39951 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -176,7 +176,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top); smoothScroll(doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop); } - afterFocus && setTimeout(() => afterFocus?.(), 500); + afterFocus && setTimeout(afterFocus, 500); } getDisplayDoc(doc: Doc, dxf: () => Transform, width: () => number) { diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 072cd23db..06c35de03 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -664,7 +664,7 @@ export class TreeView extends React.Component { ignoreFields: string[] | undefined, firstLevel: boolean, whenActiveChanged: (isActive: boolean) => void, - dontRegisterView: boolean | undeifned) { + dontRegisterView: boolean | undefined) { const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField); if (viewSpecScript) { childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 75ad8e5b0..967055638 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -104,28 +104,32 @@ export class CollectionFreeFormView extends CollectionSubView e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); } @computed get nativeWidth() { return this.fitToContent ? 0 : returnVal(this.props.NativeWidth?.(), NumCast(this.Document._nativeWidth)); } @computed get nativeHeight() { return this.fitToContent ? 0 : returnVal(this.props.NativeHeight?.(), NumCast(this.Document._nativeHeight)); } private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; } private get scaleFieldKey() { return this.props.scaleField || "_viewScale"; } private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; } - private panX = () => this.fitToContent ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document._panX || 0; - private panY = () => this.fitToContent ? (this.contentBounds.y + this.contentBounds.b) / 2 : this.Document._panY || 0; - private zoomScaling = () => (this.fitToContentScaling / this.parentScaling) * (this.fitToContent ? - Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y), - this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)) : - NumCast(this.Document[this.scaleFieldKey], 1)) - + private panX = () => this.fitToContent && !this.props.isAnnotationOverlay ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document._panX || 0; + private panY = () => this.fitToContent && !this.props.isAnnotationOverlay ? (this.contentBounds.y + this.contentBounds.b) / 2 : this.Document._panY || 0; + private zoomScaling = () => { + const mult = this.fitToContentScaling / this.parentScaling; + if (this.fitToContent) { + const zs = !this.childDocs.length ? 1 : + Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y), this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)); + return mult * (this.props.isAnnotationOverlay ? Math.min(zs, 1) : zs); + } + return mult * NumCast(this.Document[this.scaleFieldKey], 1); + } @computed get cachedCenteringShiftX(): number { const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling; - return !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / scaling : 0; // shift so pan position is at center of window for non-overlay collections + return !this.props.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / scaling : 0; // shift so pan position is at center of window for non-overlay collections } @computed get cachedCenteringShiftY(): number { const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling; - return !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / scaling : 0;// shift so pan position is at center of window for non-overlay collections + return !this.props.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / scaling : 0;// shift so pan position is at center of window for non-overlay collections } @computed get cachedGetLocalTransform(): Transform { return Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY()); @@ -776,9 +780,6 @@ export class CollectionFreeFormView extends CollectionSubView { let deltaScale = deltaY > 0 ? (1 / 1.05) : 1.05; - if (deltaScale * this.zoomScaling() < 1 && this.isAnnotationOverlay) { - deltaScale = 1 / this.zoomScaling(); - } if (deltaScale < 0) deltaScale = -deltaScale; const [x, y] = this.getTransform().transformPoint(pointX, pointY); const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); @@ -1106,7 +1107,7 @@ export class CollectionFreeFormView extends CollectionSubView this._cachedPool.set(k[0], k[1])); - const elements: ViewDefResult[] = computedElementData.slice(); + const elements = computedElementData.slice(); const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine); Array.from(newPool.entries()).filter(entry => this.isCurrent(entry[1].pair.layout)).forEach(entry => elements.push({ @@ -1127,8 +1128,9 @@ export class CollectionFreeFormView extends CollectionSubView {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => - ) + ) }
; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index e7b4b72f4..a0af8d60f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -557,7 +557,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp sidebarDown = (e: React.PointerEvent) => { setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, - () => this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "25%" : "0%")) !== "0%"); + action(() => { + const prevWidth = this.sidebarWidth(); + this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%"; + this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); + })); } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this.CurrentDiv.getBoundingClientRect(); @@ -1518,16 +1522,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } - return1000 = () => 1000; @computed get sidebarCollection() { + const fitToBox = this.props.Document._fitToBox; return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) :
{this.sidebarCollection} - {selected ?
: (null)} + {selected ?
: (null)} {!this.layoutDoc._showAudio ? (null) :
this._recording = !this._recording)} > diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index b7c7dae38..84b14cd61 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,7 +1,7 @@ import React = require("react"); import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, HeightSym, WidthSym, Field } from "../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, WidthSym, Field, Opt } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; import { Cast, FieldValue, BoolCast, NumCast, StrCast, PromiseValue } from "../../../fields/Types"; @@ -17,7 +17,7 @@ interface IAnnotationProps { focus: (doc: Doc) => void; dataDoc: Doc; fieldKey: string; - showInfo: (anno: Doc) => void; + showInfo: (anno: Opt) => void; } @observer @@ -25,7 +25,7 @@ export class Annotation extends React.Component { render() { return DocListCast(this.props.anno.annotations).map(a => - ); + ); } } @@ -40,7 +40,7 @@ interface IRegionAnnotationProps { document: Doc; dataDoc: Doc; fieldKey: string; - showInfo: (anno: Doc) => void; + showInfo: (anno: Opt) => void; } @observer diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index e54464b77..fb87da744 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -703,10 +703,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent users.user.email === this._overlayAnnoInfo!.author)?.userColor }}> {this._overlayAnnoInfo.author + " " + Field.toString(this._overlayAnnoInfo.creationDate as Field)}
-
+
; } - showInfo = action((anno: Doc) => this._overlayAnnoInfo = anno); + showInfo = action((anno: Opt) => this._overlayAnnoInfo = anno); overlayTransform = () => this.scrollXf().scale(1 / this._zoomed); panelWidth = () => (this.Document.scrollHeight || this.Document._nativeHeight || 0); panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document._nativeWidth || 0); -- cgit v1.2.3-70-g09d2 From 6d296b0904b3c93b111f96594a3f54c82c8c7bf0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 10:34:33 -0400 Subject: fixed display/edit of titles when shown as a header --- src/client/views/nodes/DocumentView.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0b2e55294..d7bd75cf4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,20 +1,22 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { Document } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; +import { RichTextField } from '../../../fields/RichTextField'; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils, returnVal, returnEmptyString } from "../../../Utils"; +import { emptyFunction, OmitKeys, returnOne, returnTransparent, returnVal, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager, dropActionType } from "../../util/DragManager"; import { InteractionUtils } from '../../util/InteractionUtils'; @@ -39,8 +41,6 @@ import { LinkDescriptionPopup } from './LinkDescriptionPopup'; import { RadialMenu } from './RadialMenu'; import { TaskCompletionBox } from './TaskCompletedBox'; import React = require("react"); -import { CurrentUserUtils } from '../../util/CurrentUserUtils'; -import { RichTextField } from '../../../fields/RichTextField'; export type DocFocusFunc = () => boolean; @@ -1045,9 +1045,10 @@ export class DocumentView extends DocComponent(Docu pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined, }}> field + ":" + (this.dataDoc || this.props.Document)[field]?.toString()).join(" ")} - display={"block"} fontSize={10} - GetValue={returnEmptyString} + contents={this.ShowTitle === "title" ? StrCast((this.dataDoc || this.props.Document).title) : this.ShowTitle.split(";").map(field => field + ":" + (this.dataDoc || this.props.Document)[field]?.toString()).join(" ")} + display={"block"} + fontSize={10} + GetValue={() => Field.toString((this.dataDoc || this.props.Document)[this.ShowTitle.split(";")[0]] as any as Field)} SetValue={undoBatch((value: string) => { this.ShowTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[this.ShowTitle] = value) ? true : true; })} -- cgit v1.2.3-70-g09d2 From 60c930b0850f87a88f032ddc7029fa4586251ae8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 11:31:41 -0400 Subject: fixed highlighting of link hypertext anchors (was offset very wrongly before). fixed setting link mark correctly when linking two hypertext anchors. fixed allowing link to parent collection when parent collection is specified by clicking its link button --- src/client/documents/Documents.ts | 4 ++-- src/client/views/nodes/DocumentLinksButton.tsx | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 14 ++++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1d7e4f386..19f719c43 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -977,9 +977,9 @@ export namespace DocUtils { DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline")); } - export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string) { + export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean) { const sv = DocumentManager.Instance.getDocumentView(source.doc); - if (sv && sv.props.ContainingCollectionDoc === target.doc) return; + if (!allowParCollectionLink && sv?.props.ContainingCollectionDoc === target.doc) return; if (target.doc === Doc.UserDoc()) return undefined; const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 0cb5b94f4..8b48acf23 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -161,7 +161,7 @@ export class DocumentLinksButton extends React.Component this.props.makeLink?.(), (linkDoc: Opt) => { if (linkDoc) { - const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast(linkDoc.anchor2.title) : "-untitled-"; - const anchor2Id = linkDoc.anchor2 instanceof Doc ? linkDoc.anchor2[Id] : ""; + const a1 = Cast(linkDoc.anchor1, Doc, null); + const a2 = Cast(linkDoc.anchor2, Doc, null); + const otherAnchor = Doc.AreProtosEqual(a1, this.rootDoc) ? a2 : a1; + const anchor2Title = StrCast(otherAnchor.title, "-untitled-"); + const anchor2Id = otherAnchor?.[Id] || ""; this.makeLinkToSelection(linkDoc[Id], anchor2Title, "add:right", anchor2Id); } }, @@ -910,15 +913,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp async (scrollToLinkID) => { const findLinkFrag = (frag: Fragment, editor: EditorView) => { const nodes: Node[] = []; - let offset = 0; frag.forEach((node, index) => { const examinedNode = findLinkNode(node, editor); if (examinedNode?.textContent) { nodes.push(examinedNode); - offset = index; + !start && (start = index); } }); - return { frag: Fragment.fromArray(nodes), start: start + offset }; + return { frag: Fragment.fromArray(nodes), start }; }; const findLinkNode = (node: Node, editor: EditorView) => { if (!node.isText) { @@ -930,7 +932,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return linkIndex !== -1 && marks[linkIndex].attrs.allLinks.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; }; - const start = 0; + let start = 0; if (this._editorView && scrollToLinkID) { const editor = this._editorView; const ret = findLinkFrag(editor.state.doc.content, editor); -- cgit v1.2.3-70-g09d2 From 1cb5ac5e07ad90589670a788e3144d9d9581a393 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 15:03:16 -0400 Subject: made pdf/web anchors pushpins by default. can now remove docs you own from sidebars you don't. made formatted text boxes alway show sidebar handle when there's content. sidebar text has no padding by default. sidebar collection doesn't scroll when text overflows. added more playground fields --- src/client/documents/Documents.ts | 21 ++++++++++++ src/client/util/CurrentUserUtils.ts | 3 +- src/client/views/DocComponent.tsx | 3 +- src/client/views/MainView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 6 ++++ .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 1 + .../nodes/formattedText/FormattedTextBox.scss | 18 +++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 40 ++++++++++++++++------ src/client/views/pdf/PDFViewer.tsx | 3 +- 12 files changed, 76 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 19f719c43..ad30e7d33 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -889,6 +889,27 @@ export namespace Docs { } export namespace DocUtils { + export function Excluded(d: Doc, docFilters: string[]) { + const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields + for (let i = 0; i < docFilters.length; i += 3) { + const [key, value, modifiers] = docFilters.slice(i, i + 3); + if (!filterFacets[key]) { + filterFacets[key] = {}; + } + filterFacets[key][value] = modifiers; + } + + if (d.z) return false; + for (const facetKey of Object.keys(filterFacets)) { + const facet = filterFacets[facetKey]; + const xs = Object.keys(facet).filter(value => facet[value] === "x"); + const failsNotEqualFacets = xs?.some(value => Doc.matchFieldValue(d, facetKey, value)); + if (failsNotEqualFacets) { + return true; + } + } + return false; + } export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField) { const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 342954a4e..3e76b189a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1127,8 +1127,9 @@ export class CurrentUserUtils { CurrentUserUtils.openDashboard(userDoc, dashboardDoc); } - public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number) { + public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean) { const tbox = Docs.Create.TextDocument("", { + _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, _width: width || 200, _height: height || 100, x: x, y: y, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize), _fontFamily: StrCast(Doc.UserDoc().fontFamily), title }); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index b3c90a68f..893b74d75 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -123,7 +123,8 @@ export function ViewBoxAnnotatableComponent

doc.isPushpin = doc.annotationOn = undefined); const targetDataDoc = this.dataDoc; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 4299dba86..5469c2358 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -86,7 +86,7 @@ export class MainView extends React.Component { document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!)); new InkStrokeProperties(); this._sidebarContent.proto = undefined; - DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollY", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's + DocServer.setPlaygroundFields(["dataTransition", "_delayAutoHeight", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollY", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg))); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 26fe00657..649b8c175 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -142,6 +142,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const docsforFilter: Doc[] = []; childDocs.forEach((d) => { + if (DocUtils.Excluded(d, docFilters)) return; let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 967055638..a3f76839d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1625,6 +1625,12 @@ class CollectionFreeFormViewPannableContents extends React.Component { + const target = e.target as any; + if (getComputedStyle(target.parentElement)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars + target.scrollTop = target.scrollLeft = 0; + } + }} style={{ transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`, transition: this.props.transition, diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e1ebb4eee..7c64fd429 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -141,7 +141,7 @@ export class MarqueeView extends React.Component(noviceFields); this.allDocs.forEach(doc => SearchBox.documentKeys(doc).filter(key => keys.add(key))); - return Array.from(keys.keys()).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_") && !key.startsWith("acl")) || noviceFields.includes(key)).sort(); + return Array.from(keys.keys()).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_")) || noviceFields.includes(key) || !Doc.UserDoc().noviceMode).sort(); } gatherFieldValues(dashboard: Doc, facetKey: string) { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index a7b534956..421aac69f 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -508,6 +508,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, - action(() => { + () => setTimeout(action(() => { const prevWidth = this.sidebarWidth(); this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%"; this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); - })); + })), false); } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this.CurrentDiv.getBoundingClientRect(); @@ -1524,6 +1524,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + @computed get audioHandle() { + return !this.layoutDoc._showAudio ? (null) : +

this._recording = !this._recording)} > + +
; + } + + @computed get sidebarHandle() { + const annotated = DocListCast(this.dataDoc[this.annotationKey]).length; + return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) : +
{ + console.log(e); + }} + />; + } + @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : @@ -1531,6 +1550,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props)); // need to make sure that we update a text box that is selected after updating the one that was deselected if (!selected && FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); } const minimal = this.props.ignoreAutoHeight; - const selPad = (selected && !this.layoutDoc._singleLine) || minimal ? -10 : 0; - const selclass = selected && !this.layoutDoc._singleLine ? "-selected" : ""; + const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0); + const selPad = Math.min(margins, 10); + const padding = Math.max(margins + ((selected && !this.layoutDoc._singleLine) || minimal ? -selPad : 0), 0); + const selclass = selected && !this.layoutDoc._singleLine && margins >= 10 ? "-selected" : ""; return (
{this.sidebarCollection} - {selected ?
: (null)} - {!this.layoutDoc._showAudio ? (null) : -
this._recording = !this._recording)} > - -
} + {this.sidebarHandle} + {this.audioHandle}
); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index fb87da744..77dd40f2a 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -642,6 +642,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent