diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/ContentFittingDocumentView.scss | 5 | ||||
| -rw-r--r-- | src/client/views/nodes/ContentFittingDocumentView.tsx | 24 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentBox.scss | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentBox.tsx | 55 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 23 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/PDFBox.tsx | 61 |
10 files changed, 145 insertions, 36 deletions
diff --git a/src/client/views/nodes/ContentFittingDocumentView.scss b/src/client/views/nodes/ContentFittingDocumentView.scss index 796e67269..2801af441 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.scss +++ b/src/client/views/nodes/ContentFittingDocumentView.scss @@ -2,10 +2,11 @@ .contentFittingDocumentView { position: relative; - height: auto !important; + display: flex; + align-items: center; .contentFittingDocumentView-previewDoc { - position: absolute; + position: relative; display: inline; } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 5e3306a11..e15790c9d 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -31,9 +31,9 @@ interface ContentFittingDocumentViewProps { CollectionDoc?: Doc; onClick?: ScriptField; getTransform: () => Transform; - addDocument: (document: Doc) => boolean; - moveDocument: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean; - removeDocument: (document: Doc) => boolean; + addDocument?: (document: Doc) => boolean; + moveDocument?: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean; + removeDocument?: (document: Doc) => boolean; active: (outsideReaction: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; @@ -47,8 +47,8 @@ interface ContentFittingDocumentViewProps { export class ContentFittingDocumentView extends React.Component<ContentFittingDocumentViewProps>{ public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive private get layoutDoc() { return this.props.Document && Doc.Layout(this.props.Document); } - private get nativeWidth() { return NumCast(this.layoutDoc!.nativeWidth, this.props.PanelWidth()); } - private get nativeHeight() { return NumCast(this.layoutDoc!.nativeHeight, this.props.PanelHeight()); } + private get nativeWidth() { return NumCast(this.layoutDoc?.nativeWidth, this.props.PanelWidth()); } + private get nativeHeight() { return NumCast(this.layoutDoc?.nativeHeight, this.props.PanelHeight()); } private contentScaling = () => { const wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth()); if (wscale * this.nativeHeight > this.props.PanelHeight()) { @@ -73,21 +73,25 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo } private PanelWidth = () => this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth(); private PanelHeight = () => this.nativeHeight && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight(); - private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling()); + private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, -this.centeringYOffset).scale(1 / this.contentScaling()); private get centeringOffset() { return this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; } + private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.contentScaling()) / 2 : 0; } - @computed get borderRounding() { return StrCast(this.props.Document!.borderRounding); } + @computed get borderRounding() { return StrCast(this.props.Document?.borderRounding); } render() { TraceMobx(); - return (<div className="contentFittingDocumentView" style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}> + return (<div className="contentFittingDocumentView" style={{ + width: Math.abs(this.centeringYOffset) > 0.001 ? "auto" : this.props.PanelWidth(), + height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight() + }}> {!this.props.Document || !this.props.PanelWidth ? (null) : ( <div className="contentFittingDocumentView-previewDoc" style={{ transform: `translate(${this.centeringOffset}px, 0px)`, borderRadius: this.borderRounding, - height: this.props.PanelHeight(), - width: `${100 * (this.props.PanelWidth() - this.centeringOffset * 2) / this.props.PanelWidth()}%` + height: Math.abs(this.centeringYOffset) > 0.001 ? `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), + width: Math.abs(this.centeringOffset) > 0.001 ? `${100 * (this.props.PanelWidth() - this.centeringOffset * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth() }}> <DocumentView {...this.props} Document={this.props.Document} diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss new file mode 100644 index 000000000..6a2f98166 --- /dev/null +++ b/src/client/views/nodes/DocumentBox.scss @@ -0,0 +1,6 @@ +.documentBox-container { + width: 100%; + height: 100%; + pointer-events: all; + background: gray; +}
\ No newline at end of file diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx new file mode 100644 index 000000000..b9a97b42d --- /dev/null +++ b/src/client/views/nodes/DocumentBox.tsx @@ -0,0 +1,55 @@ +import { observer } from "mobx-react"; +import { Doc } from "../../../new_fields/Doc"; +import { documentSchema } from "../../../new_fields/documentSchemas"; +import { makeInterface } from "../../../new_fields/Schema"; +import { ComputedField } from "../../../new_fields/ScriptField"; +import { emptyFunction, emptyPath } from "../../../Utils"; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import { DocComponent } from "../DocComponent"; +import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; +import "./DocumentBox.scss"; +import { FieldView, FieldViewProps } from "./FieldView"; +import React = require("react"); + +type DocBoxSchema = makeInterface<[typeof documentSchema]>; +const DocBoxDocument = makeInterface(documentSchema); + +@observer +export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocBoxDocument) { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocumentBox, fieldKey); } + + + specificContextMenu = (e: React.MouseEvent): void => { + const funcs: ContextMenuProps[] = []; + funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), icon: "expand-arrows-alt" }); + + ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); + } + render() { + const containedDoc = this.props.Document[this.props.fieldKey] as Doc; + return <div className="documentBox-container" onContextMenu={this.specificContextMenu}> + {!containedDoc ? (null) : <ContentFittingDocumentView + Document={containedDoc} + DataDocument={undefined} + LibraryPath={emptyPath} + fitToBox={this.props.fitToBox} + addDocument={this.props.addDocument} + moveDocument={this.props.moveDocument} + removeDocument={this.props.removeDocument} + ruleProvider={this.props.ruleProvider} + addDocTab={this.props.addDocTab} + pinToPres={this.props.pinToPres} + getTransform={this.props.ScreenToLocalTransform} + renderDepth={this.props.renderDepth - 1} + PanelWidth={this.props.PanelWidth} + PanelHeight={this.props.PanelHeight} + focus={this.props.focus} + active={this.props.active} + whenActiveChanged={this.props.whenActiveChanged} + setPreviewScript={emptyFunction} + previewScript={undefined} + />} + </div>; + } +} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 1bbc82119..8f6bfc8e1 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -14,6 +14,7 @@ import { LinkFollowBox } from "../linking/LinkFollowBox"; import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; import { AudioBox } from "./AudioBox"; import { ButtonBox } from "./ButtonBox"; +import { DocumentBox } from "./DocumentBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; @@ -102,7 +103,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, FontIconBox: FontIconBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, QueryBox, - ColorBox, DocuLinkBox, InkingStroke + ColorBox, DocuLinkBox, InkingStroke, DocumentBox }} bindings={this.CreateBindings()} jsx={this.layout} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b096d68fc..18885f272 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -43,6 +43,8 @@ import { InteractionUtils } from '../../util/InteractionUtils'; import { InkingControl } from '../InkingControl'; import { InkTool } from '../../../new_fields/InkField'; import { TraceMobx } from '../../../new_fields/util'; +import { List } from '../../../new_fields/List'; +import { FormattedTextBoxComment } from './FormattedTextBoxComment'; library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight, fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, @@ -170,6 +172,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu this.onClickHandler.script.run({ this: this.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log); } else if (this.Document.type === DocumentType.BUTTON) { ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY); + } else if (this.props.Document.isButton === "Selector") { // this should be moved to an OnClick script + FormattedTextBoxComment.Hide(); + this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)])); } else if (this.Document.isButton) { SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. this.buttonClick(e.altKey, e.ctrlKey); @@ -316,6 +321,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } @undoBatch + makeSelBtnClicked = (): void => { + if (this.Document.isButton || this.Document.onClick || this.Document.ignoreClick) { + this.Document.isButton = false; + this.Document.ignoreClick = false; + this.Document.onClick = undefined; + } else { + this.props.Document.isButton = "Selector"; + } + } + + @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { if (de.complete.annoDragData) { @@ -433,13 +449,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript("toggleDetail(this)"), icon: "window-restore" }); onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); onClicks.push({ description: this.Document.isButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.makeBtnClicked, icon: "concierge-bell" }); + onClicks.push({ description: this.props.Document.isButton ? "Remove Select Link Behavior" : "Select Link", event: this.makeSelBtnClicked, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", obj.x, obj.y) }); - onClicks.push({ - description: "Edit onClick Foreach Doc Script", icon: "edit", event: (obj: any) => { - this.props.Document.collectionContext = this.props.ContainingCollectionDoc; - ScriptBox.EditButtonScript("Foreach Collection Doc (d) => ", this.props.Document, "onClick", obj.x, obj.y, "docList(this.collectionContext.data).map(d => {", "});\n"); - } - }); !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a298fd6af..3efbd434e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -822,6 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, }); + this._editorView.state.schema.Document = this.props.Document; if (startup && this._editorView) { Doc.GetProto(doc).documentText = undefined; this._editorView.dispatch(this._editorView.state.tr.insertText(startup)); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index f6aa47f15..09e627078 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -18,7 +18,6 @@ import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from "../../views/ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; import { DocAnnotatableComponent } from '../DocComponent'; -import { InkingControl } from '../InkingControl'; import FaceRectangles from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 322d639dc..234a6a9d3 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -57,7 +57,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: "Doc" } }; + const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); if (!script.compiled) { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 0f5cc0fa9..2f1e1832e 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -3,11 +3,11 @@ import { action, observable, runInAction, reaction, IReactionDisposer, trace, un import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; -import { Opt, WidthSym, Doc } from "../../../new_fields/Doc"; +import { Opt, WidthSym, Doc, HeightSym } from "../../../new_fields/Doc"; import { makeInterface } from "../../../new_fields/Schema"; import { ScriptField } from '../../../new_fields/ScriptField'; -import { Cast, NumCast } from "../../../new_fields/Types"; -import { PdfField } from "../../../new_fields/URLField"; +import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { PdfField, URLField } from "../../../new_fields/URLField"; import { Utils } from '../../../Utils'; import { KeyCodes } from '../../northstar/utils/KeyCodes'; import { undoBatch } from '../../util/UndoManager'; @@ -49,16 +49,38 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument> constructor(props: any) { super(props); this._initialScale = this.props.ScreenToLocalTransform().Scale; + const nw = this.Document.nativeWidth = NumCast(this.extensionDocSync.nativeWidth, NumCast(this.Document.nativeWidth, 927)); + const nh = this.Document.nativeHeight = NumCast(this.extensionDocSync.nativeHeight, NumCast(this.Document.nativeHeight, 1200)); + !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw)); + + const backup = "oldPath"; + const { Document } = this.props; + const { url: { href } } = Cast(Document[this.props.fieldKey], PdfField)!; + const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g; + const matches = pathCorrectionTest.exec(href); + console.log("\nHere's the { url } being fed into the outer regex:"); + console.log(href); + console.log("And here's the 'properPath' build from the captured filename:\n"); + if (matches !== null) { + const properPath = Utils.prepend(`/files/pdfs/${matches[0]}`); + console.log(properPath); + if (!properPath.includes(href)) { + console.log(`The two (url and proper path) were not equal`); + const proto = Doc.GetProto(Document); + proto[this.props.fieldKey] = new PdfField(properPath); + proto[backup] = href; + } else { + console.log(`The two (url and proper path) were equal`); + } + } else { + console.log("Outer matches was null!"); + } } componentWillUnmount() { this._selectReactionDisposer && this._selectReactionDisposer(); } componentDidMount() { - const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); - if (pdfUrl instanceof PdfField) { - Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf)); - } this._selectReactionDisposer = reaction(() => this.props.isSelected(), () => { document.removeEventListener("keydown", this.onKeyDown); @@ -67,9 +89,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument> } loaded = (nw: number, nh: number, np: number) => { - this.dataDoc.numPages = np; - this.Document.nativeWidth = nw * 96 / 72; - this.Document.nativeHeight = nh * 96 / 72; + this.extensionDocSync.numPages = np; + this.extensionDocSync.nativeWidth = this.Document.nativeWidth = nw * 96 / 72; + this.extensionDocSync.nativeHeight = this.Document.nativeHeight = nh * 96 / 72; !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw)); } @@ -197,9 +219,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument> @computed get renderTitleBox() { const classname = "pdfBox" + (this.active() ? "-interactive" : ""); return <div className={classname} style={{ - width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.contentScaling}%`, - height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.contentScaling}%`, - transform: `scale(${this.props.ContentScaling()})` + width: !this.props.Document.fitWidth ? this.Document.nativeWidth || 0 : `${100 / this.contentScaling}%`, + height: !this.props.Document.fitWidth ? this.Document.nativeHeight || 0 : `${100 / this.contentScaling}%`, + transform: `scale(${this.contentScaling})` }} > <div className="pdfBox-title-outer"> <strong className="pdfBox-title" >{this.props.Document.title}</strong> @@ -225,10 +247,19 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument> </div>; } + _pdfjsRequested = false; render() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null); if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true; - return !pdfUrl || !this._pdf || !this.extensionDoc || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ? - this.renderTitleBox : this.renderPdfView; + if (pdfUrl && this.extensionDoc && (this._everActive || (this.extensionDoc.nativeWidth && this.props.ScreenToLocalTransform().Scale < 2.5))) { + if (pdfUrl instanceof PdfField && this._pdf) { + return this.renderPdfView; + } + if (!this._pdfjsRequested) { + this._pdfjsRequested = true; + Pdfjs.getDocument(pdfUrl.url.href).promise.then(pdf => runInAction(() => this._pdf = pdf)); + } + } + return this.renderTitleBox; } }
\ No newline at end of file |
