aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-09-21 14:36:24 -0400
committerbobzel <zzzman@gmail.com>2020-09-21 14:36:24 -0400
commit19d22f589c1ce0475b87d5c27859d3dde76c084b (patch)
tree1690c541993c9ecdcfd10caf497fb0070d9ee699
parent8089f668de934cc031a91c093c481856e7c8fe8b (diff)
fixed text box llnk preview to go away when docs are closed. fixed tree view to be more efficient by not re-rendering when items are selected. made slide view text items forceActive
-rw-r--r--src/client/views/collections/CollectionTreeView.scss1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx44
-rw-r--r--src/client/views/collections/TreeView.tsx21
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx19
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx82
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx13
6 files changed, 84 insertions, 96 deletions
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 20bfc0e9d..c5add7cfb 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -28,6 +28,7 @@
.no-indent {
padding-left: 0;
+ width: max-content;
}
.editableView-container {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index efbe5581b..e2247aec3 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -41,7 +41,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
private _mainEle?: HTMLDivElement;
public _uniqueId = Utils.GenerateGuid();
- @computed get doc() { return this.props.Document; }
+ @computed get doc() { TraceMobx(); return this.props.Document; }
@computed get dataDoc() { return this.props.DataDoc || this.doc; }
protected createTreeDropTarget = (ele: HTMLDivElement) => {
@@ -117,7 +117,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {});
@computed get renderClearButton() {
- return <div key="toolbar">
+ return !this.doc.allowClear ? (null) : <div key="toolbar">
<button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.doc)[this.props.fieldKey] = undefined))}>
<FontAwesomeIcon icon={"trash"} size="sm" />
</button>
@@ -192,37 +192,45 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
whenActiveChanged = (isActive: boolean) => { this.props.whenActiveChanged(this._isChildActive = isActive); };
active = (outsideReaction: boolean | undefined) => this.props.active(outsideReaction) || this._isChildActive;
- render() {
+ @computed get treeChildren() {
+ TraceMobx();
+ return this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs;
+ }
+ @computed get treeViewElements() {
TraceMobx();
- if (!(this.doc instanceof Doc)) return (null);
const dropAction = StrCast(this.doc.childDropAction) as dropActionType;
const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(d, target, addDoc);
- const childDocs = this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs;
- const childElements = childDocs && TreeView.GetChildElements(childDocs, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
+ return TreeView.GetChildElements(this.treeChildren, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform,
this.outerXf, this.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields),
BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick,
this.onChildClick, this.props.ignoreFields, true, this.whenActiveChanged);
+ }
+ @computed get titleBar() {
const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle;
- const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.doc.backgroundColor) || this.props.backgroundColor?.(this.doc, this.props.renderDepth);
+ return hideTitle ? (null) : (this.doc.treeViewOutlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren)
+ }
+ render() {
+ TraceMobx();
+ if (!(this.doc instanceof Doc)) return (null);
+ const background = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.doc.backgroundColor) || this.props.backgroundColor?.(this.doc, this.props.renderDepth);
+ const paddingX = `${NumCast(this.doc._xPadding, 10)}px`;
+ const paddingTop = `${NumCast(this.doc._yPadding, 20)}px`;
+ const pointerEvents = !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined;
- return !childDocs ? (null) : (
+ return !this.treeChildren ? (null) : (
<div className="collectionTreeView-container" onContextMenu={this.onContextMenu}>
<div className="collectionTreeView-dropTarget"
- style={{
- background: backgroundColor,
- paddingLeft: `${NumCast(this.doc._xPadding, 10)}px`,
- paddingRight: `${NumCast(this.doc._xPadding, 10)}px`,
- paddingTop: `${NumCast(this.doc._yPadding, 20)}px`,
- pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined,
- }}
+ style={{ background, paddingLeft: paddingX, paddingRight: paddingX, paddingTop, pointerEvents }}
onWheel={(e) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
- {hideTitle ? (null) : (this.doc.treeViewOutlineMode ? this.documentTitle : this.editableTitle)(childDocs)}
- {this.doc.allowClear ? this.renderClearButton : (null)}
- <ul className="no-indent" style={{ width: "max-content" }} > {childElements} </ul>
+ {this.titleBar}
+ {this.renderClearButton}
+ <ul className="no-indent">
+ {this.treeViewElements}
+ </ul>
</div >
</div>
);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index edb703135..486e44f6b 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -83,9 +83,9 @@ export class TreeView extends React.Component<TreeViewProps> {
private _uniqueId = Utils.GenerateGuid();
private _editMaxWidth: number | string = 0;
- get doc() { return this.props.document; }
+ @computed get doc() { TraceMobx(); return this.props.document; }
get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); }
- get displayName() { return "TreeView(" + this.doc.title + ")"; } // this makes mobx trace() statements more descriptive
+ get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive
get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; }
get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.noviceMode || this.outlineMode ? "layout" : "fields"); }
get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs ? this.fieldKey : this.defaultExpandedView); }
@@ -100,14 +100,14 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); }
@computed get dataDoc() { return this.doc[DataSym]; }
@computed get layoutDoc() { return Doc.Layout(this.doc); }
- @computed get fieldKey() { const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; }
+ @computed get fieldKey() { TraceMobx(); const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; }
childDocList(field: string) {
const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined;
return ((this.props.dataDoc ? DocListCastOrNull(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field
(layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields
DocListCastOrNull(this.doc[field])); // otherwise use the document's data field
}
- @computed get childDocs() { return this.childDocList(this.fieldKey); }
+ @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); }
@computed get childLinks() { return this.childDocList("links"); }
@computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); }
@computed get boundsOfCollectionDocument() {
@@ -130,13 +130,12 @@ export class TreeView extends React.Component<TreeViewProps> {
constructor(props: any) {
super(props);
- console.log("Ttile = " + this.props.document.title);
const titleScript = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); documentView.select();} `, { documentView: "any" });
const openScript = ScriptField.MakeScript(`openOnRight(self)`);
const treeOpenScript = ScriptField.MakeScript(`self.treeViewOpen = !self.treeViewOpen`);
this._editTitleScript = !Doc.IsSystem(this.props.document) ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript);
this._openScript = !Doc.IsSystem(this.props.document) ? openScript && (() => openScript) : undefined;
- if (Doc.GetT(this.doc, "editTitle", "string", true) === "*") Doc.SetInPlace(this.doc, "editTitle", this._uniqueId, false);
+ if (Doc.GetT(this.props.document, "editTitle", "string", true) === "*") Doc.SetInPlace(this.props.document, "editTitle", this._uniqueId, false);
}
protected createTreeDropTarget = (ele: HTMLDivElement) => {
@@ -185,7 +184,7 @@ export class TreeView extends React.Component<TreeViewProps> {
}
public static makeTextBullet() {
- const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _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-", 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<Doc>([]);
@@ -659,8 +658,7 @@ export class TreeView extends React.Component<TreeViewProps> {
onChildClick: undefined | (() => ScriptField),
ignoreFields: string[] | undefined,
firstLevel: boolean,
- whenActiveChanged: (isActive: boolean) => void
- ) {
+ whenActiveChanged: (isActive: boolean) => void) {
const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
if (viewSpecScript) {
childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
@@ -691,7 +689,7 @@ export class TreeView extends React.Component<TreeViewProps> {
}
const rowWidth = () => panelWidth() - 20;
- return docs.map((child, i) => {
+ return docs.filter(child => child instanceof Doc).map((child, i) => {
const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child);
if (!pair.layout || pair.data instanceof Promise) {
return (null);
@@ -727,13 +725,12 @@ export class TreeView extends React.Component<TreeViewProps> {
const aspect = NumCast(childLayout._nativeWidth, 0) / NumCast(childLayout._nativeHeight, 0);
return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
};
- return !(child instanceof Doc) ? (null) : <TreeView
+ return <TreeView key={child[Id]}
document={pair.layout}
dataDoc={pair.data}
containingCollection={containingCollection}
prevSibling={docs[i]}
treeView={treeView}
- key={child[Id]}
indentDocument={indent}
outdentDocument={!parentCollectionDoc ? undefined : outdent}
onCheckedClick={onCheckedClick}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 67e7c1986..e8c3662aa 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -114,22 +114,13 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
}> {
@computed get layout(): string {
TraceMobx();
- if (!this.layoutDoc) return "<p>awaiting layout</p>";
- // const layout = Cast(this.layoutDoc[StrCast(this.layoutDoc.layoutKey, this.layoutDoc === this.props.Document ? this.props.layoutKey : "layout")], "string"); // bcz: replaced this with below... is it right?
if (this.props.LayoutTemplateString) return this.props.LayoutTemplateString;
+ if (!this.layoutDoc) return "<p>awaiting layout</p>";
+ if (this.props.layoutKey === "layout_keyValue") return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, "layout")], "string");
- if (this.props.layoutKey === "layout_keyValue") {
- return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
- } else
- if (layout === undefined) {
- return this.props.Document.data ?
- "<FieldView {...props} fieldKey='data' />" :
- KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
- } else if (typeof layout === "string") {
- return layout;
- } else {
- return "<p>Loading layout</p>";
- }
+ if (layout === undefined) return this.props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
+ if (typeof layout === "string") return layout;
+ return "<p>Loading layout</p>";
}
get dataDoc() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ff2ce90b7..e92efd708 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1189,7 +1189,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this.endUndoTypingBatch();
Object.values(this._disposers).forEach(disposer => disposer?.());
this._editorView?.destroy();
- FormattedTextBoxComment.Hide();
+ FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
}
_downEvent: any;
@@ -1522,16 +1522,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
+ const selected = this.props.isSelected();
+ const active = this.active();
const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground;
- this.props.isSelected() && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
- if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) {
- setTimeout(() => FormattedTextBoxComment.Hide(), 0);
- }
+ selected && setTimeout(() => 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 = (this.props.isSelected() && !this.layoutDoc._singleLine) || minimal ? -10 : 0;
- const selclass = this.props.isSelected() && !this.layoutDoc._singleLine ? "-selected" : "";
+ const selPad = (selected && !this.layoutDoc._singleLine) || minimal ? -10 : 0;
+ const selclass = selected && !this.layoutDoc._singleLine ? "-selected" : "";
return (
<div className={"formattedTextBox-cont"} ref={this._boxRef}
style={{
@@ -1564,65 +1564,53 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
onMouseUp={this.onMouseUp}
onWheel={this.onPointerWheel}
onPointerEnter={action(() => this._entered = true)}
- onPointerLeave={action((e: React.PointerEvent<HTMLDivElement>) => {
+ onPointerLeave={action(e => {
this._entered = false;
const target = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y);
for (let child: any = target; child; child = child?.parentElement) {
- if (child === this._ref.current!) {
- this._entered = true;
- }
+ child === this._ref.current! && (this._entered = true);
}
})}
onDoubleClick={this.onDoubleClick}
>
<div className={`formattedTextBox-outer`} ref={this._scrollRef}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.active() ? "none" : undefined }}
+ style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !active ? "none" : undefined }}
onScroll={this.onscrolled} onDrop={this.ondrop} >
<div className={minimal ? "formattedTextBox-minimal" : `formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget}
style={{
overflow: this.layoutDoc._singleLine ? "hidden" : undefined,
padding: this.layoutDoc._textBoxPadding ? StrCast(this.layoutDoc._textBoxPadding) :
`${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`,
- pointerEvents: !this.props.active() ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
+ pointerEvents: !active ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
}}
/>
</div>
- {!this.layoutDoc._showSidebar ? (null) : <>
- <div className={"formattedTextBox-sidebar" + (Doc.GetSelectedTool() !== InkTool.None ? "-inking" : "")}
- style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
- {this.sidebarWidthPercent === "0%" ? (null) :
- <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
- PanelHeight={this.active() ? () => 1000 : this.props.PanelHeight}
- PanelWidth={this.sidebarWidth}
- scaleField={this.annotationKey + "-scale"}
- annotationsKey={this.annotationKey}
- isAnnotationOverlay={true}
- 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} />
- }
- </div>
- {this.props.isSelected() ? <div className="formattedTextBox-sidebar-handle" style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 5px))` }} onPointerDown={this.sidebarDown} /> : (null)}
- </>}
+ {!this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) :
+ <div className={"formattedTextBox-sidebar" + (Doc.GetSelectedTool() !== InkTool.None ? "-inking" : "")} style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ PanelHeight={active ? () => 1000 : this.props.PanelHeight}
+ PanelWidth={this.sidebarWidth}
+ scaleField={this.annotationKey + "-scale"}
+ annotationsKey={this.annotationKey}
+ isAnnotationOverlay={true}
+ 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} />
+ </div>}
+ {selected ? <div className="formattedTextBox-sidebar-handle" style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 5px))` }} onPointerDown={this.sidebarDown} /> : (null)}
{!this.layoutDoc._showAudio ? (null) :
<div className="formattedTextBox-dictation" onClick={action(e => this._recording = !this._recording)} >
- <FontAwesomeIcon className="formattedTextBox-audioFont"
- style={{
- color: this._recording ? "red" : "blue",
- transitionDelay: "0.6s",
- opacity: this._recording ? 1 : 0.25,
- }}
- icon={"microphone"} size="sm" />
+ <FontAwesomeIcon className="formattedTextBox-audioFont" style={{ color: this._recording ? "red" : "blue", transitionDelay: "0.6s", opacity: this._recording ? 1 : 0.25, }} icon={"microphone"} size="sm" />
</div>}
</div>
</div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index a37210de6..14bbee1ac 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -143,9 +143,12 @@ export class FormattedTextBoxComment {
public static Hide() {
FormattedTextBoxComment.textBox = undefined;
- FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
- ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.linkDoc = undefined;
+ FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
+ try {
+ ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
+ FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
+ } catch (e) { }
}
public static SetState(textBox: any, start: number, end: number, mark: Mark) {
FormattedTextBoxComment.textBox = textBox;
@@ -228,17 +231,17 @@ export class FormattedTextBoxComment {
if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
try {
ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
+ FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
} catch (e) { }
- FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.tooltipText = document.createElement("div");
FormattedTextBoxComment.tooltipText.style.width = "100%";
FormattedTextBoxComment.tooltipText.style.height = "100%";
FormattedTextBoxComment.tooltipText.style.textOverflow = "ellipsis";
FormattedTextBoxComment.tooltipText.style.cursor = "pointer";
- FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
-
FormattedTextBoxComment.tooltipText.textContent = "URL: " + href;
(FormattedTextBoxComment.tooltipText as any).href = href;
+ FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
+
if (href.startsWith("https://en.wikipedia.org/wiki/")) {
wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500)));
} else {