From c150d0afa46c2c45e413a5269d26bc46b64ba765 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Oct 2020 23:21:04 -0400 Subject: fixed dragging bottom of some pdfs not to grow wildly. stopped writing renderContentBounds to annotation views. fixed texts sidebar notes to not add extra chars on creation. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5236fab27..796765a8d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1441,7 +1441,7 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._renderContentBounds = new List([this.contentBounds.x, this.contentBounds.y, this.contentBounds.r, this.contentBounds.b]), 0); + !this.fitToContent && !this.props.annotationsKey && this._layoutElements?.length && setTimeout(() => this.Document._renderContentBounds = new List([this.contentBounds.x, this.contentBounds.y, this.contentBounds.r, this.contentBounds.b]), 0); return
Date: Sat, 10 Oct 2020 17:56:34 -0400 Subject: fixed scrolling down to annotations that have no height (but really do -- eg pdf selections) to at least show 50 pixels. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 796765a8d..d48961849 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -896,7 +896,7 @@ export class CollectionFreeFormView extends CollectionSubView NumCast(doc.y)) { scrollTo = NumCast(doc.y); } -- cgit v1.2.3-70-g09d2 From 3256d0f42401b8dd8745e7f32c25033e118b444b Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Oct 2020 17:22:03 -0400 Subject: removed setting fields to undefined when Acl is Private in hopes of not losing data when permissions are changed. prevented server writes on startup by making renderContentBounds setting a reaction, and making linearView not resize if documents are still promises and make text boxes not flip-flop their height all the time. --- src/client/views/collections/CollectionLinearView.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 15 +++++++++++++-- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 3 +-- src/fields/Doc.ts | 10 +++++----- 4 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 859ee9362..0eac5136a 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -38,8 +38,8 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { componentDidMount() { // is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported). - this._widthDisposer = reaction(() => this.props.Document[HeightSym]() + this.childDocs.length + (this.props.Document.linearViewIsExpanded ? 1 : 0), - () => this.props.Document._width = 5 + (this.props.Document.linearViewIsExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10), + this._widthDisposer = reaction(() => 5 + (this.props.Document.linearViewIsExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10), + width => this.childDocs.length && (this.props.Document._width = width), { fireImmediately: true } ); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d48961849..4d9906f93 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -7,7 +7,7 @@ import { Id } from "../../../../fields/FieldSymbols"; import { InkData, InkField, InkTool } from "../../../../fields/InkField"; import { List } from "../../../../fields/List"; import { RichTextField } from "../../../../fields/RichTextField"; -import { createSchema, makeInterface } from "../../../../fields/Schema"; +import { createSchema, makeInterface, listSpec } from "../../../../fields/Schema"; import { ScriptField } from "../../../../fields/ScriptField"; import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types"; import { TraceMobx } from "../../../../fields/util"; @@ -88,6 +88,7 @@ export class CollectionFreeFormView extends CollectionSubView(); private _layoutSizeData = new ObservableMap(); private _cachedPool: Map = new Map(); @@ -1159,12 +1160,22 @@ export class CollectionFreeFormView extends CollectionSubView this.doLayoutComputation, (elements) => this._layoutElements = elements || [], { fireImmediately: true, name: "doLayout" }); + if (!this.props.annotationsKey) { + this._boundsReaction = reaction(() => this.contentBounds, + bounds => (!this.fitToContent && this._layoutElements?.length) && setTimeout(() => { + const rbounds = Cast(this.Document._renderContentBounds, listSpec("number"), [0, 0, 0, 0]); + if (rbounds[0] !== bounds.x || rbounds[1] !== bounds.y || rbounds[2] !== bounds.r || rbounds[3] !== bounds.b) { + this.Document._renderContentBounds = new List([bounds.x, bounds.y, bounds.r, bounds.b]); + } + })); + } this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any); } componentWillUnmount() { this._layoutComputeReaction?.(); + this._boundsReaction?.(); this._marqueeRef.current?.removeEventListener("dashDragAutoScroll", this.onDragAutoScroll as any); } @@ -1438,10 +1449,10 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._renderContentBounds = new List([this.contentBounds.x, this.contentBounds.y, this.contentBounds.r, this.contentBounds.b]), 0); return
limitHeight) { @@ -1545,7 +1544,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.rootDoc[this.fieldKey + "-height"] = finalHeight; } catch (e) { console.log("Error in tryUpdateHeight"); } } - } + } else this.rootDoc[this.fieldKey + "-height"] = 0; } @computed get audioHandle() { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 7dd894ec4..086b7777f 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -240,11 +240,11 @@ export class Doc extends RefField { if (prev === AclPrivate && GetEffectiveAcl(this) !== AclPrivate) { DocServer.GetRefField(this[Id], true); } - if (prev !== AclPrivate && GetEffectiveAcl(this) === AclPrivate) { - this[UpdatingFromServer] = true; - this[FieldsSym](true); - this[UpdatingFromServer] = false; - } + // if (prev !== AclPrivate && GetEffectiveAcl(this) === AclPrivate) { + // this[UpdatingFromServer] = true; + // this[FieldsSym](true); + // this[UpdatingFromServer] = false; + // } }; if (sameAuthor || fKey.startsWith("acl") || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) { delete this[CachedUpdates][fKey]; -- cgit v1.2.3-70-g09d2 From 27635402ad810b910557eb1a86c7e85fa281aaee Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 12 Oct 2020 01:05:13 -0400 Subject: switched fonticonbox and colelctionsubview to test GetEffectiveAcl to determine if document is available (instead of hack of testing 'author'). made GetEffectiveAcl a computedFn. No longer create a pushpin when an annotation that's linked to text is dragged off a PDF. fixed undo of pushpin navigation (used to call finish() twice). fixed pushpin navigation to conistenly pan & sensibly toggle target --- src/client/util/DocumentManager.ts | 9 +++++---- src/client/views/collections/CollectionSubView.tsx | 5 +++-- src/client/views/collections/CollectionView.tsx | 3 ++- .../collectionFreeForm/CollectionFreeFormView.tsx | 21 +++++++++++++-------- src/client/views/nodes/FontIconBox.tsx | 5 +++-- src/client/views/pdf/Annotation.tsx | 2 ++ src/client/views/pdf/PDFViewer.tsx | 2 +- src/fields/util.ts | 14 ++++++++++---- 8 files changed, 39 insertions(+), 22 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 178daf5f0..b37181e57 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -164,13 +164,14 @@ export class DocumentManager { const sameContext = annotatedDoc && annotatedDoc === originatingDoc?.context; if (originatingDoc?.isPushpin) { const hide = !docView.props.Document.hidden; - (!hide || !sameContext) && (docView.props.Document.hidden = !docView.props.Document.hidden); - docView.props.focus(docView.props.Document, willZoom, undefined, (notfocused: boolean) => { // bcz: Argh! TODO: Need to add a notFocused argument to the after finish callback function that indicates whether the window had to scroll to show the target - notfocused && hide && (docView.props.Document.hidden = true); + docView.props.focus(docView.props.Document, willZoom, undefined, (notfocused: boolean) => { // bcz: Argh! TODO: Need to add a notFocused argument to the after finish callback function that indicates whether the window had to scroll to show the target + if (notfocused || docView.props.Document.hidden) { + docView.props.Document.hidden = !docView.props.Document.hidden; + } return focusAndFinish(); // @ts-ignore bcz: Argh TODO: Need to add a parameter to focus() everywhere for whether focus should center the target's container in the view or not. // here we don't want to focus the container if the source and target are in the same container }, sameContext); - finished?.(); + //finished?.(); } else { docView.select(false); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 493018093..b282d1e27 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -103,7 +103,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const { Document, DataDoc } = this.props; const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.annotationsKey ? DataDoc : undefined, doc)). filter(pair => { // filter out any documents that have a proto that we don't have permissions to (which we determine by not having any keys - return pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && Object.keys(pair.layout.proto).length)); + return pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); }); return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types } @@ -134,7 +134,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: rawdocs = rootDoc && !this.props.annotationsKey ? [Doc.GetProto(rootDoc)] : []; } - const docs = rawdocs.filter(d => !(d instanceof Promise) && Object.keys(d).length).map(d => d as Doc); + const docs = rawdocs.filter(d => !(d instanceof Promise) && GetEffectiveAcl(d) !== AclPrivate).map(d => d as Doc); const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField); const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; @@ -502,4 +502,5 @@ import { SelectionManager } from "../../util/SelectionManager"; import { OverlayView } from "../OverlayView"; import { setTimeout } from "timers"; import { Hypothesis } from "../../util/HypothesisUtils"; +import { GetEffectiveAcl } from "../../../fields/util"; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 80e9b41ad..cfd24545b 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -159,7 +159,8 @@ export class CollectionView extends Touchable [AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document const context = Cast(doc.context, Doc, null); - if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) { + const hasContextAnchor = DocListCast(doc.links).some(l => (l.anchor2 === doc && Cast(l.anchor1, Doc, null)?.annotationOn === context) || (l.anchor1 === doc && Cast(l.anchor2, Doc, null)?.annotationOn === context)); + if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) { const pushpin = Docs.Create.FontIconDocument({ title: "pushpin", label: "", icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7", diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4d9906f93..4df90e8ea 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -893,21 +893,24 @@ export class CollectionFreeFormView extends CollectionSubView NumCast(doc.y)) { - scrollTo = NumCast(doc.y); + scrollTo = Math.max(0, NumCast(doc.y) - 50); } - if (curScroll !== scrollTo) { + if (curScroll !== scrollTo || this.props.Document._viewTransition) { this.props.Document._scrollPY = this.props.Document._scrollY = scrollTo; delay = Math.abs(scrollTo - curScroll) > 5 ? 1000 : 0; - !dontCenter && delay && this.props.focus(this.props.Document); + !dontCenter && this.props.focus(this.props.Document); afterFocus && setTimeout(afterFocus, delay); + } else { + !dontCenter && delay && this.props.focus(this.props.Document); // @ts-ignore - } else afterFocus(true); // bcz: TODO Aragh -- need to add a parameter to afterFocus() functions to indicate whether the focus function didn't need to scroll + afterFocus(true); // bcz: TODO Aragh -- need to add a parameter to afterFocus() functions to indicate whether the focus function didn't need to scroll + + } } } else { @@ -929,14 +932,16 @@ export class CollectionFreeFormView extends CollectionSubView { - if (afterFocus?.()) { + // @ts-ignore + if (afterFocus?.(notFocused)) { // bcz: TODO Aragh -- need to add a parameter to afterFocus() functions to indicate whether the focus function didn't need to scroll this.Document._panX = savedState.px; this.Document._panY = savedState.py; this.Document[this.scaleFieldKey] = savedState.s; this.Document._viewTransition = savedState.pt; } - }, 500); + }, notFocused ? 0 : 500); } } diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 156256fe5..276c66bb1 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -8,11 +8,12 @@ import { FieldView, FieldViewProps } from './FieldView'; import { StrCast, Cast, ScriptCast } from '../../../fields/Types'; import { Utils, setupMoveUpEvents, returnFalse, emptyFunction } from "../../../Utils"; import { runInAction, observable, reaction, IReactionDisposer } from 'mobx'; -import { Doc, DocListCast } from '../../../fields/Doc'; +import { Doc, DocListCast, AclPrivate } from '../../../fields/Doc'; import { ContextMenu } from '../ContextMenu'; import { ScriptField } from '../../../fields/ScriptField'; import { Tooltip } from '@material-ui/core'; import { DragManager } from '../../util/DragManager'; +import { GetEffectiveAcl } from '../../../fields/util'; const FontIconSchema = createSchema({ icon: "string", }); @@ -105,7 +106,7 @@ export class FontIconBadge extends React.Component { render() { if (!(this.props.collection instanceof Doc)) return (null); - const length = DocListCast(this.props.collection.data).filter(d => Object.keys(d).length).length; // filter out any documents that we can't read + const length = DocListCast(this.props.collection.data).filter(d => GetEffectiveAcl(d) !== AclPrivate).length; // Object.keys(d).length).length; // filter out any documents that we can't read return
0 ? { "display": "initial" } : { "display": "none" }} onPointerDown={this.onPointerDown} > diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index e7f901091..a071abd21 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -71,6 +71,7 @@ class RegionAnnotation extends React.Component { this._reactionDisposer && this._reactionDisposer(); } + @undoBatch deleteAnnotation = () => { const annotation = DocListCast(this.props.dataDoc[this.props.fieldKey + "-annotations"]); const group = FieldValue(Cast(this.props.document.group, Doc)); @@ -86,6 +87,7 @@ class RegionAnnotation extends React.Component { PDFMenu.Instance.fadeOut(true); } + @undoBatch pinToPres = () => { const group = FieldValue(Cast(this.props.document.group, Doc)); const isPinned = group && Doc.isDocPinned(group) ? true : false; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 78b95b385..d8be3defd 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -194,7 +194,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent= 0) { - if (!this._mainCont.current) setTimeout(() => smoothScroll(1000, this._mainCont.current!, scrollY || 0)); + if (!this._mainCont.current) setTimeout(() => this._mainCont.current && smoothScroll(1000, this._mainCont.current, scrollY || 0)); else smoothScroll(1000, this._mainCont.current, scrollY || 0); this.Document._scrollPY = undefined; } diff --git a/src/fields/util.ts b/src/fields/util.ts index 881f301f3..b68d961b1 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -13,6 +13,7 @@ import { returnZero } from "../Utils"; import CursorField from "./CursorField"; import { List } from "./List"; import { SnappingManager } from "../client/util/SnappingManager"; +import { computedFn } from "mobx-utils"; function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); @@ -139,7 +140,7 @@ export function denormalizeEmail(email: string) { * * Edit: a user with edit access to a document can remove/edit that document, add/remove/edit annotations (depending on permissions), but not change any access rights to that document. * - * Add: a user with add access to a document can add documents/annotations to that document but cannot edit or delete anything. + * Add: a user with add access to a document can augment documents/annotations to that document but cannot edit or delete anything. * * View: a user with view access to a document can only view it - they cannot add/remove/edit anything. * @@ -148,7 +149,7 @@ export function denormalizeEmail(email: string) { export enum SharingPermissions { Admin = "Admin", Edit = "Can Edit", - Add = "Can Add", + Add = "Can Augment", View = "Can View", None = "Not Shared" } @@ -157,6 +158,11 @@ export enum SharingPermissions { * Calculates the effective access right to a document for the current user. */ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { + return computedFn(function (target: any, in_prop?: string | symbol | number, user?: string) { + return getEffectiveAcl(target, in_prop, user); + }, true)(target, in_prop, user); +} +function getEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { if (!target) return AclPrivate; // all changes received fromt the server must be processed as Admin @@ -219,7 +225,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc const HierarchyMapping = new Map([ ["Not Shared", 0], ["Can View", 1], - ["Can Add", 2], + ["Can Augment", 2], ["Can Edit", 3], ["Admin", 4] ]); @@ -281,7 +287,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "None"].includes(value))) return true; - // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Add", "Can View", "Not Shared", undefined].includes(value)) return true; + // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Augment", "Can View", "Not Shared", undefined].includes(value)) return true; if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) { if (!prop.startsWith("_")) { -- cgit v1.2.3-70-g09d2 From 9f6dba274539a78a541afd398c73a17dec996319 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 12 Oct 2020 01:34:00 -0400 Subject: capped zoom in at a factor of 20. fixed zoom in not to pan when it hits its zoom in limit. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4df90e8ea..71519f2b9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -783,10 +783,14 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? (1 / 1.05) : 1.05; if (deltaScale < 0) deltaScale = -deltaScale; const [x, y] = this.getTransform().transformPoint(pointX, pointY); + const invTransform = this.getLocalTransform().inverse(); + if (deltaScale * invTransform.Scale > 20) { + deltaScale = 20 / invTransform.Scale; + } const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); if (localTransform.Scale >= 0.15 || localTransform.Scale > this.zoomScaling()) { - const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40); + const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 20); this.props.Document[this.scaleFieldKey] = Math.abs(safeScale); this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale); } -- cgit v1.2.3-70-g09d2 From 072d1aa988f36220e4b74c0ee5413f0597a4b619 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Oct 2020 16:57:25 -0400 Subject: prevent zooming out on annotation overlays beyond 1-1 --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 71519f2b9..f075aefe1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -789,7 +789,7 @@ export class CollectionFreeFormView extends CollectionSubView= 0.15 || localTransform.Scale > this.zoomScaling()) { + if ((localTransform.Scale > 1 || !this.props.annotationsKey) && (localTransform.Scale >= 0.15 || localTransform.Scale > this.zoomScaling())) { const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 20); this.props.Document[this.scaleFieldKey] = Math.abs(safeScale); this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale); -- cgit v1.2.3-70-g09d2 From 79221b73d0526ce31349cf4a5b75f0047c60b829 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 14 Oct 2020 11:02:40 -0400 Subject: fixed focusDocument in freeform views to work with annotation overlays(mostly) - still an issue when original image is in a frame that doen't match its dimensions --- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/collections/TabDocView.tsx | 12 +++++++----- .../collectionFreeForm/CollectionFreeFormView.tsx | 19 +++++++++++-------- src/client/views/nodes/ImageBox.tsx | 16 +++++++++------- 4 files changed, 28 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 7535d7c24..dcbeba8cd 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -881,6 +881,7 @@ export class CurrentUserUtils { let linkDocs = await DocServer.GetRefField(linkDatabaseId); if (!linkDocs) { linkDocs = new Doc(linkDatabaseId, true); + (linkDocs as Doc).author = Doc.CurrentUserEmail; (linkDocs as Doc).data = new List([]); (linkDocs as Doc)["acl-Public"] = SharingPermissions.Add; } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 70eb5b895..0c7f39dc7 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -45,6 +45,8 @@ export class TabDocView extends React.Component { @observable private _document: Doc | undefined; @observable private _view: DocumentView | undefined; + @computed get contentScaling() { return this.ContentScaling(); } + get stack(): any { return (this.props as any).glContainer.parent.parent; } get tab() { return (this.props as any).glContainer.tab; } get view() { return this._view; } @@ -194,7 +196,7 @@ export class TabDocView extends React.Component { panelHeight = () => this.nativeAspect() && this.nativeAspect() > this._panelWidth / this._panelHeight ? this._panelWidth / this.nativeAspect() : this._panelHeight; nativeWidth = () => !this.layoutDoc?._fitWidth ? NumCast(this.layoutDoc?._nativeWidth) || this._panelWidth : 0; nativeHeight = () => !this.layoutDoc?._fitWidth ? NumCast(this.layoutDoc?._nativeHeight) || this._panelHeight : 0; - contentScaling = () => { + ContentScaling = () => { const nativeH = NumCast(this.layoutDoc?._nativeHeight); const nativeW = NumCast(this.layoutDoc?._nativeWidth); let scaling = 1; @@ -210,12 +212,12 @@ export class TabDocView extends React.Component { if (this._mainCont?.children) { const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0]?.firstChild as HTMLElement); const scale = Utils.GetScreenTransform(this._mainCont).scale; - return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale); + return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.ContentScaling() / scale); } return Transform.Identity(); } - @computed get previewPanelCenteringOffset() { return this.nativeWidth() ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; } - @computed get widthpercent() { return this.nativeWidth() ? `${(this.nativeWidth() * this.contentScaling()) / this._panelWidth * 100}% ` : undefined; } + @computed get previewPanelCenteringOffset() { return this.nativeWidth() ? (this._panelWidth - this.nativeWidth() * this.ContentScaling()) / 2 : 0; } + @computed get widthpercent() { return this.nativeWidth() ? `${(this.nativeWidth() * this.ContentScaling()) / this._panelWidth * 100}% ` : undefined; } @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } // adds a tab to the layout based on the locaiton parameter which can be: @@ -337,7 +339,7 @@ export class TabDocView extends React.Component { rootSelected={returnTrue} addDocument={undefined} removeDocument={undefined} - ContentScaling={this.contentScaling} + ContentScaling={this.ContentScaling} PanelWidth={this.panelWidth} PanelHeight={this.panelHeight} NativeHeight={this.nativeHeight() ? this.nativeHeight : undefined} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f075aefe1..8b9e84bd6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -787,9 +787,12 @@ export class CollectionFreeFormView extends CollectionSubView 20) { deltaScale = 20 / invTransform.Scale; } + if (deltaScale * invTransform.Scale < 1 && this.isAnnotationOverlay) { + deltaScale = 1 / invTransform.Scale; + } const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); - if ((localTransform.Scale > 1 || !this.props.annotationsKey) && (localTransform.Scale >= 0.15 || localTransform.Scale > this.zoomScaling())) { + if (localTransform.Scale >= 0.15 || localTransform.Scale > this.zoomScaling()) { const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 20); this.props.Document[this.scaleFieldKey] = Math.abs(safeScale); this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale); @@ -919,21 +922,21 @@ export class CollectionFreeFormView extends CollectionSubView { - const pw = this.props.PanelWidth(); - const ph = this.props.PanelHeight(); + const pw = this.isAnnotationOverlay ? NumCast(this.props.Document._nativeWidth) : this.props.PanelWidth(); + const ph = this.isAnnotationOverlay ? NumCast(this.props.Document._nativeHeight) : this.props.PanelHeight(); pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height))); } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 164456cfb..bc38a17eb 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -67,6 +67,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); @@ -266,7 +268,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { const remoteUrl = this.dataDoc.googlePhotosUrl; return !remoteUrl ? (null) : ( window.open(remoteUrl)} @@ -291,7 +293,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { const { dataDoc } = this; @@ -402,18 +404,18 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.props.ScreenToLocalTransform().translate(0, -this.ycenter / this.props.ContentScaling()); + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.ycenter / this.contentScaling); contentFunc = () => [this.content]; render() { TraceMobx(); return (