From 50fb344cd7c93539f00b3aebc8fa5be4aefc73fd Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 16 Oct 2019 11:07:36 -0400 Subject: small fixes: cursors, pdf, dragging buttons --- src/client/views/nodes/PDFBox.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 1c1d6ec95..dd909e09f 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -15,7 +15,7 @@ width: 100%; height: 100%; background: lightslategray; - .pdfBox-title-cont, .pdfBox-cont-interactive{ + .pdfBox-cont, .pdfBox-cont-interactive{ width: 150%; height: 100%; position: relative; -- cgit v1.2.3-70-g09d2 From 6d9cad19047b9970a8429771e7c0e03554e63f39 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 16 Oct 2019 12:13:30 -0400 Subject: more small fixes. dragging dragIcons, pdfmenu highlighting, fonticonbox hover text --- src/client/util/DragManager.ts | 3 +- src/client/views/DocumentDecorations.tsx | 1 + src/client/views/MainView.tsx | 4 ++- src/client/views/collections/CollectionSubView.tsx | 7 ++--- src/client/views/nodes/FontIconBox.tsx | 2 +- src/client/views/nodes/PDFBox.scss | 1 + src/client/views/pdf/PDFMenu.scss | 2 +- .../authentication/models/current_user_utils.ts | 32 +++++++++++----------- 8 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 92666c03c..dcd19e50b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -212,6 +212,7 @@ export namespace DragManager { dropAction: dropActionType; userDropAction: dropActionType; moveDocument?: MoveFunction; + isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts applyAsTemplate?: boolean; [id: string]: any; } @@ -240,7 +241,7 @@ export namespace DragManager { StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag : (dropData: { [id: string]: any }) => { (dropData.droppedDocuments = - dragData.draggedDocuments.map(d => ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result : + dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result : dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) : dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d) ); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3d73f048d..755739a11 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -202,6 +202,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument; + dragData.isSelectionMove = true; this.Interacting = true; this._hidden = true; document.removeEventListener("pointermove", this.onBackgroundMove); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 8035916a2..0e15784f7 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,7 +1,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faChevronRight, faClone, faCloudUploadAlt, faCommentAlt, faCut, faEllipsisV, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, - faMusic, faObjectGroup, faPause, faPenNib, faPen, faEraser, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt + faMusic, faObjectGroup, faPause, faMousePointer, faPenNib, faPen, faEraser, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt, faHighlighter } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, reaction, runInAction } from 'mobx'; @@ -102,7 +102,9 @@ export class MainView extends React.Component { library.add(faGlobeAsia); library.add(faUndoAlt); library.add(faRedoAlt); + library.add(faMousePointer); library.add(faPen); + library.add(faHighlighter); library.add(faEraser); library.add(faPenNib); library.add(faFilm); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index fdbe5339d..9919a9dc3 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -133,11 +133,10 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { if (de.data.dropAction || de.data.userDropAction) { added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false); } else if (de.data.moveDocument) { - let movedDocs = de.data.draggedDocuments;// de.data.options === this.props.Document[Id] ? de.data.draggedDocuments : de.data.droppedDocuments; - // note that it's possible the drag function might create a drop document that's not the same as the - // original dragged document. So we explicitly call addDocument() with a droppedDocument and + let movedDocs = de.data.draggedDocuments; added = movedDocs.reduce((added: boolean, d, i) => - de.data.moveDocument(d, this.props.Document, (doc: Doc) => this.props.addDocument(de.data.droppedDocuments[i])) || added, false); + de.data.droppedDocuments[i] !== d ? this.props.addDocument(de.data.droppedDocuments[i]) : + de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false); } else { added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false); } diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 1c2ed33eb..848afccf3 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -35,7 +35,7 @@ export class FontIconBox extends DocComponent( this._backgroundReaction && this._backgroundReaction(); } render() { - return ; diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index dd909e09f..deb98dc8d 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -7,6 +7,7 @@ overflow: hidden; position:absolute; z-index: -1; + cursor:auto; } .pdfBox-title-outer { diff --git a/src/client/views/pdf/PDFMenu.scss b/src/client/views/pdf/PDFMenu.scss index b06d19c53..44e075153 100644 --- a/src/client/views/pdf/PDFMenu.scss +++ b/src/client/views/pdf/PDFMenu.scss @@ -15,7 +15,7 @@ } .pdfMenu-button:hover { - background-color: #121212; + background-color: #d4d4d4; } .pdfMenu-dragger { diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 4abf85381..0fe8d996f 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -47,20 +47,20 @@ export class CurrentUserUtils { // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools static setupCreatorButtons(doc: Doc) { doc.activePen = doc; - let docProtoData: { title: string, icon: string, drag?: string, click?: string, unchecked?: string, activePen?: Doc, backgroundColor?: string }[] = [ - { title: "collection", icon: "folder", drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' }, - { title: "web page", icon: "globe-asia", drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' }, - { title: "image", icon: "cat", drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' }, - { title: "button", icon: "bolt", drag: 'Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" })' }, - { title: "presentation", icon: "tv", drag: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List(), { width: 200, height: 500, title: "a presentation trail" })' }, - { title: "import folder", icon: "cloud-upload-alt", drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })' }, - { title: "pen", icon: "pen-nib", click: 'activatePen(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc }, - { title: "highlighter", icon: "pen", click: 'activateBrush(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc }, - { title: "eraser", icon: "eraser", click: 'activateEraser(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', unchecked: `!sameDocs(this.activePen.pen, this)`, backgroundColor: "pink", activePen: doc }, - { title: "none", icon: "pause", click: 'deactivateInk();this.activePen.pen = this;', unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc }, + let docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, unchecked?: string, activePen?: Doc, backgroundColor?: string }[] = [ + { title: "collection", icon: "folder", ignoreClick: true, drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' }, + { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' }, + { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' }, + { title: "clickable button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" })' }, + { title: "presentation", icon: "tv", ignoreClick: true, drag: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List(), { width: 200, height: 500, title: "a presentation trail" })' }, + { title: "import folder", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })' }, + { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc }, + { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc }, + { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', unchecked: `!sameDocs(this.activePen.pen, this)`, backgroundColor: "pink", activePen: doc }, + { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', unchecked: `!sameDocs(this.activePen.pen, this) && this.activePen.pen !== undefined`, backgroundColor: "white", activePen: doc }, ]; return docProtoData.map(data => Docs.Create.FontIconDocument({ - nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, + nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick, onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, unchecked: data.unchecked ? ComputedField.MakeFunction(data.unchecked) : undefined, activePen: data.activePen, backgroundColor: data.backgroundColor, removeDropProperties: new List(["dropAction"]) @@ -144,9 +144,9 @@ export class CurrentUserUtils { /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window static setupExpandingButtons(doc: Doc) { doc.undoBtn = Docs.Create.FontIconDocument( - { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("undo()"), title: "undo button", icon: "undo-alt" }); + { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("undo()"), removeDropProperties: new List(["dropAction"]), title: "undo button", icon: "undo-alt" }); doc.redoBtn = Docs.Create.FontIconDocument( - { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("redo()"), title: "redo button", icon: "redo-alt" }); + { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("redo()"), removeDropProperties: new List(["dropAction"]), title: "redo button", icon: "redo-alt" }); 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", @@ -192,8 +192,8 @@ export class CurrentUserUtils { }); // setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet - doc.undoBtn && reaction(() => UndoManager.undoStack.slice(), () => (doc.undoBtn as Doc).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true }); - doc.redoBtn && reaction(() => UndoManager.redoStack.slice(), () => (doc.redoBtn as Doc).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true }); + doc.undoBtn && reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(doc.undoBtn as Doc).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true }); + doc.redoBtn && reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(doc.redoBtn as Doc).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true }); return doc; } -- cgit v1.2.3-70-g09d2 From 31166219e473e105b8fd9d49627fd1df58822c55 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 24 Oct 2019 00:56:00 -0400 Subject: fixed audio box shrinking layout. fixed pdf z-index issue in stacking panels. --- src/client/views/nodes/AudioBox.scss | 31 ++++++++++++++++++++++++++++--- src/client/views/nodes/AudioBox.tsx | 16 ++++++++++------ src/client/views/nodes/PDFBox.scss | 1 - 3 files changed, 38 insertions(+), 10 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 3d6f6c4f9..ccbf0d75f 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -36,6 +36,8 @@ height:100%; position: relative; display: flex; + padding-left: 2px; + border: gray solid 3px; .audiobox-player { margin-top:auto; margin-bottom:auto; @@ -59,7 +61,7 @@ background-color: red; position: absolute;; } - .audiobox-linker { + .audiobox-linker, .audiobox-linker-mini { position:absolute; width:15px; min-height:10px; @@ -76,10 +78,24 @@ top: calc(100% - 15px) !important; } } - .audiobox-linker:hover { + .audiobox-linker-mini { + width:8px; + min-height:8px; + height:8px; + box-shadow: black 1px 1px 1px; + margin-left: -1; + margin-top: -2; + .docuLinkBox-cont { + width:8px !important; + height:8px !important; + left: calc(100% - 8px) !important; + top: calc(100% - 8px) !important; + } + } + .audiobox-linker:hover, .audiobox-linker-mini:hover { transform:scale(1.5); } - .audiobox-marker-container { + .audiobox-marker-container, .audiobox-marker-minicontainer { position:absolute; width:10px; height:100%; @@ -95,6 +111,15 @@ border: orange 2px solid; } } + .audiobox-marker-minicontainer { + width:5px; + border-radius: 1px; + .audiobox-marker { + position:relative; + height: calc(100% - 8px); + margin-top: 8px; + } + } } } } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 3933c6257..cc1c63d44 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -184,7 +184,10 @@ export class AudioBox extends DocExtendableComponent this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1); + onPlay = (e: any) => { + this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1); + e.stopPropagation(); + } onStop = (e: any) => { this.pause(); this._ele!.currentTime = 0; @@ -213,7 +216,8 @@ export class AudioBox extends DocExtendableComponent +
{!this.path ? @@ -137,15 +128,13 @@ export class PDFBox extends DocAnnotatableComponent onPointerDown={e => e.stopPropagation()} style={{ display: this.active() ? "flex" : "none", position: "absolute", width: "100%", height: "100%", zIndex: 1, pointerEvents: "none" }}>
e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}> - -
@@ -200,8 +189,9 @@ export class PDFBox extends DocAnnotatableComponent ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" }); } - _initialScale: number | undefined; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live.... + render() { + trace(); const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); let noPdf = !(pdfUrl instanceof PdfField) || !this._pdf; @@ -214,11 +204,10 @@ export class PDFBox extends DocAnnotatableComponent
:
{ + }} onContextMenu={this.specificContextMenu} onPointerDown={e => { let hit = document.elementFromPoint(e.clientX, e.clientY); if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation e.button === 0 && e.stopPropagation(); @@ -228,7 +217,7 @@ export class PDFBox extends DocAnnotatableComponent setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView} renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth} Document={this.props.Document} DataDoc={this.dataDoc} ContentScaling={this.props.ContentScaling} - addDocTab={this.props.addDocTab} GoToPage={this.gotoPage} focus={this.props.focus} + addDocTab={this.props.addDocTab} focus={this.props.focus} pinToPres={this.props.pinToPres} addDocument={this.addDocument} ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select} isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 51dc6e8d6..060ba8613 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -59,7 +59,6 @@ interface IViewerProps { isSelected: () => boolean; loaded: (nw: number, nh: number, np: number) => void; active: () => boolean; - GoToPage?: (n: number) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; addDocument?: (doc: Doc) => boolean; @@ -220,7 +219,7 @@ export class PDFViewer extends DocAnnotatableComponent this.createPdfViewer(), 1000); @@ -235,9 +234,7 @@ export class PDFViewer extends DocAnnotatableComponent this._showCover = this._showWaiting = false)); var pdfLinkService = new PDFJSViewer.PDFLinkService(); - let pdfFindController = new PDFJSViewer.PDFFindController({ - linkService: pdfLinkService, - }); + let pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService }); this._pdfViewer = new PDFJSViewer.PDFViewer({ container: this._mainCont.current, viewer: this._viewer.current, @@ -626,6 +623,7 @@ export class PDFViewer extends DocAnnotatableComponent {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) => )} @@ -672,13 +670,14 @@ export class PDFViewer extends DocAnnotatableComponent this._marqueeing; visibleHeight = () => this.props.PanelHeight() / this.props.ContentScaling() * 72 / 96; render() { - return !this.extensionDoc ? (null) : (
- {this.pdfViewerDiv} - {this.annotationLayer} - {this.standinViews} - -
); + trace(); + return !this.extensionDoc ? (null) : +
+ {this.pdfViewerDiv} + {this.annotationLayer} + {this.standinViews} + +
; } } -- cgit v1.2.3-70-g09d2 From d7150995d62c498ab8435de986b90d98bdca020c Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 12 Nov 2019 15:07:03 -0500 Subject: a bunch of cleanup and bug fixes to text links and doculink buttons --- src/client/documents/Documents.ts | 5 +- src/client/util/LinkManager.ts | 2 - src/client/util/RichTextSchema.tsx | 4 +- src/client/util/TooltipTextMenu.tsx | 23 +++--- src/client/views/DocumentDecorations.tsx | 10 ++- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/Main.tsx | 24 ------- src/client/views/MainView.scss | 2 +- src/client/views/MainView.tsx | 8 +-- src/client/views/linking/LinkMenuItem.tsx | 1 - src/client/views/nodes/FormattedTextBox.tsx | 9 ++- src/client/views/nodes/FormattedTextBoxComment.tsx | 83 ++++++++++++---------- src/client/views/nodes/PDFBox.scss | 2 + src/client/views/nodes/PDFBox.tsx | 76 +++++++++++--------- src/client/views/pdf/Annotation.tsx | 6 +- src/client/views/pdf/PDFViewer.tsx | 14 +--- src/new_fields/Doc.ts | 2 +- .../authentication/models/current_user_utils.ts | 1 - 18 files changed, 127 insertions(+), 147 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d1fcabc4a..ba9f87025 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -257,6 +257,9 @@ export namespace Docs { return PrototypeMap.get(type)!; } + /** + * A collection of all links in the database. Ideally, this would be a search, but for now all links are cached here. + */ export function MainLinkDocument() { return Prototypes.get(DocumentType.LINKDOC); } @@ -703,6 +706,7 @@ export namespace DocUtils { linkDocProto.title = title === "" ? source.doc.title + " to " + target.doc.title : title; linkDocProto.linkDescription = description; + linkDocProto.isPrototype = true; linkDocProto.anchor1 = source.doc; linkDocProto.anchor2 = target.doc; @@ -714,7 +718,6 @@ 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/util/LinkManager.ts b/src/client/util/LinkManager.ts index ee2f2dadc..eedc4967d 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -34,8 +34,6 @@ export class LinkManager { // the linkmanagerdoc stores a list of docs representing all linkdocs in 'allLinks' and a list of strings representing all group types in 'allGroupTypes' // lists of strings representing the metadata keys for each group type is stored under a key that is the same as the group type public get LinkManagerDoc(): Doc | undefined { - // return FieldValue(Cast(CurrentUserUtils.UserDocument.linkManagerDoc, Doc)); - return Docs.Prototypes.MainLinkDocument(); } diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index a5e0ca720..76b8aeaa1 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -305,8 +305,8 @@ export const marks: { [index: string]: MarkSpec } = { }], toDOM(node: any) { return node.attrs.docref && node.attrs.title ? - ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, class: "prosemirror-attribution" }, node.attrs.title], ["br"]] : - ["a", { ...node.attrs }, 0]; + ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, class: "prosemirror-attribution", title: `${node.attrs.title}` }, node.attrs.title], ["br"]] : + ["a", { ...node.attrs, title: `${node.attrs.title}` }, 0]; } }, diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 9ce7acec8..38471a955 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -17,7 +17,7 @@ import { DragManager } from "./DragManager"; import { LinkManager } from "./LinkManager"; import { schema } from "./RichTextSchema"; import "./TooltipTextMenu.scss"; -import { Cast, NumCast } from '../../new_fields/Types'; +import { Cast, NumCast, StrCast } from '../../new_fields/Types'; import { updateBullets } from './ProsemirrorExampleTransfer'; import { DocumentDecorations } from '../views/DocumentDecorations'; const { toggleMark, setBlockType } = require("prosemirror-commands"); @@ -284,7 +284,7 @@ export class TooltipTextMenu { if (proto && docView) { proto.sourceContext = docView.props.ContainingCollectionDoc; } - let text = this.makeLink(linkDoc, ctrlKey ? "onRight" : "inTab"); + let text = this.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), ctrlKey ? "onRight" : "inTab"); if (linkDoc instanceof Doc && linkDoc.anchor2 instanceof Doc) { proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODODO open to more descriptive descriptions of following in text link } @@ -374,25 +374,20 @@ export class TooltipTextMenu { // let link = state.schema.mark(state.schema.marks.link, { href: target, location: location }); // } - makeLink = (targetDoc: Doc, location: string): string => { - let target = Utils.prepend("/doc/" + targetDoc[Id]); + makeLink = (targetDoc: Doc, title: string, location: string): string => { + let link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + targetDoc[Id]), title: title, location: location }); + this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link). + addMark(this.view.state.selection.from, this.view.state.selection.to, link)); let node = this.view.state.selection.$from.nodeAfter; - let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location, guid: targetDoc[Id] }); - this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link)); - this.view.dispatch(this.view.state.tr.addMark(this.view.state.selection.from, this.view.state.selection.to, link)); - node = this.view.state.selection.$from.nodeAfter; - link = node && node.marks.find(m => m.type.name === "link"); - if (node) { - if (node.text) { - return node.text; - } + if (node && node.text) { + return node.text; } return ""; } deleteLink = () => { let node = this.view.state.selection.$from.nodeAfter; - let link = node && node.marks.find(m => m.type.name === "link"); + let link = node && node.marks.find(m => m.type === this.view.state.schema.marks.link); let href = link!.attrs.href; if (href) { if (href.indexOf(Utils.prepend("/doc/")) === 0) { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 0336440d5..55c211d1d 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -24,6 +24,7 @@ import { DocumentView } from "./nodes/DocumentView"; import { FieldView } from "./nodes/FieldView"; import { IconBox } from "./nodes/IconBox"; import React = require("react"); +import { DocumentType } from '../documents/DocumentTypes'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -112,7 +113,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } else { if (SelectionManager.SelectedDocuments().length > 0) { - SelectionManager.SelectedDocuments()[0].props.Document.customTitle = true; + SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._title.startsWith("-"); let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey]; if (typeof field === "number") { SelectionManager.SelectedDocuments().forEach(d => { @@ -174,6 +175,13 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); + if (documentView.props.Document.type === DocumentType.LINK) { + let rect = documentView.ContentDiv!.getElementsByClassName("docuLinkBox-cont")[0].getBoundingClientRect(); + sptX = rect.left; + sptY = rect.top; + bptX = rect.right; + bptY = rect.bottom; + } return { x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y), r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 9ca9fc163..8f397e331 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -165,7 +165,7 @@ export default class KeyManager { } } break; - case "c": + case "t": PromiseValue(Cast(CurrentUserUtils.UserDocument.Create, Doc)).then(pv => pv && (pv.onClick as ScriptField).script.run({ this: pv })); if (MainView.Instance.flyoutWidth === 240) { MainView.Instance.flyoutWidth = 0; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index a91a2b69e..b21eb9c8f 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -3,34 +3,11 @@ import { Docs } from "../documents/Documents"; import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; import * as ReactDOM from 'react-dom'; import * as React from 'react'; -import { Cast } from "../../new_fields/Types"; -import { Doc, DocListCastAsync } from "../../new_fields/Doc"; -import { List } from "../../new_fields/List"; import { DocServer } from "../DocServer"; import { AssignAllExtensions } from "../../extensions/General/Extensions"; AssignAllExtensions(); -let swapDocs = async () => { - let oldDoc = await Cast(CurrentUserUtils.UserDocument.linkManagerDoc, Doc); - // Docs.Prototypes.MainLinkDocument().allLinks = new List(); - if (oldDoc) { - let links = await DocListCastAsync(oldDoc.allLinks); - // if (links && DocListCast(links)) { - if (links && links.length) { - let data = await DocListCastAsync(Docs.Prototypes.MainLinkDocument().allLinks); - if (data) { - data.push(...links.filter(i => data!.indexOf(i) === -1)); - Docs.Prototypes.MainLinkDocument().allLinks = new List(data.filter((i, idx) => data!.indexOf(i) === idx)); - } - else { - Docs.Prototypes.MainLinkDocument().allLinks = new List(links); - } - } - CurrentUserUtils.UserDocument.linkManagerDoc = undefined; - } -}; - (async () => { const info = await CurrentUserUtils.loadCurrentUser(); DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email); @@ -38,7 +15,6 @@ let swapDocs = async () => { if (info.id !== "__guest__") { // a guest will not have an id registered await CurrentUserUtils.loadUserDocument(info); - await swapDocs(); } document.getElementById('root')!.addEventListener('wheel', event => { if (event.ctrlKey) { diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 21b135c49..a858a73c7 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -13,7 +13,7 @@ left: 250px; } -.mainView-container { +#mainView-container { width: 100%; height: 100%; position: absolute; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 773da05df..83dbb433b 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -37,7 +37,6 @@ import { OverlayView } from './OverlayView'; import PDFMenu from './pdf/PDFMenu'; import { PreviewCursor } from './PreviewCursor'; import { Scripting } from '../util/Scripting'; -import { LinkManager } from '../util/LinkManager'; import { AudioBox } from './nodes/AudioBox'; @observer @@ -197,11 +196,6 @@ export class MainView extends React.Component { var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] }; let mainDoc = Docs.Create.DockDocument([freeformDoc], JSON.stringify(dockingLayout), {}, id); if (this.userDoc && ((workspaces = Cast(this.userDoc.workspaces, Doc)) instanceof Doc)) { - if (!this.userDoc.linkManagerDoc) { - let linkManagerDoc = new Doc(); - linkManagerDoc.allLinks = new List([]); - this.userDoc.linkManagerDoc = linkManagerDoc; - } Doc.AddDocToList(workspaces, "data", mainDoc); mainDoc.title = `Workspace ${DocListCast(workspaces.data).length}`; } @@ -504,7 +498,7 @@ export class MainView extends React.Component { } render() { - return (
+ return (
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index a6ee9c2c6..238660de3 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -8,7 +8,6 @@ import { Cast, StrCast } from '../../../new_fields/Types'; import { DragLinkAsDocument } from '../../util/DragManager'; import { LinkManager } from '../../util/LinkManager'; import { ContextMenu } from '../ContextMenu'; -import { MainView } from '../MainView'; import { LinkFollowBox } from './LinkFollowBox'; import './LinkMenu.scss'; import React = require("react"); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index abf26826c..a0f8523a2 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -842,6 +842,7 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F this._editorView && this._editorView.destroy(); } onPointerDown = (e: React.PointerEvent): void => { + FormattedTextBoxComment.textBox = this; let pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY }); pos && (this._nodeClicked = this._editorView!.state.doc.nodeAt(pos.pos)); if (this.props.onClick && e.button === 0) { @@ -1018,11 +1019,13 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F } render() { + trace(); let rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; - let interactive: "all" | "none" = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground - ? "none" : "all"; + let interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground; if (this.props.isSelected()) { FormattedTextBox._toolTipTextMenu!.updateFromDash(this._editorView!, undefined, this.props); + } else if (FormattedTextBoxComment.textBox === this) { + FormattedTextBoxComment.Hide(); } return (
{ let keep = e.target && (e.target as any).type === "checkbox" ? true : false; @@ -91,62 +93,67 @@ export class FormattedTextBoxComment { let state = view.state; // Don't do anything if the document/selection didn't change if (lastState && lastState.doc.eq(state.doc) && - lastState.selection.eq(state.selection)) return; + lastState.selection.eq(state.selection)) { + return; + } - if (!FormattedTextBoxComment.textBox || !FormattedTextBoxComment.textBox.props || !FormattedTextBoxComment.textBox.props.isSelected()) return; + const textBox = FormattedTextBoxComment.textBox; + if (!textBox || !textBox.props) { + return; + } let set = "none"; - if (FormattedTextBoxComment.textBox && state.selection.$from) { - let nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark); + let nbef = 0; + // this section checks to see if the insertion point is over text entered by a different user. If so, it sets ths comment text to indicate the user and the modification date + if (state.selection.$from) { + nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark); let naft = findEndOfMark(state.selection.$from, view, findOtherUserMark); - const spos = state.selection.$from.pos - nbef; - const epos = state.selection.$from.pos + naft; - let child = state.selection.$from.nodeBefore; - let mark = child && findOtherUserMark(child.marks); let noselection = view.state.selection.$from === view.state.selection.$to; + let child: any = null; + state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node)); + let mark = child && findOtherUserMark(child.marks); if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) { - FormattedTextBoxComment.SetState(this, mark.attrs.opened, spos, epos, mark); + FormattedTextBoxComment.SetState(FormattedTextBoxComment.textBox, mark.attrs.opened, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark); } - if (mark && child && nbef && naft) { - FormattedTextBoxComment.tooltipText.textContent = mark.attrs.userid + " " + mark.attrs.modified; - // These are in screen coordinates - // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to); - let start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef); - // The box in which the tooltip is positioned, to use as base - let box = (document.getElementById("main-div") as any).getBoundingClientRect(); - // Find a center-ish x position from the selection endpoints (when - // crossing lines, end may be more to the left) - let left = Math.max((start.left + end.left) / 2, start.left + 3); - FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px"; - FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px"; + if (mark && child && ((nbef && naft) || !noselection)) { + FormattedTextBoxComment.tooltipText.textContent = mark.attrs.userid + " date=" + (new Date(mark.attrs.modified * 5000)).toDateString(); set = ""; } } + // this checks if the selection is a hyperlink. If so, it displays the target doc's text for internal links, and the url of the target for external links. if (set === "none" && state.selection.$from) { - FormattedTextBoxComment.textBox = undefined; - let nbef = findStartOfMark(state.selection.$from, view, findLinkMark); + nbef = findStartOfMark(state.selection.$from, view, findLinkMark); let naft = findEndOfMark(state.selection.$from, view, findLinkMark); - let child = state.selection.$from.nodeBefore; + let child: any = null; + state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node)); let mark = child && findLinkMark(child.marks); if (mark && child && nbef && naft) { - FormattedTextBoxComment.tooltipText.textContent = "link : " + (mark.attrs.title || mark.attrs.href); + FormattedTextBoxComment.tooltipText.textContent = "external => " + mark.attrs.href; if (mark.attrs.href.indexOf(Utils.prepend("/doc/")) === 0) { let docTarget = mark.attrs.href.replace(Utils.prepend("/doc/"), "").split("?")[0]; - docTarget && DocServer.GetRefField(docTarget).then(linkDoc => - (linkDoc as Doc) && (FormattedTextBoxComment.tooltipText.textContent = "link :" + StrCast((linkDoc as Doc).title))); + docTarget && DocServer.GetRefField(docTarget).then(linkDoc => { + if (linkDoc instanceof Doc) { + let target = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(linkDoc.anchor1, Doc)), textBox.props.Document) ? Cast(linkDoc.anchor2, Doc) : Cast(linkDoc.anchor1, Doc)); + let ext = (target && Doc.fieldExtensionDoc(target, "data")) || target; // try guessing that the target doc's data is in the 'data' field. probably need an 'overviewLayout' and then just display the target Document .... + let text = ext && StrCast(ext.text); + ext && (FormattedTextBoxComment.tooltipText.textContent = "=> " + (text || StrCast(ext.title))); + } + }); } - // These are in screen coordinates - // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to); - let start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef); - // The box in which the tooltip is positioned, to use as base - let box = (document.getElementById("main-div") as any).getBoundingClientRect(); - // Find a center-ish x position from the selection endpoints (when - // crossing lines, end may be more to the left) - let left = Math.max((start.left + end.left) / 2, start.left + 3); - FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px"; - FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px"; set = ""; } } + if (set !== "none") { + // These are in screen coordinates + // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to); + let start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef); + // The box in which the tooltip is positioned, to use as base + let box = (document.getElementById("mainView-container") as any).getBoundingClientRect(); + // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + let left = Math.max((start.left + end.left) / 2, start.left + 3); + FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px"; + FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px"; + } FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = set); } diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 963205206..2d92c9581 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -48,6 +48,7 @@ } .pdfViewer-text { .textLayer { + will-change: transform; span { user-select: none; } @@ -59,6 +60,7 @@ pointer-events: all; .pdfViewer-text { .textLayer { + will-change: transform; span { user-select: text; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 3baa6eb09..8e0515f8a 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable, runInAction, reaction, IReactionDisposer, trace } from 'mobx'; +import { action, observable, runInAction, reaction, IReactionDisposer, trace, untracked, computed } from 'mobx'; import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; @@ -32,7 +32,7 @@ export class PDFBox extends DocAnnotatableComponent private _valueValue: string = ""; private _scriptValue: string = ""; private _searchString: string = ""; - private _initialScale: number | undefined; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live. + private _initialScale: number = 0; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live. private _everActive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title private _pdfViewer: PDFViewer | undefined; private _searchRef = React.createRef(); @@ -46,6 +46,11 @@ export class PDFBox extends DocAnnotatableComponent @observable private _pdf: Opt; @observable private _pageControls = false; + constructor(props: any) { + super(props); + this._initialScale = this.props.ScreenToLocalTransform().Scale; + } + componentWillUnmount() { this._selectReactionDisposer && this._selectReactionDisposer(); } @@ -190,39 +195,46 @@ export class PDFBox extends DocAnnotatableComponent ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" }); } - render() { + @computed get renderTitleBox() { + let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); + return
+
+ {` ${this.props.Document.title}`} +
+
; + } + + @computed get renderPdfView() { trace(); const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); - let noPdf = !(pdfUrl instanceof PdfField) || !this._pdf; - if (this._initialScale === undefined) this._initialScale = this.props.ScreenToLocalTransform().Scale; + return
{ + let hit = document.elementFromPoint(e.clientX, e.clientY); + if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation + e.button === 0 && e.stopPropagation(); + } + }}> + + {this.settingsPanel()} +
; + } + + render() { + const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null); if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true; - return (!this.extensionDoc || noPdf || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ? -
-
- {` ${this.props.Document.title}`} -
-
: -
{ - let hit = document.elementFromPoint(e.clientX, e.clientY); - if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation - e.button === 0 && e.stopPropagation(); - } - }}> - - {this.settingsPanel()} -
); + return !pdfUrl || !this._pdf || !this.extensionDoc || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ? + this.renderTitleBox : this.renderPdfView; } } \ No newline at end of file diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 2d8f47666..936af9ab8 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -52,11 +52,7 @@ class RegionAnnotation extends React.Component { this._brushDisposer = reaction( () => FieldValue(Cast(this.props.document.group, Doc)) && Doc.isBrushedHighlightedDegree(FieldValue(Cast(this.props.document.group, Doc))!), - (brushed) => { - if (brushed !== undefined) { - runInAction(() => this._brushed = brushed !== 0); - } - } + brushed => brushed !== undefined && runInAction(() => this._brushed = brushed !== 0) ); } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 060ba8613..0cb671156 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -199,7 +199,7 @@ export class PDFViewer extends DocAnnotatableComponent this.extensionDoc && DocListCast(this.extensionDoc.annotations), - annotations => annotations && annotations.length && this.renderAnnotations(annotations, true), + annotations => annotations && annotations.length && (this._annotations = annotations), { fireImmediately: true }); this._filterReactionDisposer = reaction( @@ -297,18 +297,6 @@ export class PDFViewer extends DocAnnotatableComponent { - if (removeOldAnnotations) { - this._annotations = annotations; - } - else { - this._annotations.push(...annotations); - this._annotations = new Array(...this._annotations); - } - } - @action prevAnnotation = () => { this.Index = Math.max(this.Index - 1, 0); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 6aad4a6be..3bf1129b5 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -669,8 +669,8 @@ export namespace Doc { return doc; } - export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } + export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } export function linkFollowUnhighlight() { Doc.UnhighlightAll(); document.removeEventListener("pointerdown", linkFollowUnhighlight); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 56ea5bfe1..833e44bf6 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -15,7 +15,6 @@ import { RouteStore } from "../../RouteStore"; import { InkingControl } from "../../../client/views/InkingControl"; import { DragManager } from "../../../client/util/DragManager"; import { nullAudio } from "../../../new_fields/URLField"; -import { LinkManager } from "../../../client/util/LinkManager"; export class CurrentUserUtils { private static curr_id: string; -- cgit v1.2.3-70-g09d2 From e5e4265a1959abd783f09961325f763bd51213ca Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 18 Nov 2019 16:46:51 -0500 Subject: trying to get pdfs to work --- .../collectionFreeForm/MarqueeView.scss | 2 +- src/client/views/nodes/PDFBox.scss | 2 - src/client/views/nodes/PDFBox.tsx | 9 +-- src/client/views/pdf/PDFViewer.scss | 14 +++- src/client/views/pdf/PDFViewer.tsx | 75 +++++++++++++--------- 5 files changed, 57 insertions(+), 45 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.scss b/src/client/views/collections/collectionFreeForm/MarqueeView.scss index 53b07318f..d14495626 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.scss +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.scss @@ -8,7 +8,7 @@ } .marqueeView { overflow: hidden; - pointer-events: all; + pointer-events: inherit; } .marqueeView:focus-within { diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 2d92c9581..963205206 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -48,7 +48,6 @@ } .pdfViewer-text { .textLayer { - will-change: transform; span { user-select: none; } @@ -60,7 +59,6 @@ pointer-events: all; .pdfViewer-text { .textLayer { - will-change: transform; span { user-select: text; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index ecbe2d309..b039484d0 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -196,7 +196,7 @@ export class PDFBox extends DocAnnotatableComponent } @computed get renderTitleBox() { - let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); + let classname = "pdfBox-cont"; return
{` ${this.props.Document.title}`} @@ -207,12 +207,7 @@ export class PDFBox extends DocAnnotatableComponent @computed get renderPdfView() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); - return
{ - let hit = document.elementFromPoint(e.clientX, e.clientY); - if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation - e.button === 0 && e.stopPropagation(); - } - }}> + return
{ + !this.props.Document.lockedTransform && (this.props.Document.lockedTransform = true); // change the address to be the file address of the PNG version of each page // file address of the pdf this._coverPath = JSON.parse(await rp.get(Utils.prepend(`/thumbnail${this.props.url.substring("files/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.PNG`))); @@ -391,6 +392,10 @@ export class PDFViewer extends DocAnnotatableComponent { + let hit = document.elementFromPoint(e.clientX, e.clientY); + if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation + e.button === 0 && e.stopPropagation(); + } // if alt+left click, drag and annotate this._downX = e.clientX; this._downY = e.clientY; @@ -612,38 +617,42 @@ export class PDFViewer extends DocAnnotatableComponent + return
{this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) => )} -
- (this.Document.scrollHeight || this.Document.nativeHeight || 0)} - PanelWidth={() => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document.nativeWidth || 0)} - VisibleHeight={this.visibleHeight} - focus={this.props.focus} - isSelected={this.props.isSelected} - isAnnotationOverlay={true} - select={emptyFunction} - active={this.active} - ContentScaling={returnOne} - whenActiveChanged={this.whenActiveChanged} - removeDocument={this.removeDocument} - moveDocument={this.moveDocument} - addDocument={this.addDocument} - CollectionView={undefined} - ScreenToLocalTransform={this.scrollXf} - ruleProvider={undefined} - renderDepth={this.props.renderDepth + 1} - ContainingCollectionDoc={this.props.ContainingCollectionView?.props.Document} - chromeCollapsed={true}> - -
; } + @computed get overlayLayer() { + return
+ (this.Document.scrollHeight || this.Document.nativeHeight || 0)} + PanelWidth={() => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document.nativeWidth || 0)} + VisibleHeight={this.visibleHeight} + focus={this.props.focus} + isSelected={this.props.isSelected} + isAnnotationOverlay={true} + select={emptyFunction} + active={this.active} + ContentScaling={returnOne} + whenActiveChanged={this.whenActiveChanged} + removeDocument={this.removeDocument} + moveDocument={this.moveDocument} + addDocument={this.addDocument} + CollectionView={undefined} + ScreenToLocalTransform={this.scrollXf} + ruleProvider={undefined} + renderDepth={this.props.renderDepth + 1} + ContainingCollectionDoc={this.props.ContainingCollectionView?.props.Document} + chromeCollapsed={true}> + +
+ } @computed get pdfViewerDiv() { - return
; + return
; } @computed get standinViews() { return <> @@ -660,12 +669,14 @@ export class PDFViewer extends DocAnnotatableComponent +
{this.pdfViewerDiv} + {this.overlayLayer} {this.annotationLayer} {this.standinViews} -- cgit v1.2.3-70-g09d2 From 617798db46a204ff089bf3400832af67872cc02f Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 19 Nov 2019 09:45:10 -0500 Subject: more fixes to pdfs --- src/client/documents/Documents.ts | 2 +- src/client/views/DocComponent.tsx | 6 +++--- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 1 - src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 5 ++++- src/client/views/nodes/PDFBox.scss | 4 ++-- src/client/views/nodes/PDFBox.tsx | 4 +++- src/client/views/pdf/PDFViewer.scss | 10 +++++----- src/client/views/pdf/PDFViewer.tsx | 3 ++- 8 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3c88173cd..c5bf109a1 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -647,7 +647,7 @@ export namespace Docs { } if (type.indexOf("pdf") !== -1) { ctor = Docs.Create.PdfDocument; - options.nativeWidth = 1200; + options.nativeWidth = 927; options.nativeHeight = 1200; } if (type.indexOf("excel") !== -1) { diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index b59bd4f1d..961a5a016 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Doc } from '../../new_fields/Doc'; import { Touchable } from './Touchable'; -import { computed, action } from 'mobx'; +import { computed, action, observable } from 'mobx'; import { Cast } from '../../new_fields/Types'; import { listSpec } from '../../new_fields/Schema'; import { InkingControl } from './InkingControl'; @@ -54,7 +54,7 @@ interface DocAnnotatableProps { } export function DocAnnotatableComponent

(schemaCtor: (doc: Doc) => T) { class Component extends React.Component

{ - _isChildActive = false; + @observable _isChildActive = false; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then @computed get Document(): T { return schemaCtor(this.props.Document); } @computed get layoutDoc() { return Doc.Layout(this.props.Document); } @@ -81,7 +81,7 @@ export function DocAnnotatableComponent

(schema return this.extensionDoc && Doc.AddDocToList(this.extensionDoc, this.annotationsKey, doc) ? true : false; } - whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); + whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); active = () => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) && (this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false) } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 985d1d272..3b313c34a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -484,7 +484,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action zoom = (pointX: number, pointY: number, deltaY: number): void => { - console.log(deltaY); let deltaScale = deltaY > 0 ? (1 / 1.1) : 1.1; if (deltaScale * this.zoomScaling() < 1 && this.isAnnotationOverlay) { deltaScale = 1 / this.zoomScaling(); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a035bdc3d..d0e1d1922 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -28,7 +28,10 @@ export class CollectionFreeFormDocumentView extends DocComponent let classname = "pdfBox-cont" + (this.active() ? "-interactive" : ""); return

- {` ${this.props.Document.title}`} + {this.props.Document.title}
; } + isChildActive = () => this._isChildActive; @computed get renderPdfView() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); return
@@ -215,6 +216,7 @@ export class PDFBox extends DocAnnotatableComponent pinToPres={this.props.pinToPres} addDocument={this.addDocument} ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select} isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged} + isChildActive={this.isChildActive} fieldKey={this.props.fieldKey} startupLive={this._initialScale < 2.5 ? true : false} /> {this.settingsPanel()}
; diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 62c9298c6..f69bdeeb6 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -41,11 +41,11 @@ user-select: text; } } - // .pdfViewer-text { - // .textLayer { - // will-change: transform; - // } - // } + .pdfViewer-text { + .textLayer { + will-change: transform; + } + } .pdfViewer-dragAnnotationBox { position:absolute; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 4ee548447..f34c4abd3 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -59,6 +59,7 @@ interface IViewerProps { isSelected: () => boolean; loaded: (nw: number, nh: number, np: number) => void; active: () => boolean; + isChildActive: () => boolean; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; addDocument?: (doc: Doc) => boolean; @@ -653,7 +654,7 @@ export class PDFViewer extends DocAnnotatableComponent } @computed get pdfViewerDiv() { - return
; } -- cgit v1.2.3-70-g09d2 From dc9e21ebab1d40747c2be3550b9601f8b46b9221 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 19 Nov 2019 10:30:38 -0500 Subject: fixes to captions/titles --- src/client/views/nodes/DocumentView.scss | 2 ++ src/client/views/nodes/DocumentView.tsx | 2 -- src/client/views/nodes/PDFBox.scss | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 142036354..dfb84ed5c 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -59,6 +59,7 @@ color: white; transform-origin: top left; top: 0; + width: 100%; height: 25; background: rgba(0, 0, 0, .4); padding: 4px; @@ -78,6 +79,7 @@ .documentView-captionWrapper { position: absolute; bottom: 0; + width: 100%; transform-origin: bottom left; } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d9e1f2c6b..797b6ecb2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -596,7 +596,6 @@ export class DocumentView extends DocComponent(Docu
); const captionView = (!showCaption ? (null) :
- {/* style={{ width: `${100 * this.props.ContentScaling()}%`, transform: `scale(${1 / this.props.ContentScaling()})` }}> */} (Docu
); const titleView = (!showTitle ? (null) :
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 2674c0de6..53388711b 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -8,6 +8,7 @@ position:absolute; cursor:auto; transform-origin: top left; + z-index: 0; } .pdfBox-title-outer { -- cgit v1.2.3-70-g09d2 From d259cf7b16e64794bc12ae420f9b512a75eee46c Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 19 Nov 2019 11:02:42 -0500 Subject: fixed some details with pdfs --- src/client/views/nodes/DocumentView.tsx | 1 - src/client/views/nodes/PDFBox.scss | 2 ++ src/client/views/nodes/PDFBox.tsx | 8 +++----- src/client/views/pdf/PDFViewer.tsx | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/PDFBox.scss') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 797b6ecb2..da4489bef 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -591,7 +591,6 @@ export class DocumentView extends DocComponent(Docu const showTextTitle = showTitle && StrCast(this.Document.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined; const searchHighlight = (!this.Document.searchFields ? (null) :
- {/* style={{ width: `${100 * this.props.ContentScaling()}%`, transform: `scale(${1 / this.props.ContentScaling()})` }}> */} {this.Document.searchFields}
); const captionView = (!showCaption ? (null) : diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 53388711b..5a5f784a1 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -183,6 +183,8 @@ align-items: center; margin-left: -2px; border-radius: 3px; + position: absolute; + pointer-events: all; } } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 634cd67c3..5cfd4b019 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -111,20 +111,18 @@ export class PDFBox extends DocAnnotatableComponent private newValueChange = (e: React.ChangeEvent) => this._valueValue = e.currentTarget.value; private newScriptChange = (e: React.ChangeEvent) => this._scriptValue = e.currentTarget.value; - whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); + whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; }; searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; settingsPanel() { let pageBtns = <> ; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 8142d2ac2..5058ce851 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -673,12 +673,12 @@ export class PDFViewer extends DocAnnotatableComponent + }} onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}> {this.pdfViewerDiv} {this.overlayLayer} {this.annotationLayer} -- cgit v1.2.3-70-g09d2