From 929584999080616adb350df638b640f770c6f44a Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 17 Oct 2019 19:47:01 -0400 Subject: fixed some display issues with templates and linking --- .../collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index fe92eed10..a59fda6d9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -37,8 +37,8 @@ export class CollectionFreeFormLinkView extends React.Component Date: Thu, 17 Oct 2019 23:40:29 -0400 Subject: working version of link lines between anchors --- src/client/documents/Documents.ts | 1 + src/client/util/DocumentManager.ts | 7 ++- src/client/util/LinkManager.ts | 6 ++- src/client/views/OverlayView.tsx | 2 + .../CollectionFreeFormLinkView.scss | 3 -- .../CollectionFreeFormLinkView.tsx | 63 ++++++---------------- .../CollectionFreeFormLinksView.scss | 5 +- .../CollectionFreeFormLinksView.tsx | 44 +++++---------- .../collectionFreeForm/CollectionFreeFormView.tsx | 8 ++- src/client/views/nodes/DocuLinkBox.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/new_fields/Doc.ts | 2 +- 12 files changed, 50 insertions(+), 97 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index edc2ac653..d979e0a3f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -724,6 +724,7 @@ export namespace DocUtils { linkDocProto.layoutKey2 = DocuLinkBox.LayoutString("anchor2"); linkDocProto.width = linkDocProto.height = 0; linkDocProto.isBackground = true; + linkDocProto.isButton = true; LinkManager.Instance.addLink(linkDocProto); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index e23ac55c2..fc406c6ab 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -9,6 +9,7 @@ import { DocumentView } from '../views/nodes/DocumentView'; import { LinkManager } from './LinkManager'; import { Scripting } from './Scripting'; import { SelectionManager } from './SelectionManager'; +import { DocumentType } from '../documents/DocumentTypes'; export class DocumentManager { @@ -110,14 +111,18 @@ export class DocumentManager { @computed public get LinkedDocumentViews() { + console.log("START"); let pairs = DocumentManager.Instance.DocumentViews.filter(dv => dv.isSelected() || Doc.IsBrushed(dv.props.Document)).reduce((pairs, dv) => { + console.log("DOC = " + dv.props.Document.title + " " + dv.props.Document.layout); let linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document); pairs.push(...linksList.reduce((pairs, link) => { if (link) { let linkToDoc = LinkManager.Instance.getOppositeAnchor(link, dv.props.Document); if (linkToDoc) { DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => { - pairs.push({ a: dv, b: docView1, l: link }); + if (dv.props.Document.type !== DocumentType.LINK || dv.props.layoutKey !== docView1.props.layoutKey) { + pairs.push({ a: dv, b: docView1, l: link }); + } }); } } diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 8a668e8d8..35c0f023f 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -79,7 +79,7 @@ export class LinkManager { let related = LinkManager.Instance.getAllLinks().filter(link => { let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null)); let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null)); - return protomatch1 || protomatch2; + return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor); }); return related; } @@ -244,8 +244,10 @@ export class LinkManager { public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined { if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) { return Cast(linkDoc.anchor2, Doc, null); - } else { + } else if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor2, Doc, null))) { return Cast(linkDoc.anchor1, Doc, null); + } else if (Doc.AreProtosEqual(anchor, linkDoc)) { + return linkDoc; } } } diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 95c7b2683..9869e24d1 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -12,6 +12,7 @@ import { Transform } from "../util/Transform"; import { CollectionFreeFormDocumentView } from "./nodes/CollectionFreeFormDocumentView"; import { DocumentContentsView } from "./nodes/DocumentContentsView"; import { NumCast } from "../../new_fields/Types"; +import { CollectionFreeFormLinksView } from "./collections/collectionFreeForm/CollectionFreeFormLinksView"; export type OverlayDisposer = () => void; @@ -206,6 +207,7 @@ export class OverlayView extends React.Component {
{this._elements}
+ {this.overlayDocs} ); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss index cfd18ad35..1f1bca2f2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss @@ -1,6 +1,5 @@ .collectionfreeformlinkview-linkLine { stroke: black; - transform: translate(10000px,10000px); opacity: 0.8; pointer-events: all; stroke-width: 3px; @@ -8,13 +7,11 @@ .collectionfreeformlinkview-linkCircle { stroke: rgb(0,0,0); opacity: 0.5; - transform: translate(10000px,10000px); pointer-events: all; cursor: pointer; } .collectionfreeformlinkview-linkText { stroke: rgb(0,0,0); opacity: 0.5; - transform: translate(10000px,10000px); pointer-events: all; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index a59fda6d9..4e1faccd7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,63 +1,30 @@ import { observer } from "mobx-react"; -import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc"; -import { BoolCast, NumCast, StrCast } from "../../../../new_fields/Types"; -import { InkingControl } from "../../InkingControl"; +import { Doc } from "../../../../new_fields/Doc"; +import { Utils } from '../../../../Utils'; +import { DocumentView } from "../../nodes/DocumentView"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); import v5 = require("uuid/v5"); +import { DocumentType } from "../../../documents/DocumentTypes"; export interface CollectionFreeFormLinkViewProps { - A: Doc; - B: Doc; + A: DocumentView; + B: DocumentView; LinkDocs: Doc[]; - addDocument: (document: Doc) => boolean; - removeDocument: (document: Doc) => boolean; } @observer export class CollectionFreeFormLinkView extends React.Component { - onPointerDown = (e: React.PointerEvent) => { - if (e.button === 0 && !InkingControl.Instance.selectedTool) { - let a = this.props.A; - let b = this.props.B; - let x1 = NumCast(a.x) + (BoolCast(a.isMinimized) ? 5 : a[WidthSym]() / 2); - let y1 = NumCast(a.y) + (BoolCast(a.isMinimized) ? 5 : a[HeightSym]() / 2); - let x2 = NumCast(b.x) + (BoolCast(b.isMinimized) ? 5 : b[WidthSym]() / 2); - let y2 = NumCast(b.y) + (BoolCast(b.isMinimized) ? 5 : b[HeightSym]() / 2); - // this.props.LinkDocs.map(l => { - // let width = l[WidthSym](); - // l.x = (x1 + x2) / 2 - width / 2; - // l.y = (y1 + y2) / 2 + 10; - // if (!this.props.removeDocument(l)) this.props.addDocument(l, false); - // }); - e.stopPropagation(); - e.preventDefault(); - } - } render() { - // let l = this.props.LinkDocs; - let a = this.props.A.layout instanceof Doc ? this.props.A.layout : this.props.A; - let b = this.props.B.layout instanceof Doc ? this.props.B.layout : this.props.B; - let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.width) / 2); - let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.height) / 2); - let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.width) / 2); - let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.height) / 2); - let text = ""; - // let first = this.props.LinkDocs[0]; - // if (this.props.LinkDocs.length === 1) text += first.title + (first.linkDescription ? "(" + StrCast(first.linkDescription) + ")" : ""); - // else text = "-multiple-"; - return ( - <> - - {/* */} - - {text} - - - ); + let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : []; + let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : []; + let a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect(); + let b = (bcont.length ? bcont[0] : this.props.B.ContentDiv!).getBoundingClientRect(); + let pt1 = Utils.getNearestPointInPerimeter(a.left, a.top, a.width, a.height, b.left + b.width / 2, b.top + b.height / 2); + let pt2 = Utils.getNearestPointInPerimeter(b.left, b.top, b.width, b.height, a.left + a.width / 2, a.top + a.height / 2); + return (); } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss index 30e158603..cb5cef29c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss @@ -1,10 +1,9 @@ .collectionfreeformlinksview-svgCanvas{ - transform: translate(-10000px,-10000px); position: absolute; top: 0; left: 0; - width: 20000px; - height: 20000px; + width: 100%; + height: 100%; pointer-events: none; } .collectionfreeformlinksview-container { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 189981e35..cf0e55ccf 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,17 +1,17 @@ import { computed, IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast } from "../../../../new_fields/Doc"; +import { Doc } from "../../../../new_fields/Doc"; import { Id } from "../../../../new_fields/FieldSymbols"; -import { Cast, FieldValue } from "../../../../new_fields/Types"; import { DocumentManager } from "../../../util/DocumentManager"; import { DocumentView } from "../../nodes/DocumentView"; -import { CollectionViewProps } from "../CollectionSubView"; import "./CollectionFreeFormLinksView.scss"; import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView"; import React = require("react"); +import { Utils } from "../../../../Utils"; +import { SelectionManager } from "../../../util/SelectionManager"; @observer -export class CollectionFreeFormLinksView extends React.Component { +export class CollectionFreeFormLinksView extends React.Component { _brushReactionDisposer?: IReactionDisposer; componentDidMount() { @@ -71,35 +71,18 @@ export class CollectionFreeFormLinksView extends React.Component - child[Id] === collid).map(view => - DocumentManager.Instance.getDocumentViews(view).map(view => - equalViews.push(view))); - } - return equalViews.filter(sv => sv.props.ContainingCollectionDoc === this.props.Document); - } - @computed get uniqueConnections() { let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => { - let srcViews = this.documentAnchors(connection.a); - let targetViews = this.documentAnchors(connection.b); + let srcViews = [connection.a]; + let targetViews = [connection.b]; - let possiblePairs: { a: Doc, b: Doc, }[] = []; - srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv.props.Document, b: tv.props.Document }))); + let possiblePairs: { a: DocumentView, b: DocumentView, }[] = []; + srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv, b: tv }))); possiblePairs.map(possiblePair => { if (!drawnPairs.reduce((found, drawnPair) => { - let match1 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.a) && Doc.AreProtosEqual(possiblePair.b, drawnPair.b)); - let match2 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.b) && Doc.AreProtosEqual(possiblePair.b, drawnPair.a)); + let match1 = (Doc.AreProtosEqual(possiblePair.a.props.Document, drawnPair.a.props.Document) && Doc.AreProtosEqual(possiblePair.b.props.Document, drawnPair.b.props.Document)); + let match2 = (Doc.AreProtosEqual(possiblePair.a.props.Document, drawnPair.b.props.Document) && Doc.AreProtosEqual(possiblePair.b.props.Document, drawnPair.a.props.Document)); let match = match1 || match2; if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) { drawnPair.l.push(connection.l); @@ -110,16 +93,15 @@ export class CollectionFreeFormLinksView extends React.Component p + l[Id], "")} A={c.a} B={c.b} LinkDocs={c.l} - removeDocument={this.props.removeDocument} addDocument={this.props.addDocument} />); + }, [] as { a: DocumentView, b: DocumentView, l: Doc[] }[]); + return connections.map(c => ); } render() { return (
- {this.uniqueConnections} + {SelectionManager.GetIsDragging() ? (null) : this.uniqueConnections} {this.props.children}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5dccb5bf0..b3270d507 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -705,11 +705,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}> - - - {this.childViews} - - + + {this.childViews} + diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx index 8c41b9d4f..f56bf4ad3 100644 --- a/src/client/views/nodes/DocuLinkBox.tsx +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -54,12 +54,12 @@ export class DocuLinkBox extends DocComponent(Doc onPointerUp = (e: PointerEvent) => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button === 2 || e.ctrlKey)) { + if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button === 2 || e.ctrlKey || !this.props.Document.isButton)) { this.props.select(false); } } onClick = (e: React.MouseEvent) => { - if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button !== 2 && !e.ctrlKey)) { + if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button !== 2 && !e.ctrlKey && this.props.Document.isButton)) { DocumentManager.Instance.FollowLink(this.props.Document, this.props.Document[this.props.fieldKey] as Doc, document => this.props.addDocTab(document, undefined, "inTab"), false); } e.stopPropagation(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 6775655eb..0bcaa99aa 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -697,7 +697,7 @@ export class DocumentView extends DocComponent(Docu opacity: this.Document.opacity }} onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick} - onPointerEnter={() => Doc.BrushDoc(this.props.Document)} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)} + onPointerEnter={() => { Doc.UnBrushAllDocs(); Doc.BrushDoc(this.props.Document); }} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)} > {this.props.Document.links && DocListCast(this.props.Document.links).map((d, i) =>
)} diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 04f310785..26355d0e7 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -734,7 +734,7 @@ export namespace Doc { } export function UnBrushAllDocs() { - manager.BrushedDoc.clear(); + brushManager.BrushedDoc.clear(); } export function setChildLayout(target: Doc, source?: Doc) { -- cgit v1.2.3-70-g09d2 From b3ccf5df0bab87d76b7227ffc5f147b4e4b41b90 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 18 Oct 2019 14:25:29 -0400 Subject: fixes so that link lines update when endpoints change. --- .../collectionFreeForm/CollectionFreeFormLinkView.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 4e1faccd7..c5bc2e7fb 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -6,6 +6,7 @@ import "./CollectionFreeFormLinkView.scss"; import React = require("react"); import v5 = require("uuid/v5"); import { DocumentType } from "../../../documents/DocumentTypes"; +import { observable, action } from "mobx"; export interface CollectionFreeFormLinkViewProps { A: DocumentView; @@ -15,8 +16,25 @@ export interface CollectionFreeFormLinkViewProps { @observer export class CollectionFreeFormLinkView extends React.Component { + @observable _alive: number = 0; + @action + componentDidMount() { + this._alive = 1; + setTimeout(this.rerender, 50); + } + @action + componentWillUnmount() { + this._alive = 0; + } + rerender = action(() => { + if (this._alive) { + setTimeout(this.rerender, 50); + this._alive++; + } + }) render() { + let y = this._alive; let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : []; let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : []; let a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect(); -- cgit v1.2.3-70-g09d2 From 1f3576a69a6a0396d07e965c700bb7d69d77a0a3 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 18 Oct 2019 17:06:41 -0400 Subject: fixed up creator buttons - factored out convert to buttons code into a dropConverter script. fixed issues with template loading for images. --- src/client/documents/Documents.ts | 2 +- src/client/util/DragManager.ts | 3 ++ src/client/util/DropConverter.ts | 46 ++++++++++++++++++++++ src/client/views/CollectionLinearView.tsx | 40 ------------------- .../views/collections/CollectionStackingView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 6 ++- .../views/collections/CollectionTreeView.scss | 1 - .../views/collections/CollectionTreeView.tsx | 2 +- .../CollectionFreeFormLinkView.tsx | 2 +- .../authentication/models/current_user_utils.ts | 11 ++++-- 10 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 src/client/util/DropConverter.ts (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 651662ded..32fda1954 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -105,7 +105,7 @@ export interface DocumentOptions { yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts panel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script - convertToButtons?: boolean; // whether documents dropped onto a collection should be converted to buttons that will construct the dropped document + dropConverter?: ScriptField; // script to run when documents are dropped on this Document. // [key: string]: Opt; } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 576b16bc8..bbc29585c 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -14,6 +14,8 @@ import { ScriptField } from "../../new_fields/ScriptField"; import { List } from "../../new_fields/List"; import { PrefetchProxy } from "../../new_fields/Proxy"; import { listSpec } from "../../new_fields/Schema"; +import { Scripting } from "./Scripting"; +import { convertDropDataToButtons } from "./DropConverter"; export type dropActionType = "alias" | "copy" | undefined; export function SetupDrag( @@ -497,3 +499,4 @@ export namespace DragManager { } } } +Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); }); diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts new file mode 100644 index 000000000..eea3da1bc --- /dev/null +++ b/src/client/util/DropConverter.ts @@ -0,0 +1,46 @@ +import { DragManager } from "./DragManager"; +import { CollectionViewType } from "../views/collections/CollectionBaseView"; +import { Doc, DocListCast } from "../../new_fields/Doc"; +import { DocumentType } from "../documents/DocumentTypes"; +import { ObjectField } from "../../new_fields/ObjectField"; +import { StrCast } from "../../new_fields/Types"; +import { Docs } from "../documents/Documents"; +import { ScriptField } from "../../new_fields/ScriptField"; + + +function makeTemplate(doc: Doc): boolean { + let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; + let layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0]; + let fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, ""); + let docs = DocListCast(layoutDoc[fieldKey]); + let any = false; + docs.map(d => { + if (!StrCast(d.title).startsWith("-")) { + any = true; + return Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc)); + } + if (d.type === DocumentType.COL) return makeTemplate(d); + return false; + }); + return any; +} +export function convertDropDataToButtons(data: DragManager.DocumentDragData) { + data && data.draggedDocuments.map((doc, i) => { + let dbox = doc; + if (!doc.onDragStart && !doc.onClick && doc.viewType !== CollectionViewType.Linear) { + let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; + if (layoutDoc.type === DocumentType.COL) { + layoutDoc.isTemplateDoc = makeTemplate(layoutDoc); + } else { + layoutDoc.isTemplateDoc = (layoutDoc.type === DocumentType.TEXT || layoutDoc.layout instanceof Doc) && !data.userDropAction; + } + dbox = Docs.Create.FontIconDocument({ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); + dbox.dragFactory = layoutDoc; + dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined; + dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); + } else if (doc.viewType === CollectionViewType.Linear) { + dbox.ignoreClick = true; + } + data.droppedDocuments[i] = dbox; + }); +} diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx index 04e131135..e8ef20899 100644 --- a/src/client/views/CollectionLinearView.tsx +++ b/src/client/views/CollectionLinearView.tsx @@ -47,46 +47,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { } } - makeTemplate = (doc: Doc): boolean => { - let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; - let layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0]; - let fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, ""); - let docs = DocListCast(layoutDoc[fieldKey]); - let any = false; - docs.map(d => { - if (!StrCast(d.title).startsWith("-")) { - any = true; - return Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc)); - } - if (d.type === DocumentType.COL) return this.makeTemplate(d); - return false; - }); - return any; - } - - drop = action((e: Event, de: DragManager.DropEvent) => { - (de.data as DragManager.DocumentDragData).draggedDocuments.map((doc, i) => { - let dbox = doc; - if (!doc.onDragStart && !doc.onClick && this.props.Document.convertToButtons && doc.viewType !== CollectionViewType.Linear) { - let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; - if (layoutDoc.type === DocumentType.COL) { - layoutDoc.isTemplateDoc = this.makeTemplate(layoutDoc); - } else { - layoutDoc.isTemplateDoc = (layoutDoc.type === DocumentType.TEXT || layoutDoc.layout instanceof Doc) && de.data instanceof DragManager.DocumentDragData && !de.data.userDropAction; - } - dbox = Docs.Create.FontIconDocument({ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); - dbox.dragFactory = layoutDoc; - dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined; - dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); - } else if (doc.viewType === CollectionViewType.Linear) { - dbox.ignoreClick = true; - } - (de.data as DragManager.DocumentDragData).droppedDocuments[i] = dbox; - }); - e.stopPropagation(); - return super.drop(e, de); - }); - public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } dimension = () => NumCast(this.props.Document.height); // 2 * the padding diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index e54374ad7..f9f040c6b 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -65,7 +65,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap); let style = this.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` }; return
- {this.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)} + {pair.layout instanceof Doc && this.getDisplayDoc(pair.layout, pair.data, dxf, width)}
; }); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 1f8c0b18f..bc61492d0 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -6,7 +6,7 @@ import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; import { ScriptField } from "../../../new_fields/ScriptField"; -import { Cast } from "../../../new_fields/Types"; +import { Cast, StrCast } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { RouteStore } from "../../../server/RouteStore"; import { Utils } from "../../../Utils"; @@ -23,6 +23,8 @@ import React = require("react"); var path = require('path'); import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils"; import { ImageUtils } from "../../util/Import & Export/ImageUtils"; +import { CollectionViewType } from "./CollectionBaseView"; +import { ObjectField } from "../../../new_fields/ObjectField"; export interface CollectionViewProps extends FieldViewProps { addDocument: (document: Doc) => boolean; @@ -126,6 +128,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { @undoBatch @action protected drop(e: Event, de: DragManager.DropEvent): boolean { + (this.props.Document.dropConverter instanceof ScriptField) && + this.props.Document.dropConverter.script.run({ dragData: de.data }); if (de.data instanceof DragManager.DocumentDragData && !de.data.applyAsTemplate) { if (de.mods === "AltKey" && de.data.draggedDocuments.length) { this.childDocs.map(doc => diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index bff8ce5c1..7d0c900a6 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -10,7 +10,6 @@ width:100%; position: relative; top:0; - padding-top: 20px; padding-left: 10px; padding-right: 10px; background: $light-color-secondary; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 2c77c4b5b..5d88e6290 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -576,7 +576,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); return !this.childDocs ? (null) : (
this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index c5bc2e7fb..962fe2a1c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -31,7 +31,7 @@ export class CollectionFreeFormLinkView extends React.Component(["dropAction"]), dragFactory: data.dragFactory + backgroundColor: data.backgroundColor, removeDropProperties: new List(["dropAction"]), dragFactory: data.dragFactory, })); } @@ -69,7 +70,8 @@ export class CurrentUserUtils { static setupCreatePanel(sidebarContainer: Doc, doc: Doc) { // setup a masonry view of all he creators const dragCreators = Docs.Create.MasonryDocument(CurrentUserUtils.setupCreatorButtons(doc), { - width: 500, autoHeight: true, columnWidth: 35, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons" + width: 500, autoHeight: true, columnWidth: 35, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons", + dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), yMargin: 0 }); // setup a color picker const color = Docs.Create.ColorDocument({ @@ -81,7 +83,7 @@ export class CurrentUserUtils { panel: Docs.Create.StackingDocument([dragCreators, color], { width: 500, height: 800, chromeStatus: "disabled", title: "creator stack" }), - onClick: ScriptField.MakeScript("this.targetContainer.proto = this.panel") + onClick: ScriptField.MakeScript("this.targetContainer.proto = this.panel"), }); } @@ -148,7 +150,8 @@ export class CurrentUserUtils { doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc], { title: "expanding buttons", gridGap: 5, xMargin: 5, yMargin: 5, height: 42, width: 100, boxShadow: "0 0", - backgroundColor: "black", preventTreeViewOpen: true, forceActive: true, lockedPosition: true, convertToButtons: true, + backgroundColor: "black", preventTreeViewOpen: true, forceActive: true, lockedPosition: true, + dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }) }); } -- cgit v1.2.3-70-g09d2 From c97b98c165e318da787361b8fc11382b0b98afa4 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 24 Oct 2019 11:54:03 -0400 Subject: several fixes to audioboxes. --- src/client/documents/Documents.ts | 3 ++- .../collections/CollectionMasonryViewFieldRow.tsx | 2 +- .../views/collections/CollectionStackingView.scss | 5 ++++ .../CollectionFreeFormLinkView.scss | 1 + .../CollectionFreeFormLinkView.tsx | 3 +++ src/client/views/nodes/AudioBox.scss | 28 ++++++++++++++-------- src/client/views/nodes/AudioBox.tsx | 19 +++++++-------- src/client/views/nodes/DocuLinkBox.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 9 files changed, 40 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f26594e04..d1fcabc4a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -171,7 +171,7 @@ export namespace Docs { }], [DocumentType.AUDIO, { layout: { view: AudioBox, dataField: data }, - options: { height: 35, backgroundColor: "lightGray", borderRounding: "20%" } + options: { height: 35, backgroundColor: "lightGray" } }], [DocumentType.PDF, { layout: { view: PDFBox, dataField: data }, @@ -714,6 +714,7 @@ export namespace DocUtils { linkDocProto.anchor2Timecode = target.doc.currentTimecode; linkDocProto.layoutKey1 = DocuLinkBox.LayoutString("anchor1"); linkDocProto.layoutKey2 = DocuLinkBox.LayoutString("anchor2"); + linkDocProto.borderRounding = "20"; linkDocProto.width = linkDocProto.height = 0; linkDocProto.isBackground = true; linkDocProto.isButton = true; diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 4259e948b..0249b90b4 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -366,7 +366,7 @@ export class CollectionMasonryViewFieldRow extends React.Component {headingView} {collapsed ? (null) : - < div > + < div style={{ position: "relative" }}>
div { + height: 100%; + position: relative; + display: inline-block; + } .collectionSchemaView-previewDoc { height: 100%; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss index 1f1bca2f2..75af11537 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss @@ -3,6 +3,7 @@ opacity: 0.8; pointer-events: all; stroke-width: 3px; + transition: opacity 0.5s ease-in; } .collectionfreeformlinkview-linkCircle { stroke: rgb(0,0,0); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 962fe2a1c..837413842 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -17,10 +17,12 @@ export interface CollectionFreeFormLinkViewProps { @observer export class CollectionFreeFormLinkView extends React.Component { @observable _alive: number = 0; + @observable _opacity: number = 1; @action componentDidMount() { this._alive = 1; setTimeout(this.rerender, 50); + setTimeout(action(() => this._opacity = 0.05), 50); } @action componentWillUnmount() { @@ -42,6 +44,7 @@ export class CollectionFreeFormLinkView extends React.Component); } diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index ccbf0d75f..3b19a6dba 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -44,22 +44,27 @@ width:100%; height: 80%; position: relative; + padding-right: 5px; display: flex; .audiobox-playhead { position: relative; margin-top: auto; margin-bottom: auto; width: 25px; + padding: 2px; } .audiobox-timeline { position:relative; height:100%; width:100%; + background: white; + border: gray solid 1px; + border-radius: 3px; .audiobox-current { width: 1px; height:100%; background-color: red; - position: absolute;; + position: absolute; } .audiobox-linker, .audiobox-linker-mini { position:absolute; @@ -72,10 +77,11 @@ background-color: transparent; box-shadow: black 2px 2px 1px; .docuLinkBox-cont { - width:15px !important; - height:15px !important; - left: calc(100% - 15px) !important; - top: calc(100% - 15px) !important; + position: relative !important; + height: 100% !important; + width: 100% !important; + left:unset !important; + top:unset !important; } } .audiobox-linker-mini { @@ -86,10 +92,11 @@ margin-left: -1; margin-top: -2; .docuLinkBox-cont { - width:8px !important; - height:8px !important; - left: calc(100% - 8px) !important; - top: calc(100% - 8px) !important; + position: relative !important; + height: 100% !important; + width: 100% !important; + left:unset !important; + top:unset !important; } } .audiobox-linker:hover, .audiobox-linker-mini:hover { @@ -98,7 +105,8 @@ .audiobox-marker-container, .audiobox-marker-minicontainer { position:absolute; width:10px; - height:100%; + height:90%; + top:2.5%; background:gray; border-radius: 5px; box-shadow: black 2px 2px 1px; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index cc1c63d44..bd1caaf1b 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -12,12 +12,11 @@ import { RouteStore } from "../../../server/RouteStore"; import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx"; import { DateField } from "../../../new_fields/DateField"; import { SelectionManager } from "../../util/SelectionManager"; -import { Doc, DocListCast, WidthSym } from "../../../new_fields/Doc"; +import { Doc, DocListCast } from "../../../new_fields/Doc"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; import { Id } from "../../../new_fields/FieldSymbols"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { DocumentManager } from "../../util/DocumentManager"; import { DocumentView } from "./DocumentView"; interface Window { @@ -59,7 +58,7 @@ export class AudioBox extends DocExtendableComponent l[Id] === scrollLinkId).map(l => { let la1 = l.anchor1 as Doc; let linkTime = Doc.AreProtosEqual(la1, this.dataDoc) ? NumCast(l.anchor1Timecode) : NumCast(l.anchor2Timecode); - setTimeout(() => this.playFrom(linkTime), 250); + setTimeout(() => { this.playFrom(linkTime); Doc.linkFollowHighlight(l); }, 250); }); scrollLinkId && Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false); }, { fireImmediately: true }); @@ -75,11 +74,9 @@ export class AudioBox extends DocExtendableComponent { - const extensionDoc = this.extensionDoc; const htmlEle = this._ele; - const start = extensionDoc && DateCast(extensionDoc.recordingStart); - if (start && htmlEle) { - htmlEle && htmlEle.duration && htmlEle.duration !== Infinity && runInAction(() => this.dataDoc.duration = htmlEle.duration); + if (this._audioState === "recorded" && htmlEle) { + htmlEle.duration && htmlEle.duration !== Infinity && runInAction(() => this.dataDoc.duration = htmlEle.duration); DocListCast(this.dataDoc.links).map(l => { let la1 = l.anchor1 as Doc; let linkTime = NumCast(l.anchor2Timecode); @@ -195,7 +192,7 @@ export class AudioBox extends DocExtendableComponent { - e && e.addEventListener("timeupdate", action(() => this.Document.currentTimecode = e!.currentTime)); + e && e.addEventListener("timeupdate", this.timecodeChanged); this._ele = e; } @@ -225,13 +222,13 @@ export class AudioBox extends DocExtendableComponent :
- -
+
+
e.stopPropagation()} onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { let rect = (e.target as any).getBoundingClientRect(); - this._ele!.currentTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); + this._ele!.currentTime = this.Document.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); this.pause(); e.stopPropagation(); } diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx index f2ab6fcd8..8f68effe8 100644 --- a/src/client/views/nodes/DocuLinkBox.tsx +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -73,7 +73,7 @@ export class DocuLinkBox extends DocComponent(Doc let c = StrCast(this.props.Document.backgroundColor, "lightblue"); return
; } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 566b698bd..cf55a10ba 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -192,7 +192,7 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F } let 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 - 5000))); + 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.extensionDoc && (this.extensionDoc.text = state.doc.textBetween(0, state.doc.content.size, "\n\n")); this.extensionDoc && (this.extensionDoc.lastModified = new DateField(new Date(Date.now()))); -- cgit v1.2.3-70-g09d2