diff options
Diffstat (limited to 'src')
6 files changed, 81 insertions, 73 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 78ab2b3d4..7c81d92d4 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -151,13 +151,10 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>() const indocs = doc instanceof Doc ? [doc] : doc; const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin); if (docs.length) { - setTimeout(() => - docs.map(doc => { - // this allows 'addDocument' to see the annotationOn field in order to create a pushin - Doc.SetInPlace(doc, 'followLinkToggle', undefined, true); - doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true); - }) - ); + docs.map(doc => { + Doc.SetInPlace(doc, 'followLinkToggle', undefined, true); + doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true); + }); const targetDataDoc = this.dataDoc; const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]); const toRemove = value.filter(v => docs.includes(v)); diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index abb4b6bc6..32f6207ed 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -9,54 +9,58 @@ import { DragManager } from '../../util/DragManager'; import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProvider'; -import "./CollectionCarouselView.scss"; +import './CollectionCarouselView.scss'; import { CollectionSubView } from './CollectionSubView'; @observer export class CollectionCarouselView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; - componentWillUnmount() { this._dropDisposer?.(); } + componentWillUnmount() { + this._dropDisposer?.(); + } - protected createDashEventsTarget = (ele: HTMLDivElement | null) => { //used for stacking and masonry view + protected createDashEventsTarget = (ele: HTMLDivElement | null) => { + //used for stacking and masonry view this._dropDisposer?.(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } - } + }; advance = (e: React.MouseEvent) => { e.stopPropagation(); this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) + 1) % this.childLayoutPairs.length; - } + }; goback = (e: React.MouseEvent) => { e.stopPropagation(); this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length; - } - captionStyleProvider = (doc: (Doc | undefined), captionProps: Opt<DocumentViewProps>, property: string): any => { + }; + captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<DocumentViewProps>, property: string): any => { // first look for properties on the document in the carousel, then fallback to properties on the container - const childValue = doc?.["caption-" + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined; + const childValue = doc?.['caption-' + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined; return childValue ?? this.props.styleProvider?.(this.layoutDoc, captionProps, property); - } + }; panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._showCaption) ? 50 : 0); onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); @computed get content() { const index = NumCast(this.layoutDoc._itemIndex); const curDoc = this.childLayoutPairs?.[index]; - const captionProps = { ...OmitKeys(this.props, ["setHeight",]).omit, fieldKey: "caption" }; - const marginX = NumCast(this.layoutDoc["caption-xMargin"]); - const marginY = NumCast(this.layoutDoc["caption-yMargin"]); + const captionProps = { ...OmitKeys(this.props, ['setHeight']).omit, fieldKey: 'caption' }; + const marginX = NumCast(this.layoutDoc['caption-xMargin']); + const marginY = NumCast(this.layoutDoc['caption-yMargin']); const showCaptions = StrCast(this.layoutDoc._showCaption); - return !(curDoc?.layout instanceof Doc) ? (null) : + return !(curDoc?.layout instanceof Doc) ? null : ( <> <div className="collectionCarouselView-image" key="image"> - <DocumentView {...OmitKeys(this.props, ["setHeight", "NativeWidth", "NativeHeight", "childLayoutTemplate", "childLayoutString"]).omit} + <DocumentView + {...OmitKeys(this.props, ['setHeight', 'NativeWidth', 'NativeHeight', 'childLayoutTemplate', 'childLayoutString']).omit} onDoubleClick={this.onContentDoubleClick} onClick={this.onContentClick} hideCaptions={showCaptions ? true : false} renderDepth={this.props.renderDepth + 1} - ContainingCollectionView={this} + ContainingCollectionView={this.props.CollectionView} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} Document={curDoc.layout} @@ -65,40 +69,46 @@ export class CollectionCarouselView extends CollectionSubView() { bringToFront={returnFalse} /> </div> - <div className="collectionCarouselView-caption" key="caption" + <div + className="collectionCarouselView-caption" + key="caption" style={{ - display: showCaptions ? undefined : "none", + display: showCaptions ? undefined : 'none', borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding), - marginRight: marginX, marginLeft: marginX, - width: `calc(100% - ${marginX * 2}px)` + marginRight: marginX, + marginLeft: marginX, + width: `calc(100% - ${marginX * 2}px)`, }}> - <FormattedTextBox key={index} {...captionProps} - fieldKey={showCaptions} - styleProvider={this.captionStyleProvider} - Document={curDoc.layout} - DataDoc={undefined} /> + <FormattedTextBox key={index} {...captionProps} fieldKey={showCaptions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} /> </div> - </>; + </> + ); } @computed get buttons() { - return <> - <div key="back" className="carouselView-back" onClick={this.goback}> - <FontAwesomeIcon icon={"chevron-left"} size={"2x"} /> - </div> - <div key="fwd" className="carouselView-fwd" onClick={this.advance}> - <FontAwesomeIcon icon={"chevron-right"} size={"2x"} /> - </div> - </>; + return ( + <> + <div key="back" className="carouselView-back" onClick={this.goback}> + <FontAwesomeIcon icon={'chevron-left'} size={'2x'} /> + </div> + <div key="fwd" className="carouselView-fwd" onClick={this.advance}> + <FontAwesomeIcon icon={'chevron-right'} size={'2x'} /> + </div> + </> + ); } render() { - return <div className="collectionCarouselView-outer" ref={this.createDashEventsTarget} - style={{ - background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), - color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color), - }}> - {this.content} - {this.props.Document._chromeHidden ? (null) : this.buttons} - </div>; + return ( + <div + className="collectionCarouselView-outer" + ref={this.createDashEventsTarget} + style={{ + background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), + color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color), + }}> + {this.content} + {this.props.Document._chromeHidden ? null : this.buttons} + </div> + ); } -}
\ No newline at end of file +} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index acf59b5da..2f495d55c 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -639,6 +639,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection return sections.map((section, i) => (this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0))); } + return35 = () => 35; @computed get buttonMenu() { const menuDoc: Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null); // TODO:glr Allow support for multiple buttons @@ -660,8 +661,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection rootSelected={this.props.isSelected} removeDocument={this.props.removeDocument} ScreenToLocalTransform={Transform.Identity} - PanelWidth={() => 35} - PanelHeight={() => 35} + PanelWidth={this.return35} + PanelHeight={this.return35} renderDepth={this.props.renderDepth} focus={emptyFunction} styleProvider={this.props.styleProvider} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5cf4cb31f..695d500e9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -12,7 +12,7 @@ import { ObjectField } from '../../../../fields/ObjectField'; import { RichTextField } from '../../../../fields/RichTextField'; import { listSpec } from '../../../../fields/Schema'; import { ScriptField } from '../../../../fields/ScriptField'; -import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { TraceMobx } from '../../../../fields/util'; import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; @@ -269,7 +269,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const dispTime = NumCast(doc._timecodeToShow, -1); const endTime = NumCast(doc._timecodeToHide, dispTime + 1.5); const curTime = NumCast(this.Document._currentTimecode, -1); - return dispTime === -1 || (curTime - dispTime >= -1e-4 && curTime <= endTime); + return dispTime === -1 || curTime === -1 || (curTime - dispTime >= -1e-4 && curTime <= endTime); } @action @@ -1344,15 +1344,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection case OpenWhere.inParent: return this.props.addDocument?.(doc) || false; case OpenWhere.inParentFromScreen: + const docContext = DocCast((doc instanceof Doc ? doc : doc?.[0])?.context); return ( - this.props.addDocument?.( + (this.props.addDocument?.( (doc instanceof Doc ? [doc] : doc).map(doc => { const pt = this.getTransform().transformPoint(NumCast(doc.x), NumCast(doc.y)); doc.x = pt[0]; doc.y = pt[1]; return doc; }) - ) || false + ) && + (!docContext || this.props.removeDocument?.(docContext))) || + false ); case OpenWhere.inPlace: if (this.layoutDoc.isInPlaceContainer) { @@ -1747,7 +1750,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection doc.y = scr?.[1]; }); this.props.addDocTab(childDocs as any as Doc, OpenWhere.inParentFromScreen); - this.props.ContainingCollectionView?.removeDocument(this.props.Document); }; @undoBatch @@ -1766,7 +1768,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection toggleNativeDimensions = () => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight); onContextMenu = (e: React.MouseEvent) => { - if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return; + if (this.props.isAnnotationOverlay || !ContextMenu.Instance) return; const appearance = ContextMenu.Instance.findByDescription('Appearance...'); const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : []; @@ -1786,7 +1788,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection }); appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, { pinViewport: MarqueeView.CurViewBounds(this.rootDoc, this.props.PanelWidth(), this.props.PanelHeight()) }), icon: 'map-pin' }); //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" }); - this.props.ContainingCollectionView && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' }); + appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' }); this.props.Document._isGroup && this.Document.transcription && appearanceItems.push({ description: 'Ink to text', event: () => this.transcribeStrokes(false), icon: 'font' }); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index dcbadc5f3..0b7854926 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -433,25 +433,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque @action collection = (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => { const selected = this.marqueeSelect(false); + const activeFrame = selected.reduce((v, d) => v ?? Cast(d._activeFrame, 'number', null), undefined as number | undefined); if (e instanceof KeyboardEvent ? 'cg'.includes(e.key) : true) { - selected.map( - action(d => { - const dx = NumCast(d.x); - const dy = NumCast(d.y); - delete d.x; - delete d.y; - delete d.activeFrame; - delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection - delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection - d.x = dx - this.Bounds.left - this.Bounds.width / 2; - d.y = dy - this.Bounds.top - this.Bounds.height / 2; - return d; - }) - ); this.props.removeDocument?.(selected); } - // TODO: nda - this is the code to actually get a new grouped collection + const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === 't' ? Docs.Create.StackingDocument : undefined, group); + newCollection._panX = this.Bounds.left + this.Bounds.width / 2; + newCollection._panY = this.Bounds.top + this.Bounds.height / 2; + newCollection._currentFrame = activeFrame; this.props.addDocument?.(newCollection); this.props.selectDocuments([newCollection]); MarqueeOptionsMenu.Instance.fadeOut(true); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 80832c9be..619c59f0e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1612,7 +1612,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps onBlur = (e: any) => { if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { + const stordMarks = this._editorView?.state.storedMarks?.slice(); this.autoLink(); + if (this._editorView?.state.tr) { + const tr = stordMarks?.reduce((tr, m) => { + tr.addStoredMark(m); + return tr; + }, this._editorView.state.tr); + tr && this._editorView.dispatch(tr); + } } FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined); if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) { |