From b78280f34fca6346ee1e9136d3e318c1564d5055 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 28 Sep 2020 15:10:40 -0400 Subject: fixed display of info about pdf annotations. made userColor change background color of settings dialogue. --- src/client/util/SettingsManager.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 17e93ad17..cd01fea5a 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { ColorState, SketchPicker } from "react-color"; import { Doc } from "../../fields/Doc"; -import { BoolCast, StrCast } from "../../fields/Types"; +import { BoolCast, StrCast, Cast } from "../../fields/Types"; import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; import { GoogleAuthenticationManager } from "../apis/GoogleAuthenticationManager"; import { DocServer } from "../DocServer"; @@ -205,6 +205,6 @@ export class SettingsManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: "600px" }} />; + dialogueBoxStyle={{ width: "600px", background: Cast(Doc.UserDoc().userColor, "string", null) }} />; } } \ No newline at end of file -- 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/client/util') 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 Date: Tue, 29 Sep 2020 14:37:59 -0500 Subject: undo for linking --- src/client/util/DocumentManager.ts | 2 ++ src/client/views/linking/LinkMenuItem.tsx | 49 +++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 116883fcb..c40df1c13 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -11,6 +11,7 @@ import { SelectionManager } from './SelectionManager'; import { DocumentType } from '../documents/DocumentTypes'; import { TraceMobx } from '../../fields/util'; import { returnFalse } from '../../Utils'; +import { undoBatch } from './UndoManager'; export type CreateViewFunc = (doc: Doc, followLinkLocation: string, finished?: () => void) => void; @@ -219,6 +220,7 @@ export class DocumentManager { } } + @undoBatch public async FollowLink(link: Opt, doc: Doc, createViewFunc: CreateViewFunc, zoom = false, currentContext?: Doc, finished?: () => void, traverseBacklink?: boolean) { const linkDocs = link ? [link] : DocListCast(doc.links); SelectionManager.DeselectAll(); diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index d3fbf39a2..a48f6ea49 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -2,8 +2,8 @@ import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontaw import { Tooltip } from '@material-ui/core'; import { action, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; -import { Doc, DocListCast } from '../../../fields/Doc'; -import { Cast, StrCast } from '../../../fields/Types'; +import { Doc, DocListCast, Opt } from '../../../fields/Doc'; +import { BoolCast, Cast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -11,7 +11,7 @@ import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; import { Hypothesis } from '../../util/HypothesisUtils'; import { LinkManager } from '../../util/LinkManager'; -import { undoBatch } from '../../util/UndoManager'; +import { undoBatch, UndoManager } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { DocumentView } from '../nodes/DocumentView'; @@ -146,14 +146,41 @@ export class LinkMenuItem extends React.Component { ContextMenu.Instance.displayMenu(e.clientX, e.clientY); } - @action.bound + followLinkClick = async (linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc, addDocTab: (doc: Doc, where: string) => void) => { + const batch = UndoManager.StartBatch("follow link click"); + const dv = DocumentManager.Instance.getFirstDocumentView(destinationDoc); + // open up target if it's not already in view ... + const createViewFunc = (doc: Doc, followLoc: string, finished: Opt<() => void>) => { + const targetFocusAfterDocFocus = () => { + const where = StrCast(destinationDoc.followLinkLocation) || followLoc; + const hackToCallFinishAfterFocus = () => { + finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. + return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false + }; + this.props.addDocTab(doc, where) && dv?.props.focus(doc, BoolCast(destinationDoc.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); // add the target and focus on it. + return where !== "inPlace"; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) + }; + if (!destinationDoc.followLinkZoom) { + targetFocusAfterDocFocus(); + } else { + // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target + dv?.props.focus(destinationDoc, BoolCast(destinationDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); + } + }; + + await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, undefined, dv?.props.ContainingCollectionDoc, batch.end, undefined); + } + + @action public static followDefault(linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc, addDocTab: (doc: Doc, where: string) => void) { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; if (linkDoc.followLinkLocation === "openExternal" && destinationDoc.type === DocumentType.WEB) { - window.open(`${StrCast(linkDoc.annotationUri)}#annotations:${StrCast(linkDoc.annotationId)}`, '_blank'); - return; + undoBatch(() => { + window.open(`${StrCast(linkDoc.annotationUri)}#annotations:${StrCast(linkDoc.annotationId)}`, '_blank'); + return; + })(); } if (linkDoc.followLinkLocation && linkDoc.followLinkLocation !== "default") { @@ -162,11 +189,15 @@ export class LinkMenuItem extends React.Component { if (annotationOn) { setTimeout(() => { const dv = DocumentManager.Instance.getFirstDocumentView(destinationDoc); - dv?.props.focus(destinationDoc, false); + undoBatch(() => { + dv?.props.focus(destinationDoc, false); + })(); }); } } else { - DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, doc => addDocTab(doc, "add:right"), false); + undoBatch(() => { + DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, doc => addDocTab(doc, "add:right"), false); + })(); } linkDoc.linksToAnnotation && Hypothesis.scrollToAnnotation(StrCast(linkDoc.annotationId), destinationDoc); @@ -249,7 +280,7 @@ export class LinkMenuItem extends React.Component {

LinkMenuItem.followDefault(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc, this.props.addDocTab)}> + onPointerDown={() => this.followLinkClick(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc, this.props.addDocTab)}> {this.props.linkDoc.linksToAnnotation && Cast(this.props.destinationDoc.data, WebField)?.url.href === this.props.linkDoc.annotationUri ? "Annotation in" : ""} {title}

-- cgit v1.2.3-70-g09d2 From 7e5779c7404d92fdd64958d6240a1418a2ee57d7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 20:37:26 -0400 Subject: simplfiled ':' menu and fixed creating items to not assume a template. add emptyNote. fixed scrolling in stacking views broken in previous commit. changed formattedTextBox to support stacking sidebar. --- src/client/documents/Documents.ts | 19 +++--- src/client/util/CurrentUserUtils.ts | 7 ++- .../views/collections/CollectionStackingView.tsx | 36 ++++++----- .../CollectionStackingViewFieldColumn.tsx | 31 +++++----- src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 69 +++++++++++++--------- 7 files changed, 97 insertions(+), 69 deletions(-) (limited to 'src/client/util') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ad30e7d33..47fa7067d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,7 +1,8 @@ import { runInAction } from "mobx"; import { basename, extname } from "path"; import { DateField } from "../../fields/DateField"; -import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclAddonly } from "../../fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc"; +import { Id } from "../../fields/FieldSymbols"; import { HtmlField } from "../../fields/HtmlField"; import { InkField } from "../../fields/InkField"; import { List } from "../../fields/List"; @@ -11,6 +12,7 @@ import { SchemaHeaderField } from "../../fields/SchemaHeaderField"; import { ComputedField, ScriptField } from "../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../fields/Types"; import { AudioField, ImageField, PdfField, VideoField, WebField, YoutubeField } from "../../fields/URLField"; +import { SharingPermissions } from "../../fields/util"; import { MessageStore } from "../../server/Message"; import { Upload } from "../../server/SharedMediaTypes"; import { OmitKeys, Utils } from "../../Utils"; @@ -33,6 +35,7 @@ import { AudioBox } from "../views/nodes/AudioBox"; import { ColorBox } from "../views/nodes/ColorBox"; import { ComparisonBox } from "../views/nodes/ComparisonBox"; import { DocHolderBox } from "../views/nodes/DocHolderBox"; +import { FilterBox } from "../views/nodes/FilterBox"; import { FontIconBox } from "../views/nodes/FontIconBox"; import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox"; import { ImageBox } from "../views/nodes/ImageBox"; @@ -50,9 +53,6 @@ import { PresElementBox } from "../views/presentationview/PresElementBox"; import { SearchBox } from "../views/search/SearchBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; -import { FilterBox } from "../views/nodes/FilterBox"; -import { SharingPermissions } from "../../fields/util"; -import { SharingManager } from "../util/SharingManager"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); @@ -208,6 +208,8 @@ export interface DocumentOptions { treeViewOutlineMode?: boolean; // whether slide should function as a text outline treeViewLockExpandedView?: boolean; // whether the expanded view can be changed treeViewDefaultExpandedView?: string; // default expanded view + sidebarColor?: string; // background color of text sidebar + sidebarViewType?: string; // collection type of text sidebar limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents // [key: string]: Opt; pointerHack?: boolean; // for buttons, allows onClick handler to fire onPointerDown @@ -1094,8 +1096,8 @@ export namespace DocUtils { return ctor ? ctor(path, options) : undefined; } - export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number): void { - ContextMenu.Instance.addItem({ + export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false): void { + !simpleMenu && ContextMenu.Instance.addItem({ description: "Add Note ...", subitems: DocListCast((Doc.UserDoc()["template-notes"] as Doc).data).map((note, i) => ({ description: ":" + StrCast(note.title), @@ -1114,14 +1116,15 @@ export namespace DocUtils { }); ContextMenu.Instance.addItem({ description: "Add Template Doc ...", - subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc).map((dragDoc, i) => ({ + subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({ description: ":" + StrCast(dragDoc.title), event: undoBatch((args: { x: number, y: number }) => { - const newDoc = Doc.ApplyTemplate(dragDoc); + const newDoc = Doc.copyDragFactory(dragDoc); if (newDoc) { newDoc.author = Doc.CurrentUserEmail; newDoc.x = x; newDoc.y = y; + if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id]; docAdder(newDoc); } }), diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 3e76b189a..7cc35d67a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -422,9 +422,13 @@ export class CurrentUserUtils { doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); } if (doc.emptyAudio === undefined) { - doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "ready to record audio", system: true, cloneFieldFilter: new List(["system"]) }); + doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "audio recording", system: true, cloneFieldFilter: new List(["system"]) }); ((doc.emptyAudio as Doc).proto as Doc)["dragFactory-count"] = 0; } + if (doc.emptyNote === undefined) { + doc.emptyNote = Docs.Create.TextDocument("", { _width: 200, title: "text note", system: true, cloneFieldFilter: new List(["system"]) }); + ((doc.emptyNote as Doc).proto as Doc)["dragFactory-count"] = 0; + } if (doc.emptyImage === undefined) { doc.emptyImage = Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth: 250, title: "an image of a cat", system: true }); } @@ -444,6 +448,7 @@ export class CurrentUserUtils { this.setupActiveMobileMenu(doc); } return [ + { toolTip: "Tap to create a note in a new pane, drag for a note", title: "Note", icon: "sticky-note", click: 'openOnRight(copyDragFactory(this.clickFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyNote as Doc, noviceMode: true, clickFactory: doc.emptyNote as Doc, }, { toolTip: "Tap to create a collection in a new pane, drag for a collection", title: "Col", icon: "folder", click: 'openOnRight(copyDragFactory(this.clickFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyCollection as Doc, noviceMode: true, clickFactory: doc.emptyPane as Doc, }, { toolTip: "Tap to create a webpage in a new pane, drag for a webpage", title: "Web", icon: "globe-asia", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWebpage as Doc, noviceMode: true }, { toolTip: "Tap to create a progressive slide", title: "Slide", icon: "file", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySlide as Doc, noviceMode: true }, diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 423d39951..daaee67dc 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -33,8 +33,12 @@ const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; const StackingDocument = makeInterface(collectionSchema, documentSchema); +export type collectionStackingViewProps = { + chromeStatus?: string; +}; + @observer -export class CollectionStackingView extends CollectionSubView(StackingDocument) { +export class CollectionStackingView extends CollectionSubView>(StackingDocument) { _masonryGridRef: HTMLDivElement | null = null; _draggerRef = React.createRef(); _pivotFieldDisposer?: IReactionDisposer; @@ -44,15 +48,16 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) @observable _heightMap = new Map(); @observable _cursor: CursorProperty = "grab"; @observable _scroll = 0; // used to force the document decoration to update when scrolling + @computed get chromeStatus() { return this.props.chromeStatus || StrCast(this.layoutDoc._chromeStatus); } @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField)); } @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); } @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout); } @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } - @computed get yMargin() { return Math.max(this.layoutDoc._showTitle && !this.layoutDoc._showTitleHover ? 30 : 0, NumCast(this.layoutDoc._yMargin, 5)); } // 2 * this.gridGap)); } + @computed get yMargin() { return Math.max(this.layoutDoc._showTitle && !this.layoutDoc._showTitleHover ? 30 : 0, this.props.yMargin || NumCast(this.layoutDoc._yMargin, 5)); } // 2 * this.gridGap)); } @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); } @computed get isStackingView() { return BoolCast(this.layoutDoc._columnsStack, true); } @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; } - @computed get showAddAGroup() { return (this.pivotField && (this.layoutDoc._chromeStatus !== 'view-mode' && this.layoutDoc._chromeStatus !== 'disabled')); } + @computed get showAddAGroup() { return (this.pivotField && (this.chromeStatus !== 'view-mode' && this.chromeStatus !== 'disabled')); } @computed get columnWidth() { return Math.min(this.props.PanelWidth() / this.props.ContentScaling() - 2 * this.xMargin, this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250)); @@ -354,7 +359,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { - Doc.Layout(doc)._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); + const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); + Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); } })); this.observer.observe(ref); @@ -406,7 +412,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { - Doc.Layout(doc)._height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); + const height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); + Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); } })); this.observer.observe(ref); @@ -444,10 +451,6 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1; } - onToggle = (checked: Boolean) => { - this.layoutDoc._chromeStatus = checked ? "collapsed" : "view-mode"; - } - onContextMenu = (e: React.MouseEvent): void => { // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout if (!e.isPropagationStopped()) { @@ -504,13 +507,14 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> } - {this.layoutDoc._chromeStatus !== 'disabled' && this.props.isSelected() ? : null} + {/* {this.chromeStatus === 'disabled' || !this.props.isSelected() ? (null) : + } */} ); } diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 44d264b36..1bc989e83 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -22,6 +22,8 @@ import { ContextMenuProps } from "../ContextMenuItem"; import { EditableView } from "../EditableView"; import { CollectionStackingView } from "./CollectionStackingView"; import "./CollectionStackingView.scss"; +import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; +import { Id } from "../../../fields/FieldSymbols"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -137,8 +139,9 @@ export class CollectionStackingViewFieldColumn extends React.Component NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0); const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3; newDoc.heading = heading; - this.props.parent.props.addDocument(newDoc); - return false; + FormattedTextBox.SelectOnLoad = newDoc[Id]; + FormattedTextBox.SelectOnLoadChar = " "; + return this.props.parent.props.addDocument(newDoc); } @action @@ -228,7 +231,10 @@ export class CollectionStackingViewFieldColumn extends React.Component { + FormattedTextBox.SelectOnLoad = doc[Id]; + return this.props.parent.props.addDocument(doc); + }, this.props.parent.props.addDocument, x, y, true); Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey => docItems.push({ @@ -256,13 +262,8 @@ export class CollectionStackingViewFieldColumn extends React.Component this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); - layoutItems.push({ description: ":carousel", event: () => this.props.parent.props.addDocument(Docs.Create.CarouselDocument([], { _width: 400, _height: 200 })), icon: "compress-arrows-alt" }); - layoutItems.push({ description: ":columns", event: () => this.props.parent.props.addDocument(Docs.Create.MulticolumnDocument([], { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); - layoutItems.push({ description: ":image", event: () => this.props.parent.props.addDocument(Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); - - ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" }); - ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" }); + !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" }); + !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" }); ContextMenu.Instance.setDefaultItem("::", (name: string): void => { Doc.GetProto(this.props.parent.props.Document)[name] = ""; const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true }); @@ -285,7 +286,7 @@ export class CollectionStackingViewFieldColumn extends React.Component headings.indexOf(i) === idx); const evContents = heading ? heading : this.props?.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`; const headerEditableViewProps = { @@ -306,10 +307,10 @@ export class CollectionStackingViewFieldColumn extends React.Component
{/* the default bucket (no key value) has a tooltip that describes what it is. @@ -342,7 +343,7 @@ export class CollectionStackingViewFieldColumn extends React.Component : (null); for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `; - const chromeStatus = this.props.parent.props.Document._chromeStatus; + const chromeStatus = this.props.parent.chromeStatus; const type = this.props.parent.props.Document.type; return <> {this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView} @@ -365,7 +366,7 @@ export class CollectionStackingViewFieldColumn extends React.Component {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== DocumentType.PRES) ?
+ style={{ width: style.columnWidth / style.numGroupColumns, marginBottom: 10 }}>
: null} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 06c35de03..1dfa5615a 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -185,7 +185,7 @@ export class TreeView extends React.Component { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", forceActive: true, _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", "sidebarColor": "transparent", "sidebarViewType": CollectionViewType.Freeform, forceActive: true, _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List([]); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a3f76839d..89e0450d7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1627,7 +1627,7 @@ 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 + if (getComputedStyle(target)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars target.scrollTop = target.scrollLeft = 0; } }} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 1148087c6..93eb94854 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { isEqual } from "lodash"; +import { isEqual, max } from "lodash"; import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { baseKeymap, selectAll } from "prosemirror-commands"; @@ -58,6 +58,8 @@ import "./FormattedTextBox.scss"; import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark } from './FormattedTextBoxComment'; import React = require("react"); import { DocumentManager } from '../../../util/DocumentManager'; +import { CollectionStackingView } from '../../collections/CollectionStackingView'; +import { CollectionViewType } from '../../collections/CollectionView'; export interface FormattedTextBoxProps { makeLink?: () => Opt; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text @@ -1166,7 +1168,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); const curMarks = this._editorView.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? []; const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark]; - this._editorView.dispatch(this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar).setStoredMarks(storedMarks)); + const tr = this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar, this._editorView.state.doc.content.size - 1, this._editorView.state.doc.content.size).setStoredMarks(storedMarks); + this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size)))); FormattedTextBox.SelectOnLoadChar = ""; } else if (curText?.Text) { selectAll(this._editorView!.state, this._editorView?.dispatch); @@ -1496,6 +1499,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @action tryUpdateHeight(limitHeight?: number) { let scrollHeight = this.ProseRef?.scrollHeight || 0; + this.rootDoc[this.fieldKey + "-height"] = 0; if (this.props.renderDepth && this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight && !this.props.dontRegisterView) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation scrollHeight = scrollHeight * NumCast(this.layoutDoc._viewScale, 1); if (limitHeight && scrollHeight > limitHeight) { @@ -1517,8 +1521,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp try { const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); - this.rootDoc._height = newHeight + Math.max(0, outer); - this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; + const finalHeight = newHeight + Math.max(0, outer); + const maxsidebar = !this.sidebarWidth() ? 0 : Array.from(this._boxRef.current!.getElementsByClassName("collectionStackingViewFieldColumn")).reduce((prev, ele) => Math.max(prev, Number(getComputedStyle(ele).height.replace("px", ""))), 0); + if (this.rootDoc._height !== finalHeight && finalHeight > maxsidebar) { + this.rootDoc._height = finalHeight; + this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; + } + this.rootDoc[this.fieldKey + "-height"] = finalHeight; } catch (e) { console.log("Error in tryUpdateHeight"); } } } @@ -1545,36 +1554,42 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; + const collectionProps = { + ...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit, + PanelHeight: this.props.PanelHeight, + PanelWidth: this.sidebarWidth, + xMargin: 0, + yMargin: 0, + chromeStatus: "enabled", + scaleField: this.annotationKey + "-scale", + annotationsKey: this.annotationKey, + isAnnotationOverlay: true, + fitToBox: fitToBox, + focus: this.props.focus, + isSelected: this.props.isSelected, + select: emptyFunction, + active: this.annotationsActive, + ContentScaling: returnOne, + whenActiveChanged: this.whenActiveChanged, + removeDocument: this.removeDocument, + moveDocument: this.moveDocument, + addDocument: this.addDocument, + CollectionView: undefined, + ScreenToLocalTransform: this.sidebarScreenToLocal, + renderDepth: this.props.renderDepth + 1, + ContainingCollectionDoc: this.props.ContainingCollectionDoc, + }; return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : -
- +
+ {this.layoutDoc.sidebarViewType === CollectionViewType.Freeform ? : }
; } @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); - @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } + @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } render() { TraceMobx(); const selected = this.props.isSelected(); -- cgit v1.2.3-70-g09d2 From a64e926beeda627fb9d7935b7fef2233bb09a869 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 21:12:45 -0400 Subject: removed unncessary undoBatch's --- src/client/util/DocumentManager.ts | 13 +++++-------- src/client/views/linking/LinkMenuItem.tsx | 9 ++------- 2 files changed, 7 insertions(+), 15 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index c40df1c13..d7ff03344 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -1,17 +1,15 @@ -import { action, computed, observable } from 'mobx'; -import { Doc, DocListCastAsync, DocListCast, Opt } from '../../fields/Doc'; +import { action, observable } from 'mobx'; +import { Doc, DocListCast, DocListCastAsync, Opt } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { Cast, NumCast, StrCast } from '../../fields/Types'; +import { returnFalse } from '../../Utils'; +import { DocumentType } from '../documents/DocumentTypes'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { CollectionView } from '../views/collections/CollectionView'; -import { DocumentView, DocFocusFunc } from '../views/nodes/DocumentView'; +import { DocumentView } from '../views/nodes/DocumentView'; import { LinkManager } from './LinkManager'; import { Scripting } from './Scripting'; import { SelectionManager } from './SelectionManager'; -import { DocumentType } from '../documents/DocumentTypes'; -import { TraceMobx } from '../../fields/util'; -import { returnFalse } from '../../Utils'; -import { undoBatch } from './UndoManager'; export type CreateViewFunc = (doc: Doc, followLinkLocation: string, finished?: () => void) => void; @@ -220,7 +218,6 @@ export class DocumentManager { } } - @undoBatch public async FollowLink(link: Opt, doc: Doc, createViewFunc: CreateViewFunc, zoom = false, currentContext?: Doc, finished?: () => void, traverseBacklink?: boolean) { const linkDocs = link ? [link] : DocListCast(doc.links); SelectionManager.DeselectAll(); diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index c05efed45..866db958a 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -178,10 +178,7 @@ export class LinkMenuItem extends React.Component { LinkDocPreview.LinkInfo = undefined; if (linkDoc.followLinkLocation === "openExternal" && destinationDoc.type === DocumentType.WEB) { - undoBatch(() => { - window.open(`${StrCast(linkDoc.annotationUri)}#annotations:${StrCast(linkDoc.annotationId)}`, '_blank'); - return; - })(); + window.open(`${StrCast(linkDoc.annotationUri)}#annotations:${StrCast(linkDoc.annotationId)}`, '_blank'); } if (linkDoc.followLinkLocation && linkDoc.followLinkLocation !== "default") { @@ -196,9 +193,7 @@ export class LinkMenuItem extends React.Component { }); } } else { - undoBatch(() => { - DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, doc => addDocTab(doc, "add:right"), false); - })(); + DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, doc => addDocTab(doc, "add:right"), false); } linkDoc.linksToAnnotation && Hypothesis.scrollToAnnotation(StrCast(linkDoc.annotationId), destinationDoc); -- cgit v1.2.3-70-g09d2