diff options
| author | bobzel <zzzman@gmail.com> | 2023-05-22 11:25:32 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2023-05-22 11:25:32 -0400 |
| commit | bed3309e1fda6597b2a8fea10ad82cd3a0402051 (patch) | |
| tree | fe599bbdc5fca2c221e1e0f7a60995b7cd39f870 /src/client/views/DocumentButtonBar.tsx | |
| parent | 887a4f7e0fc25fde87b20a5de2e7b0aee561cc78 (diff) | |
| parent | 3d26d5b2654841a9b92f3d66b28d1dc8e36cca6a (diff) | |
merged physics with master
Diffstat (limited to 'src/client/views/DocumentButtonBar.tsx')
| -rw-r--r-- | src/client/views/DocumentButtonBar.tsx | 123 |
1 files changed, 92 insertions, 31 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index f61d147cf..547d844ca 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; -import { action, computed, observable, runInAction, trace } from 'mobx'; +import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; import { RichTextField } from '../../fields/RichTextField'; @@ -11,6 +11,7 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; import { Docs, DocUtils } from '../documents/Documents'; import { DragManager } from '../util/DragManager'; +import { IsFollowLinkScript } from '../util/LinkFollower'; import { SelectionManager } from '../util/SelectionManager'; import { SharingManager } from '../util/SharingManager'; import { undoBatch, UndoManager } from '../util/UndoManager'; @@ -24,10 +25,9 @@ import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from './nodes/DocumentView'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; import { GoogleRef } from './nodes/formattedText/FormattedTextBox'; +import { PinProps } from './nodes/trails'; import { TemplateMenu } from './TemplateMenu'; import React = require('react'); -import { DocumentType } from '../documents/DocumentTypes'; -import { FontIconBox } from './nodes/button/FontIconBox'; const higflyout = require('@hig/flyout'); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -178,7 +178,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV e.preventDefault(); let googleDoc = await Cast(dataDoc.googleDoc, Doc); if (!googleDoc) { - const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, useCors: false }; + const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, data_useCors: false }; googleDoc = Docs.Create.WebDocument(googleDocUrl, options); dataDoc.googleDoc = googleDoc; } @@ -237,12 +237,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV </Tooltip> ); }; + const followLink = IsFollowLinkScript(targetDoc?.onClick); return !targetDoc ? null : ( <Tooltip title={<div className="dash-tooltip">Set onClick to follow primary link</div>}> <div className="documentButtonBar-icon documentButtonBar-follow" - style={{ backgroundColor: targetDoc.isLinkButton ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: targetDoc.isLinkButton ? Colors.BLACK : Colors.WHITE }} - onClick={undoBatch(e => this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, undefined, false)))}> + style={{ backgroundColor: followLink ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: followLink ? Colors.BLACK : Colors.WHITE }} + onClick={undoBatch(e => this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, false)))}> <div className="documentButtonBar-followTypes"> {followBtn( true, @@ -285,12 +286,53 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV </div> ); } + @observable subEndLink = ''; + @computed + get endLinkButton() { + const linkBtn = (pinLayout: boolean, pinContent: boolean, icon: IconProp) => { + const tooltip = `Finish Link and Save ${this.subEndLink} data`; + return !this.view0 ? null : ( + <Tooltip title={<div className="dash-tooltip">{tooltip}</div>}> + <div className="documentButtonBar-pinIcon"> + <FontAwesomeIcon + className="documentdecorations-icon" + style={{ width: 20 }} + key={icon.toString()} + size="sm" + icon={icon} + onPointerEnter={action(e => (this.subEndLink = (pinLayout ? 'Layout' : '') + (pinLayout && pinContent ? ' &' : '') + (pinContent ? ' Content' : '')))} + onPointerLeave={action(e => (this.subEndLink = ''))} + onClick={e => { + this.view0 && + DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.view0.props.Document, true, this.view0, { + pinDocLayout: pinLayout, + pinData: !pinContent ? {} : { poslayoutview: true, dataannos: true, dataview: pinContent }, + } as PinProps); + + e.stopPropagation(); + }} + /> + </div> + </Tooltip> + ); + }; + return !this.view0 ? null : ( + <div className="documentButtonBar-icon documentButtonBar-pin"> + <div className="documentButtonBar-pinTypes"> + {linkBtn(true, false, 'window-maximize')} + {linkBtn(false, true, 'address-card')} + {linkBtn(true, true, 'id-card')} + </div> + <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} /> + </div> + ); + } @observable subPin = ''; @computed get pinButton() { const targetDoc = this.view0?.props.Document; - const pinBtn = (pinDocLayout: boolean, pinDocContent: boolean, icon: IconProp) => { + const pinBtn = (pinLayoutView: boolean, pinContentView: boolean, icon: IconProp) => { const tooltip = `Pin Document and Save ${this.subPin} to trail`; return !tooltip ? null : ( <Tooltip title={<div className="dash-tooltip">{tooltip}</div>}> @@ -304,10 +346,10 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV onPointerEnter={action( e => (this.subPin = - (pinDocLayout ? 'Layout' : '') + - (pinDocLayout && pinDocContent ? ' &' : '') + - (pinDocContent ? ' Content View' : '') + - (pinDocLayout && pinDocContent ? '(shift+alt)' : pinDocLayout ? '(shift)' : pinDocContent ? '(alt)' : '')) + (pinLayoutView ? 'Layout' : '') + + (pinLayoutView && pinContentView ? ' &' : '') + + (pinContentView ? ' Content View' : '') + + (pinLayoutView && pinContentView ? '(shift+alt)' : pinLayoutView ? '(shift)' : pinContentView ? '(alt)' : '')) )} onPointerLeave={action(e => (this.subPin = ''))} onClick={e => { @@ -315,7 +357,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV .views() .filter(v => v) .map(dv => dv!.rootDoc); - TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout, pinDocContent, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null), currentFrame: Cast(docs.lastElement()?.currentFrame, 'number', null) }); + TabDocView.PinDoc(docs, { + pinAudioPlay: true, + pinDocLayout: pinLayoutView, + pinData: { dataview: pinContentView }, + activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null), + currentFrame: Cast(docs.lastElement()?.currentFrame, 'number', null), + }); e.stopPropagation(); }} /> @@ -332,7 +380,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV .views() .filter(v => v) .map(dv => dv!.rootDoc); - TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinDocContent: e.altKey, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) }); + TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) }); e.stopPropagation(); }}> <div className="documentButtonBar-pinTypes"> @@ -363,7 +411,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const targetDoc = this.view0?.props.Document; return !targetDoc ? null : ( <Tooltip title={<div className="dash-tooltip">{`Open Context Menu`}</div>}> - <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onClick={e => this.openContextMenu(e)}> + <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onClick={this.openContextMenu}> <FontAwesomeIcon className="documentdecorations-icon" icon="bars" /> </div> </Tooltip> @@ -425,17 +473,17 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV </Tooltip> ); } - @observable _aliasDown = false; + @observable _embedDown = false; onTemplateButton = action((e: React.PointerEvent): void => { this._tooltipOpen = false; - setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction); + setupMoveUpEvents(this, e, this.onEmbedButtonMoved, emptyFunction, emptyFunction); }); - onAliasButtonMoved = () => { + onEmbedButtonMoved = () => { if (this._dragRef.current) { const dragDocView = this.view0!; const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]); const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - dragData.defaultDropAction = 'alias'; + dragData.defaultDropAction = 'embed'; dragData.canEmbed = true; DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false }); return true; @@ -450,14 +498,14 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const view0 = this.view0; const views = this.props.views(); return !view0 ? null : ( - <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embeddable alias</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom"> + <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom"> <div className="documentButtonBar-linkFlyout" ref={this._dragRef} onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}> <Flyout anchorPoint={anchorPoints.LEFT_TOP} - onOpen={action(() => (this._aliasDown = true))} - onClose={action(() => (this._aliasDown = false))} + onOpen={action(() => (this._embedDown = true))} + onClose={action(() => (this._embedDown = false))} content={ - !this._aliasDown ? null : ( + !this._embedDown ? null : ( <div ref={this._ref}> {' '} <TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} /> @@ -465,7 +513,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV ) }> <div className={'documentButtonBar-linkButton-empty'} ref={this._dragRef} onPointerDown={this.onTemplateButton}> - {<FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" />} + <FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" /> </div> </Flyout> </div> @@ -491,15 +539,32 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV this._showLinkPopup = !this._showLinkPopup; e.stopPropagation(); }; + + @observable _captureEndLinkLayout = false; + @action + captureEndLinkLayout = (e: React.PointerEvent) => { + this._captureEndLinkLayout = !this._captureEndLinkLayout; + }; + @observable _captureEndLinkContent = false; + @action + captureEndLinkContent = (e: React.PointerEvent) => { + this._captureEndLinkContent = !this._captureEndLinkContent; + }; + + @action + captureEndLinkState = (e: React.PointerEvent) => { + this._captureEndLinkContent = this._captureEndLinkLayout = !this._captureEndLinkLayout; + }; + @action toggleTrail = (e: React.PointerEvent) => { const rootView = this.props.views()[0]; const rootDoc = rootView?.rootDoc; if (rootDoc) { - const anchor = rootView.ComponentView?.getAnchor?.(true) ?? rootDoc; + const anchor = rootView.ComponentView?.getAnchor?.(false) ?? rootDoc; const trail = DocCast(anchor.presTrail) ?? Doc.MakeCopy(DocCast(Doc.UserDoc().emptyTrail), true); if (trail !== anchor.presTrail) { - DocUtils.MakeLink({ doc: anchor }, { doc: trail }, 'link trail'); + DocUtils.MakeLink(anchor, trail, { link_relationship: 'link trail' }); anchor.presTrail = trail; } Doc.ActivePresentation = trail; @@ -524,7 +589,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV <LinkPopup key="popup" showPopup={this._showLinkPopup} - linkCreated={link => (link.linkDisplay = !this.props.views().lastElement()?.rootDoc.isLinkButton)} + linkCreated={link => (link.layout_linkDisplay = !IsFollowLinkScript(this.props.views().lastElement()?.rootDoc.onClick))} linkCreateAnchor={() => this.props.views().lastElement()?.ComponentView?.getAnchor?.(true)} linkFrom={() => this.props.views().lastElement()?.rootDoc} /> @@ -533,11 +598,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV <div className="documentButtonBar-button">{this.linkButton}</div> )} - {(DocumentLinksButton.StartLink || Doc.UserDoc()['documentLinksButton-fullMenu']) && DocumentLinksButton.StartLink !== doc ? ( - <div className="documentButtonBar-button"> - <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} /> - </div> - ) : null} + {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== doc ? <div className="documentButtonBar-button">{this.endLinkButton} </div> : null} { Doc.noviceMode ? null : <div className="documentButtonBar-button">{this.templateButton}</div> /*<div className="documentButtonBar-button"> {this.metadataButton} </div> */ |
