From 2a84a002b06bdff969483f19390bf5a6d416d3a9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 24 Nov 2019 23:39:44 -0500 Subject: lots of fixes for full screen image/pdf/video views. fixes to image box fade image. --- src/client/views/nodes/ImageBox.scss | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'src/client/views/nodes/ImageBox.scss') diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index ba4ef8879..f28ca98f7 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,3 +1,12 @@ +.imageBox { + pointer-events: all; + border-radius: inherit; + width:100%; + height:100%; + position: absolute; + transform-origin: top left; +} + .imageBox-cont, .imageBox-cont-interactive { padding: 0vw; position: absolute; @@ -10,16 +19,7 @@ background:transparent; } -.imageBox-container { - pointer-events: all; - border-radius: inherit; - width:100%; - height:100%; - position: absolute; - transform-origin: top left; -} - -.imageBox-cont-interactive { +.imageBox-fader { pointer-events: all; } @@ -100,12 +100,11 @@ } } -#cf { +.imageBox-fader { position: relative; width: 100%; margin: 0 auto; display: flex; - align-items: center; height: 100%; overflow: hidden; @@ -126,7 +125,7 @@ } } -#cf img { +.imageBox-fader img { position: absolute; left: 0; } @@ -138,10 +137,12 @@ transition: opacity 1s ease-in-out; } -.imageBox-fadeBlocker:hover { - -webkit-transition: opacity 1s ease-in-out; - -moz-transition: opacity 1s ease-in-out; - -o-transition: opacity 1s ease-in-out; - transition: opacity 1s ease-in-out; - opacity: 0; +.imageBox:hover { + .imageBox-fadeBlocker { + -webkit-transition: opacity 1s ease-in-out; + -moz-transition: opacity 1s ease-in-out; + -o-transition: opacity 1s ease-in-out; + transition: opacity 1s ease-in-out; + opacity: 0; + } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6cd6e035fc67812afd7a40f8abd0f07f8874f04a Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 26 Nov 2019 14:34:41 -0500 Subject: fixes for tree view drag drop with images. --- src/client/views/EditableView.tsx | 4 +- .../views/collections/CollectionTreeView.tsx | 62 +++++++++++++--------- src/client/views/nodes/ImageBox.scss | 25 ++++----- src/client/views/nodes/ImageBox.tsx | 59 ++++++++++---------- 4 files changed, 79 insertions(+), 71 deletions(-) (limited to 'src/client/views/nodes/ImageBox.scss') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 8e86f58ee..f78b61892 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -21,7 +21,7 @@ export interface EditableProps { OnFillDown?(value: string): void; - OnTab?(): void; + OnTab?(shift?: boolean): void; /** * The contents to render when not editing @@ -79,7 +79,7 @@ export class EditableView extends React.Component { if (e.key === "Tab") { e.stopPropagation(); this.finalizeEdit(e.currentTarget.value, e.shiftKey); - this.props.OnTab && this.props.OnTab(); + this.props.OnTab && this.props.OnTab(e.shiftKey); } else if (e.key === "Enter") { e.stopPropagation(); if (!e.ctrlKey) { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index a21bc6c14..42cdd1455 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,7 +1,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, trace, runInAction } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; @@ -34,6 +34,7 @@ export interface TreeViewProps { document: Doc; dataDoc?: Doc; containingCollection: Doc; + prevSibling?: Doc; renderDepth: number; deleteDoc: (doc: Doc) => boolean; ruleProvider: Doc | undefined; @@ -46,12 +47,13 @@ export interface TreeViewProps { ChromeHeight: undefined | (() => number); addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; indentDocument?: () => void; + outdentDocument?: () => void; ScreenToLocalTransform: () => Transform; outerXf: () => { translateX: number, translateY: number }; treeViewId: string; parentKey: string; active: (outsideReaction?: boolean) => boolean; - showHeaderFields: () => boolean; + hideHeaderFields: () => boolean; preventTreeViewOpen: boolean; renderedIds: string[]; } @@ -82,11 +84,13 @@ class TreeView extends React.Component { private _header?: React.RefObject = React.createRef(); private _treedropDisposer?: DragManager.DragDropDisposer; private _dref = React.createRef(); + get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive + get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); } @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; } - @computed get treeViewOpen() { trace(); return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; } + @computed get treeViewOpen() { return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; } @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); } @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; } @@ -145,11 +149,10 @@ class TreeView extends React.Component { } onDragMove = (e: PointerEvent): void => { Doc.UnBrushDoc(this.dataDoc); - let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let pt = [e.clientX, e.clientY] let rect = this._header!.current!.getBoundingClientRect(); - let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; - let inside = x[0] > bounds[0] + 75; + let before = pt[1] < rect.top + rect.height / 2; + let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length); this._header!.current!.className = "treeViewItem-header"; if (inside) this._header!.current!.className += " treeViewItem-header-inside"; else if (before) this._header!.current!.className += " treeViewItem-header-above"; @@ -174,9 +177,9 @@ class TreeView extends React.Component { TreeView.loadId = doc[Id]; return this.props.addDocument(doc); })} - OnTab={undoBatch(() => { + OnTab={undoBatch((shift?: boolean) => { TreeView.loadId = this.dataDoc[Id]; - this.props.indentDocument?.(); + shift ? this.props.outdentDocument?.() : this.props.indentDocument?.(); setTimeout(() => { // unsetting/setting brushing for this doc will recreate & refocus this editableView after all other treeview changes have been made to the Dom (which may remove focus from this document). Doc.UnBrushDoc(this.props.document); Doc.BrushDoc(this.props.document); @@ -212,11 +215,10 @@ class TreeView extends React.Component { @undoBatch treeDrop = (e: Event, de: DragManager.DropEvent) => { - let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + let pt = [de.x, de.y]; let rect = this._header!.current!.getBoundingClientRect(); - let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; - let inside = x[0] > bounds[0] + 75 || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length); + let before = pt[1] < rect.top + rect.height / 2; + let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length); if (de.data instanceof DragManager.LinkDragData) { let sourceDoc = de.data.linkSourceDocument; let destDoc = this.props.document; @@ -268,7 +270,6 @@ class TreeView extends React.Component { } @computed get expandedField() { - trace(); let ids: { [key: string]: string } = {}; let doc = this.props.document; doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)); @@ -282,9 +283,9 @@ class TreeView extends React.Component { let remDoc = (doc: Doc) => this.remove(doc, key); let 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, addDoc, remDoc, this.move, + 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.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen, + this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen, [...this.props.renderedIds, doc[Id]]); } else { contentElement = { noOverlays = (doc: Doc) => ({ title: "", caption: "" }); @computed get renderContent() { - trace(); const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined; if (expandKey !== undefined) { let remDoc = (doc: Doc) => this.remove(doc, expandKey); @@ -316,9 +316,9 @@ class TreeView extends React.Component { return
    {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document), - this.templateDataDoc, expandKey, addDoc, remDoc, this.move, + 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.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen, + this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen, [...this.props.renderedIds, this.props.document[Id]])}
; } else if (this.treeViewExpandedView === "fields") { @@ -354,7 +354,6 @@ class TreeView extends React.Component { @computed get renderBullet() { - trace(); return
{ this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> {}
; @@ -394,13 +393,12 @@ class TreeView extends React.Component { }} > {this.editableView("title")} - {this.props.showHeaderFields() ? headerElements : (null)} + {this.props.hideHeaderFields() ? (null) : headerElements} {openRight} ; } render() { - trace(); return
  • @@ -419,6 +417,8 @@ class TreeView extends React.Component { containingCollection: Doc, dataDoc: Doc | undefined, key: string, + parentCollectionDoc: Doc | undefined, + parentPrevSibling: Doc | undefined, add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean, remove: ((doc: Doc) => boolean), move: DragManager.MoveFunction, @@ -431,7 +431,7 @@ class TreeView extends React.Component { panelWidth: () => number, ChromeHeight: undefined | (() => number), renderDepth: number, - showHeaderFields: () => boolean, + hideHeaderFields: () => boolean, preventTreeViewOpen: boolean, renderedIds: string[] ) { @@ -497,6 +497,15 @@ class TreeView extends React.Component { } } }; + let outdent = !parentCollectionDoc ? undefined : () => { + if (StrCast(parentCollectionDoc.layout).indexOf("fieldKey") !== -1) { + let fieldKeysub = StrCast(parentCollectionDoc.layout).split("fieldKey")[1]; + let fieldKey = fieldKeysub.split("\"")[1]; + Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false); + parentCollectionDoc.treeViewOpen = true; + remove(child); + } + }; let addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => { return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false); }; @@ -509,10 +518,12 @@ class TreeView extends React.Component { document={pair.layout} dataDoc={pair.data} containingCollection={containingCollection} + prevSibling={docs[i]} treeViewId={treeViewId} ruleProvider={containingCollection.isRuleProvider && pair.layout.type !== DocumentType.TEXT ? containingCollection : containingCollection.ruleProvider as Doc} key={child[Id]} indentDocument={indent} + outdentDocument={outdent} renderDepth={renderDepth} deleteDoc={remove} addDocument={addDocument} @@ -527,7 +538,7 @@ class TreeView extends React.Component { outerXf={outerXf} parentKey={key} active={active} - showHeaderFields={showHeaderFields} + hideHeaderFields={hideHeaderFields} preventTreeViewOpen={preventTreeViewOpen} renderedIds={renderedIds} />; }); @@ -594,7 +605,6 @@ export class CollectionTreeView extends CollectionSubView(Document) { } render() { - trace(); let dropAction = StrCast(this.props.Document.dropAction) as dropActionType; let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false); let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); @@ -622,7 +632,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { {this.props.Document.allowClear ? this.renderClearButton : (null)}
      { - TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove, + TreeView.GetChildElements(this.childDocs, this.props.Document[Id], 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, this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => !this.props.Document.hideHeaderFields, BoolCast(this.props.Document.preventTreeViewOpen), []) diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index f28ca98f7..96ea4d0d6 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -7,7 +7,7 @@ transform-origin: top left; } -.imageBox-cont, .imageBox-cont-interactive { +.imageBox-cont, .imageBox-cont-dragging { padding: 0vw; position: absolute; text-align: center; @@ -17,10 +17,20 @@ max-height: 100%; pointer-events: none; background:transparent; + img { + height: auto; + width: 100%; + pointer-events: all; + } + .imageBox-fader { + pointer-events: all; + } } -.imageBox-fader { - pointer-events: all; +.imageBox-cont-dragging { + .imageBox-fader { + pointer-events: none; + } } .imageBox-dot { @@ -33,15 +43,6 @@ background: gray; } -.imageBox-cont img { - height: auto; - width: 100%; -} - -.imageBox-cont-interactive img { - height: auto; - width: 100%; -} #google-photos { transition: all 0.5s ease 0s; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 323b05a5a..bf82da281 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -28,6 +28,7 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec import { documentSchema } from '../../../new_fields/documentSchemas'; import { Id } from '../../../new_fields/FieldSymbols'; import { TraceMobx } from '../../../new_fields/util'; +import { SelectionManager } from '../../util/SelectionManager'; var requestImageSize = require('../../util/request-image-size'); var path = require('path'); const { Howl } = require('howler'); @@ -292,7 +293,7 @@ export class ImageBox extends DocAnnotatableComponent -
      - +
      + + {fadepath === srcpath ? (null) :
      + - {fadepath === srcpath ? (null) :
      -
      } -
      -
      - -
      - {this.considerGooglePhotosLink()} - -
      ); + onError={this.onError} />
      } +
    +
    + +
    + {this.considerGooglePhotosLink()} + +
  • ; } contentFunc = () => [this.content]; -- cgit v1.2.3-70-g09d2 From e5ba8e86b4da2af65bde85589baad5a6fae9f627 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 27 Nov 2019 09:39:19 -0500 Subject: fixes for fade image overlays --- src/client/views/nodes/ImageBox.scss | 1 + src/client/views/nodes/ImageBox.tsx | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src/client/views/nodes/ImageBox.scss') diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 96ea4d0d6..3b42c2352 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -112,6 +112,7 @@ .imageBox-fadeBlocker { width: 100%; height: 100%; + position: absolute; background: black; display: flex; flex-direction: row; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index bf82da281..14523b2b4 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -232,6 +232,22 @@ export class ImageBox extends DocAnnotatableComponent console.log(err)); } + fadesize = (srcpath: string) => { + requestImageSize(srcpath) + .then((size: any) => { + let rotation = NumCast(this.dataDoc.rotation) % 180; + let realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size; + let aspect = realsize.height / realsize.width; + if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) { + setTimeout(action(() => { + this.Document.height = this.Document[WidthSym]() * aspect; + this.Document.nativeHeight = realsize.height; + this.Document.nativeWidth = realsize.width; + }), 0); + } + }) + .catch((err: any) => console.log(err)); + } @action onPointerEnter = () => { @@ -280,25 +296,26 @@ export class ImageBox extends DocAnnotatableComponent 20) { let alts = DocListCast(extensionDoc.Alternates); - let altpaths = alts.filter(doc => doc.data instanceof ImageField).map(doc => this.choosePath((doc.data as ImageField).url)); + let altpaths = alts.filter(doc => doc.data instanceof ImageField).map(doc => [this.choosePath((doc.data as ImageField).url), doc[WidthSym]() / doc[HeightSym]()]); let field = this.dataDoc[this.props.fieldKey]; // if (w < 100 && this._smallRetryCount < 10) this._curSuffix = "_s"; // else if (w < 600 && this._mediumRetryCount < 10) this._curSuffix = "_m"; // else if (this._largeRetryCount < 10) this._curSuffix = "_l"; - if (field instanceof ImageField) paths = [this.choosePath(field.url)]; + if (field instanceof ImageField) paths = [[this.choosePath(field.url), nativeWidth / nativeHeight]]; paths.push(...altpaths); // } let dragging = !SelectionManager.GetIsDragging() ? "" : "-dragging"; let rotation = NumCast(this.Document.rotation, 0); let aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1; let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0; - let srcpath = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))]; - let fadepath = paths[Math.min(paths.length - 1, 1)]; + let srcpath = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][0] as string; + let srcaspect = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][1] as number; + let fadepath = paths[Math.min(paths.length - 1, 1)][0] as string; !this.Document.ignoreAspect && this.resize(srcpath); @@ -310,7 +327,7 @@ export class ImageBox extends DocAnnotatableComponent - {fadepath === srcpath ? (null) :
    + {fadepath === srcpath ? (null) :