diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/DropConverter.ts | 9 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 111 | ||||
-rw-r--r-- | src/client/views/nodes/FieldView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/nodes/FontIconBox.tsx | 19 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 10 |
5 files changed, 49 insertions, 106 deletions
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 5543edf78..03d8ac953 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -15,16 +15,15 @@ export function makeTemplate(doc: Doc): boolean { let any = false; docs.forEach(d => { if (!StrCast(d.title).startsWith("-")) { - any = true; - Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc)); + any = Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc)) || any; } else if (d.type === DocumentType.COL || d.data instanceof RichTextField) { any = makeTemplate(d) || any; } }); if (layoutDoc[fieldKey] instanceof RichTextField) { - layoutDoc._textTemplate = ComputedField.MakeFunction("copyField(this.data)", { this: Doc.name }); - layoutDoc.isTemplateForField = "data"; - any = true; + if (!StrCast(layoutDoc.title).startsWith("-")) { + any = Doc.MakeMetadataFieldTemplate(layoutDoc, Doc.GetProto(layoutDoc)); + } } return any; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8b0f34bdf..7c4391ec0 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,30 +1,25 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; import { faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, reaction, runInAction } from "mobx"; +import { action, computed, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCastAsync } from "../../new_fields/Doc"; +import { Doc } from "../../new_fields/Doc"; import { PositionDocument } from '../../new_fields/documentSchemas'; -import { List } from "../../new_fields/List"; import { ObjectField } from '../../new_fields/ObjectField'; -import { Cast, NumCast, StrCast } from "../../new_fields/Types"; +import { ScriptField } from '../../new_fields/ScriptField'; +import { Cast, StrCast } from "../../new_fields/Types"; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { Utils } from "../../Utils"; -import { Docs, DocUtils } from "../documents/Documents"; -import { DocumentManager } from "../util/DocumentManager"; +import { DocUtils } from "../documents/Documents"; +import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch, UndoManager } from "../util/UndoManager"; -import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; -import { CollectionView } from "./collections/CollectionView"; import { DocumentButtonBar } from './DocumentButtonBar'; import './DocumentDecorations.scss'; import { DocumentView } from "./nodes/DocumentView"; -import { FieldView } from "./nodes/FieldView"; import { IconBox } from "./nodes/IconBox"; import React = require("react"); -import { DocumentType } from '../documents/DocumentTypes'; -import { ScriptField } from '../../new_fields/ScriptField'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -51,17 +46,13 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> private _titleHeight = 20; private _downX = 0; private _downY = 0; - private _iconDoc?: Doc = undefined; private _resizeUndo?: UndoManager.Batch; private _radiusDown = [0, 0]; @observable private _accumulatedTitle = ""; - @observable private _minimizedX = 0; - @observable private _minimizedY = 0; @observable private _titleControlString: string = "#title"; @observable private _edtingTitle = false; @observable private _hidden = false; @observable private _opacity = 1; - @observable private _removeIcon = false; @observable public Interacting = false; @observable public pushIcon: IconProp = "arrow-alt-circle-up"; @@ -245,15 +236,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onMinimizeDown = (e: React.PointerEvent): void => { e.stopPropagation(); - this._iconDoc = undefined; if (e.button === 0) { - this._downX = e.pageX; - this._downY = e.pageY; - this._removeIcon = false; - const selDoc = SelectionManager.SelectedDocuments()[0]; - const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); - this._minimizedX = selDocPos[0] + 12; - this._minimizedY = selDocPos[1] + 12; document.removeEventListener("pointermove", this.onMinimizeMove); document.addEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); @@ -266,20 +249,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> e.stopPropagation(); if (Math.abs(e.pageX - this._downX) > Utils.DRAG_THRESHOLD || Math.abs(e.pageY - this._downY) > Utils.DRAG_THRESHOLD) { - const selDoc = SelectionManager.SelectedDocuments()[0]; - const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); - const snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20; - this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX; - this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY; - const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - - if (selectedDocs.length > 1) { - this._iconDoc = this._iconDoc ? this._iconDoc : this.createIcon(SelectionManager.SelectedDocuments(), CollectionView.LayoutString("")); - this.moveIconDoc(this._iconDoc); - } else { - this.getIconDoc(selectedDocs[0]).then(icon => icon && this.moveIconDoc(this._iconDoc = icon)); - } - this._removeIcon = snapped; + document.removeEventListener("pointermove", this.onMinimizeMove); + document.removeEventListener("pointerup", this.onMinimizeUp); } } @undoBatch @@ -290,59 +261,19 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.removeEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - if (this._iconDoc && selectedDocs.length === 1 && this._removeIcon) { - selectedDocs[0].props.removeDocument && selectedDocs[0].props.removeDocument(this._iconDoc); - } - if (!this._removeIcon && selectedDocs.length === 1) { // if you click on the top-left button when just 1 doc is selected, then collapse it. not sure why we don't do it for multiple selections - this.getIconDoc(selectedDocs[0]).then(async icon => { - const minimizedDoc = await Cast(selectedDocs[0].props.Document.minimizedDoc, Doc); - if (minimizedDoc) { - const scrpt = selectedDocs[0].props.ScreenToLocalTransform().scale(selectedDocs[0].props.ContentScaling()).inverse().transformPoint( - NumCast(minimizedDoc.x) - NumCast(selectedDocs[0].Document.x), NumCast(minimizedDoc.y) - NumCast(selectedDocs[0].Document.y)); - SelectionManager.DeselectAll(); - DocumentManager.Instance.animateBetweenPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)); - } - }); - } - this._removeIcon = false; - } - runInAction(() => this._minimizedX = this._minimizedY = 0); - } - - @undoBatch - @action createIcon = (selected: DocumentView[], layoutString: string): Doc => { - const doc = selected[0].props.Document; - const iconDoc = Docs.Create.IconDocument(layoutString); - iconDoc.isButton = true; - - IconBox.AutomaticTitle(iconDoc); - //iconDoc.proto![this._fieldKey] = selected.length > 1 ? "collection" : undefined; - iconDoc._width = Number(MINIMIZED_ICON_SIZE); - iconDoc._height = Number(MINIMIZED_ICON_SIZE); - iconDoc.x = NumCast(doc.x); - iconDoc.y = NumCast(doc.y) - 24; - iconDoc.maximizedDocs = new List<Doc>(selected.map(s => s.props.Document)); - selected.length === 1 && (doc.minimizedDoc = iconDoc); - selected[0].props.addDocument && selected[0].props.addDocument(iconDoc); - return iconDoc; - } - @action - public getIconDoc = async (docView: DocumentView): Promise<Doc | undefined> => { - const doc = docView.props.Document; - let iconDoc: Doc | undefined = await Cast(doc.minimizedDoc, Doc); - - if (!iconDoc || !DocumentManager.Instance.getDocumentView(iconDoc)) { - const layout = StrCast(doc.layout, FieldView.LayoutString(DocumentView, "")); - iconDoc = this.createIcon([docView], layout); + selectedDocs.map(dv => { + const layoutKey = Cast(dv.props.Document.layoutKey, "string", null); + const collapse = layoutKey !== "layout_icon"; + if (collapse) { + if (layoutKey) dv.props.Document.deiconifyLayout = layoutKey.replace("layout_", ""); + dv.setCustomView(collapse, "icon"); + } else { + const deiconifyLayout = Cast(dv.props.Document.deiconifyLayout, "string", null); + dv.setCustomView(deiconifyLayout ? true : false, deiconifyLayout); + dv.props.Document.deiconifyLayout = undefined; + } + }); } - return iconDoc; - } - moveIconDoc(iconDoc: Doc) { - const selView = SelectionManager.SelectedDocuments()[0]; - const where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()). - transformPoint(this._minimizedX - 12, this._minimizedY - 12); - iconDoc.x = where[0] + NumCast(selView.props.Document.x); - iconDoc.y = where[1] + NumCast(selView.props.Document.y); } @action @@ -578,8 +509,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> }}> {minimizeIcon} - {/* <RichTextMenu /> */} - {this._edtingTitle ? <input ref={this._keyinput} className="title" type="text" name="dynbox" value={this._accumulatedTitle} onBlur={e => this.titleBlur(true)} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> : <div className="title" onPointerDown={this.onTitleDown} ><span>{`${this.selectionTitle}`}</span></div>} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 4904ee5c3..dbbb76f83 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -72,9 +72,9 @@ export class FieldView extends React.Component<FieldViewProps> { // else if (field instanceof RichTextField) { // return <FormattedTextBox {...this.props} />; // } - else if (field instanceof ImageField) { - return <ImageBox {...this.props} />; - } + // else if (field instanceof ImageField) { + // return <ImageBox {...this.props} />; + // } // else if (field instaceof PresBox) { // return <PresBox {...this.props} />; // } diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 2433251b3..a191ac4f4 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -5,10 +5,11 @@ import { createSchema, makeInterface } from '../../../new_fields/Schema'; import { DocComponent } from '../DocComponent'; import './FontIconBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; -import { StrCast } from '../../../new_fields/Types'; +import { StrCast, Cast } from '../../../new_fields/Types'; import { Utils } from "../../../Utils"; import { runInAction, observable, reaction, IReactionDisposer } from 'mobx'; import { Doc } from '../../../new_fields/Doc'; +import { ContextMenu } from '../ContextMenu'; const FontIconSchema = createSchema({ icon: "string" }); @@ -32,13 +33,25 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>( } }, { fireImmediately: true }); } + + showTemplate = (): void => { + const dragFactory = Cast(this.props.Document.dragFactory, Doc, null); + dragFactory && this.props.addDocTab(dragFactory, undefined, "onRight"); + } + + specificContextMenu = (): void => { + const cm = ContextMenu.Instance; + cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" }); + } + componentWillUnmount() { - this._backgroundReaction && this._backgroundReaction(); + this._backgroundReaction?.(); } + render() { const referenceDoc = (this.props.Document.dragFactory instanceof Doc ? this.props.Document.dragFactory : this.props.Document); const referenceLayout = Doc.Layout(referenceDoc); - return <button className="fontIconBox-outerDiv" title={StrCast(this.props.Document.title)} ref={this._ref} + return <button className="fontIconBox-outerDiv" title={StrCast(this.props.Document.title)} ref={this._ref} onContextMenu={this.specificContextMenu} style={{ background: StrCast(referenceLayout.backgroundColor), boxShadow: this.props.Document.ischecked ? `4px 4px 12px black` : undefined diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 113bb19f6..0d97c3029 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1,7 +1,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faEdit, faSmile, faTextHeight, faUpload } from '@fortawesome/free-solid-svg-icons'; import { isEqual } from "lodash"; -import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx"; +import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace, _allowStateChangesInsideComputed } from "mobx"; import { observer } from "mobx-react"; import { baseKeymap } from "prosemirror-commands"; import { history } from "prosemirror-history"; @@ -185,9 +185,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & const tsel = this._editorView.state.selection.$from; tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 5000 - 1000))); this._applyingChange = true; - this.dataDoc[this.props.fieldKey + "-lastModified"] && (this.dataDoc[this.props.fieldKey + "-backgroundColor"] = "lightGray"); - this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); - this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()), state.doc.textBetween(0, state.doc.content.size, "\n\n")); + if (!this.props.Document._textTemplate || Doc.GetProto(this.props.Document) === this.dataDoc) { + this.dataDoc[this.props.fieldKey + "-lastModified"] && (this.dataDoc[this.props.fieldKey + "-backgroundColor"] = "lightGray"); + this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); + this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()), state.doc.textBetween(0, state.doc.content.size, "\n\n")); + } this._applyingChange = false; this.updateTitle(); this.tryUpdateHeight(); |