From 6376a4b6d6a730c6c170fa25dd5f19dea6b8f82a Mon Sep 17 00:00:00 2001 From: geireann Date: Wed, 25 Aug 2021 05:20:50 -0400 Subject: many updates --- src/fields/InkField.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/fields') diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts index 1270a2dab..f16e143d8 100644 --- a/src/fields/InkField.ts +++ b/src/fields/InkField.ts @@ -1,8 +1,8 @@ +import { createSimpleSchema, list, object, serializable } from "serializr"; +import { Scripting } from "../client/util/Scripting"; import { Deserializable } from "../client/util/SerializationHelper"; -import { serializable, custom, createSimpleSchema, list, object, map } from "serializr"; +import { Copy, ToScriptString, ToString } from "./FieldSymbols"; import { ObjectField } from "./ObjectField"; -import { Copy, ToScriptString, ToString, Update } from "./FieldSymbols"; -import { Scripting } from "../client/util/Scripting"; // Helps keep track of the current ink tool in use. export enum InkTool { -- cgit v1.2.3-70-g09d2 From be825152070aa609817a2df7880e9cc377f7cfc1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 1 Sep 2021 12:19:38 -0400 Subject: changed ctrl-click to open alias to reuse existing alias. changed documentview to not clearout docView field when invalidated to allow webBox componentView to be persistent which allows proper settting of scrollHeight and allows webBox to grow to vertical space available in tab or lightbox. --- src/client/views/DocumentDecorations.tsx | 17 ++++++++--------- src/client/views/SidebarAnnos.tsx | 3 ++- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 7 ++++--- src/client/views/nodes/WebBox.tsx | 12 ++++++------ src/fields/documentSchemas.ts | 1 - 6 files changed, 21 insertions(+), 21 deletions(-) (limited to 'src/fields') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index e454be618..a570bdb34 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from '@material-ui/core'; import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { AclAdmin, AclEdit, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc"; +import { AclAdmin, AclEdit, DataSym, Doc, Field, HeightSym, WidthSym, DocListCast } from "../../fields/Doc"; import { Document } from '../../fields/documentSchemas'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from "../../fields/InkField"; @@ -159,9 +159,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b const selectedDocs = SelectionManager.Views(); if (selectedDocs.length) { if (e.ctrlKey) { // open an alias in a new tab with Ctrl Key - selectedDocs[0].props.Document._fullScreenView = Doc.MakeAlias(selectedDocs[0].props.Document); - (selectedDocs[0].props.Document._fullScreenView as Doc).context = undefined; - CollectionDockingView.AddSplit(selectedDocs[0].props.Document._fullScreenView as Doc, "right"); + const bestAlias = DocListCast(selectedDocs[0].props.Document.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail); + CollectionDockingView.AddSplit(bestAlias ?? Doc.MakeAlias(selectedDocs[0].props.Document), "right"); } else if (e.shiftKey) { // open centered in a new workspace with Shift Key const alias = Doc.MakeAlias(selectedDocs[0].props.Document); alias.context = undefined; @@ -169,7 +168,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b alias.y = -alias[HeightSym]() / 2; CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([alias], { title: "Tab for " + alias.title }), "right"); } else if (e.altKey) { // open same document in new tab - CollectionDockingView.ToggleSplit(Cast(selectedDocs[0].props.Document._fullScreenView, Doc, null) || selectedDocs[0].props.Document, "right"); + CollectionDockingView.ToggleSplit(selectedDocs[0].props.Document, "right"); } else { LightboxView.SetLightboxDoc(selectedDocs[0].props.Document, undefined, selectedDocs.slice(1).map(view => view.props.Document)); } @@ -391,10 +390,10 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._inkDragDocs.map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] })) .forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => { Doc.GetProto(doc).data = new InkField(inkPts.map(ipt => // (new x — oldx) + newWidth * (oldxpoint /oldWidth) - ({ - X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, - Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height - }))); + ({ + X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, + Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height + }))); Doc.SetNativeWidth(doc, undefined); Doc.SetNativeHeight(doc, undefined); }); diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 1f9763d18..0e3663f65 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -90,6 +90,7 @@ export class SidebarAnnos extends React.Component { } return this.props.styleProvider?.(doc, props, property); } + setHeightCallback = (height: number) => this.props.setHeight(height + this.filtersHeight()); render() { const renderTag = (tag: string) => { const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:check`); @@ -126,7 +127,7 @@ export class SidebarAnnos extends React.Component { styleProvider={this.sidebarStyleProvider} docFilters={this.docFilters} scaleField={this.sidebarKey + "-scale"} - setHeight={(height) => this.props.setHeight(height + this.filtersHeight())} + setHeight={this.setHeightCallback} isAnnotationOverlay={false} select={emptyFunction} scaling={returnOne} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index e8f345782..b9487054b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -154,7 +154,7 @@ export class TreeView extends React.Component { } else { // choose an appropriate alias or make one. --- choose the first alias that (1) user owns, (2) has no context field ... otherwise make a new alias // this.props.addDocTab(CurrentUserUtils.ActiveDashboard.isShared ? Doc.MakeAlias(this.props.document) : this.props.document, "add:right"); - const bestAlias = DocListCast(this.props.document.aliases).find(doc => !doc.context); + const bestAlias = DocListCast(this.props.document.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail); this.props.addDocTab(bestAlias ?? Doc.MakeAlias(this.props.document), "add:right"); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index fda84dd2d..6b9513b8b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -93,6 +93,7 @@ export interface DocComponentView { fieldKey?: string; annotationKey?: string; getTitle?: () => string; + getScrollHeight?: () => number; } export interface DocumentViewSharedProps { renderDepth: number; @@ -464,7 +465,6 @@ export class DocumentViewInternal extends DocComponent LightboxView.AddDocTab(this.rootDoc, "lightbox", this.props.LayoutTemplate?.()) - //this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox") , "double tap"); SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); @@ -983,6 +983,7 @@ export class DocumentViewInternal extends DocComponent; } render() { + TraceMobx(); const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : 0) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString const highlightColor = (Doc.UserDoc().colorScheme === ColorScheme.Dark ? ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] : @@ -1075,7 +1076,7 @@ export class DocumentView extends React.Component { @computed get panelWidth() { return this.effectiveNativeWidth ? this.effectiveNativeWidth * this.nativeScaling : this.props.PanelWidth(); } @computed get panelHeight() { if (this.effectiveNativeHeight) { - return Math.min(this.props.PanelHeight(), Math.max(NumCast(this.layoutDoc.scrollHeight), this.effectiveNativeHeight) * this.nativeScaling); + return Math.min(this.props.PanelHeight(), Math.max(this.ComponentView?.getScrollHeight?.() ?? NumCast(this.layoutDoc.scrollHeight), this.effectiveNativeHeight) * this.nativeScaling); } return this.props.PanelHeight(); } @@ -1182,7 +1183,7 @@ export class DocumentView extends React.Component { ScreenToLocalTransform={this.screenToLocalTransform} focus={this.props.focus || emptyFunction} bringToFront={emptyFunction} - ref={action((r: DocumentViewInternal | null) => this.docView = r)} /> + ref={action((r: DocumentViewInternal | null) => r && (this.docView = r))} /> )} ); } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index e4d4557af..719e5a796 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import * as WebRequest from 'web-request'; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; @@ -13,9 +13,8 @@ import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { WebField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, Utils, returnEmptyString, returnEmptyFilter } from "../../../Utils"; +import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils"; import { Docs } from "../../documents/Documents"; -import { DocumentType } from '../../documents/DocumentTypes'; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { Scripting } from "../../util/Scripting"; import { SnappingManager } from "../../util/SnappingManager"; @@ -59,7 +58,7 @@ export class WebBox extends ViewBoxAnnotatableComponent(); - @observable private _scrollHeight = 1500; + @observable private _scrollHeight = NumCast(this.layoutDoc.scrollHeight, 1500); @computed get _url() { return this.webField?.toString() || ""; } @computed get _urlHash() { return this._url ? WebBox.urlHash(this._url) + "" : ""; } @computed get scrollHeight() { return this._scrollHeight; } @@ -229,6 +228,8 @@ export class WebBox extends ViewBoxAnnotatableComponent this._scrollHeight; + isFirefox = () => { return "InstallTrigger" in window; // navigator.userAgent.indexOf("Chrome") !== -1; } @@ -417,8 +418,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Fri, 10 Sep 2021 00:32:06 -0400 Subject: fixed sidebar annos to filter on metdata as well as hashtags. --- src/client/documents/Documents.ts | 10 +++++++--- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/SidebarAnnos.tsx | 15 +++++++++++---- src/fields/Doc.ts | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src/fields') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 9a45da440..f50f306a3 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -959,12 +959,16 @@ export namespace DocUtils { // facets that have a check next to them const checks = Object.keys(facet).filter(value => facet[value] === "check"); + // metadata facets that exist + const exists = Object.keys(facet).filter(value => facet[value] === "exists"); + // facets that have an x next to them const xs = Object.keys(facet).filter(value => facet[value] === "x"); - if (!xs.length && !checks.length && !matches.length) return true; + if (!exists.length && !xs.length && !checks.length && !matches.length) return true; const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value)); + const satisfiesExistsFacets = !exists.length ? true : exists.some(value => d[facetKey] !== undefined); const satisfiesMatchFacets = !matches.length ? true : matches.some(value => { if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc const allKeys = Array.from(Object.keys(d)); @@ -976,11 +980,11 @@ export namespace DocUtils { }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria if ((parentCollection?.currentFilter as Doc)?.filterBoolean === "OR") { - if (satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; + if (satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria else { - if (!satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; + if (!satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; } } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 60bb375c8..d58917704 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -455,7 +455,7 @@ export class CurrentUserUtils { "" + ` ` + " " + - ` Metadata` + + ` Metadata` + ""; // "
" + diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index dd851c764..659eb86d1 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -38,10 +38,10 @@ export class SidebarAnnos extends React.Component { // this.props.dataDoc[this.sidebarKey] = new List(); // bcz: can't do this here. it blows away existing things and isn't a robust solution for making sure the field exists -- instead this should happen when the document is created and/or shared } _stackRef = React.createRef(); - @computed get allHashtags() { + @computed get allMetadata() { const keys = new Set(); DocListCast(this.props.rootDoc[this.sidebarKey]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort(); + return Array.from(keys.keys()).filter(key => key[0]).filter(key => key[0] !== "_" && (key[0] === key[0].toUpperCase())).sort(); } @computed get allUsers() { const keys = new Set(); @@ -59,7 +59,7 @@ export class SidebarAnnos extends React.Component { }); FormattedTextBox.SelectOnLoad = target[Id]; FormattedTextBox.DontSelectInitialText = true; - this.allHashtags.map(tag => target[tag] = tag); + this.allMetadata.map(tag => target[tag] = tag); DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation"); this.addDocument(target); this._stackRef.current?.focusDocument(target); @@ -93,6 +93,13 @@ export class SidebarAnnos extends React.Component { {tag}
; }; + const renderMeta = (tag: string) => { + const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:exists`); + return
Doc.setDocFilter(this.props.rootDoc, tag, tag, "exists", true, this.sidebarKey, e.shiftKey)}> + {tag} +
; + }; const renderUsers = (user: string) => { const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`author:${user}:check`); return
{
e.stopPropagation()}> {this.allUsers.map(renderUsers)} - {this.allHashtags.map(renderTag)} + {this.allMetadata.map(renderMeta)}
, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { + export function setDocFilter(container: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { if (!container) return; const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters"; const docFilters = Cast(container[filterField], listSpec("string"), []); -- cgit v1.2.3-70-g09d2 From f097eefd91614d4efa2a89b3d8c7d1071d6c0b6f Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 17 Sep 2021 14:07:09 -0400 Subject: added 'unset' docFilters. changed link doc views to use comparison box with title/caption. fixed linkEditor to write to data doc. generalized comparisonBox rendering to use parameterized fields. fixed pdf/web to honor pointerEvents none prop and fixed textAnnotations to get rendered once as an Annotation. moved filterIcon stuff into DocumentView --- src/Utils.ts | 4 +++- src/client/DocServer.ts | 2 ++ src/client/documents/Documents.ts | 17 +++++++++++------ src/client/views/collections/CollectionView.tsx | 12 ------------ .../collectionFreeForm/CollectionFreeFormLinkView.tsx | 6 +++--- src/client/views/linking/LinkEditor.tsx | 11 ++++++----- src/client/views/nodes/ComparisonBox.tsx | 8 +++++--- src/client/views/nodes/DocumentView.tsx | 19 +++++++++++++++++-- src/client/views/nodes/LinkBox.tsx | 19 ++++++------------- src/client/views/nodes/LinkDescriptionPopup.tsx | 7 ++++--- src/client/views/nodes/PDFBox.tsx | 9 ++++----- src/client/views/nodes/WebBox.tsx | 14 ++++++++------ src/client/views/pdf/Annotation.scss | 3 +++ src/client/views/pdf/PDFViewer.tsx | 13 +++++++------ src/fields/Doc.ts | 2 +- 15 files changed, 80 insertions(+), 66 deletions(-) (limited to 'src/fields') diff --git a/src/Utils.ts b/src/Utils.ts index 6eacd8296..e11f1154e 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -125,7 +125,9 @@ export namespace Utils { // bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:x`;// bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field } - + export function PropUnsetFilter(prop: string) { + return `${prop}:any,${noRecursionHack}:unset`; + } export function toRGBAstr(col: { r: number, g: number, b: number, a?: number }) { return "rgba(" + col.r + "," + col.g + "," + col.b + (col.a !== undefined ? "," + col.a : "") + ")"; diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index e498a7cca..3b376a0e7 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -241,6 +241,7 @@ export namespace DocServer { // the field has been returned from the server const getSerializedField = Utils.EmitCallback(_socket, MessageStore.GetRefField, id); + console.log(id) // when the serialized RefField has been received, go head and begin deserializing it into an object. // Here, once deserialized, we also invoke .proto to 'load' the document's prototype, which ensures that all // future .proto calls on the Doc won't have to go farther than the cache to get their actual value. @@ -264,6 +265,7 @@ export namespace DocServer { } else { delete _cache[id]; } + console.log(id, field); return field; // either way, overwrite or delete any promises cached at this id (that we inserted as flags // to indicate that the field was in the process of being fetched). Now everything diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f50f306a3..e8185400e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -962,13 +962,17 @@ export namespace DocUtils { // metadata facets that exist const exists = Object.keys(facet).filter(value => facet[value] === "exists"); + // metadata facets that exist + const unsets = Object.keys(facet).filter(value => facet[value] === "unset"); + // facets that have an x next to them const xs = Object.keys(facet).filter(value => facet[value] === "x"); - if (!exists.length && !xs.length && !checks.length && !matches.length) return true; + if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true; const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesExistsFacets = !exists.length ? true : exists.some(value => d[facetKey] !== undefined); + const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined); const satisfiesMatchFacets = !matches.length ? true : matches.some(value => { if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc const allKeys = Array.from(Object.keys(d)); @@ -980,11 +984,11 @@ export namespace DocUtils { }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria if ((parentCollection?.currentFilter as Doc)?.filterBoolean === "OR") { - if (satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; + if (satisfiesUnsetsFacets && satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria else { - if (!satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; + if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; } } @@ -1088,10 +1092,11 @@ export namespace DocUtils { "anchor2-useLinkSmallAnchor": target.doc.useLinkSmallAnchor ? true : undefined, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment, - layout_linkView: Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null), - linkDisplay: true, hidden: true, + linkDisplay: true, + hidden: true, linkRelationship, - _layoutKey: "layout_linkView", + _showCaption: "description", + _showTitle: "linkRelationship", description }, id), showPopup); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5c9c8063b..38e027fb3 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -246,12 +246,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent this.props.childLayoutTemplate?.() || Cast(this.rootDoc.childLayoutTemplate, Doc, null); @computed get childLayoutString() { return StrCast(this.rootDoc.childLayoutString); } - /** - * Shows the filter icon if it's a user-created collection which isn't a dashboard and has some docFilters applied on it or on the current dashboard. - */ - @computed get showFilterIcon() { - return this.props.Document.viewType !== CollectionViewType.Docking && !Doc.IsSystem(this.props.Document) && this._subView?.IsFiltered(); - } @observable _subView: any = undefined; @@ -280,12 +274,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} - {this.showFilterIcon ? - { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })} - /> - : (null)}
); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 3b3e069d8..2cb487588 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,6 +1,6 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../../../fields/Doc"; +import { Doc, Field } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; import { List } from "../../../../fields/List"; import { NumCast, StrCast } from "../../../../fields/Types"; @@ -180,7 +180,7 @@ export class CollectionFreeFormLinkView extends React.Component; const linkColorList = Doc.UserDoc().linkColorList as List; //access stroke color using index of the relationship in the color list (default black) @@ -189,7 +189,7 @@ export class CollectionFreeFormLinkView extends React.Component {textX === undefined ? (null) : - {StrCast(this.props.LinkDocs[0].description)} + {Field.toString(this.props.LinkDocs[0].description as any as Field)} } ); } diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 240a71c3e..219f7d3a2 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -2,13 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, StrListCast } from "../../../fields/Doc"; -import { DateCast, StrCast } from "../../../fields/Types"; +import { Doc, StrListCast, Field } from "../../../fields/Doc"; +import { DateCast, StrCast, Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; import './LinkEditor.scss'; import { LinkRelationshipSearch } from "./LinkRelationshipSearch"; import React = require("react"); +import { ToString } from "../../../fields/FieldSymbols"; interface LinkEditorProps { @@ -20,7 +21,7 @@ interface LinkEditorProps { @observer export class LinkEditor extends React.Component { - @observable description = StrCast(LinkManager.currentLink?.description); + @observable description = Field.toString(LinkManager.currentLink?.description as any as Field); @observable relationship = StrCast(LinkManager.currentLink?.linkRelationship); @observable openDropdown: boolean = false; @observable showInfo: boolean = false; @@ -41,7 +42,7 @@ export class LinkEditor extends React.Component { @undoBatch setRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { - LinkManager.currentLink.linkRelationship = value; + Doc.GetProto(LinkManager.currentLink).linkRelationship = value; const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); const linkColorList = StrListCast(Doc.UserDoc().linkColorList); // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color @@ -79,7 +80,7 @@ export class LinkEditor extends React.Component { @undoBatch setDescripValue = action((value: string) => { if (LinkManager.currentLink) { - LinkManager.currentLink.description = value; + Doc.GetProto(LinkManager.currentLink).description = value; this.buttonColor = "rgb(62, 133, 55)"; setTimeout(action(() => this.buttonColor = ""), 750); return true; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 6708a08ee..72c7e4f45 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -15,6 +15,7 @@ import "./ComparisonBox.scss"; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import React = require("react"); +import { DocumentType } from '../../documents/DocumentTypes'; export const comparisonSchema = createSchema({}); @@ -87,7 +88,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent; }; const displayDoc = (which: string) => { - const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null); + var whichDoc = Cast(this.dataDoc[which], Doc, null); + if (whichDoc.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null); return whichDoc ? <> - {displayBox("after", 1, this.props.PanelWidth() - 3)} + {displayBox(this.fieldKey === "data" ? "compareBox-after" : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)}
- {displayBox("before", 0, 0)} + {displayBox(this.fieldKey === "data" ? "compareBox-before" : `${this.fieldKey}1`, 0, 0)}
(this.props.PanelWidth() - 5) / this.props.PanelWidth() ? "w-resize" : undefined }} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 46a8b6629..35249c7f4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { AudioField } from "../../../fields/URLField"; import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; -import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick } from "../../../Utils"; +import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick, returnEmptyString } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -802,6 +802,12 @@ export class DocumentViewInternal extends DocComponent StrListCast(this.props.Document._docFilters); + collectionRangeDocFilters = () => StrListCast(this.props.Document._docRangeFilters); + @computed get showFilterIcon() { + return this.collectionFilters().length || this.collectionRangeDocFilters().length ? "hasFilter" : + this.props.docFilters?.().filter(f => Utils.IsRecursiveFilter(f)).length || this.props.docRangeFilters().length ? "inheritsFilter" : undefined + } rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); @@ -832,7 +838,7 @@ export class DocumentViewInternal extends DocComponent; return
this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { switch (property) { + case StyleProp.ShowTitle: return ""; case StyleProp.PointerEvents: return "none"; case StyleProp.LinkSource: return this.props.Document;// pass the LinkSource to the LinkAnchorBox default: return this.props.styleProvider?.(doc, props, property); @@ -901,6 +908,8 @@ export class DocumentViewInternal extends DocComponent } + {this.showFilterIcon ? + { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })} + /> + : (null)}
; } } diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 55ea45bb8..b82d16677 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -2,10 +2,10 @@ import React = require("react"); import { observer } from "mobx-react"; import { documentSchema } from "../../../fields/documentSchemas"; import { makeInterface } from "../../../fields/Schema"; -import { returnFalse } from "../../../Utils"; -import { CollectionTreeView } from "../collections/CollectionTreeView"; +import { emptyFunction, returnFalse } from "../../../Utils"; import { ViewBoxBaseComponent } from "../DocComponent"; import { StyleProp } from "../StyleProvider"; +import { ComparisonBox } from "./ComparisonBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./LinkBox.scss"; @@ -20,22 +20,15 @@ export class LinkBox extends ViewBoxBaseComponent( if (this.dataDoc.treeViewOpen === undefined) setTimeout(() => this.dataDoc.treeViewOpen = true); return
- - + moveDocument={returnFalse} />
; } } \ No newline at end of file diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index b62a4dd56..a9d33f161 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -1,8 +1,9 @@ import React = require("react"); +import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import "./LinkDescriptionPopup.scss"; -import { observable, action } from "mobx"; +import { Doc } from "../../../fields/Doc"; import { LinkManager } from "../../util/LinkManager"; +import "./LinkDescriptionPopup.scss"; import { TaskCompletionBox } from "./TaskCompletedBox"; @@ -25,7 +26,7 @@ export class LinkDescriptionPopup extends React.Component<{}> { onDismiss = (add: boolean) => { LinkDescriptionPopup.descriptionPopup = false; if (add) { - LinkManager.currentLink && (LinkManager.currentLink.description = this.description); + LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).description = this.description); } } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index f0a502e31..30b4dc92a 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -3,9 +3,9 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; -import { Doc, DocListCast, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, DocListCast, Opt, WidthSym, StrListCast } from "../../../fields/Doc"; import { documentSchema } from '../../../fields/documentSchemas'; -import { makeInterface } from "../../../fields/Schema"; +import { makeInterface, listSpec } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { PdfField } from "../../../fields/URLField"; import { TraceMobx } from '../../../fields/util'; @@ -25,6 +25,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @@ -249,9 +250,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { - return 1; - } + contentScaling = () => 1; @computed get renderPdfView() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 6a20ca14a..60a83d612 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -532,7 +532,8 @@ export class WebBox extends ViewBoxAnnotatableComponent {this.urlContent}
; @@ -575,10 +576,11 @@ export class WebBox extends ViewBoxAnnotatableComponent this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; - transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; - opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; + basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")]; + transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()]; + opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()]; render() { - const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : undefined; + const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents ? this.props.pointerEvents as any : undefined; const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; const scale = previewScale * (this.props.scaling?.() || 1); const renderAnnotations = (docFilters?: () => string[]) => @@ -593,7 +595,7 @@ export class WebBox extends ViewBoxAnnotatableComponent; return (
+ style={{ pointerEvents: this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none" }} >
{ let focusSpeed: Opt; 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; @@ -502,8 +502,9 @@ export class PDFViewer extends React.Component { 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); - transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()]; - opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()]; + basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")]; + transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()]; + opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()]; @computed get overlayLayer() { const renderAnnotations = (docFilters?: () => string[]) => { select={emptyFunction} ContentScaling={this.contentZoom} bringToFront={emptyFunction} - docFilters={docFilters || this.props.docFilters} + docFilters={docFilters || this.basicFilter} dontRenderDocuments={docFilters ? false : true} CollectionView={undefined} ScreenToLocalTransform={this.overlayTransform} @@ -543,7 +544,7 @@ export class PDFViewer extends React.Component {
; } @computed get pdfViewerDiv() { - return
; + return
; } @computed get contentScaling() { return this.props.ContentScaling?.() || 1; } @computed get standinViews() { @@ -556,7 +557,7 @@ export class PDFViewer extends React.Component { render() { TraceMobx(); return
-
, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { + export function setDocFilter(container: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists" | "unset", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { if (!container) return; const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters"; const docFilters = Cast(container[filterField], listSpec("string"), []); -- cgit v1.2.3-70-g09d2 From 385c635159bfa9bff86ddd6e46c96b934d2a9391 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 17 Sep 2021 17:51:46 -0400 Subject: fixed following links to documents in sidebars that haven't been opened to still open the sidebar and show the document. required a change to how ProxyFields set field promises and use field caches. --- src/client/views/SidebarAnnos.tsx | 2 +- src/fields/Proxy.ts | 66 ++++++--------------------------------- 2 files changed, 11 insertions(+), 57 deletions(-) (limited to 'src/fields') diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 659eb86d1..6a5b0a3ae 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -68,8 +68,8 @@ export class SidebarAnnos extends React.Component { if (DocListCast(this.props.rootDoc[this.sidebarKey]).includes(doc)) { if (this.props.layoutDoc[this.filtersKey]) { this.props.layoutDoc[this.filtersKey] = new List(); - return true; } + return true; } return false; } diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index 62734d3d2..07553f17c 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -9,72 +9,33 @@ import { Id, Copy, ToScriptString, ToString } from "./FieldSymbols"; import { scriptingGlobal } from "../client/util/Scripting"; import { Plugins } from "./util"; -function deserializeProxy(field: any) { - if (!field.cache) { - field.cache = DocServer.GetCachedRefField(field.fieldId) as any; - } -} -@Deserializable("proxy", deserializeProxy) +@Deserializable("proxy") export class ProxyField extends ObjectField { constructor(); constructor(value: T); constructor(fieldId: string); constructor(value?: T | string) { super(); - if (typeof value === "string") { - this.cache = DocServer.GetCachedRefField(value) as any; - this.fieldId = value; - } else if (value) { - this.cache = value; - this.fieldId = value[Id]; - } - } - - [Copy]() { - if (this.cache) return new ProxyField(this.cache); - return new ProxyField(this.fieldId); + this.fieldId = typeof value === "string" ? value : (value?.[Id] ?? ""); } - [ToScriptString]() { - return "invalid"; - } - [ToString]() { - return "ProxyField"; - } + [Copy]() { return new ProxyField((this.cache ?? this.fieldId) as T); } + [ToScriptString]() { return "invalid"; } + [ToString]() { return "ProxyField"; } @serializable(primitive()) readonly fieldId: string = ""; - - // This getter/setter and nested object thing is - // because mobx doesn't play well with observable proxies - @observable.ref - private _cache: { readonly field: T | undefined } = { field: undefined }; - private get cache(): T | undefined { - return this._cache.field; - } - private set cache(field: T | undefined) { - this._cache = { field }; - } - private failed = false; private promise?: Promise; + private get cache(): T | undefined { return DocServer.GetCachedRefField(this.fieldId) as T } + value(): T | undefined | FieldWaiting { - if (this.cache) { - return this.cache; - } - if (this.failed) { - return undefined; - } + if (this.cache) return this.cache; + if (this.failed) return undefined; if (!this.promise) { - const cached = DocServer.GetCachedRefField(this.fieldId); - if (cached !== undefined) { - runInAction(() => this.cache = cached as any); - return cached as any; - } this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => { this.promise = undefined; - this.cache = field; if (field === undefined) this.failed = true; return field; })); @@ -83,14 +44,7 @@ export class ProxyField extends ObjectField { } promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; } setPromise(promise: any) { - this.promise = promise; - } - @action - setValue(field: any) { - this.promise = undefined; - this.cache = field; - if (field === undefined) this.failed = true; - return field; + if (this.cache === undefined) this.promise = promise; } } -- cgit v1.2.3-70-g09d2 From 7e3bb99b81dd9494c927abacc2ebf920282f3ccb Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 17 Sep 2021 19:13:23 -0400 Subject: reverting last change. --- src/fields/Proxy.ts | 66 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 10 deletions(-) (limited to 'src/fields') diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index 07553f17c..62734d3d2 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -9,33 +9,72 @@ import { Id, Copy, ToScriptString, ToString } from "./FieldSymbols"; import { scriptingGlobal } from "../client/util/Scripting"; import { Plugins } from "./util"; -@Deserializable("proxy") +function deserializeProxy(field: any) { + if (!field.cache) { + field.cache = DocServer.GetCachedRefField(field.fieldId) as any; + } +} +@Deserializable("proxy", deserializeProxy) export class ProxyField extends ObjectField { constructor(); constructor(value: T); constructor(fieldId: string); constructor(value?: T | string) { super(); - this.fieldId = typeof value === "string" ? value : (value?.[Id] ?? ""); + if (typeof value === "string") { + this.cache = DocServer.GetCachedRefField(value) as any; + this.fieldId = value; + } else if (value) { + this.cache = value; + this.fieldId = value[Id]; + } + } + + [Copy]() { + if (this.cache) return new ProxyField(this.cache); + return new ProxyField(this.fieldId); } - [Copy]() { return new ProxyField((this.cache ?? this.fieldId) as T); } - [ToScriptString]() { return "invalid"; } - [ToString]() { return "ProxyField"; } + [ToScriptString]() { + return "invalid"; + } + [ToString]() { + return "ProxyField"; + } @serializable(primitive()) readonly fieldId: string = ""; + + // This getter/setter and nested object thing is + // because mobx doesn't play well with observable proxies + @observable.ref + private _cache: { readonly field: T | undefined } = { field: undefined }; + private get cache(): T | undefined { + return this._cache.field; + } + private set cache(field: T | undefined) { + this._cache = { field }; + } + private failed = false; private promise?: Promise; - private get cache(): T | undefined { return DocServer.GetCachedRefField(this.fieldId) as T } - value(): T | undefined | FieldWaiting { - if (this.cache) return this.cache; - if (this.failed) return undefined; + if (this.cache) { + return this.cache; + } + if (this.failed) { + return undefined; + } if (!this.promise) { + const cached = DocServer.GetCachedRefField(this.fieldId); + if (cached !== undefined) { + runInAction(() => this.cache = cached as any); + return cached as any; + } this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => { this.promise = undefined; + this.cache = field; if (field === undefined) this.failed = true; return field; })); @@ -44,7 +83,14 @@ export class ProxyField extends ObjectField { } promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; } setPromise(promise: any) { - if (this.cache === undefined) this.promise = promise; + this.promise = promise; + } + @action + setValue(field: any) { + this.promise = undefined; + this.cache = field; + if (field === undefined) this.failed = true; + return field; } } -- cgit v1.2.3-70-g09d2 From 75c47275853bfe422d6ae8a53be8ffe1996e1e76 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 17 Sep 2021 19:46:42 -0400 Subject: more conservative fix for previous. --- src/fields/Proxy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/fields') diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index 62734d3d2..f01b502c9 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -79,7 +79,7 @@ export class ProxyField extends ObjectField { return field; })); } - return this.promise as any; + return DocServer.GetCachedRefField(this.fieldId) ?? (this.promise as any); } promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; } setPromise(promise: any) { -- cgit v1.2.3-70-g09d2