From 4859d4e3f5827c3341d43d19a5309d2ec25ab67b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 1 Apr 2020 17:15:14 -0400 Subject: fixed warnings and some compile errors. Made a key value layout and extened DocumentBox to have a childLayoutKey field --- src/client/util/RichTextSchema.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index a2fb7c11b..81ab95ff5 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -810,7 +810,7 @@ export class DashDocView { this._dashSpan.style.height = this._outer.style.height = Math.max(20, dim[1]) + "px"; this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray")); }, { fireImmediately: true }); - let doReactRender = (finalLayout: Doc, resolvedDataDoc: Doc) => { + const doReactRender = (finalLayout: Doc, resolvedDataDoc: Doc) => { ReactDOM.unmountComponentAtNode(this._dashSpan); ReactDOM.render( { if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { @@ -939,7 +939,7 @@ export class DashFieldView { this._fieldCheck.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; this._fieldCheck.onchange = function (e: any) { self._dashDoc![self._fieldKey] = e.target.checked; - } + }; this._fieldSpan = document.createElement("div"); this._fieldSpan.id = Utils.GenerateGuid(); @@ -1095,12 +1095,12 @@ export class FootnoteView { "Mod-y": () => redo(this.outerView.state, this.outerView.dispatch), "Mod-b": toggleMark(schema.marks.strong) }), - new Plugin({ - view(newView) { - // TODO -- make this work with RichTextMenu - // return FormattedTextBox.getToolTip(newView); - } - }) + // new Plugin({ + // view(newView) { + // // TODO -- make this work with RichTextMenu + // // return FormattedTextBox.getToolTip(newView); + // } + // }) ], }), -- cgit v1.2.3-70-g09d2 From cf77e5f861c0927956e5453873839c81f0229374 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 1 Apr 2020 23:24:12 -0400 Subject: made it possible to link from one text selection to another --- src/client/util/DragManager.ts | 1 + src/client/views/DocumentButtonBar.tsx | 9 +++----- src/client/views/nodes/DocumentContentsView.tsx | 4 +++- src/client/views/nodes/DocumentView.tsx | 7 +++++- src/client/views/nodes/FormattedTextBox.tsx | 29 +++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 8 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 63a11c85a..8d3f6751e 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -148,6 +148,7 @@ export namespace DragManager { linkSourceDocument: Doc; dontClearTextBox?: boolean; linkDocument?: Doc; + linkDropCallback?: (data: LinkDragData) => void; } export class ColumnDragData { constructor(colKey: SchemaHeaderField) { diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index b0c701b65..b95cc6627 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -4,12 +4,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast } from "../../new_fields/Doc"; -import { Id } from '../../new_fields/FieldSymbols'; import { RichTextField } from '../../new_fields/RichTextField'; import { NumCast, StrCast } from "../../new_fields/Types"; import { emptyFunction } from "../../Utils"; import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; -import RichTextMenu from '../util/RichTextMenu'; import { UndoManager } from "../util/UndoManager"; import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView'; import { ParentDocSelector } from './collections/ParentDocumentSelector'; @@ -121,10 +119,9 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop if (this.view0 && linkDoc) { Doc.GetProto(linkDoc).linkRelationship = "hyperlink"; - - const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast(linkDoc.anchor2.title) : "-untitled-"; - const anchor2Id = linkDoc.anchor2 instanceof Doc ? linkDoc.anchor2[Id] : ""; - const text = RichTextMenu.Instance.MakeLinkToSelection(linkDoc[Id], anchor2Title, e.ctrlKey ? "onRight" : "inTab", anchor2Id); + dropEv.linkDragData?.linkDropCallback?.(dropEv.linkDragData); + runInAction(() => this.view0!._link = linkDoc); + setTimeout(action(() => this.view0!._link = undefined), 0); } linkDrag?.end(); }, diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index c250da874..da035a6ce 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -58,7 +58,9 @@ export class DocumentContentsView extends React.Component void, layoutKey: string, forceLayout?: string, - forceFieldKey?: string + forceFieldKey?: string, + hideOnLeave?:boolean, + makeLink?: () => Opt; }> { @computed get layout(): string { TraceMobx(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7770a5caf..d8bbd88ce 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -40,7 +40,6 @@ import { ScriptBox } from '../ScriptBox'; import { ScriptingRepl } from '../ScriptingRepl'; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; -import { FormattedTextBox } from './FormattedTextBox'; import React = require("react"); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField'; @@ -967,6 +966,7 @@ export class DocumentView extends DocComponent(Docu Document={this.props.Document} DataDoc={this.props.DataDoc} LayoutDoc={this.props.LayoutDoc} + makeLink={this.makeLink} fitToBox={this.props.fitToBox} LibraryPath={this.props.LibraryPath} addDocument={this.props.addDocument} @@ -1002,6 +1002,11 @@ export class DocumentView extends DocComponent(Docu const ept = Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1_timecode : linkDoc.anchor2_timecode; return anchor.type === DocumentType.AUDIO && NumCast(ept) ? false : true; } +c + @observable _link:Opt; + makeLink = () => { + return this._link; + } @computed get innards() { TraceMobx(); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index bc43beab9..241345f3e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -54,6 +54,7 @@ library.add(faSmile, faTextHeight, faUpload); export interface FormattedTextBoxProps { hideOnLeave?: boolean; + makeLink?: () => Opt; } const richTextSchema = createSchema({ @@ -91,6 +92,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & private _pullReactionDisposer: Opt; private _pushReactionDisposer: Opt; private _buttonBarReactionDisposer: Opt; + private _linkMakerDisposer: Opt; private _scrollDisposer: Opt; private dropDisposer?: DragManager.DragDropDisposer; @@ -282,8 +284,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & e.stopPropagation(); // } } // otherwise, fall through to outer collection to handle drop + } else if (de.complete.linkDragData) { + de.complete.linkDragData.linkDropCallback = this.linkDrop; } } + linkDrop = (data: DragManager.LinkDragData) => { + const linkDoc = data.linkDocument!; + const anchor1Title = linkDoc.anchor1 instanceof Doc ? StrCast(linkDoc.anchor1.title) : "-untitled-"; + const anchor1Id = linkDoc.anchor1 instanceof Doc ? linkDoc.anchor1[Id] : ""; + this.makeLinkToSelection(linkDoc[Id], anchor1Title, "onRight", anchor1Id) + } getNodeEndpoints(context: Node, node: Node): { from: number, to: number } | null { let offset = 0; @@ -513,6 +523,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & }; } + makeLinkToSelection(linkDocId: string, title: string, location: string, targetDocId: string) { + if (this._editorView) { + const link = this._editorView.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, linkId: linkDocId, targetId: targetDocId }); + this._editorView.dispatch(this._editorView.state.tr.removeMark(this._editorView.state.selection.from, this._editorView.state.selection.to, this._editorView.state.schema.marks.link). + addMark(this._editorView.state.selection.from, this._editorView.state.selection.to, link)); + } + } componentDidMount() { this._buttonBarReactionDisposer = reaction( () => DocumentButtonBar.Instance, @@ -523,6 +540,17 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & } } ); + this._linkMakerDisposer = reaction( + () => this.props.makeLink?.(), + (linkDoc: Opt) => { + if (linkDoc) { + const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast(linkDoc.anchor2.title) : "-untitled-"; + const anchor2Id = linkDoc.anchor2 instanceof Doc ? linkDoc.anchor2[Id] : ""; + this.makeLinkToSelection(linkDoc[Id], anchor2Title, "onRight", anchor2Id); + } + }, + { fireImmediately: true } + ); this._reactionDisposer = reaction( () => { @@ -858,6 +886,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & this._searchReactionDisposer?.(); this._recordReactionDisposer?.(); this._buttonBarReactionDisposer?.(); + this._linkMakerDisposer?.(); this._editorView?.destroy(); } -- cgit v1.2.3-70-g09d2 From 6596e9aa8a23abe6f126e9cada5e3e8b8545884f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 2 Apr 2020 12:42:44 -0400 Subject: cleaned up applying template code. fixed DocumentBox to work better with excluding collections + locking selection. --- .../apis/google_docs/GooglePhotosClientUtils.ts | 2 +- src/client/util/DragManager.ts | 1 - src/client/util/RichTextSchema.tsx | 2 +- src/client/views/TemplateMenu.tsx | 2 +- .../views/collections/CollectionTimeView.tsx | 2 +- src/client/views/nodes/DocumentBox.scss | 3 + src/client/views/nodes/DocumentBox.tsx | 19 +++- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 118 ++++++++------------- src/client/views/pdf/PDFViewer.tsx | 2 +- src/new_fields/Doc.ts | 10 +- src/new_fields/RichTextUtils.ts | 4 +- src/new_fields/documentSchemas.ts | 3 +- .../authentication/models/current_user_utils.ts | 21 ++-- 14 files changed, 89 insertions(+), 102 deletions(-) (limited to 'src/client/util') diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts index f8723f02d..7c4137f59 100644 --- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts +++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts @@ -340,7 +340,7 @@ export namespace GooglePhotos { const url = data.url.href; const target = Doc.MakeAlias(source); const description = parseDescription(target, descriptionKey); - await DocumentView.makeCustomViewClicked(target, undefined, Docs.Create.FreeformDocument); + await DocumentView.makeCustomViewClicked(target, Docs.Create.FreeformDocument); media.push({ url, description }); } if (media.length) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 8d3f6751e..db7a54ca8 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -137,7 +137,6 @@ export namespace DragManager { userDropAction: dropActionType; embedDoc?: boolean; moveDocument?: MoveFunction; - applyAsTemplate?: boolean; isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts } export class LinkDragData { diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 81ab95ff5..094cd58f3 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -776,7 +776,7 @@ export class DashDocView { if (dashDocBase instanceof Doc) { const aliasedDoc = Doc.MakeAlias(dashDocBase, docid + alias); aliasedDoc.layoutKey = "layout"; - node.attrs.fieldKey && DocumentView.makeCustomViewClicked(aliasedDoc, undefined, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); + node.attrs.fieldKey && DocumentView.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); self.doRender(aliasedDoc, removeDoc, node, view, getPos); } }); diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 996928cca..8eb5c5050 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -171,7 +171,7 @@ Scripting.addGlobal(function switchView(doc: Doc, template: Doc) { template = Cast(template.dragFactory, Doc, null); } const templateTitle = StrCast(template?.title); - return templateTitle && DocumentView.makeCustomViewClicked(doc, undefined, Docs.Create.FreeformDocument, templateTitle, template); + return templateTitle && DocumentView.makeCustomViewClicked(doc, Docs.Create.FreeformDocument, templateTitle, template); }); Scripting.addGlobal(function templateIsUsed(templateDoc: Doc, firstDocTitlte: string) { diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 0d2207b27..4f77e8b0e 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -31,7 +31,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { componentDidMount() { this.props.Document._freezeOnDrop = true; const childDetailed = this.props.Document.childDetailed; // bcz: needs to be here to make sure the childDetailed layout template has been loaded when the first item is clicked; - const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(containingCollection.childDetailed, alias, 'layout_detailView'); alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; + const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(containingCollection.childDetailed, alias, 'layout_detailView'); alias.layoutKey='layout_detailedView'; alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "string", containingCollection: Doc.name, shiftKey: "boolean" }); this.props.Document._fitToBox = true; if (!this.props.Document.onViewDefClick) { diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss index 6fc87e4f1..ce21391ce 100644 --- a/src/client/views/nodes/DocumentBox.scss +++ b/src/client/views/nodes/DocumentBox.scss @@ -8,4 +8,7 @@ color: white; position: absolute; } + .contentFittingDocumentView { + position: absolute; + } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index 9d1c08389..debe104d7 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -15,6 +15,8 @@ import "./DocumentBox.scss"; import { FieldView, FieldViewProps } from "./FieldView"; import React = require("react"); import { TraceMobx } from "../../../new_fields/util"; +import { DocumentView } from "./DocumentView"; +import { Docs } from "../../documents/Documents"; type DocBoxSchema = makeInterface<[typeof documentSchema]>; const DocBoxDocument = makeInterface(documentSchema); @@ -35,12 +37,12 @@ export class DocumentBox extends DocAnnotatableComponent { const funcs: ContextMenuProps[] = []; funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" }); - funcs.push({ description: (this.props.Document.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.props.Document.excludeCollections = !this.props.Document.excludeCollections, icon: "expand-arrows-alt" }); + funcs.push({ description: (this.props.Document.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => Doc.GetProto(this.props.Document).excludeCollections = !this.props.Document.excludeCollections, icon: "expand-arrows-alt" }); funcs.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); @@ -105,14 +107,21 @@ export class DocumentBox extends DocAnnotatableComponent this.props.PanelHeight() - 2 * this.yPad; getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad); get renderContents() { - const containedDoc = this.contentDoc[this.props.fieldKey]; + const containedDoc = Cast(this.contentDoc[this.props.fieldKey], Doc, null); + const childTemplateName = StrCast(this.props.Document.childTemplateName); + if (containedDoc && childTemplateName && !containedDoc["layout_" + childTemplateName]) { + setTimeout(() => { + DocumentView.createCustomView(containedDoc, Docs.Create.StackingDocument, childTemplateName); + Doc.expandTemplateLayout(Cast(containedDoc["layout_" + childTemplateName], Doc, null)!, containedDoc, undefined); + }, 0); + } const contents = !(containedDoc instanceof Doc) ? (null) : + {this.renderContents}
- {this.renderContents} ; } } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index da035a6ce..68501fca2 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -59,7 +59,7 @@ export class DocumentContentsView extends React.Component Opt; }> { @computed get layout(): string { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d8bbd88ce..02a1ac527 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -508,58 +508,49 @@ export class DocumentView extends DocComponent(Docu @undoBatch deleteClicked = (): void => { SelectionManager.DeselectAll(); this.props.removeDocument?.(this.props.Document); } - static makeNativeViewClicked = (doc: Doc) => { - undoBatch(() => Doc.setNativeView(doc))(); - } - - static makeCustomViewClicked = (doc: Doc, dataDoc: Opt, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { - const userDoc = Doc.UserDoc(); - const imgView = Cast(userDoc.iconView, Doc, null); - const iconImgView = Cast(userDoc.iconImageView, Doc, null); - const iconColView = Cast(userDoc.iconColView, Doc, null); - const iconViews = [imgView, iconImgView, iconColView]; - const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data); - const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data); - const allTemplates = iconViews.concat(templateButtons).concat(noteTypes); - const templateName = templateSignature.replace(/\(.*\)/, ""); - !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { - if (StrCast(tempDoc.title) === doc.type + "_" + templateName) { - docLayoutTemplate = tempDoc; - } - }); - !docLayoutTemplate && allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { - if (StrCast(tempDoc.title) === templateName) { - docLayoutTemplate = tempDoc; + // applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView) + static makeCustomViewClicked = (doc: Doc, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { + const batch = UndoManager.StartBatch("makeCustomViewClicked"); + runInAction(() => { + doc.layoutKey = "layout_" + templateSignature; + if (doc[doc.layoutKey] === undefined) { + DocumentView.createCustomView(doc, creator, templateSignature, docLayoutTemplate); } }); + batch.end(); + } + static createCustomView = (doc: Doc, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { + const iconViews = DocListCast(Cast(Doc.UserDoc().iconViews, Doc, null)?.data); + const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data); + const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data); + const allTemplates = iconViews.concat(templBtns).concat(noteTypes).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); + const templateName = templateSignature.replace(/\(.*\)/, ""); + // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized + // first try to find a template that matches the specific document type (_). otherwise, fallback to a general match on + !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === doc.type + "_" + templateName && (docLayoutTemplate = tempDoc)); + !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc)); - const batch = UndoManager.StartBatch("CustomViewClicked"); const customName = "layout_" + templateSignature; - if (doc[customName] === undefined) { - const _width = NumCast(doc._width); - const _height = NumCast(doc._height); - const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false }; - - let fieldTemplate: Opt; - if (doc.data instanceof RichTextField || typeof (doc.data) === "string") { - fieldTemplate = Docs.Create.TextDocument("", options); - } else if (doc.data instanceof PdfField) { - fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options); - } else if (doc.data instanceof VideoField) { - fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options); - } else if (doc.data instanceof AudioField) { - fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options); - } else if (doc.data instanceof ImageField) { - fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options); - } - const docTemplate = docLayoutTemplate || creator(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) }); - - fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate)); - Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined); - } else { - doc.layoutKey = customName; + const _width = NumCast(doc._width); + const _height = NumCast(doc._height); + const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false }; + + let fieldTemplate: Opt; + if (doc.data instanceof RichTextField || typeof (doc.data) === "string") { + fieldTemplate = Docs.Create.TextDocument("", options); + } else if (doc.data instanceof PdfField) { + fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options); + } else if (doc.data instanceof VideoField) { + fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options); + } else if (doc.data instanceof AudioField) { + fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options); + } else if (doc.data instanceof ImageField) { + fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options); } - batch.end(); + const docTemplate = docLayoutTemplate || creator(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) }); + + fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate)); + Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined); } @undoBatch @@ -583,29 +574,6 @@ export class DocumentView extends DocComponent(Docu DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link"); } - if (de.complete.docDragData) { - if (de.complete.docDragData.applyAsTemplate) { - Doc.ApplyTemplateTo(de.complete.docDragData.draggedDocuments[0], this.props.Document, "layout_custom", undefined); - e.stopPropagation(); - } - else if (de.complete.docDragData.draggedDocuments[0].type === "text") { - const text = Cast(de.complete.docDragData.draggedDocuments[0].data, RichTextField)?.Text; - if (text && text[0] === "{" && text[text.length - 1] === "}" && text.includes(":")) { - const loc = text.indexOf(":"); - const key = text.slice(1, loc); - const value = text.slice(loc + 1, text.length - 1); - console.log(key); - console.log(value); - console.log(this.props.Document); - this.props.Document[key] = value; - console.log(de.complete.docDragData.draggedDocuments[0].x); - console.log(de.complete.docDragData.draggedDocuments[0].x); - e.preventDefault(); - e.stopPropagation(); - de.complete.aborted = true; - } - } - } if (de.complete.linkDragData) { e.stopPropagation(); // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true); @@ -646,9 +614,9 @@ export class DocumentView extends DocComponent(Docu @undoBatch @action setCustomView = (custom: boolean, layout: string): void => { - DocumentView.makeNativeViewClicked(this.props.Document); + Doc.setNativeView(this.props.Document); if (custom) { - DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, Docs.Create.StackingDocument, layout, undefined); + DocumentView.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined); } } @@ -1002,9 +970,9 @@ export class DocumentView extends DocComponent(Docu const ept = Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1_timecode : linkDoc.anchor2_timecode; return anchor.type === DocumentType.AUDIO && NumCast(ept) ? false : true; } -c - @observable _link:Opt; - makeLink = () => { + + @observable _link: Opt; + makeLink = () => { return this._link; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index cc187cd67..71495d95f 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -575,7 +575,7 @@ export class PDFViewer extends DocAnnotatableComponent([clipDoc]); - DocumentView.makeCustomViewClicked(targetDoc, undefined, Docs.Create.StackingDocument, "slideView", undefined); + DocumentView.makeCustomViewClicked(targetDoc, Docs.Create.StackingDocument, "slideView", undefined); // const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title }); // Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy](); // const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() }); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 440f13d6b..a6cbabf42 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -592,7 +592,10 @@ export namespace Doc { let _applyCount: number = 0; export function ApplyTemplate(templateDoc: Doc) { if (templateDoc) { - const applied = ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), StrCast(templateDoc.layoutKey, "layout"), templateDoc.title + "(..." + _applyCount++ + ")"); + const target = Doc.MakeDelegate(new Doc()); + const targetKey = StrCast(templateDoc.layoutKey, "layout"); + const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + "(..." + _applyCount++ + ")"); + target.layoutKey = targetKey; applied && (Doc.GetProto(applied).type = templateDoc.type); return applied; } @@ -615,7 +618,6 @@ export namespace Doc { Doc.GetProto(target)[targetKey] = new PrefetchProxy(templateDoc); } } - target.layoutKey = targetKey; return target; } @@ -920,7 +922,9 @@ Scripting.addGlobal(function curPresentationItem() { }); Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().SelectedDocs = new List([doc]); }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { - const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null))); + const docs = DocListCast(Doc.UserDoc().SelectedDocs). + filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && + (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))); return docs.length ? new List(docs) : prevValue; }); Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) { Doc.setDocFilter(container, key, value, modifiers); }); diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts index 1d90c984d..c211b3d3c 100644 --- a/src/new_fields/RichTextUtils.ts +++ b/src/new_fields/RichTextUtils.ts @@ -274,7 +274,7 @@ export namespace RichTextUtils { const backingDocId = StrCast(textNote[guid]); if (!backingDocId) { const backingDoc = Docs.Create.ImageDocument(agnostic, { _width: 300, _height: 300 }); - DocumentView.makeCustomViewClicked(backingDoc, undefined, Docs.Create.FreeformDocument); + DocumentView.makeCustomViewClicked(backingDoc, Docs.Create.FreeformDocument); docid = backingDoc[Id]; textNote[guid] = docid; } else { @@ -403,7 +403,7 @@ export namespace RichTextUtils { let exported = (await Cast(linkDoc.anchor2, Doc))!; if (!exported.customLayout) { exported = Doc.MakeAlias(exported); - DocumentView.makeCustomViewClicked(exported, undefined, Docs.Create.FreeformDocument); + DocumentView.makeCustomViewClicked(exported, Docs.Create.FreeformDocument); linkDoc.anchor2 = exported; } url = Utils.shareUrl(exported[Id]); diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts index e06452a4e..91ea32bee 100644 --- a/src/new_fields/documentSchemas.ts +++ b/src/new_fields/documentSchemas.ts @@ -61,7 +61,8 @@ export const documentSchema = createSchema({ fontSize: "string", fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view letterSpacing: "string", - textTransform: "string" + textTransform: "string", + childTemplateName: "string" // the name of a template to use to override the layoutKey when rendering a document in DocumentBox }); export const positionSchema = createSchema({ diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index d9f354cf2..4f82da44d 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -55,6 +55,16 @@ export class CurrentUserUtils { Doc.addFieldEnumerations(Doc.GetProto(noteTemplates[4]), "taskStatus", taskStatusValues); doc.noteTypes = new PrefetchProxy(Docs.Create.TreeDocument(noteTemplates.map(nt => makeTemplate(nt, true, StrCast(nt.style)) ? nt : nt), { title: "Note Layouts", _height: 75 })); } + static setupDefaultIconTypes(doc: Doc, buttons?: string[]) { + doc.iconView = new PrefetchProxy(Docs.Create.TextDocument("", { title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); + Doc.GetProto(doc.iconView as any as Doc).icon = new RichTextField('{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"title","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}', ""); + doc.isTemplateDoc = makeTemplate(doc.iconView as any as Doc); + doc.iconImageView = new PrefetchProxy(Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { title: "data", _width: 50, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); + doc.isTemplateDoc = makeTemplate(doc.iconImageView as any as Doc, true, "image_icon"); + doc.iconColView = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); + doc.isTemplateDoc = makeTemplate(doc.iconColView as any as Doc, true, "collection_icon"); + doc.iconViews = Docs.Create.TreeDocument([doc.iconView as any as Doc, doc.iconImageView as any as Doc, doc.iconColView as any as Doc], { title: "icon types", _height: 75 }); + } // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools static setupCreatorButtons(doc: Doc, alreadyCreatedButtons?: string[]) { @@ -63,7 +73,7 @@ export class CurrentUserUtils { doc.activePen = doc; const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [ { title: "collection", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: emptyCollection }, - { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' }, + { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' }, { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", {_width: 300, _height: 300, title: "New Webpage" })' }, { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' }, { title: "buxton", icon: "cloud-upload-alt", ignoreClick: true, drag: "Docs.Create.Buxton()" }, @@ -278,14 +288,6 @@ export class CurrentUserUtils { Doc.GetProto(descriptionTemplate).layout = FormattedTextBox.LayoutString("description"); descriptionTemplate.isTemplateDoc = makeTemplate(descriptionTemplate, true, "descriptionView"); - doc.iconView = new PrefetchProxy(Docs.Create.TextDocument("", { title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); - Doc.GetProto(doc.iconView as any as Doc).icon = new RichTextField('{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"title","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}', ""); - doc.isTemplateDoc = makeTemplate(doc.iconView as any as Doc); - doc.iconImageView = new PrefetchProxy(Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { title: "data", _width: 50, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); - doc.isTemplateDoc = makeTemplate(doc.iconImageView as any as Doc, true, "image_icon"); - doc.iconColView = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(this)") })); - doc.isTemplateDoc = makeTemplate(doc.iconColView as any as Doc, true, "collection_icon"); - const ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({ ...opts, dontSelect: true, dropAction: "alias", removeDropProperties: new List(["dropAction"]), _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100 })) as any as Doc; const blist = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, { ...opts, @@ -324,6 +326,7 @@ export class CurrentUserUtils { static updateUserDocument(doc: Doc) { doc.title = Doc.CurrentUserEmail; new InkingControl(); + (doc.iconTypes === undefined) && CurrentUserUtils.setupDefaultIconTypes(doc); (doc.noteTypes === undefined) && CurrentUserUtils.setupDefaultDocTemplates(doc); (doc.optionalRightCollection === undefined) && CurrentUserUtils.setupMobileUploads(doc); (doc.overlays === undefined) && CurrentUserUtils.setupOverlays(doc); -- cgit v1.2.3-70-g09d2 From bb351bcf0a56be9708c6c833c8023300e26223c1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 2 Apr 2020 17:24:19 -0400 Subject: added copy with alt+ctrl . fixed border radius --- src/client/util/DragManager.ts | 2 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 ++- src/client/views/search/SearchBox.tsx | 2 +- src/new_fields/Doc.ts | 3 ++- 5 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index db7a54ca8..1f2312032 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -351,7 +351,7 @@ export namespace DragManager { const moveHandler = (e: PointerEvent) => { e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop if (dragData instanceof DocumentDragData) { - dragData.userDropAction = e.ctrlKey ? "alias" : undefined; + dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } if (e.shiftKey && CollectionDockingView.Instance && dragData.droppedDocuments.length === 1) { AbortDrag(); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3e07fd109..79600b7c1 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -266,7 +266,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dist = Math.sqrt((e.clientX - down[0]) * (e.clientX - down[0]) + (e.clientY - down[1]) * (e.clientY - down[1])); dist = dist < 3 ? 0 : dist; SelectionManager.SelectedDocuments().map(dv => dv.props.Document).map(doc => doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc)). - map(d => d.borderRounding = `${Math.max(0, dist)}%`); + map(d => d.borderRounding = `${Math.max(0, dist)}px`); return false; } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 68eb4493a..e710b3075 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -439,7 +439,8 @@ export class ImageBox extends DocAnnotatableComponent - +
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index a6cbabf42..85926e393 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -565,7 +565,8 @@ export namespace Doc { } else if (cfield instanceof ComputedField) { copy[key] = ComputedField.MakeFunction(cfield.script.originalScript); } else if (field instanceof ObjectField) { - copy[key] = key.includes("layout[") && doc[key] instanceof Doc ? Doc.MakeCopy(doc[key] as Doc, false) : ObjectField.MakeCopy(field); + copy[key] = key.includes("layout[") && doc[key] instanceof Doc ? Doc.MakeCopy(doc[key] as Doc, false) : + doc[key] instanceof Doc ? doc[key] : ObjectField.MakeCopy(field); } else if (field instanceof Promise) { debugger; //This shouldn't happend... } else { -- cgit v1.2.3-70-g09d2