diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/documents/Documents.ts | 25 | ||||
| -rw-r--r-- | src/client/util/DocumentManager.ts | 14 | ||||
| -rw-r--r-- | src/client/views/MainView.tsx | 10 | ||||
| -rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 7 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 8 | ||||
| -rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 14 |
6 files changed, 55 insertions, 23 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 9b1912fb6..5b32bf76a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -432,17 +432,28 @@ export namespace Docs { parentProto.data = new List<Doc>(); } if (device) { - const { __images } = device; + const { title, __images, additionalMedia } = device; delete device.__images; + delete device.additionalMedia; const { ImageDocument, StackingDocument } = Docs.Create; const constructed = __images.map(({ url, nativeWidth, nativeHeight }) => ({ url: Utils.prepend(url), nativeWidth, nativeHeight })); - const deviceImages = constructed.map(({ url, nativeWidth, nativeHeight }, i) => ImageDocument(url, { - title: `image${i}.${extname(url)}`, - _nativeWidth: nativeWidth, - _nativeHeight: nativeHeight - })); + const deviceImages = constructed.map(({ url, nativeWidth, nativeHeight }, i) => { + const imageDoc = ImageDocument(url, { + title: `image${i}.${extname(url)}`, + _nativeWidth: nativeWidth, + _nativeHeight: nativeHeight + }); + const media = additionalMedia[i]; + if (media) { + for (const key of Object.keys(media)) { + imageDoc[`additionalMedia_${key}`] = Utils.prepend(`/files/${key}/buxton/${media[key]}`); + } + } + return imageDoc; + }); // the main document we create - const doc = StackingDocument(deviceImages, { title: device.title, _LODdisable: true, hero: new ImageField(constructed[0].url) }); + const doc = StackingDocument(deviceImages, { title, _LODdisable: true, hero: new ImageField(constructed[0].url) }); + doc.nameAliases = new List<string>([title.toLowerCase()]); // add the parsed attributes to this main document Docs.Get.FromJson({ data: device, appendToExisting: { targetDoc: Doc.GetProto(doc) } }); Doc.AddDocToList(parentProto, "data", doc); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ab087335e..67f2f244c 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -126,13 +126,13 @@ export class DocumentManager { finished?.(); } public jumpToDocument = async ( - targetDoc: Doc, - willZoom: boolean, - createViewFunc = DocumentManager.addRightSplit, - docContext?: Doc, - linkId?: string, - closeContextIfNotFound: boolean = false, - originatingDoc: Opt<Doc> = undefined, + targetDoc: Doc, // document to display + willZoom: boolean, // whether to zoom doc to take up most of screen + createViewFunc = DocumentManager.addRightSplit, // how to create a view of the doc if it doesn't exist + docContext?: Doc, // context to load that should contain the target + linkId?: string, // link that's being followed + closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there + originatingDoc: Opt<Doc> = undefined, // doc that initiated the display of the target odoc finished?: () => void ): Promise<void> => { const getFirstDocView = DocumentManager.Instance.getFirstDocumentView; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index a0a6adab7..a1d1b0ece 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -51,6 +51,8 @@ import { PreviewCursor } from './PreviewCursor'; import { ScriptField } from '../../fields/ScriptField'; import { TimelineMenu } from './animationtimeline/TimelineMenu'; import { SnappingManager } from '../util/SnappingManager'; +import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; +import { DocumentManager } from '../util/DocumentManager'; @observer export class MainView extends React.Component { @@ -83,6 +85,14 @@ export class MainView extends React.Component { window.removeEventListener("keydown", KeyManager.Instance.handle); window.addEventListener("keydown", KeyManager.Instance.handle); window.addEventListener("paste", KeyManager.Instance.paste as any); + document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on + const id = FormattedTextBox.GetDocFromUrl(e.detail); + DocServer.GetRefField(id).then(doc => { + if (doc instanceof Doc) { + DocumentManager.Instance.jumpToDocument(doc, false, undefined); + } + }); + }); } componentWillUnMount() { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 87fe79e19..b2e1c0f73 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -717,7 +717,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll } ContextMenu.Instance.addItem({ description: "Buxton Layout", icon: "eye", event: () => { - const { ImageDocument } = Docs.Create; + const { ImageDocument, PdfDocument } = Docs.Create; const { Document } = this.props; const fallbackImg = "http://www.cs.brown.edu/~bcz/face.gif"; const detailView = Cast(Cast(Doc.UserDoc()["template-button-detail"], Doc, null)?.dragFactory, Doc, null); @@ -726,13 +726,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll heroView._showTitle = "title"; heroView._showTitleHover = "titlehover"; - const doubleClickView = ImageDocument("http://cs.brown.edu/~bcz/face.gif", { _width: 400 }); // replace with desired double click target + const fallback = ImageDocument("http://cs.brown.edu/~bcz/face.gif", { _width: 400 }); // replace with desired double click target + let pdfContent: string; DocListCast(this.dataDoc[this.props.fieldKey]).map(d => { DocListCast(d.data).map((img, i) => { const caption = (d.captions as any)[i]; if (caption) { Doc.GetProto(img).caption = caption; - Doc.GetProto(img).doubleClickView = doubleClickView; + Doc.GetProto(img).doubleClickView = (pdfContent = StrCast(img.additionalMedia_pdfs)) ? PdfDocument(pdfContent, { title: pdfContent }) : fallback; } }); Doc.GetProto(d).type = "buxton"; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7a4ecfa9c..e245e045c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -742,16 +742,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu const more = cm.findByDescription("More..."); const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : []; - moreItems.push({ description: "Make Add Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "addOnly", icon: "concierge-bell" }); - moreItems.push({ description: "Make Read Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "readOnly", icon: "concierge-bell" }); - moreItems.push({ description: "Make Private", event: () => this.layoutDoc[AclSym] = this.dataDoc[AclSym] = "noAccess", icon: "concierge-bell" }); + moreItems.push({ description: "Make Add Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "addOnly", icon: "concierge-bell" }); + moreItems.push({ description: "Make Read Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "readOnly", icon: "concierge-bell" }); + moreItems.push({ description: "Make Private", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "noAccess", icon: "concierge-bell" }); moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); if (!ClientUtils.RELEASE) { // let copies: ContextMenuProps[] = []; - moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" }); + moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); // cm.addItem({ description: "Copy...", subitems: copies, icon: "copy" }); } if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 217032c1f..5bad248be 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -34,6 +34,7 @@ import React = require("react"); import { SnappingManager } from "../../util/SnappingManager"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); +import { Networking } from "../../Network"; export const pageSchema = createSchema({ curPage: "number", @@ -129,8 +130,17 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu // change the address to be the file address of the PNG version of each page // file address of the pdf const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!; - const addr = Utils.prepend(`/thumbnail${this.props.url.substring("files/pdfs/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.png`); - this._coverPath = href.startsWith(window.location.origin) ? JSON.parse(await rp.get(addr)) : { width: 100, height: 100, path: "" }; + const { url: relative } = this.props; + const pathComponents = relative.split("/pdfs/")[1].split("/"); + const coreFilename = pathComponents.pop()!.split(".")[0]; + const params: any = { + coreFilename, + pageNum: this.Document.curPage || 1, + }; + if (pathComponents.length) { + params.subtree = `${pathComponents.join("/")}/`; + } + this._coverPath = href.startsWith(window.location.origin) ? await Networking.PostToServer("/thumbnail", params) : { width: 100, height: 100, path: "" }; runInAction(() => this._showWaiting = this._showCover = true); this.props.startupLive && this.setupPdfJsViewer(); this._searchReactionDisposer = reaction(() => this.Document.searchMatch, search => { |
