From 553fb2a11aa638c35192a1a2f7da99729867e542 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 13 Feb 2020 22:30:32 -0500 Subject: starting a broad cleanup of code. trying to make standard doc field names be more regular --- src/client/views/collections/CollectionCarouselView.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src/client/views/collections/CollectionCarouselView.tsx') diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index f462e20b4..3c86bd799 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -12,7 +12,6 @@ import { CollectionSubView } from './CollectionSubView'; import { faCaretLeft, faCaretRight } from '@fortawesome/free-solid-svg-icons'; import { Doc } from '../../../new_fields/Doc'; import { FormattedTextBox } from '../nodes/FormattedTextBox'; -import { ContextMenuProps } from '../ContextMenuItem'; import { ContextMenu } from '../ContextMenu'; import { ObjectField } from '../../../new_fields/ObjectField'; -- cgit v1.2.3-70-g09d2 From 5aecc6d75868dcafd0b1bb560ad5a4ad8ab976fa Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 14 Feb 2020 14:25:53 -0500 Subject: cleaned up backgroundColor settings and cluster overrides. added a darkScheme --- src/client/documents/Documents.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/MainView.tsx | 27 ++++++++++++----- .../views/collections/CollectionCarouselView.tsx | 1 + .../views/collections/CollectionDockingView.tsx | 3 +- .../views/collections/CollectionSchemaCells.tsx | 3 +- .../views/collections/CollectionStackingView.tsx | 1 + .../views/collections/CollectionTreeView.scss | 9 ++++-- .../views/collections/CollectionTreeView.tsx | 16 ++++++---- src/client/views/collections/CollectionView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 12 ++++---- .../collections/collectionFreeForm/MarqueeView.tsx | 3 +- .../CollectionMulticolumnView.tsx | 1 + .../CollectionMultirowView.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 7 ++--- .../views/nodes/ContentFittingDocumentView.tsx | 5 ++-- src/client/views/nodes/DocumentView.tsx | 34 +++++----------------- src/client/views/nodes/FieldView.tsx | 6 ++-- src/client/views/nodes/FormattedTextBox.tsx | 3 +- 19 files changed, 72 insertions(+), 67 deletions(-) (limited to 'src/client/views/collections/CollectionCarouselView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index adcdf260d..53671707e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -168,7 +168,7 @@ export namespace Docs { const TemplateMap: TemplateMap = new Map([ [DocumentType.TEXT, { layout: { view: FormattedTextBox, dataField: data }, - options: { _height: 150, backgroundColor: "#f1efeb", defaultBackgroundColor: "#f1efeb" } + options: { _height: 150 } }], [DocumentType.HIST, { layout: { view: HistogramBox, dataField: data }, diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index ff0d2718c..2201fe710 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -301,7 +301,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | const view0 = this.view0; const templates: Map = new Map(); Array.from(Object.values(Templates.TemplateList)).map(template => - templates.set(template, this.props.views.reduce((checked, doc) => checked || doc?.getLayoutPropStr("_show" + template.Name) ? true : false, false as boolean))); + templates.set(template, this.props.views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); return !view0 ? (null) :
v).map(v => v as DocumentView)} templates={templates} />}> diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 192f3b8fb..ba49a2b53 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -13,7 +13,7 @@ import { Doc, DocListCast, Field, FieldResult, Opt } from '../../new_fields/Doc' import { Id } from '../../new_fields/FieldSymbols'; import { List } from '../../new_fields/List'; import { listSpec } from '../../new_fields/Schema'; -import { Cast, FieldValue, StrCast } from '../../new_fields/Types'; +import { Cast, FieldValue, StrCast, BoolCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils, emptyPath } from '../../Utils'; import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager'; @@ -43,6 +43,7 @@ import SettingsManager from '../util/SettingsManager'; import { TraceMobx } from '../../new_fields/util'; import { RadialMenu } from './nodes/RadialMenu'; import RichTextMenu from '../util/RichTextMenu'; +import { DocumentType } from '../documents/DocumentTypes'; @observer export class MainView extends React.Component { @@ -56,8 +57,9 @@ export class MainView extends React.Component { @observable private _panelHeight: number = 0; @observable private _flyoutTranslate: boolean = true; @observable public flyoutWidth: number = 250; + private get darkScheme() { return BoolCast(Cast(this.userDoc.activeWorkspace, Doc, null)?.darkScheme); } - @computed private get userDoc() { return CurrentUserUtils.UserDocument; } + @computed private get userDoc() { return Doc.UserDoc(); } @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; } @computed public get mainFreeform(): Opt { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); } @computed public get sidebarButtonsDoc() { return Cast(CurrentUserUtils.UserDocument.sidebarButtons, Doc) as Doc; } @@ -207,7 +209,6 @@ export class MainView extends React.Component { _width: this._panelWidth * .7, _height: this._panelHeight, title: "Collection " + workspaceCount, - backgroundColor: "white" }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); Doc.AddDocToList(Doc.GetProto(CurrentUserUtils.UserDocument.documents as Doc), "data", freeformDoc); @@ -273,6 +274,16 @@ export class MainView extends React.Component { getPHeight = () => this._panelHeight; getContentsHeight = () => this._panelHeight - this._buttonBarHeight; + childBackgroundColor = (doc: Doc) => { + if (this.darkScheme) { + return doc.type === DocumentType.TEXT ? "#112423" : "black"; + } + return doc.type === DocumentType.TEXT ? "#f1efeb" : + doc.type === DocumentType.COL && doc._viewType === CollectionViewType.Tree ? "lightgray" : "white"; + } + sidebarBackgroundColor = (doc: Doc) => { + return this.childBackgroundColor(doc); + } @computed get mainDocView() { return new Transform(0, -this._buttonBarHeight, 1); @computed get flyout() { - const sidebarContent = this.userDoc && this.userDoc.sidebarContainer; + const sidebarContent = this.userDoc?.sidebarContainer; if (!(sidebarContent instanceof Doc)) { return (null); } @@ -388,7 +399,7 @@ export class MainView extends React.Component { PanelHeight={this.getPHeight} renderDepth={0} focus={emptyFunction} - backgroundColor={returnEmptyString} + backgroundColor={this.sidebarBackgroundColor} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -414,7 +425,7 @@ export class MainView extends React.Component { PanelHeight={this.getContentsHeight} renderDepth={0} focus={emptyFunction} - backgroundColor={returnEmptyString} + backgroundColor={this.sidebarBackgroundColor} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -437,7 +448,7 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc && this.userDoc.sidebarContainer; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : ( -
+
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 3c86bd799..226a1c813 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -52,6 +52,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
string| undefined; //collectionDockingView: CollectionDockingView } @observer @@ -756,7 +757,7 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyFunction} - backgroundColor={returnEmptyString} + backgroundColor={CollectionDockingView.Instance.props.backgroundColor} addDocTab={this.addDocTab} pinToPres={DockedFrameRenderer.PinDoc} ContainingCollectionView={undefined} diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index caffa7eb1..a3b1b5ec0 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -37,7 +37,8 @@ export interface CellProps { renderDepth: number; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; - moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean; + moveDocument: (document: Doc, targetCollection: Doc | undefined, + addDocument: (document: Doc) => boolean) => boolean; isFocused: boolean; changeFocusedCellByIndex: (row: number, col: number) => void; setIsEditing: (isEditing: boolean) => void; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 7d1f2c284..055035b3e 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -159,6 +159,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { return void; outdentDocument?: () => void; ScreenToLocalTransform: () => Transform; + backgroundColor?: (doc: Doc) => string | undefined; outerXf: () => { translateX: number, translateY: number }; treeViewId: Doc; parentKey: string; @@ -289,7 +290,7 @@ class TreeView extends React.Component { const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true); contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, + this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, doc[Id]], this.props.libraryPath, this.props.onCheckedClick); } else { @@ -332,7 +333,7 @@ class TreeView extends React.Component { {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document), this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, + this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath, this.props.onCheckedClick)} ; @@ -348,6 +349,7 @@ class TreeView extends React.Component { DataDocument={this.templateDataDoc} LibraryPath={emptyPath} renderDepth={this.props.renderDepth + 1} + backgroundColor={this.props.backgroundColor} fitToBox={this.boundsOfCollectionDocument !== undefined} PanelWidth={this.docWidth} PanelHeight={this.docHeight} @@ -384,7 +386,7 @@ class TreeView extends React.Component { @computed get renderBullet() { const checked = this.props.document.type === DocumentType.COL ? undefined : this.props.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined; - return
+ return
{}
; } @@ -415,7 +417,7 @@ class TreeView extends React.Component { return <>
{ dropAction: dropActionType, addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean, pinToPres: (document: Doc) => void, + backgroundColor: undefined | ((document: Doc) => string | undefined), screenToLocalXf: () => Transform, outerXf: () => { translateX: number, translateY: number }, active: (outsideReaction?: boolean) => boolean, @@ -561,6 +564,7 @@ class TreeView extends React.Component { renderDepth={renderDepth} deleteDoc={remove} addDocument={addDocument} + backgroundColor={backgroundColor} panelWidth={rowWidth} panelHeight={rowHeight} ChromeHeight={ChromeHeight} @@ -714,7 +718,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { const moveDoc = (d: Doc, target: Doc | undefined, 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} @@ -737,7 +741,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
    { TreeView.GetChildElements(this.childDocs, this.props.Document, this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, - moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, + moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => BoolCast(this.props.Document.treeViewHideHeaderFields), BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, ScriptCast(this.props.Document.onCheckedClick)) } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 39ce4d6e8..be971eda6 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -38,6 +38,7 @@ import { CollectionViewBaseChrome } from './CollectionViewChromes'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { List } from '../../../new_fields/List'; +import { SubCollectionViewProps } from './CollectionSubView'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); @@ -177,7 +178,7 @@ export class CollectionView extends Touchable { } private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => { - const props = { ...this.props, ...renderProps, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" }; + const props: SubCollectionViewProps = { ...this.props, ...renderProps, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" }; switch (type) { case CollectionViewType.Schema: return (); case CollectionViewType.Docking: return (); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e1854fc2d..969d6b3c8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -10,7 +10,7 @@ import { Id } from "../../../../new_fields/FieldSymbols"; import { InkTool } from "../../../../new_fields/InkField"; import { createSchema, listSpec, makeInterface } from "../../../../new_fields/Schema"; import { ScriptField } from "../../../../new_fields/ScriptField"; -import { Cast, NumCast, ScriptCast, StrCast } from "../../../../new_fields/Types"; +import { Cast, NumCast, ScriptCast, BoolCast, StrCast } from "../../../../new_fields/Types"; import { TraceMobx } from "../../../../new_fields/util"; import { GestureUtils } from "../../../../pen-gestures/GestureUtils"; import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils"; @@ -206,6 +206,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } @undoBatch + @action updateClusters(useClusters: boolean) { this.props.Document.useClusters = useClusters; this._clusterSets.length = 0; @@ -243,7 +244,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { docs.map(doc => this._clusterSets[doc.cluster = NumCast(docFirst.cluster)].push(doc)); } childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.cluster === i) && this.updateCluster(child)); - childLayouts.map(child => Doc.GetProto(child).clusterStr = child.cluster?.toString()); } } @@ -279,16 +279,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } getClusterColor = (doc: Doc) => { - let clusterColor = ""; + let clusterColor = this.props.backgroundColor?.(doc); const cluster = NumCast(doc.cluster); if (this.Document.useClusters) { if (this._clusterSets.length <= cluster) { setTimeout(() => this.updateCluster(doc), 0); } else { // choose a cluster color from a palette - const colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"]; + const colors = ["#da42429e", "#31ea318c", "rgba(197, 87, 20, 0.55)", "#4a7ae2c4", "rgba(216, 9, 255, 0.5)", "#ff7601", "#1dffff", "yellow", "rgba(27, 130, 49, 0.55)", "rgba(0, 0, 0, 0.268)"]; clusterColor = colors[cluster % colors.length]; - const set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor)); + const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor); // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor)); set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor)); @@ -709,6 +709,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; } @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } + backgroundHalo = () => BoolCast(this.Document.useClusters); getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { return { @@ -728,6 +729,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { ContainingCollectionDoc: this.props.Document, focus: this.focusDocument, backgroundColor: this.getClusterColor, + backgroundHalo: this.backgroundHalo, parentActive: this.props.active, bringToFront: this.bringToFront, zoomToScale: this.zoomToScale, diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4b0855635..85cda4ecb 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -308,8 +308,7 @@ export class MarqueeView extends React.Component this.nativeWidth > 0 && !this.props.Document.ignoreAspect && !this.props.fitToBox ? this.width / this.nativeWidth : 1; - clusterColorFunc = (doc: Doc) => this.clusterColor; panelWidth = () => (this.dataProvider?.width || this.props.PanelWidth()); panelHeight = () => (this.dataProvider?.height || this.props.PanelHeight()); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) .scale(1 / this.contentScaling()) - @computed - get clusterColor() { return this.props.backgroundColor(this.props.Document); } focusDoc = (doc: Doc) => this.props.focus(doc, false); render() { TraceMobx(); @@ -78,7 +75,7 @@ export class CollectionFreeFormDocumentView extends DocComponent : string | undefined; getTransform: () => Transform; addDocument?: (document: Doc) => boolean; moveDocument?: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean; @@ -86,6 +87,7 @@ export class ContentFittingDocumentView extends React.Component boolean; pinToPres: (document: Doc) => void; zoomToScale: (scale: number) => void; - backgroundColor: (doc: Doc) => string | undefined; + backgroundHalo?: () => boolean; + backgroundColor?: (doc: Doc) => string | undefined; getScale: () => number; animateBetweenIcon?: (maximize: boolean, target: number[]) => void; ChromeHeight?: () => number; @@ -295,12 +296,6 @@ export class DocumentView extends DocComponent(Docu this._downX = touch.clientX; this._downY = touch.clientY; if (!e.nativeEvent.cancelBubble) { - this._hitTemplateDrag = false; - for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) { - if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") { - this._hitTemplateDrag = true; - } - } if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); this.removeMoveListeners(); this.addMoveListeners(); @@ -778,14 +773,6 @@ export class DocumentView extends DocComponent(Docu }); } - // does Document set a layout prop - setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)] && this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)]; - // get the a layout prop by first choosing the prop from Document, then falling back to the layout doc otherwise. - getLayoutPropStr = (prop: string) => { - return StrCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : Cast(this.layoutDoc?.expandedTemplate, Doc, null)?.[prop] || this.layoutDoc[prop]); - } - getLayoutPropNum = (prop: string) => NumCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]); - isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction); select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; @@ -848,9 +835,9 @@ export class DocumentView extends DocComponent(Docu @computed get innards() { TraceMobx(); - const showTitle = StrCast(this.getLayoutPropStr("_showTitle")); - const showTitleHover = StrCast(this.getLayoutPropStr("_showTitleHover")); - const showCaption = this.getLayoutPropStr("_showCaption"); + const showTitle = StrCast(this.layoutDoc._showTitle); + const showTitleHover = StrCast(this.layoutDoc._showTitleHover); + const showCaption = StrCast(this.layoutDoc._showCaption); const showTextTitle = showTitle && (StrCast(this.layoutDoc.layout).indexOf("PresBox") !== -1 || StrCast(this.layoutDoc.layout).indexOf("FormattedTextBox") !== -1) ? showTitle : undefined; const searchHighlight = (!this.Document.searchFields ? (null) :
    @@ -921,14 +908,9 @@ export class DocumentView extends DocComponent(Docu render() { if (!(this.props.Document instanceof Doc)) return (null); - const colorSet = this.setsLayoutProp("backgroundColor"); - const clusterCol = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.clusterOverridesDefaultBackground; - const backgroundColor = (clusterCol && !colorSet) ? - this.props.backgroundColor(this.Document) || StrCast(this.layoutDoc.backgroundColor) : - StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.Document); - + const backgroundColor = StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor?.(this.Document); const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document); - const borderRounding = this.getLayoutPropStr("borderRounding"); + const borderRounding = this.layoutDoc.borderRounding; const localScale = fullDegree; const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"]; @@ -943,7 +925,7 @@ export class DocumentView extends DocComponent(Docu transform: this._animate ? `scale(${this._animate})` : undefined, transition: !this._animate ? StrCast(this.Document.transition) : this._animate < 1 ? "transform 0.5s ease-in" : "transform 0.5s ease-out", pointerEvents: this.ignorePointerEvents ? "none" : "all", - color: StrCast(this.Document.color), + color: StrCast(this.Document.color, "inherit"), outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px", border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined, boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined, diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 8250f41f3..00f00dd52 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -3,14 +3,13 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../new_fields/DateField"; import { Doc, FieldResult, Opt } from "../../../new_fields/Doc"; -import { IconField } from "../../../new_fields/IconField"; import { List } from "../../../new_fields/List"; -import { AudioField, ImageField, VideoField } from "../../../new_fields/URLField"; +import { ScriptField } from "../../../new_fields/ScriptField"; +import { AudioField, VideoField } from "../../../new_fields/URLField"; import { Transform } from "../../util/Transform"; import { CollectionView } from "../collections/CollectionView"; import { AudioBox } from "./AudioBox"; import { VideoBox } from "./VideoBox"; -import { ScriptField } from "../../../new_fields/ScriptField"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -34,6 +33,7 @@ export interface FieldViewProps { pinToPres: (document: Doc) => void; removeDocument?: (document: Doc) => boolean; moveDocument?: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean; + backgroundColor?: (document: Doc) => string | undefined; ScreenToLocalTransform: () => Transform; active: (outsideReaction?: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 2fb61f9db..3c64b3974 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -186,7 +186,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & 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; 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")); } @@ -1075,7 +1074,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
    Date: Fri, 14 Feb 2020 16:20:15 -0500 Subject: carousel cleanup --- .../views/collections/CollectionCarouselView.tsx | 34 +++++++++------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections/CollectionCarouselView.tsx') diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 226a1c813..8167416c6 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -20,17 +20,12 @@ const CarouselDocument = makeInterface(documentSchema); @observer export class CollectionCarouselView extends CollectionSubView(CarouselDocument) { - @observable public addMenuToggle = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; - componentWillUnmount() { - this._dropDisposer && this._dropDisposer(); - } + componentWillUnmount() { this._dropDisposer?.(); } - componentDidMount() { - } protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view - this._dropDisposer && this._dropDisposer(); + this._dropDisposer?.(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); } @@ -46,22 +41,21 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) } panelHeight = () => this.props.PanelHeight() - 50; - @computed get content() { + @computed get content() { const index = NumCast(this.layoutDoc._itemIndex); return !(this.childLayoutPairs?.[index]?.layout instanceof Doc) ? (null) : -
    -
    - -
    -
    - -
    + <> +
    + +
    +
    +
    + } @computed get buttons() { return <> -- cgit v1.2.3-70-g09d2 From b42e1e1e2da941955d7751b6003f18fecd5f2f8d Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Sun, 16 Feb 2020 12:22:10 -0500 Subject: collection sub view and google authentication manager cleanup, deleteAssets route added --- src/client/apis/GoogleAuthenticationManager.tsx | 46 ++-- .../views/collections/CollectionCarouselView.tsx | 28 +-- .../views/collections/CollectionLinearView.tsx | 2 +- .../collections/CollectionMasonryViewFieldRow.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 7 +- .../views/collections/CollectionStackingView.tsx | 12 +- .../CollectionStackingViewFieldColumn.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 264 +++++++++++---------- .../views/collections/CollectionTreeView.tsx | 6 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 +- .../CollectionMulticolumnView.tsx | 6 +- .../CollectionMultirowView.tsx | 6 +- src/server/ApiManagers/DeleteManager.ts | 31 +-- 13 files changed, 213 insertions(+), 209 deletions(-) (limited to 'src/client/views/collections/CollectionCarouselView.tsx') diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx index ce1277667..417dc3c3b 100644 --- a/src/client/apis/GoogleAuthenticationManager.tsx +++ b/src/client/apis/GoogleAuthenticationManager.tsx @@ -12,8 +12,8 @@ const prompt = "Paste authorization code here..."; @observer export default class GoogleAuthenticationManager extends React.Component<{}> { public static Instance: GoogleAuthenticationManager; - @observable private openState = false; private authenticationLink: Opt = undefined; + @observable private openState = false; @observable private authenticationCode: Opt = undefined; @observable private clickedState = false; @observable private success: Opt = undefined; @@ -39,24 +39,18 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { const disposer = reaction( () => this.authenticationCode, async authenticationCode => { - if (!authenticationCode) { - return; + if (authenticationCode) { + disposer(); + const { access_token, avatar, name } = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode }); + runInAction(() => { + this.avatar = avatar; + this.username = name; + this.hasBeenClicked = false; + this.success = false; + }); + this.beginFadeout(); + resolve(access_token); } - const { access_token, avatar, name } = await Networking.PostToServer( - "/writeGoogleAccessToken", - { authenticationCode } - ); - runInAction(() => { - this.avatar = avatar; - this.username = name; - }); - this.beginFadeout(); - disposer(); - resolve(access_token); - action(() => { - this.hasBeenClicked = false; - this.success = false; - }); } ); }); @@ -86,26 +80,20 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { GoogleAuthenticationManager.Instance = this; } - private handleClick = () => { - window.open(this.authenticationLink); - setTimeout(() => this.hasBeenClicked = true, 500); - } - - private handlePaste = action((e: React.ChangeEvent) => { - this.authenticationCode = e.currentTarget.value; - }); - private get renderPrompt() { return (
    {this.displayLauncher ? : (null)} {this.clickedState ? this.authenticationCode = e.currentTarget.value)} placeholder={prompt} /> : (null)} {this.avatar ? { //used for stacking and masonry view this._dropDisposer?.(); if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); } } @@ -41,21 +41,21 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) } panelHeight = () => this.props.PanelHeight() - 50; - @computed get content() { + @computed get content() { const index = NumCast(this.layoutDoc._itemIndex); return !(this.childLayoutPairs?.[index]?.layout instanceof Doc) ? (null) : - <> -
    - -
    -
    - -
    - + <> +
    + +
    +
    + +
    + ; } @computed get buttons() { return <> diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 7eb316cf0..9bbc9f1b6 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -67,7 +67,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view this._dropDisposer && this._dropDisposer(); if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); } } diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index e25a2f5eb..f3d512a97 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -80,7 +80,7 @@ export class CollectionMasonryViewFieldRow extends React.Component d[key] = castedValue); - this.props.parent.drop(e, de); + this.props.parent.onInternalDrop(e, de); e.stopPropagation(); } }); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index fa8be5177..c422c38f1 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -14,7 +14,6 @@ import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { ComputedField } from "../../../new_fields/ScriptField"; import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types"; import { Docs, DocumentOptions } from "../../documents/Documents"; -import { DocumentType } from "../../documents/DocumentTypes"; import { Gateway } from "../../northstar/manager/Gateway"; import { CompileScript, Transformer, ts } from "../../util/Scripting"; import { Transform } from "../../util/Transform"; @@ -175,7 +174,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { moveDocument={this.props.moveDocument} ScreenToLocalTransform={this.props.ScreenToLocalTransform} active={this.props.active} - onDrop={this.onDrop} + onDrop={this.onExternalDrop} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} isSelected={this.props.isSelected} @@ -199,7 +198,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { render() { return
    -
    this.props.active(true) && e.stopPropagation()} onDrop={e => this.onDrop(e, {})} ref={this.createTarget}> +
    this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} ref={this.createTarget}> {this.schemaTable}
    {this.dividerDragger} @@ -692,7 +691,7 @@ export class SchemaTable extends React.Component { onContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 // ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB, icon: "table" }); - ContextMenu.Instance.addItem({ description: "Toggle text wrapping", event: this.toggleTextwrap, icon: "table" }) + ContextMenu.Instance.addItem({ description: "Toggle text wrapping", event: this.toggleTextwrap, icon: "table" }); } } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 055035b3e..a9cefae6a 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -189,7 +189,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDocHeight(d?: Doc) { if (!d) return 0; - let layoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.()); + const layoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.()); const nw = NumCast(layoutDoc._nativeWidth); const nh = NumCast(layoutDoc._nativeHeight); let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); @@ -234,7 +234,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { @undoBatch @action - drop = (e: Event, de: DragManager.DropEvent) => { + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { const where = [de.x, de.y]; let targInd = -1; let plusOne = 0; @@ -248,7 +248,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { plusOne = where[axis] > (pos[axis] + pos1[axis]) / 2 ? 1 : 0; } }); - if (super.drop(e, de)) { + if (super.onInternalDrop(e, de)) { const newDoc = de.complete.docDragData.droppedDocuments[0]; const docs = this.childDocList; if (docs) { @@ -264,7 +264,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } @undoBatch @action - onDrop = async (e: React.DragEvent): Promise => { + onExternalDrop = async (e: React.DragEvent): Promise => { const where = [e.clientX, e.clientY]; let targInd = -1; this._docXfs.map((cd, i) => { @@ -274,7 +274,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { targInd = i; } }); - super.onDrop(e, {}, () => { + super.onExternalDrop(e, {}, () => { if (targInd !== -1) { const newDoc = this.childDocs[this.childDocs.length - 1]; const docs = this.childDocList; @@ -405,7 +405,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { transformOrigin: "top left", }} onScroll={action((e: React.UIEvent) => this._scroll = e.currentTarget.scrollTop)} - onDrop={this.onDrop.bind(this)} + onDrop={this.onExternalDrop.bind(this)} onContextMenu={this.onContextMenu} onWheel={e => this.props.active() && e.stopPropagation()} > {this.renderedSections} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 2ff477c57..87c35679f 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -71,7 +71,7 @@ export class CollectionStackingViewFieldColumn extends React.Component d[key] = undefined); } - this.props.parent.drop(e, de); + this.props.parent.onInternalDrop(e, de); e.stopPropagation(); } }); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index e80e1c802..042385dcd 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -57,7 +57,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { this.gestureDisposer?.(); this.multiTouchDisposer?.(); if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this)); this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this)); } @@ -156,7 +156,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { @undoBatch @action - protected drop(e: Event, de: DragManager.DropEvent): boolean { + protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { const docDragData = de.complete.docDragData; (this.props.Document.dropConverter instanceof ScriptField) && this.props.Document.dropConverter.script.run({ dragData: docDragData }); /// bcz: check this @@ -195,158 +195,172 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { @undoBatch @action - protected async onDrop(e: React.DragEvent, options: DocumentOptions, completed?: () => void) { + protected async onExternalDrop(e: React.DragEvent, options: DocumentOptions, completed?: () => void) { if (e.ctrlKey) { e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl return; } - const html = e.dataTransfer.getData("text/html"); - const text = e.dataTransfer.getData("text/plain"); + + const { dataTransfer } = e; + const html = dataTransfer.getData("text/html"); + const text = dataTransfer.getData("text/plain"); if (text && text.startsWith(" { - if (f instanceof Doc) { - if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView - (f instanceof Doc) && this.props.addDocument(f); - } - }); - } else { - this.props.addDocument && this.props.addDocument(Docs.Create.WebDocument(href, { ...options, title: href })); - } - } else if (text) { - this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument(text, { ...options, _width: 100, _height: 25 })); - } + const { addDocument } = this.props; + if (!addDocument) { + alert("this.props.addDocument does not exist. Aborting drop operation."); return; } - if (html && !html.startsWith(" 1 && tags[1].startsWith("img") ? tags[1] : ""; - if (img) { - const split = img.split("src=\"")[1].split("\"")[0]; - let source = split; - if (split.startsWith("data:image") && split.includes("base64")) { - const [{ accessPaths }] = await Networking.PostToServer("/uploadRemoteImage", { sources: [split] }); - source = Utils.prepend(accessPaths.agnostic.client); + + if (html) { + if (FormattedTextBox.IsFragment(html)) { + const href = FormattedTextBox.GetHref(html); + if (href) { + const docid = FormattedTextBox.GetDocFromUrl(href); + if (docid) { // prosemirror text containing link to dash document + DocServer.GetRefField(docid).then(f => { + if (f instanceof Doc) { + if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView + (f instanceof Doc) && addDocument(f); + } + }); + } else { + addDocument(Docs.Create.WebDocument(href, { ...options, title: href })); + } + } else if (text) { + addDocument(Docs.Create.TextDocument(text, { ...options, _width: 100, _height: 25 })); } - const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 }); - ImageUtils.ExtractExif(doc); - this.props.addDocument(doc); return; - } else { - const path = window.location.origin + "/doc/"; - if (text.startsWith(path)) { - const docid = text.replace(Utils.prepend("/doc/"), "").split("?")[0]; - DocServer.GetRefField(docid).then(f => { - if (f instanceof Doc) { - if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView - (f instanceof Doc) && this.props.addDocument(f); - } - }); + } + if (!html.startsWith(" 1 && tags[1].startsWith("img") ? tags[1] : ""; + if (img) { + const split = img.split("src=\"")[1].split("\"")[0]; + let source = split; + if (split.startsWith("data:image") && split.includes("base64")) { + const [{ accessPaths }] = await Networking.PostToServer("/uploadRemoteImage", { sources: [split] }); + source = Utils.prepend(accessPaths.agnostic.client); + } + const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 }); + ImageUtils.ExtractExif(doc); + addDocument(doc); + return; } else { - const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300 }); - Doc.GetProto(htmlDoc)["data-text"] = text; - this.props.addDocument(htmlDoc); + const path = window.location.origin + "/doc/"; + if (text.startsWith(path)) { + const docid = text.replace(Utils.prepend("/doc/"), "").split("?")[0]; + DocServer.GetRefField(docid).then(f => { + if (f instanceof Doc) { + if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView + (f instanceof Doc) && this.props.addDocument(f); + } + }); + } else { + const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300 }); + Doc.GetProto(htmlDoc)["data-text"] = text; + this.props.addDocument(htmlDoc); + } + return; } - return; } } - if (text && text.indexOf("www.youtube.com/watch") !== -1) { - const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/"); - this.props.addDocument(Docs.Create.VideoDocument(url, { ...options, title: url, _width: 400, _height: 315, _nativeWidth: 600, _nativeHeight: 472.5 })); - return; - } - let matches: RegExpExecArray | null; - if ((matches = /(https:\/\/)?docs\.google\.com\/document\/d\/([^\\]+)\/edit/g.exec(text)) !== null) { - const newBox = Docs.Create.TextDocument("", { ...options, _width: 400, _height: 200, title: "Awaiting title from Google Docs..." }); - const proto = newBox.proto!; - const documentId = matches[2]; - proto[GoogleRef] = documentId; - proto.data = "Please select this document and then click on its pull button to load its contents from from Google Docs..."; - proto.backgroundColor = "#eeeeff"; - this.props.addDocument(newBox); - // const parent = Docs.Create.StackingDocument([newBox], { title: `Google Doc Import (${documentId})` }); - // CollectionDockingView.Instance.AddRightSplit(parent, undefined); - // proto.height = parent[HeightSym](); - return; - } - if ((matches = /(https:\/\/)?photos\.google\.com\/(u\/3\/)?album\/([^\\]+)/g.exec(text)) !== null) { - const albums = await GooglePhotos.Transactions.ListAlbums(); - const albumId = matches[3]; - const mediaItems = await GooglePhotos.Query.AlbumSearch(albumId); - console.log(mediaItems); - return; + + if (text) { + if (text.includes("www.youtube.com/watch")) { + const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/"); + addDocument(Docs.Create.VideoDocument(url, { + ...options, + title: url, + _width: 400, + _height: 315, + _nativeWidth: 600, + _nativeHeight: 472.5 + })); + return; + } + let matches: RegExpExecArray | null; + if ((matches = /(https:\/\/)?docs\.google\.com\/document\/d\/([^\\]+)\/edit/g.exec(text)) !== null) { + const newBox = Docs.Create.TextDocument("", { ...options, _width: 400, _height: 200, title: "Awaiting title from Google Docs..." }); + const proto = newBox.proto!; + const documentId = matches[2]; + proto[GoogleRef] = documentId; + proto.data = "Please select this document and then click on its pull button to load its contents from from Google Docs..."; + proto.backgroundColor = "#eeeeff"; + addDocument(newBox); + return; + } + if ((matches = /(https:\/\/)?photos\.google\.com\/(u\/3\/)?album\/([^\\]+)/g.exec(text)) !== null) { + const albumId = matches[3]; + const mediaItems = await GooglePhotos.Query.AlbumSearch(albumId); + console.log(mediaItems); + return; + } } + const { items } = e.dataTransfer; const { length } = items; const files: File[] = []; - if (length) { - const batch = UndoManager.StartBatch("collection view drop"); - const promises: Promise[] = []; - // tslint:disable-next-line:prefer-for-of - for (let i = 0; i < length; i++) { - const item = e.dataTransfer.items[i]; - if (item.kind === "string" && item.type.indexOf("uri") !== -1) { - let str: string; - const prom = new Promise(resolve => item.getAsString(resolve)) - .then(action((s: string) => rp.head(Utils.CorsProxy(str = s)))) - .then(result => { - const type = result["content-type"]; - if (type) { - Docs.Get.DocumentFromType(type, str, options) - .then(doc => doc && this.props.addDocument(doc)); - } - }); - promises.push(prom); - } - if (item.kind === "file") { - const file = item.getAsFile(); - file && file.type && files.push(file); + const generatedDocuments: Doc[] = []; + if (!length) { + alert("No uploadable content found."); + return; + } + + const batch = UndoManager.StartBatch("collection view drop"); + for (let i = 0; i < length; i++) { + const item = e.dataTransfer.items[i]; + if (item.kind === "string" && item.type.includes("uri")) { + const stringContents = await new Promise(resolve => item.getAsString(resolve)); + const type = (await rp.head(Utils.CorsProxy(stringContents)))["content-type"]; + if (type) { + const doc = await Docs.Get.DocumentFromType(type, stringContents, options); + doc && generatedDocuments.push(doc); } } - promises.push(Networking.UploadFilesToServer(files).then(responses => responses.forEach(({ source: { name, type }, result }) => { - if (result instanceof Error) { - alert(`Upload failed: ${result.message}`); - return; - } - const full = { ...options, _width: 300, title: name }; - const pathname = Utils.prepend(result.accessPaths.agnostic.client); - Docs.Get.DocumentFromType(type, pathname, full).then(doc => { - if (doc) { - const proto = Doc.GetProto(doc); - proto.fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""); - if (Upload.isImageInformation(result)) { - proto["data-nativeWidth"] = result.nativeWidth; - proto["data-nativeHeight"] = result.nativeHeight; - proto.contentSize = result.contentSize; - } - this.props?.addDocument(doc); - } - }); - }))); - if (promises.length) { - Promise.all(promises).finally(() => { completed && completed(); batch.end(); }); - } else { - if (text && !text.includes("https://")) { - this.props.addDocument(Docs.Create.TextDocument(text, { ...options, _width: 400, _height: 315 })); - } - batch.end(); + if (item.kind === "file") { + const file = item.getAsFile(); + file && file.type && files.push(file); + } + } + for (const { source: { name, type }, result } of await Networking.UploadFilesToServer(files)) { + if (result instanceof Error) { + alert(`Upload failed: ${result.message}`); + return; } + const full = { ...options, _width: 300, title: name }; + const pathname = Utils.prepend(result.accessPaths.agnostic.client); + const doc = await Docs.Get.DocumentFromType(type, pathname, full); + if (!doc) { + continue; + } + const proto = Doc.GetProto(doc); + proto.fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""); + if (Upload.isImageInformation(result)) { + proto["data-nativeWidth"] = result.nativeWidth; + proto["data-nativeHeight"] = result.nativeHeight; + proto.contentSize = result.contentSize; + } + generatedDocuments.push(doc); + } + if (generatedDocuments.length) { + generatedDocuments.forEach(addDocument); + completed && completed(); } else { - alert("No uploadable content found."); + if (text && !text.includes("https://")) { + addDocument(Docs.Create.TextDocument(text, { ...options, _width: 400, _height: 315 })); + } } + batch.end(); } } + return CollectionSubView; } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 8720ce002..13ab7c1a4 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -210,7 +210,7 @@ class TreeView extends React.Component { } else { ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" }); ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" }); - } + } ContextMenu.Instance.addItem({ description: "Toggle Theme Colors", event: () => this.props.document.darkScheme = !this.props.document.darkScheme, icon: "minus" }); ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { _width: 300, _height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" }); ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" }); @@ -594,7 +594,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { protected createTreeDropTarget = (ele: HTMLDivElement) => { this.treedropDisposer && this.treedropDisposer(); if (this._mainEle = ele) { - this.treedropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); } } @@ -702,7 +702,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); } outerXf = () => Utils.GetScreenTransform(this._mainEle!); - onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {}); + onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {}); @computed get renderClearButton() { return
    diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 969d6b3c8..bdc5e03e3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -117,20 +117,20 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } @action - onDrop = (e: React.DragEvent): Promise => { + onExternalDrop = (e: React.DragEvent): Promise => { const pt = this.getTransform().transformPoint(e.pageX, e.pageY); - return super.onDrop(e, { x: pt[0], y: pt[1] }); + return super.onExternalDrop(e, { x: pt[0], y: pt[1] }); } @undoBatch @action - drop = (e: Event, de: DragManager.DropEvent) => { + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (this.props.Document.isBackground) return false; const xf = this.getTransform(); const xfo = this.getTransformOverlay(); const [xp, yp] = xf.transformPoint(de.x, de.y); const [xpo, ypo] = xfo.transformPoint(de.x, de.y); - if (super.drop(e, de)) { + if (super.onInternalDrop(e, de)) { if (de.complete.docDragData) { if (de.complete.docDragData.droppedDocuments.length) { const firstDoc = de.complete.docDragData.droppedDocuments[0]; @@ -1079,7 +1079,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return
    { - if (super.drop(e, de)) { + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { + if (super.onInternalDrop(e, de)) { de.complete.docDragData?.droppedDocuments.forEach(action((d: Doc) => { d.dimUnit = "*"; d.dimMagnitude = 1; @@ -214,7 +214,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu getTransform={dxf} onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} - /> + />; } /** * @returns the resolved list of rendered child documents, displayed diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 630a178cf..5e59f8237 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -190,8 +190,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) @undoBatch @action - drop = (e: Event, de: DragManager.DropEvent) => { - if (super.drop(e, de)) { + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { + if (super.onInternalDrop(e, de)) { de.complete.docDragData?.droppedDocuments.forEach(action((d: Doc) => { d.dimUnit = "*"; d.dimMagnitude = 1; @@ -215,7 +215,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) getTransform={dxf} onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} - /> + />; } /** * @returns the resolved list of rendered child documents, displayed diff --git a/src/server/ApiManagers/DeleteManager.ts b/src/server/ApiManagers/DeleteManager.ts index be452c0ff..9e70af2eb 100644 --- a/src/server/ApiManagers/DeleteManager.ts +++ b/src/server/ApiManagers/DeleteManager.ts @@ -2,6 +2,11 @@ import ApiManager, { Registration } from "./ApiManager"; import { Method, _permission_denied, PublicHandler } from "../RouteManager"; import { WebSocket } from "../Websocket/Websocket"; import { Database } from "../database"; +import rimraf = require("rimraf"); +import { pathToDirectory, Directory } from "./UploadManager"; +import { filesDirectory } from ".."; +import { DashUploadUtils } from "../DashUploadUtils"; +import { mkdirSync } from "fs"; export default class DeleteManager extends ApiManager { @@ -31,21 +36,19 @@ export default class DeleteManager extends ApiManager { } }); - const hi: PublicHandler = async ({ res, isRelease }) => { - if (isRelease) { - return _permission_denied(res, deletionPermissionError); + register({ + method: Method.GET, + subscription: "/deleteAssets", + secureHandler: async ({ res, isRelease }) => { + if (isRelease) { + return _permission_denied(res, deletionPermissionError); + } + rimraf.sync(filesDirectory); + mkdirSync(filesDirectory); + await DashUploadUtils.buildFileDirectories(); + res.redirect("/delete"); } - await Database.Instance.deleteAll('users'); - res.redirect("/home"); - }; - - // register({ - // method: Method.GET, - // subscription: "/deleteUsers", - // onValidation: hi, - // onUnauthenticated: hi - // }); - + }); register({ method: Method.GET, -- cgit v1.2.3-70-g09d2