diff options
-rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 7 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 2 | ||||
-rw-r--r-- | src/client/views/SearchBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/LinkMenuItem.tsx | 15 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 6 | ||||
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 2 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 19 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 2 | ||||
-rw-r--r-- | src/new_fields/Schema.ts | 2 | ||||
-rw-r--r-- | src/server/index.ts | 6 |
12 files changed, 43 insertions, 23 deletions
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index f4579fc51..309d19016 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -19,6 +19,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie import { DocumentManager } from "./DocumentManager"; import { Id } from "../../new_fields/FieldSymbols"; import { FormattedTextBoxProps } from "../views/nodes/FormattedTextBox"; +import { SelectionManager } from "./SelectionManager"; //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc. export class TooltipTextMenu { @@ -239,6 +240,8 @@ export class TooltipTextMenu { this.linkDrag.onpointerdown = (e: PointerEvent) => { let dragData = new DragManager.LinkDragData(this.editorProps.Document); dragData.dontClearTextBox = true; + // hack to get source context -sy + let docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document); e.stopPropagation(); let ctrlKey = e.ctrlKey; DragManager.StartLinkDrag(this.linkDrag!, dragData, e.clientX, e.clientY, @@ -247,6 +250,10 @@ export class TooltipTextMenu { dragComplete: action(() => { // let m = dragData.droppedDocuments; let linkDoc = dragData.linkDocument; + let proto = Doc.GetProto(linkDoc); + if (docView && docView.props.ContainingCollectionView) { + proto.sourceContext = docView.props.ContainingCollectionView.props.Document; + } linkDoc instanceof Doc && this.makeLink(DocServer.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab"); }), }, diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 398974cb6..fb5104915 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -534,7 +534,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> doc.width = actualdW; if (fixedAspect) doc.height = nheight / nwidth * doc.width; else doc.height = actualdH; - Doc.SetInPlace(element.props.Document, "nativeHeight", (doc.height || 0) / doc.width * (doc.nativeWidth || 0), true); } else { if (!fixedAspect) { @@ -543,7 +542,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> doc.height = actualdH; if (fixedAspect) doc.width = nwidth / nheight * doc.height; else doc.width = actualdW; - Doc.SetInPlace(element.props.Document, "nativeWidth", (doc.width || 0) / doc.height * (doc.nativeHeight || 0), true); } } else { dW && (doc.width = actualdW); diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 8fb43021a..1b9be841f 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -163,7 +163,7 @@ export class SearchBox extends React.Component { </div> {this._resultsOpen ? ( <div className="searchBox-results"> - {this._results.map(result => <SearchItem doc={result} key={result[Id]} />)} + {this._results.map(result => <SearchItem doc={result} key={result[Id]} highlighting={[]} />)} </div> ) : null} </div> diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 8e8d5708b..4fd11add4 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -180,7 +180,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { } 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 })); + this.props.addDocument(Docs.Create.VideoDocument(url, { ...options, title: url, width: 400, height: 315, nativeWidth: 600, nativeHeight: 472.5 })); return; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 970ef24d8..245dd319d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -556,6 +556,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu }, icon: "search" }); cm.addItem({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" }); + cm.addItem({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" }); cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])), icon: "link" }); cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" }); cm.addItem({ description: "Delete", event: this.deleteClicked, icon: "trash" }); diff --git a/src/client/views/nodes/LinkMenuItem.tsx b/src/client/views/nodes/LinkMenuItem.tsx index 6191774ed..659b56e5d 100644 --- a/src/client/views/nodes/LinkMenuItem.tsx +++ b/src/client/views/nodes/LinkMenuItem.tsx @@ -40,15 +40,20 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { } let proto = Doc.GetProto(this.props.linkDoc); let targetContext = await Cast(proto.targetContext, Doc); + let sourceContext = await Cast(proto.sourceContext, Doc); + let self = this; if (DocumentManager.Instance.getDocumentView(jumpToDoc)) { - let self = this; DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((this.props.destinationDoc === self.props.linkDoc.anchor2 ? self.props.linkDoc.anchor2Page : self.props.linkDoc.anchor1Page))); } - else if (targetContext) { - DocumentManager.Instance.jumpToDocument(targetContext, e.altKey, false, document => CollectionDockingView.Instance.AddRightSplit(document, undefined)); - } else { - // CollectionDockingView.Instance.AddRightSplit(jumpToDoc, undefined); + else if (!((this.props.destinationDoc === self.props.linkDoc.anchor2 && targetContext) || (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext))) { DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, document => CollectionDockingView.Instance.AddRightSplit(document, undefined)); + } else { + if (this.props.destinationDoc === self.props.linkDoc.anchor2 && targetContext) { + DocumentManager.Instance.jumpToDocument(targetContext, e.altKey, false, document => CollectionDockingView.Instance.AddRightSplit(document, undefined)); + } + else if (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext) { + DocumentManager.Instance.jumpToDocument(sourceContext, e.altKey, false, document => CollectionDockingView.Instance.AddRightSplit(document, undefined)); + } } } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 7796c6744..8b8e500c4 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,5 +1,5 @@ import React = require("react"); -import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked } from "mobx"; +import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked, trace } from "mobx"; import { observer } from "mobx-react"; import * as rp from 'request-promise'; import { InkTool } from "../../../new_fields/InkField"; @@ -94,7 +94,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD let youtubeaspect = 400 / 315; var nativeWidth = FieldValue(this.Document.nativeWidth, 0); var nativeHeight = FieldValue(this.Document.nativeHeight, 0); - if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { + if (!nativeWidth || !nativeHeight) { if (!this.Document.nativeWidth) this.Document.nativeWidth = 600; this.Document.nativeHeight = this.Document.nativeWidth / youtubeaspect; this.Document.height = FieldValue(this.Document.width, 0) / youtubeaspect; @@ -240,7 +240,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD let style = "videoBox-content-YouTube" + (this._fullScreen ? "-fullScreen" : ""); let start = untracked(() => Math.round(NumCast(this.props.Document.curPage))); return <iframe key={this._youtubeIframeId} id={`${this.youtubeVideoId + this._youtubeIframeId}-player`} - onLoad={this.youtubeIframeLoaded} className={`${style}`} width="640" height="390" + onLoad={this.youtubeIframeLoaded} className={`${style}`} width={NumCast(this.props.Document.nativeWidth, 640)} height={NumCast(this.props.Document.nativeHeight, 390)} src={`https://www.youtube.com/embed/${this.youtubeVideoId}?enablejsapi=1&rel=0&showinfo=1&autoplay=1&mute=1&start=${start}&modestbranding=1&controls=${VideoBox._showControls ? 1 : 0}`} ></iframe>; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 1e10cb022..699a1ffd7 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -351,7 +351,7 @@ export class Viewer extends React.Component<IViewerProps> { <img key={res.path} src={res.path} onError={handleError} style={{ width: `${parseInt(res.width) * scale}px`, height: `${parseInt(res.height) * scale}px` }} />); } catch (e) { - + console.log(e); } } } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 108492e90..8399605fb 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -24,7 +24,7 @@ export class SearchBox extends React.Component { @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; @observable private _results: [Doc, string[]][] = []; - private _resultsSet = new Set<Doc>(); + private _resultsSet = new Map<Doc, number>(); @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; @@ -143,16 +143,23 @@ export class SearchBox extends React.Component { this._numTotalResults = res.numFound; } - const highlighing = res.highlighting || {}; + const highlighting = res.highlighting || {}; + const highlightList = res.docs.map(doc => highlighting[doc[Id]]); const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); + const highlights: typeof res.highlighting = {}; + docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); runInAction(() => { // this._results.push(...filteredDocs); filteredDocs.forEach(doc => { - if (!this._resultsSet.has(doc)) { - const highlight = highlighing[doc[Id]]; - this._results.push([doc, highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []]); - this._resultsSet.add(doc); + const index = this._resultsSet.get(doc); + const highlight = highlights[doc[Id]]; + const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : [] + if (index === undefined) { + this._resultsSet.set(doc, this._results.length); + this._results.push([doc, hlights]); + } else { + this._results[index][1].push(...hlights); } }); }); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 0d9fa540f..1dd721396 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -371,6 +371,8 @@ export namespace Doc { copy[key] = field; } else if (field instanceof ObjectField) { copy[key] = ObjectField.MakeCopy(field); + } else if (field instanceof Promise) { + field.then(f => (copy[key] === undefined) && (copy[key] = f)); //TODO what should we do here? } else { copy[key] = field; } diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts index 2355304d5..b1a449e08 100644 --- a/src/new_fields/Schema.ts +++ b/src/new_fields/Schema.ts @@ -104,7 +104,7 @@ export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc) } export function createSchema<T extends Interface>(schema: T): T & { proto: ToConstructor<Doc> } { - schema.proto = Doc; + (schema as any).proto = Doc; return schema as any; } diff --git a/src/server/index.ts b/src/server/index.ts index d70f87bd9..51fafbdc3 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -183,7 +183,7 @@ app.get("/whosOnline", (req, res) => { app.get("/thumbnail/:filename", (req, res) => { let filename = req.params.filename; let noExt = filename.substring(0, filename.length - ".png".length); - let pagenumber = parseInt(noExt[noExt.length - 1]); + let pagenumber = parseInt(noExt.split('-')[1]); fs.exists(uploadDir + filename, (exists: boolean) => { console.log(`${uploadDir + filename} ${exists ? "exists" : "does not exist"}`); if (exists) { @@ -191,14 +191,14 @@ app.get("/thumbnail/:filename", (req, res) => { probe(input, (err: any, result: any) => { if (err) { console.log(err); - console.log(filename); + console.log(`error on ${filename}`); return; } res.send({ path: "/files/" + filename, width: result.width, height: result.height }); }); } else { - LoadPage(uploadDir + filename.substring(0, filename.length - "-n.png".length) + ".pdf", pagenumber, res); + LoadPage(uploadDir + filename.substring(0, filename.length - noExt.split('-')[1].length - ".PNG".length - 1) + ".pdf", pagenumber, res); } }); }); |