diff options
Diffstat (limited to 'src/client/views/collections/collectionLinear/CollectionLinearView.tsx')
| -rw-r--r-- | src/client/views/collections/collectionLinear/CollectionLinearView.tsx | 296 |
1 files changed, 166 insertions, 130 deletions
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index c31267e87..0d7d67dd8 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -7,27 +7,23 @@ import { Doc, HeightSym, Opt, WidthSym } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnTrue, Utils } from '../../../../Utils'; -import { DocUtils } from '../../../documents/Documents'; -import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; -import { DocumentManager } from "../../../util/DocumentManager"; +import { CollectionViewType } from '../../../documents/DocumentTypes'; +import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; import { Colors, Shadows } from '../../global/globalEnums'; -import { AudioBox } from '../../nodes/AudioBox'; import { DocumentLinksButton } from '../../nodes/DocumentLinksButton'; import { DocumentView } from '../../nodes/DocumentView'; import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup'; import { StyleProp } from '../../StyleProvider'; import { CollectionStackedTimeline } from '../CollectionStackedTimeline'; import { CollectionSubView } from '../CollectionSubView'; -import { CollectionViewType } from '../CollectionView'; -import "./CollectionLinearView.scss"; - +import './CollectionLinearView.scss'; /** - * CollectionLinearView is the class for rendering the horizontal collection + * CollectionLinearView is the class for rendering the horizontal collection * of documents, it useful for horizontal menus. It can either be expandable - * or not using the linearViewExpandable field. + * or not using the linearViewExpandable field. * It is used in the following locations: * - It is used in the popup menu on the bottom left (see docButtons() in MainView.tsx) * - It is used for the context sensitive toolbar at the top (see contMenuButtons() in CollectionMenu.tsx) @@ -48,45 +44,47 @@ export class CollectionLinearView extends CollectionSubView() { } componentDidMount() { - this._widthDisposer = reaction(() => 5 + (this.layoutDoc.linearViewIsExpanded ? this.childDocs.length * (this.rootDoc[HeightSym]()) : 10), + this._widthDisposer = reaction( + () => 5 + (this.layoutDoc.linearViewIsExpanded ? this.childDocs.length * this.rootDoc[HeightSym]() : 10), width => this.childDocs.length && (this.layoutDoc._width = width), { fireImmediately: true } ); this._selectedDisposer = reaction( () => NumCast(this.layoutDoc.selectedIndex), - (i) => runInAction(() => { - this._selectedIndex = i; - let selected: any = undefined; - this.childLayoutPairs.map(async (pair, ind) => { - const isSelected = this._selectedIndex === ind; - if (isSelected) { - selected = pair; - } - else { - ScriptCast(pair.layout.proto?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log); + i => + runInAction(() => { + this._selectedIndex = i; + let selected: any = undefined; + this.childLayoutPairs.map(async (pair, ind) => { + const isSelected = this._selectedIndex === ind; + if (isSelected) { + selected = pair; + } else { + ScriptCast(pair.layout.proto?.onPointerUp)?.script.run({ this: pair.layout.proto }, console.log); + } + }); + if (selected && selected.layout) { + ScriptCast(selected.layout.proto?.onPointerDown)?.script.run({ this: selected.layout.proto }, console.log); } - }); - if (selected && selected.layout) { - ScriptCast(selected.layout.proto?.onPointerDown)?.script.run({ this: selected.layout.proto }, console.log); - } - }), + }), { fireImmediately: true } ); } - protected createDashEventsTarget = (ele: HTMLDivElement | null) => { //used for stacking and masonry view + protected createDashEventsTarget = (ele: HTMLDivElement | null) => { + //used for stacking and masonry view this._dropDisposer && this._dropDisposer(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } - } + }; dimension = () => NumCast(this.rootDoc._height); // 2 * the padding getTransform = (ele: Opt<HTMLDivElement>) => { if (!ele) return Transform.Identity(); const { scale, translateX, translateY } = Utils.GetScreenTransform(ele); return new Transform(-translateX, -translateY, 1); - } + }; @action exitLongLinks = () => { @@ -99,28 +97,27 @@ export class CollectionLinearView extends CollectionSubView() { } DocumentLinksButton.StartLink = undefined; DocumentLinksButton.StartLinkView = undefined; - } + }; @action changeDescriptionSetting = () => { if (LinkDescriptionPopup.showDescriptions) { - if (LinkDescriptionPopup.showDescriptions === "ON") { - LinkDescriptionPopup.showDescriptions = "OFF"; + if (LinkDescriptionPopup.showDescriptions === 'ON') { + LinkDescriptionPopup.showDescriptions = 'OFF'; LinkDescriptionPopup.descriptionPopup = false; } else { - LinkDescriptionPopup.showDescriptions = "ON"; + LinkDescriptionPopup.showDescriptions = 'ON'; } } else { - LinkDescriptionPopup.showDescriptions = "OFF"; + LinkDescriptionPopup.showDescriptions = 'OFF'; LinkDescriptionPopup.descriptionPopup = false; } - } + }; myContextMenu = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); - } - + }; getDisplayDoc = (doc: Doc, preview: boolean = false) => { const nested = doc._viewType === CollectionViewType.Linear; @@ -129,44 +126,50 @@ export class CollectionLinearView extends CollectionSubView() { let dref: Opt<HTMLDivElement>; const docXf = () => this.getTransform(dref); // const scalable = pair.layout.onClick || pair.layout.onDragStart; - return hidden ? (null) : <div className={preview ? "preview" : `collectionLinearView-docBtn`} key={doc[Id]} ref={r => dref = r || undefined} - style={{ - pointerEvents: "all", - width: nested ? undefined : NumCast(doc._width), - height: nested ? undefined : NumCast(doc._height), - marginLeft: !nested ? 2.5 : 0, - marginRight: !nested ? 2.5 : 0, - // width: NumCast(pair.layout._width), - // height: NumCast(pair.layout._height), - }} > - <DocumentView - Document={doc} - isContentActive={this.props.isContentActive} - isDocumentActive={returnTrue} - addDocument={this.props.addDocument} - moveDocument={this.props.moveDocument} - addDocTab={this.props.addDocTab} - pinToPres={emptyFunction} - rootSelected={this.props.isSelected} - removeDocument={this.props.removeDocument} - ScreenToLocalTransform={docXf} - PanelWidth={nested ? doc[WidthSym] : this.dimension} - PanelHeight={nested || doc._height ? doc[HeightSym] : this.dimension} - renderDepth={this.props.renderDepth + 1} - dontRegisterView={BoolCast(this.rootDoc.childDontRegisterViews)} - focus={emptyFunction} - styleProvider={this.props.styleProvider} - docViewPath={returnEmptyDoclist} - whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} - docFilters={this.props.docFilters} - docRangeFilters={this.props.docRangeFilters} - searchFilterDocs={this.props.searchFilterDocs} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} - hideResizeHandles={true} /> - </div>; - } + return hidden ? null : ( + <div + className={preview ? 'preview' : `collectionLinearView-docBtn`} + key={doc[Id]} + ref={r => (dref = r || undefined)} + style={{ + pointerEvents: 'all', + width: nested ? undefined : NumCast(doc._width), + height: nested ? undefined : NumCast(doc._height), + marginLeft: !nested ? 2.5 : 0, + marginRight: !nested ? 2.5 : 0, + // width: NumCast(pair.layout._width), + // height: NumCast(pair.layout._height), + }}> + <DocumentView + Document={doc} + isContentActive={this.props.isContentActive} + isDocumentActive={returnTrue} + addDocument={this.props.addDocument} + moveDocument={this.props.moveDocument} + addDocTab={this.props.addDocTab} + pinToPres={emptyFunction} + rootSelected={this.props.isSelected} + removeDocument={this.props.removeDocument} + ScreenToLocalTransform={docXf} + PanelWidth={nested ? doc[WidthSym] : this.dimension} + PanelHeight={nested || doc._height ? doc[HeightSym] : this.dimension} + renderDepth={this.props.renderDepth + 1} + dontRegisterView={BoolCast(this.rootDoc.childDontRegisterViews)} + focus={emptyFunction} + styleProvider={this.props.styleProvider} + docViewPath={returnEmptyDoclist} + whenChildContentsActiveChanged={emptyFunction} + bringToFront={emptyFunction} + docFilters={this.props.docFilters} + docRangeFilters={this.props.docRangeFilters} + searchFilterDocs={this.props.searchFilterDocs} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + hideResizeHandles={true} + /> + </div> + ); + }; render() { const guid = Utils.GenerateGuid(); // Generate a unique ID to use as the label @@ -178,66 +181,99 @@ export class CollectionLinearView extends CollectionSubView() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const icon: string = StrCast(this.props.Document.icon); // Menu opener toggle - const menuOpener = <label htmlFor={`${guid}`} - style={{ - boxShadow: floating ? Shadows.STANDARD_SHADOW : undefined, - color: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.BLACK, - backgroundColor: backgroundColor === color ? "black" : BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.LIGHT_GRAY - }} - onPointerDown={e => e.stopPropagation()} > - <div className="collectionLinearView-menuOpener"> - {BoolCast(this.layoutDoc.linearViewIsExpanded) ? icon ? icon : <FontAwesomeIcon icon={"minus"} /> : icon ? icon : <FontAwesomeIcon icon={"plus"} />} - </div> - </label>; - - return <div className={`collectionLinearView-outer ${this.layoutDoc.linearViewSubMenu}`} style={{ backgroundColor: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : "transparent" }}> - <div className="collectionLinearView" ref={this.createDashEventsTarget} - onContextMenu={this.myContextMenu} > - {!expandable ? (null) : <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close" : "Open"}</div></>} placement="top"> - {menuOpener} - </Tooltip>} - <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle} - onChange={action(() => this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> - - <div className="collectionLinearView-content" - style={{ - height: this.dimension(), - flexDirection: flexDir, - gap: flexGap - }}> - {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))} - </div> - {!DocumentLinksButton.StartLink || this.layoutDoc !== CurrentUserUtils.MyDockedBtns ? null : - <span className="bottomPopup-background" style={{ pointerEvents: "all" }} - onPointerDown={e => e.stopPropagation()} > - <span className="bottomPopup-text" > - Creating link from: <b>{DocumentLinksButton.AnnotationId ? "Annotation in " : " "} {StrCast(DocumentLinksButton.StartLink.title).length < 51 ? DocumentLinksButton.StartLink.title : StrCast(DocumentLinksButton.StartLink.title).slice(0, 50) + '...'}</b> - </span> + const menuOpener = ( + <label + htmlFor={`${guid}`} + style={{ + boxShadow: floating ? Shadows.STANDARD_SHADOW : undefined, + color: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.BLACK, + backgroundColor: backgroundColor === color ? 'black' : BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.LIGHT_GRAY, + }} + onPointerDown={e => e.stopPropagation()}> + <div className="collectionLinearView-menuOpener">{BoolCast(this.layoutDoc.linearViewIsExpanded) ? icon ? icon : <FontAwesomeIcon icon={'minus'} /> : icon ? icon : <FontAwesomeIcon icon={'plus'} />}</div> + </label> + ); - <Tooltip title={<><div className="dash-tooltip">{"Toggle description pop-up"} </div></>} placement="top"> - <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}> - Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"} - </span> + return ( + <div className={`collectionLinearView-outer ${this.layoutDoc.linearViewSubMenu}`} style={{ backgroundColor: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : 'transparent' }}> + <div className="collectionLinearView" ref={this.createDashEventsTarget} onContextMenu={this.myContextMenu}> + {!expandable ? null : ( + <Tooltip + title={ + <> + <div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? 'Close' : 'Open'}</div> + </> + } + placement="top"> + {menuOpener} </Tooltip> + )} + <input + id={`${guid}`} + type="checkbox" + checked={BoolCast(this.props.Document.linearViewIsExpanded)} + ref={this.addMenuToggle} + onChange={action(() => (this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked))} + /> - <Tooltip title={<><div className="dash-tooltip">Exit linking mode</div></>} placement="top"> - <span className="bottomPopup-exit" onClick={this.exitLongLinks}> - Stop + <div + className="collectionLinearView-content" + style={{ + height: this.dimension(), + flexDirection: flexDir, + gap: flexGap, + }}> + {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))} + </div> + {!DocumentLinksButton.StartLink || this.layoutDoc !== Doc.MyDockedBtns ? null : ( + <span className="bottomPopup-background" style={{ pointerEvents: 'all' }} onPointerDown={e => e.stopPropagation()}> + <span className="bottomPopup-text"> + Creating link from:{' '} + <b> + {(DocumentLinksButton.AnnotationId ? 'Annotation in ' : ' ') + + (StrCast(DocumentLinksButton.StartLink.title).length < 51 ? DocumentLinksButton.StartLink.title : StrCast(DocumentLinksButton.StartLink.title).slice(0, 50) + '...')} + </b> </span> - </Tooltip> - </span>} - {!CollectionStackedTimeline.CurrentlyPlaying || !CollectionStackedTimeline.CurrentlyPlaying.length || this.layoutDoc !== CurrentUserUtils.MyDockedBtns ? (null) : - <span className="bottomPopup-background"> - <span className="bottomPopup-text"> - Currently playing: - {CollectionStackedTimeline.CurrentlyPlaying.map((clip, i) => - <span className="audio-title" onPointerDown={() => DocumentManager.Instance.jumpToDocument(clip, true, undefined, [])}> - {clip.title + (i === CollectionStackedTimeline.CurrentlyPlaying.length - 1 ? "" : ",")} - </span>)} - </span> - </span>} + <Tooltip + title={ + <> + <div className="dash-tooltip">{'Toggle description pop-up'} </div> + </> + } + placement="top"> + <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}> + Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : 'ON'} + </span> + </Tooltip> + + <Tooltip + title={ + <> + <div className="dash-tooltip">Exit linking mode</div> + </> + } + placement="top"> + <span className="bottomPopup-exit" onClick={this.exitLongLinks}> + Stop + </span> + </Tooltip> + </span> + )} + {!CollectionStackedTimeline.CurrentlyPlaying || !CollectionStackedTimeline.CurrentlyPlaying.length || this.layoutDoc !== Doc.MyDockedBtns ? null : ( + <span className="bottomPopup-background"> + <span className="bottomPopup-text"> + Currently playing: + {CollectionStackedTimeline.CurrentlyPlaying.map((clip, i) => ( + <span className="audio-title" onPointerDown={() => DocumentManager.Instance.jumpToDocument(clip, true, undefined, [])}> + {clip.title + (i === CollectionStackedTimeline.CurrentlyPlaying.length - 1 ? '' : ',')} + </span> + ))} + </span> + </span> + )} + </div> </div> - </div>; + ); } -}
\ No newline at end of file +} |
