diff options
Diffstat (limited to 'src/client/views')
6 files changed, 42 insertions, 21 deletions
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 0a336c544..0ca0a463e 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -35,6 +35,18 @@ export class CollectionPileView extends CollectionSubView() { layoutEngine = () => StrCast(this.Document._pileLayoutEngine); + @undoBatch + addPileDoc = (doc: Doc | Doc[]) => { + (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); + return this.props.addDocument?.(doc) || false; + } + + @undoBatch + removePileDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { + (doc instanceof Doc ? [doc] : doc).map(undoBatch((d) => Doc.deiconifyView(d))); + return this.props.moveDocument?.(doc, targetCollection, addDoc) || false; + } + // returns the contents of the pileup in a CollectionFreeFormView @computed get contents() { const isStarburst = this.layoutEngine() === "starburst"; @@ -47,14 +59,8 @@ export class CollectionPileView extends CollectionSubView() { <CollectionFreeFormView {...this.props} layoutEngine={this.layoutEngine} childDocumentsActive={isStarburst ? returnTrue : undefined} - addDocument={undoBatch((doc: Doc | Doc[]) => { - (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); - return this.props.addDocument?.(doc) || false; - })} - moveDocument={undoBatch((doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { - (doc instanceof Doc ? [doc] : doc).map(undoBatch((d) => Doc.deiconifyView(d))); - return this.props.moveDocument?.(doc, targetCollection, addDoc) || false; - })} /> + addDocument={this.addPileDoc} + moveDocument={this.removePileDoc} /> </div>; } @@ -62,19 +68,16 @@ export class CollectionPileView extends CollectionSubView() { toggleStarburst = action(() => { if (this.layoutEngine() === 'starburst') { const defaultSize = 110; - this.layoutDoc._overflow = undefined; - this.childDocs.forEach(d => DocUtils.iconify(d)); this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - NumCast(this.layoutDoc._starburstPileWidth, defaultSize) / 2; this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2; this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize); this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize); - DocUtils.pileup(this.childDocs); + DocUtils.pileup(this.childDocs, undefined, undefined, false); this.layoutDoc._panX = 0; this.layoutDoc._panY = -10; this.props.Document._pileLayoutEngine = 'pass'; } else { const defaultSize = 25; - this.layoutDoc._overflow = 'visible'; !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 500); !this.layoutDoc._starburstDocScale && (this.layoutDoc._starburstDocScale = 2.5); if (this.layoutEngine() === 'pass') { diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 42e157396..d8f1287cd 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -453,7 +453,7 @@ export function CollectionSubView<X>(moreProps?: X) { if (completed) completed(set); else { if (isFreeformView && generatedDocuments.length > 1) { - addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)); + addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!); } else { generatedDocuments.forEach(addDocument); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e2ea81392..b2697cf08 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1152,6 +1152,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection renderDepth={this.props.renderDepth + 1} replica={entry.replica} renderIndex={renderIndex} + dataTransition={entry.transition} renderCutoffProvider={this.renderCutoffProvider} ContainingCollectionView={this.props.CollectionView} ContainingCollectionDoc={this.props.Document} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b10b0912f..b8f687489 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -374,7 +374,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque const selected = this.marqueeSelect(false); SelectionManager.DeselectAll(); selected.forEach(d => this.props.removeDocument?.(d)); - const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2); + const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2)!; this.props.addDocument?.(newCollection); this.props.selectDocuments([newCollection]); MarqueeOptionsMenu.Instance.fadeOut(true); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 979e86738..a9abf066e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -116,6 +116,7 @@ export interface DocumentViewSharedProps { PanelWidth: () => number; PanelHeight: () => number; docViewPath: () => DocumentView[]; + dataTransition?: string; // specifies animation transition - used by collectionPile and potentially other layout engines when changing the size of documents so that the change won't be abrupt layerProvider: undefined | ((doc: Doc, assign?: boolean) => boolean); styleProvider: Opt<StyleProviderFunc>; focus: DocFocusFunc; @@ -182,6 +183,7 @@ export interface DocumentViewInternalProps extends DocumentViewProps { @observer export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps>() { public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered. + _animateScaleTime = 300; // milliseconds; @observable _animateScalingTo = 0; @observable _mediaState = 0; @observable _pendingDoubleClick = false; @@ -1078,9 +1080,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps color: StrCast(this.layoutDoc.color, "inherit"), fontFamily: StrCast(this.Document._fontFamily, "inherit"), fontSize: Cast(this.Document._fontSize, "string", null), - transformOrigin: this._animateScalingTo ? "center center" : undefined, transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined, - transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform 0.5s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, + transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform ${this._animateScaleTime / 1000}s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, }}> {this.innards} @@ -1247,8 +1248,8 @@ export class DocumentView extends React.Component<DocumentViewProps> { setTimeout(action(() => { this.setCustomView(custom, view); this.docView && (this.docView._animateScalingTo = 1); // expand it - setTimeout(action(() => this.docView && (this.docView._animateScalingTo = 0)), 400); - }), 400); + setTimeout(action(() => this.docView && (this.docView._animateScalingTo = 0)), this.docView!._animateScaleTime - 10); + }), this.docView!._animateScaleTime - 10); }); startDragging = (x: number, y: number, dropAction: dropActionType, hideSource = false) => this.docView?.startDragging(x, y, dropAction, hideSource); @@ -1293,6 +1294,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { {!this.props.Document || !this.props.PanelWidth() ? (null) : ( <div className="contentFittingDocumentView-previewDoc" ref={this.ContentRef} style={{ + transition: this.props.dataTransition, position: this.props.Document.isInkMask ? "absolute" : undefined, transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`, width: isButton ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, @@ -1318,6 +1320,15 @@ export class DocumentView extends React.Component<DocumentViewProps> { } } +export function deiconifyViewFunc(documentView: DocumentView) { + documentView.iconify(); + //StrCast(doc.layoutKey).split("_")[1] === "icon" && setNativeView(doc); +} +ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { + documentView.iconify(); +} +); + ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) { if (dv.Document.layoutKey === "layout_" + detailLayoutKeySuffix) dv.switchViews(false, "layout"); else dv.switchViews(true, detailLayoutKeySuffix); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 75f0978a8..1f7e557d9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -359,18 +359,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp DocListCast(Doc.UserDoc().myPublishedDocs).forEach(term => tr = this.hyperlinkTerm(tr, term, newAutoLinks)); tr = tr.setSelection(new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t))); this._editorView?.dispatch(tr); - oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink)).forEach(LinkManager.Instance.deleteLink); + oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.anchor2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink); } } updateTitle = () => { + const title = StrCast(this.dataDoc.title) if (!this.props.dontRegisterView && // (this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing - StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.dataDoc["title-custom"] && + (title.startsWith("-") || title.startsWith("@")) && this._editorView && !this.dataDoc["title-custom"] && (Doc.LayoutFieldKey(this.rootDoc) === this.fieldKey || this.fieldKey === "text")) { let node = this._editorView.state.doc; while (node.firstChild && node.firstChild.type.name !== "text") node = node.firstChild; const str = node.textContent; - this.dataDoc.title = "-" + str.substr(0, Math.min(40, str.length)) + (str.length > 40 ? "..." : ""); + const prefix = str.startsWith("@") ? "" : "-"; + this.dataDoc.title = prefix + str.substring(0, Math.min(40, str.length)) + (str.length > 40 ? "..." : ""); + if (str.startsWith("@") && str.length > 1) { + Doc.AddDocToList(Doc.UserDoc(), "myPublishedDocs", this.rootDoc); + } } } @@ -909,6 +914,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } if (this._editorView && selected) { RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props); + this.autoLink(); } }), { fireImmediately: true }); |
