aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx259
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx192
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx505
-rw-r--r--src/client/views/nodes/PDFBox.tsx451
-rw-r--r--src/client/views/nodes/formattedText/schema_rts.ts13
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx2285
6 files changed, 2243 insertions, 1462 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 96ac3e332..f1d8123da 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,48 +1,48 @@
-import { computed } from "mobx";
-import { observer } from "mobx-react";
-import { AclPrivate, Doc, Opt } from "../../../fields/Doc";
-import { ScriptField } from "../../../fields/ScriptField";
-import { Cast, StrCast } from "../../../fields/Types";
-import { GetEffectiveAcl, TraceMobx } from "../../../fields/util";
-import { emptyPath, OmitKeys, Without } from "../../../Utils";
-import { DirectoryImportBox } from "../../util/Import & Export/DirectoryImportBox";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
-import { CollectionSchemaView } from "../collections/collectionSchema/CollectionSchemaView";
-import { CollectionView } from "../collections/CollectionView";
-import { InkingStroke } from "../InkingStroke";
-import { PresElementBox } from "../nodes/trails/PresElementBox";
-import { SearchBox } from "../search/SearchBox";
-import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
-import { YoutubeBox } from "./../../apis/youtube/YoutubeBox";
-import { AudioBox } from "./AudioBox";
-import { FontIconBox } from "./button/FontIconBox";
-import { ColorBox } from "./ColorBox";
-import { ComparisonBox } from "./ComparisonBox";
-import { DataVizBox } from "./DataVizBox/DataVizBox";
-import { DocumentViewProps } from "./DocumentView";
-import "./DocumentView.scss";
-import { EquationBox } from "./EquationBox";
-import { FieldView, FieldViewProps } from "./FieldView";
-import { FilterBox } from "./FilterBox";
-import { FormattedTextBox, FormattedTextBoxProps } from "./formattedText/FormattedTextBox";
-import { FunctionPlotBox } from "./FunctionPlotBox";
-import { ImageBox } from "./ImageBox";
-import { KeyValueBox } from "./KeyValueBox";
-import { LabelBox } from "./LabelBox";
-import { LinkAnchorBox } from "./LinkAnchorBox";
-import { LinkBox } from "./LinkBox";
-import { MapBox } from "./MapBox/MapBox";
-import { PDFBox } from "./PDFBox";
-import { RecordingBox } from "./RecordingBox";
-import { ScreenshotBox } from "./ScreenshotBox";
-import { ScriptingBox } from "./ScriptingBox";
-import { SliderBox } from "./SliderBox";
-import { PresBox } from "./trails/PresBox";
-import { VideoBox } from "./VideoBox";
-import { WebBox } from "./WebBox";
-import React = require("react");
-import XRegExp = require("xregexp");
+import { computed } from 'mobx';
+import { observer } from 'mobx-react';
+import { AclPrivate, Doc, Opt } from '../../../fields/Doc';
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, StrCast } from '../../../fields/Types';
+import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
+import { emptyPath, OmitKeys, Without } from '../../../Utils';
+import { DirectoryImportBox } from '../../util/Import & Export/DirectoryImportBox';
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
+import { CollectionView } from '../collections/CollectionView';
+import { InkingStroke } from '../InkingStroke';
+import { PresElementBox } from '../nodes/trails/PresElementBox';
+import { SearchBox } from '../search/SearchBox';
+import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
+import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
+import { AudioBox } from './AudioBox';
+import { FontIconBox } from './button/FontIconBox';
+import { ColorBox } from './ColorBox';
+import { ComparisonBox } from './ComparisonBox';
+import { DataVizBox } from './DataVizBox/DataVizBox';
+import { DocumentViewProps } from './DocumentView';
+import './DocumentView.scss';
+import { EquationBox } from './EquationBox';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FilterBox } from './FilterBox';
+import { FormattedTextBox, FormattedTextBoxProps } from './formattedText/FormattedTextBox';
+import { FunctionPlotBox } from './FunctionPlotBox';
+import { ImageBox } from './ImageBox';
+import { KeyValueBox } from './KeyValueBox';
+import { LabelBox } from './LabelBox';
+import { LinkAnchorBox } from './LinkAnchorBox';
+import { LinkBox } from './LinkBox';
+import { MapBox } from './MapBox/MapBox';
+import { PDFBox } from './PDFBox';
+import { RecordingBox } from './RecordingBox';
+import { ScreenshotBox } from './ScreenshotBox';
+import { ScriptingBox } from './ScriptingBox';
+import { SliderBox } from './SliderBox';
+import { PresBox } from './trails/PresBox';
+import { VideoBox } from './VideoBox';
+import { WebBox } from './WebBox';
+import React = require('react');
+import XRegExp = require('xregexp');
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -60,7 +60,6 @@ class ObserverJsxParser1 extends JsxParser {
const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
-
interface HTMLtagProps {
Document: Doc;
RootDoc: Doc;
@@ -68,16 +67,17 @@ interface HTMLtagProps {
onClick?: ScriptField;
onInput?: ScriptField;
scaling: number;
+ children?: JSX.Element[];
}
//"<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
-//"<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
-// transform='rotate({2*this.x+this.y}deg)'
+//"<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
+// transform='rotate({2*this.x+this.y}deg)'
// onClick = { this.bannerColor = this.bannerColor === 'red' ? 'green' : 'red' } >
// <ImageBox {...props} fieldKey={'data'}/>
-// <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px'
-// transform='translate(-40px, 45px) rotate(-45deg)' position='absolute'
-// color='{this.bannerColor===`green`?`light`:`dark`}blue'
+// <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px'
+// transform='translate(-40px, 45px) rotate(-45deg)' position='absolute'
+// color='{this.bannerColor===`green`?`light`:`dark`}blue'
// backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'>
// {this.title}
// </HTMLspan>
@@ -87,45 +87,51 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
click = (e: React.MouseEvent) => {
const clickScript = (this.props as any).onClick as Opt<ScriptField>;
clickScript?.script.run({ this: this.props.Document, self: this.props.RootDoc, scale: this.props.scaling });
- }
+ };
onInput = (e: React.FormEvent<HTMLDivElement>) => {
const onInputScript = (this.props as any).onInput as Opt<ScriptField>;
onInputScript?.script.run({ this: this.props.Document, self: this.props.RootDoc, value: (e.target as any).textContent });
- }
+ };
render() {
const style: { [key: string]: any } = {};
- const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "scaling", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
- const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: "number" })?.script.run({ self: this.props.RootDoc, this: this.props.Document, scale: this.props.scaling }).result as string || "";
+ const divKeys = OmitKeys(this.props, ['children', 'htmltag', 'RootDoc', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit;
+ const replacer = (match: any, expr: string, offset: any, string: any) => {
+ // bcz: this executes a script to convert a propery expression string: { script } into a value
+ return (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.RootDoc, this: this.props.Document, scale: this.props.scaling }).result as string) || '';
};
Object.keys(divKeys).map((prop: string) => {
const p = (this.props as any)[prop] as string;
style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
});
const Tag = this.props.htmltag as keyof JSX.IntrinsicElements;
- return <Tag style={style} onClick={this.click} onInput={this.onInput as any}>
- {this.props.children}
- </Tag>;
+ return (
+ <Tag style={style} onClick={this.click} onInput={this.onInput as any}>
+ {this.props.children}
+ </Tag>
+ );
}
}
@observer
-export class DocumentContentsView extends React.Component<DocumentViewProps & FormattedTextBoxProps & {
- isSelected: (outsideReaction: boolean) => boolean,
- select: (ctrl: boolean) => void,
- scaling?: () => number,
- setHeight?: (height: number) => void,
- layoutKey: string,
-}> {
+export class DocumentContentsView extends React.Component<
+ DocumentViewProps &
+ FormattedTextBoxProps & {
+ isSelected: (outsideReaction: boolean) => boolean;
+ select: (ctrl: boolean) => void;
+ scaling?: () => number;
+ setHeight?: (height: number) => void;
+ layoutKey: string;
+ }
+> {
@computed get layout(): string {
TraceMobx();
if (this.props.LayoutTemplateString) return this.props.LayoutTemplateString;
- if (!this.layoutDoc) return "<p>awaiting layout</p>";
- if (this.props.layoutKey === "layout_keyValue") return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
- const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, "layout")], "string");
- if (layout === undefined) return this.props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
- if (typeof layout === "string") return layout;
- return "<p>Loading layout</p>";
+ if (!this.layoutDoc) return '<p>awaiting layout</p>';
+ if (this.props.layoutKey === 'layout_keyValue') return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString('data'));
+ const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, 'layout')], 'string');
+ if (layout === undefined) return this.props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString(this.layoutDoc.proto ? 'proto' : '');
+ if (typeof layout === 'string') return layout;
+ return '<p>Loading layout</p>';
}
get dataDoc() {
@@ -136,36 +142,39 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
const params = StrCast(this.props.Document.PARAMS);
// bcz: replaced this with below : is it correct? change was made to accommodate passing fieldKey's from a layout script
// const template: Doc = this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
- const template: Doc = this.props.LayoutTemplate?.() || (this.props.LayoutTemplateString && this.props.Document) ||
+ const template: Doc =
+ this.props.LayoutTemplate?.() ||
+ (this.props.LayoutTemplateString && this.props.Document) ||
(this.props.layoutKey && StrCast(this.props.Document[this.props.layoutKey]) && this.props.Document) ||
Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
- return Doc.expandTemplateLayout(template, this.props.Document, params ? "(" + params + ")" : this.props.layoutKey);
+ return Doc.expandTemplateLayout(template, this.props.Document, params ? '(' + params + ')' : this.props.layoutKey);
}
CreateBindings(onClick: Opt<ScriptField>, onInput: Opt<ScriptField>): JsxBindings {
- const docOnlyProps = [ // these are the properties in DocumentViewProps that need to be removed to pass on only DocumentSharedViewProps to the FieldViews
- "hideResizeHandles",
- "hideTitle",
- "treeViewDoc",
- "contentPointerEvents",
- "radialMenu",
- "LayoutTemplateString",
- "LayoutTemplate",
- "dontCenter",
- "ContentScaling",
- "contextMenuItems",
- "onClick",
- "onDoubleClick",
- "onPointerDown",
- "onPointerUp",
+ const docOnlyProps = [
+ // these are the properties in DocumentViewProps that need to be removed to pass on only DocumentSharedViewProps to the FieldViews
+ 'hideResizeHandles',
+ 'hideTitle',
+ 'treeViewDoc',
+ 'contentPointerEvents',
+ 'radialMenu',
+ 'LayoutTemplateString',
+ 'LayoutTemplate',
+ 'dontCenter',
+ 'ContentScaling',
+ 'contextMenuItems',
+ 'onClick',
+ 'onDoubleClick',
+ 'onPointerDown',
+ 'onPointerUp',
];
const list = {
- ...OmitKeys(this.props, [...docOnlyProps], "").omit,
+ ...OmitKeys(this.props, [...docOnlyProps], '').omit,
RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc,
Document: this.layoutDoc,
DataDoc: this.dataDoc,
onClick: onClick,
- onInput: onInput
+ onInput: onInput,
};
return { props: list };
}
@@ -180,17 +189,17 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
// replace code content with a script >{content}< as in <HTMLdiv>{this.title}</HTMLdiv>
const replacer = (match: any, prefix: string, expr: string, postfix: string, offset: any, string: any) => {
- return prefix + (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }).result as string || "") + postfix;
+ return prefix + ((ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }).result as string) || '') + postfix;
};
layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer);
- // replace HTML<tag> with corresponding HTML tag as in: <HTMLdiv> becomes <HTMLtag Document={props.Document} htmltag='div'>
+ // replace HTML<tag> with corresponding HTML tag as in: <HTMLdiv> becomes <HTMLtag Document={props.Document} htmltag='div'>
const replacer2 = (match: any, p1: string, offset: any, string: any) => {
return `<HTMLtag RootDoc={props.RootDoc} Document={props.Document} scaling='${this.props.scaling?.() || 1}' htmltag='${p1}'`;
};
layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
- // replace /HTML<tag> with </HTMLdiv> as in: </HTMLdiv> becomes </HTMLtag>
+ // replace /HTML<tag> with </HTMLdiv> as in: </HTMLdiv> becomes </HTMLtag>
const replacer3 = (match: any, p1: string, offset: any, string: any) => {
return `</HTMLtag`;
};
@@ -200,16 +209,16 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
const makeFuncProp = (func: string) => {
const splits = layoutFrame.split(`${func}=`);
if (splits.length > 1) {
- const code = XRegExp.matchRecursive(splits[1], "{", "}", "", { valueNames: ["between", "left", "match", "right", "between"] });
+ const code = XRegExp.matchRecursive(splits[1], '{', '}', '', { valueNames: ['between', 'left', 'match', 'right', 'between'] });
layoutFrame = splits[0] + ` ${func}={props.${func}} ` + splits[1].substring(code[1].end + 1);
- const script = code[1].value.replace(/^‘/, "").replace(/’$/, ""); // ‘’ are not valid quotes in javascript so get rid of them -- they may be present to make it easier to write complex scripts - see headerTemplate in currentUserUtils.ts
- return ScriptField.MakeScript(script, { this: Doc.name, self: Doc.name, scale: "number", value: "string" });
+ const script = code[1].value.replace(/^‘/, '').replace(/’$/, ''); // ‘’ are not valid quotes in javascript so get rid of them -- they may be present to make it easier to write complex scripts - see headerTemplate in currentUserUtils.ts
+ return ScriptField.MakeScript(script, { this: Doc.name, self: Doc.name, scale: 'number', value: 'string' });
}
return undefined;
// add input function to props
};
- const onClick = makeFuncProp("onClick");
- const onInput = makeFuncProp("onInput");
+ const onClick = makeFuncProp('onClick');
+ const onInput = makeFuncProp('onInput');
const bindings = this.CreateBindings(onClick, onInput);
return { bindings, layoutFrame };
}
@@ -218,23 +227,55 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
TraceMobx();
const { bindings, layoutFrame } = this.renderData;
- return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc || GetEffectiveAcl(this.layoutDoc) === AclPrivate) ? (null) :
+ return this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc || GetEffectiveAcl(this.layoutDoc) === AclPrivate ? null : (
<ObserverJsxParser
key={42}
blacklistedAttrs={emptyPath}
renderInWrapper={false}
components={{
- FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, EquationBox, SliderBox, FieldView,
- CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
- PDFBox, VideoBox, AudioBox, RecordingBox, PresBox, YoutubeBox, PresElementBox, SearchBox, FilterBox, FunctionPlotBox,
- ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, LinkBox, ScriptingBox, MapBox,
- ScreenshotBox, DataVizBox, HTMLtag, ComparisonBox
+ FormattedTextBox,
+ ImageBox,
+ DirectoryImportBox,
+ FontIconBox,
+ LabelBox,
+ EquationBox,
+ SliderBox,
+ FieldView,
+ CollectionFreeFormView,
+ CollectionDockingView,
+ CollectionSchemaView,
+ CollectionView,
+ WebBox,
+ KeyValueBox,
+ PDFBox,
+ VideoBox,
+ AudioBox,
+ RecordingBox,
+ PresBox,
+ YoutubeBox,
+ PresElementBox,
+ SearchBox,
+ FilterBox,
+ FunctionPlotBox,
+ ColorBox,
+ DashWebRTCVideo,
+ LinkAnchorBox,
+ InkingStroke,
+ LinkBox,
+ ScriptingBox,
+ MapBox,
+ ScreenshotBox,
+ DataVizBox,
+ HTMLtag,
+ ComparisonBox,
}}
bindings={bindings}
jsx={layoutFrame}
showWarnings={true}
-
- onError={(test: any) => { console.log("DocumentContentsView:" + test); }}
- />;
+ onError={(test: any) => {
+ console.log('DocumentContentsView:' + test);
+ }}
+ />
+ );
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 6c7e174f7..47d5c662e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -1,19 +1,19 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { action, computed, observable } from 'mobx';
-import { observer } from "mobx-react";
-import wiki from "wikijs";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocCastAsync } from "../../../fields/Doc";
-import { NumCast, StrCast, Cast } from "../../../fields/Types";
-import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, setupMoveUpEvents, Utils } from "../../../Utils";
+import { observer } from 'mobx-react';
+import wiki from 'wikijs';
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocCastAsync } from '../../../fields/Doc';
+import { NumCast, StrCast, Cast } from '../../../fields/Types';
+import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, setupMoveUpEvents, Utils } from '../../../Utils';
import { DocServer } from '../../DocServer';
-import { Docs, DocUtils } from "../../documents/Documents";
+import { Docs, DocUtils } from '../../documents/Documents';
import { LinkManager } from '../../util/LinkManager';
-import { Transform } from "../../util/Transform";
+import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
-import { DocumentView, DocumentViewSharedProps } from "./DocumentView";
+import { DocumentView, DocumentViewSharedProps } from './DocumentView';
import './LinkDocPreview.scss';
-import React = require("react");
+import React = require('react');
import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
@@ -27,15 +27,19 @@ interface LinkDocPreviewProps {
}
@observer
export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
- @action public static Clear() { LinkDocPreview.LinkInfo = undefined; }
- @action public static SetLinkInfo(info?: LinkDocPreviewProps) { LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info); }
+ @action public static Clear() {
+ LinkDocPreview.LinkInfo = undefined;
+ }
+ @action public static SetLinkInfo(info?: LinkDocPreviewProps) {
+ LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info);
+ }
_infoRef = React.createRef<HTMLDivElement>();
@observable public static LinkInfo: Opt<LinkDocPreviewProps>;
@observable _targetDoc: Opt<Doc>;
@observable _linkDoc: Opt<Doc>;
@observable _linkSrc: Opt<Doc>;
- @observable _toolTipText = "";
+ @observable _toolTipText = '';
@observable _hrefInd = 0;
@action init() {
@@ -47,113 +51,136 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
if (anchor1 && anchor2) {
linkTarget = Doc.AreProtosEqual(anchor1, this._linkSrc) || Doc.AreProtosEqual(anchor1?.annotationOn as Doc, this._linkSrc) ? anchor2 : anchor1;
}
- if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) { // want to show annotation context document if annotation is not text
- linkTarget && DocCastAsync(linkTarget.annotationOn).then(action(anno => this._targetDoc = anno));
+ if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) {
+ // want to show annotation context document if annotation is not text
+ linkTarget && DocCastAsync(linkTarget.annotationOn).then(action(anno => (this._targetDoc = anno)));
} else {
this._targetDoc = linkTarget;
}
- this._toolTipText = "";
+ this._toolTipText = '';
}
componentDidUpdate(props: any) {
if (props.linkSrc !== this.props.linkSrc || props.linkDoc !== this.props.linkDoc || props.hrefs !== this.props.hrefs) this.init();
}
componentDidMount() {
this.init();
- document.addEventListener("pointerdown", this.onPointerDown);
+ document.addEventListener('pointerdown', this.onPointerDown);
}
componentWillUnmount() {
LinkDocPreview.SetLinkInfo(undefined);
- document.removeEventListener("pointerdown", this.onPointerDown);
+ document.removeEventListener('pointerdown', this.onPointerDown);
}
onPointerDown = (e: PointerEvent) => {
!this._infoRef.current?.contains(e.target as any) && LinkDocPreview.Clear(); // close preview when not clicking anywhere other than the info bar of the preview
- }
+ };
@computed get href() {
if (this.props.hrefs?.length) {
const href = this.props.hrefs[this._hrefInd];
- if (href.indexOf(Doc.localServerPath()) !== 0) { // link to a web page URL -- try to show a preview
- if (href.startsWith("https://en.wikipedia.org/wiki/")) {
- wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(action(summary => this._toolTipText = summary.substring(0, 500))));
+ if (href.indexOf(Doc.localServerPath()) !== 0) {
+ // link to a web page URL -- try to show a preview
+ if (href.startsWith('https://en.wikipedia.org/wiki/')) {
+ wiki()
+ .page(href.replace('https://en.wikipedia.org/wiki/', ''))
+ .then(page => page.summary().then(action(summary => (this._toolTipText = summary.substring(0, 500)))));
} else {
- setTimeout(action(() => this._toolTipText = "url => " + href));
+ setTimeout(action(() => (this._toolTipText = 'url => ' + href)));
}
- } else { // hyperlink to a document .. decode doc id and retrieve from the server. this will trigger vals() being invalidated
- const anchorDoc = href.replace(Doc.localServerPath(), "").split("?")[0];
- anchorDoc && DocServer.GetRefField(anchorDoc).then(action(anchor => {
- if (anchor instanceof Doc && DocListCast(anchor.links).length) {
- this._linkDoc = this._linkDoc ?? DocListCast(anchor.links)[0];
- const automaticLink = this._linkDoc.linkRelationship === LinkManager.AutoKeywords;
- if (automaticLink) { // automatic links specify the target in the link info, not the source
- const linkTarget = anchor;
- this._linkSrc = LinkManager.getOppositeAnchor(this._linkDoc, linkTarget);
- this._targetDoc = linkTarget;
- } else {
- this._linkSrc = anchor;
- const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
- this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
- }
- this._toolTipText = "";
- }
- }));
+ } else {
+ // hyperlink to a document .. decode doc id and retrieve from the server. this will trigger vals() being invalidated
+ const anchorDoc = href.replace(Doc.localServerPath(), '').split('?')[0];
+ anchorDoc &&
+ DocServer.GetRefField(anchorDoc).then(
+ action(anchor => {
+ if (anchor instanceof Doc && DocListCast(anchor.links).length) {
+ this._linkDoc = this._linkDoc ?? DocListCast(anchor.links)[0];
+ const automaticLink = this._linkDoc.linkRelationship === LinkManager.AutoKeywords;
+ if (automaticLink) {
+ // automatic links specify the target in the link info, not the source
+ const linkTarget = anchor;
+ this._linkSrc = LinkManager.getOppositeAnchor(this._linkDoc, linkTarget);
+ this._targetDoc = linkTarget;
+ } else {
+ this._linkSrc = anchor;
+ const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
+ }
+ this._toolTipText = '';
+ }
+ })
+ );
}
return href;
}
return undefined;
}
deleteLink = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(() => this._linkDoc && LinkManager.Instance.deleteLink(this._linkDoc)));
- }
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoBatch(() => this._linkDoc && LinkManager.Instance.deleteLink(this._linkDoc))
+ );
+ };
nextHref = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, action(() => {
- const nextHrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
- if (nextHrefInd !== this._hrefInd) {
- this._linkDoc = undefined;
- this._hrefInd = nextHrefInd;
- }
- }), true);
- }
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ action(() => {
+ const nextHrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+ if (nextHrefInd !== this._hrefInd) {
+ this._linkDoc = undefined;
+ this._hrefInd = nextHrefInd;
+ }
+ }),
+ true
+ );
+ };
followLink = (e: React.PointerEvent) => {
if (this._linkDoc && this._linkSrc) {
LinkDocPreview.Clear();
LinkManager.FollowLink(this._linkDoc, this._linkSrc, this.props.docProps, false);
} else if (this.props.hrefs?.length) {
- this.props.docProps?.addDocTab(Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true }), "add:right");
+ this.props.docProps?.addDocTab(Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true }), 'add:right');
}
- }
+ };
width = () => {
if (!this._targetDoc) return 225;
if (this._targetDoc[WidthSym]() < this._targetDoc?.[HeightSym]()) {
- return Math.min(225, this._targetDoc[HeightSym]()) * this._targetDoc[WidthSym]() / this._targetDoc[HeightSym]();
+ return (Math.min(225, this._targetDoc[HeightSym]()) * this._targetDoc[WidthSym]()) / this._targetDoc[HeightSym]();
}
return Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
- }
+ };
height = () => {
if (!this._targetDoc) return 225;
if (this._targetDoc[WidthSym]() > this._targetDoc?.[HeightSym]()) {
- return Math.min(225, this._targetDoc[WidthSym]()) * this._targetDoc[HeightSym]() / this._targetDoc[WidthSym]();
+ return (Math.min(225, this._targetDoc[WidthSym]()) * this._targetDoc[HeightSym]()) / this._targetDoc[WidthSym]();
}
return Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225));
- }
+ };
@computed get previewHeader() {
- return !this._linkDoc || !this._targetDoc || !this._linkSrc ? (null) :
+ return !this._linkDoc || !this._targetDoc || !this._linkSrc ? null : (
<div className="linkDocPreview-info" ref={this._infoRef}>
- <div className="linkDocPreview-title" style={{ pointerEvents: "all" }}
+ <div
+ className="linkDocPreview-title"
+ style={{ pointerEvents: 'all' }}
onPointerDown={e => {
- DragManager.StartDocumentDrag([this._infoRef.current!],
- new DragManager.DocumentDragData([this._targetDoc!]), e.pageX, e.pageY);
+ DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), e.pageX, e.pageY);
e.stopPropagation();
LinkDocPreview.Clear();
}}>
- {StrCast(this._targetDoc.title).length > 16 ? StrCast(this._targetDoc.title).substr(0, 16) + "..." : this._targetDoc.title}
+ {StrCast(this._targetDoc.title).length > 16 ? StrCast(this._targetDoc.title).substr(0, 16) + '...' : StrCast(this._targetDoc.title)}
<p className="linkDocPreview-description"> {StrCast(this._linkDoc.description)}</p>
</div>
- <div className="linkDocPreview-buttonBar" >
+ <div className="linkDocPreview-buttonBar">
<Tooltip title={<div className="dash-tooltip">Next Link</div>} placement="top">
- <div className="linkDocPreview-button" style={{ background: (this.props.hrefs?.length || 0) <= 1 ? "gray" : "green" }} onPointerDown={this.nextHref}>
+ <div className="linkDocPreview-button" style={{ background: (this.props.hrefs?.length || 0) <= 1 ? 'gray' : 'green' }} onPointerDown={this.nextHref}>
<FontAwesomeIcon className="linkDocPreview-fa-icon" icon="chevron-right" color="white" size="sm" />
</div>
</Tooltip>
@@ -164,20 +191,24 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
</div>
</Tooltip>
</div>
- </div>;
+ </div>
+ );
}
@computed get docPreview() {
const href = this.href; // needs to be here to trigger lookup of web pages and docs on server
- return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? (null) :
+ return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? null : (
<div className="linkDocPreview-inner">
- {!this.props.showHeader ? (null) : this.previewHeader}
- <div className="linkDocPreview-preview-wrapper" style={{ maxHeight: this._toolTipText ? "100%" : undefined, overflow: "auto" }}>
- {this._toolTipText ? this._toolTipText :
- <DocumentView ref={(r) => {
- const targetanchor = this._linkDoc && this._linkSrc && LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
- targetanchor && this._targetDoc !== targetanchor && r?.focus(targetanchor);
- }}
+ {!this.props.showHeader ? null : this.previewHeader}
+ <div className="linkDocPreview-preview-wrapper" style={{ maxHeight: this._toolTipText ? '100%' : undefined, overflow: 'auto' }}>
+ {this._toolTipText ? (
+ this._toolTipText
+ ) : (
+ <DocumentView
+ ref={r => {
+ const targetanchor = this._linkDoc && this._linkSrc && LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ targetanchor && this._targetDoc !== targetanchor && r?.focus(targetanchor);
+ }}
Document={this._targetDoc!}
moveDocument={returnFalse}
rootSelected={returnFalse}
@@ -206,16 +237,19 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
bringToFront={returnFalse}
NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined}
NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined}
- />}
+ />
+ )}
</div>
- </div>;
+ </div>
+ );
}
render() {
const borders = 16; // 8px border on each side
- return <div className="linkDocPreview" onPointerDown={this.followLink}
- style={{ left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}>
- {this.docPreview}
- </div>;
+ return (
+ <div className="linkDocPreview" onPointerDown={this.followLink} style={{ left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}>
+ {this.docPreview}
+ </div>
+ );
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 0b7264d79..18a6b5453 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,8 +1,8 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api';
import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx';
-import { observer } from "mobx-react";
-import * as React from "react";
+import { observer } from 'mobx-react';
+import * as React from 'react';
import { Doc, DocListCast, Opt, WidthSym } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
@@ -22,17 +22,17 @@ import { Annotation } from '../../pdf/Annotation';
import { SidebarAnnos } from '../../SidebarAnnos';
import { StyleProp } from '../../StyleProvider';
import { FieldView, FieldViewProps } from '../FieldView';
-import "./MapBox.scss";
+import './MapBox.scss';
import { MapBoxInfoWindow } from './MapBoxInfoWindow';
/**
* MapBox architecture:
* Main component: MapBox.tsx
* Supporting Components: SidebarAnnos, CollectionStackingView
- *
- * MapBox is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content.
- * The main body of MapBox uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view.
- * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available,
+ *
+ * MapBox is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content.
+ * The main body of MapBox uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view.
+ * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available,
* sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map).
* The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts).
* A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps
@@ -77,26 +77,30 @@ document.head.appendChild(script);
// },
// });
-
// options for searchbox in Google Maps Places Autocomplete API
const options = {
- fields: ["formatted_address", "geometry", "name"], // note: level of details is charged by item per retrieval, not recommended to return all fields
+ fields: ['formatted_address', 'geometry', 'name'], // note: level of details is charged by item per retrieval, not recommended to return all fields
strictBounds: false,
- types: ["establishment"], // type pf places, subject of change according to user need
+ types: ['establishment'], // type pf places, subject of change according to user need
} as google.maps.places.AutocompleteOptions;
@observer
export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>>() {
-
private _dropDisposer?: DragManager.DragDropDisposer;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
@observable private _overlayAnnoInfo: Opt<Doc>;
- showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno);
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MapBox, fieldKey); }
- public get SidebarKey() { return this.fieldKey + "-sidebar"; }
+ showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno));
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(MapBox, fieldKey);
+ }
+ public get SidebarKey() {
+ return this.fieldKey + '-sidebar';
+ }
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
- @computed get inlineTextAnnotations() { return this.allMapMarkers.filter(a => a.textInlineAnnotations); }
+ @computed get inlineTextAnnotations() {
+ return this.allMapMarkers.filter(a => a.textInlineAnnotations);
+ }
@observable private _map: google.maps.Map = null as unknown as google.maps.Map;
@observable private selectedPlace: Doc | undefined;
@@ -108,14 +112,19 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable private searchMarkers: google.maps.Marker[] = [];
@observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options);
@observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
- @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); }
- @computed get allMapMarkers() { return DocListCast(this.dataDoc[this.annotationKey]); }
+ @computed get allSidebarDocs() {
+ return DocListCast(this.dataDoc[this.SidebarKey]);
+ }
+ @computed get allMapMarkers() {
+ return DocListCast(this.dataDoc[this.annotationKey]);
+ }
@observable private toggleAddMarker = false;
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-
@observable _showSidebar = false;
- @computed get SidebarShown() { return this._showSidebar || this.layoutDoc._showSidebar ? true : false; }
+ @computed get SidebarShown() {
+ return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ }
static _canAnnotate = true;
static _hadSelection: boolean = false;
@@ -129,109 +138,106 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
private setSearchBox = (searchBox: any) => {
this.searchBox = searchBox;
- }
+ };
// iterate allMarkers to size, center, and zoom map to contain all markers
private fitBounds = (map: google.maps.Map) => {
const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds();
- const isFitting = this.allMapMarkers.reduce((fits, place) =>
- fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean);
- !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) =>
- bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }),
- new window.google.maps.LatLngBounds()));
- }
+ const isFitting = this.allMapMarkers.reduce((fits, place) => fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean);
+ !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds()));
+ };
/**
* Custom control for add marker button
- * @param controlDiv
- * @param map
+ * @param controlDiv
+ * @param map
*/
private CenterControl = () => {
- const controlDiv = document.createElement("div");
- controlDiv.className = "mapBox-addMarker";
+ const controlDiv = document.createElement('div');
+ controlDiv.className = 'mapBox-addMarker';
// Set CSS for the control border.
- const controlUI = document.createElement("div");
- controlUI.style.backgroundColor = "#fff";
- controlUI.style.borderRadius = "3px";
- controlUI.style.cursor = "pointer";
- controlUI.style.marginTop = "10px";
- controlUI.style.borderRadius = "4px";
- controlUI.style.marginBottom = "22px";
- controlUI.style.textAlign = "center";
- controlUI.style.position = "absolute";
- controlUI.style.width = "32px";
- controlUI.style.height = "32px";
- controlUI.title = "Click to toggle marker mode. In marker mode, click on map to place a marker.";
-
- const plIcon = document.createElement("img");
- plIcon.src = "https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png";
- plIcon.style.color = "rgb(25,25,25)";
- plIcon.style.fontFamily = "Roboto,Arial,sans-serif";
- plIcon.style.fontSize = "16px";
- plIcon.style.lineHeight = "32px";
- plIcon.style.left = "18";
- plIcon.style.top = "15";
- plIcon.style.position = "absolute";
+ const controlUI = document.createElement('div');
+ controlUI.style.backgroundColor = '#fff';
+ controlUI.style.borderRadius = '3px';
+ controlUI.style.cursor = 'pointer';
+ controlUI.style.marginTop = '10px';
+ controlUI.style.borderRadius = '4px';
+ controlUI.style.marginBottom = '22px';
+ controlUI.style.textAlign = 'center';
+ controlUI.style.position = 'absolute';
+ controlUI.style.width = '32px';
+ controlUI.style.height = '32px';
+ controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.';
+
+ const plIcon = document.createElement('img');
+ plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png';
+ plIcon.style.color = 'rgb(25,25,25)';
+ plIcon.style.fontFamily = 'Roboto,Arial,sans-serif';
+ plIcon.style.fontSize = '16px';
+ plIcon.style.lineHeight = '32px';
+ plIcon.style.left = '18';
+ plIcon.style.top = '15';
+ plIcon.style.position = 'absolute';
plIcon.width = 14;
plIcon.height = 14;
- plIcon.innerHTML = "Add";
+ plIcon.innerHTML = 'Add';
controlUI.appendChild(plIcon);
// Set CSS for the control interior.
- const markerIcon = document.createElement("img");
- markerIcon.src = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png";
- markerIcon.style.color = "rgb(25,25,25)";
- markerIcon.style.fontFamily = "Roboto,Arial,sans-serif";
- markerIcon.style.fontSize = "16px";
- markerIcon.style.lineHeight = "32px";
- markerIcon.style.left = "-2";
- markerIcon.style.top = "1";
+ const markerIcon = document.createElement('img');
+ markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png';
+ markerIcon.style.color = 'rgb(25,25,25)';
+ markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif';
+ markerIcon.style.fontSize = '16px';
+ markerIcon.style.lineHeight = '32px';
+ markerIcon.style.left = '-2';
+ markerIcon.style.top = '1';
markerIcon.width = 30;
markerIcon.height = 30;
- markerIcon.style.position = "absolute";
- markerIcon.innerHTML = "Add";
+ markerIcon.style.position = 'absolute';
+ markerIcon.innerHTML = 'Add';
controlUI.appendChild(markerIcon);
// Setup the click event listeners
- controlUI.addEventListener("click", () => {
+ controlUI.addEventListener('click', () => {
if (this.toggleAddMarker === true) {
this.toggleAddMarker = false;
- console.log("add marker button status:" + this.toggleAddMarker);
- controlUI.style.backgroundColor = "#fff";
- markerIcon.style.color = "rgb(25,25,25)";
+ console.log('add marker button status:' + this.toggleAddMarker);
+ controlUI.style.backgroundColor = '#fff';
+ markerIcon.style.color = 'rgb(25,25,25)';
} else {
this.toggleAddMarker = true;
- console.log("add marker button status:" + this.toggleAddMarker);
- controlUI.style.backgroundColor = "#4476f7";
- markerIcon.style.color = "rgb(255,255,255)";
+ console.log('add marker button status:' + this.toggleAddMarker);
+ controlUI.style.backgroundColor = '#4476f7';
+ markerIcon.style.color = 'rgb(255,255,255)';
}
});
controlDiv.appendChild(controlUI);
return controlDiv;
- }
+ };
/**
* Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list
* @param position - the LatLng position where the marker is placed
- * @param map
+ * @param map
*/
@action
private placeMarker = (position: google.maps.LatLng, map: google.maps.Map) => {
const marker = new google.maps.Marker({
position: position,
- map: map
+ map: map,
});
map.panTo(position);
const mapMarker = Docs.Create.MapMarkerDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {});
this.addDocument(mapMarker, this.annotationKey);
- }
+ };
_loadPending = true;
/**
* store a reference to google map instance
* setup the drawing manager on the top right corner of map
- * fit map bounds to contain all markers
- * @param map
+ * fit map bounds to contain all markers
+ * @param map
*/
@action
private loadHandler = (map: google.maps.Map) => {
@@ -256,7 +262,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
map.setZoom(NumCast(this.dataDoc.mapZoom, 2.5));
map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng)));
setTimeout(() => {
-
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
@@ -268,7 +273,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.placeMarker((e as any).latLng, map);
}
});
- }
+ };
@action
centered = () => {
@@ -278,7 +283,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
this.dataDoc.mapLat = this._map.getCenter()?.lat();
this.dataDoc.mapLng = this._map.getCenter()?.lng();
- }
+ };
@action
zoomChanged = () => {
@@ -287,64 +292,64 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
}
this.dataDoc.mapZoom = this._map.getZoom();
- }
+ };
/**
* Load and render all map markers
- * @param marker
- * @param place
+ * @param marker
+ * @param place
*/
@action
private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => {
- place[Id] ? this.markerMap[place[Id]] = marker : null;
- }
+ place[Id] ? (this.markerMap[place[Id]] = marker) : null;
+ };
/**
* on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true
- * @param e
- * @param place
+ * @param e
+ * @param place
*/
@action
private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => {
// set which place was clicked
this.selectedPlace = place;
place.infoWindowOpen = true;
- }
+ };
/**
* Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts
- * @param doc
- * @param sidebarKey
- * @returns
+ * @param doc
+ * @param sidebarKey
+ * @returns
*/
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
- console.log("print all sidebar Docs");
+ console.log('print all sidebar Docs');
console.log(this.allSidebarDocs);
if (!this.layoutDoc._showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
docs.forEach(doc => {
if (doc.lat !== undefined && doc.lng !== undefined) {
const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng);
- doc.onClickBehavior = "enterPortal";
+ doc.onClickBehavior = 'enterPortal';
if (existingMarker) {
- Doc.AddDocToList(existingMarker, "data", doc);
+ Doc.AddDocToList(existingMarker, 'data', doc);
} else {
const marker = Docs.Create.MapMarkerDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {});
this.addDocument(marker, this.annotationKey);
}
}
}); //add to annotation list
- console.log("sidebaraddDocument");
+ console.log('sidebaraddDocument');
console.log(doc);
return this.addDocument(doc, sidebarKey); // add to sidebar list
- }
+ };
/**
* Removing documents from the sidebar
- * @param doc
- * @param sidebarKey
- * @returns
+ * @param doc
+ * @param sidebarKey
+ * @returns
*/
sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
if (this.layoutDoc._showSidebar) this.toggleSidebar();
@@ -354,31 +359,43 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
console.log(this.allSidebarDocs);
});
return this.removeDocument(doc, sidebarKey);
- }
+ };
/**
* Toggle sidebar onclick the tiny comment button on the top right corner
- * @param e
+ * @param e
*/
sidebarBtnDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, (e, down, delta) => {
- const localDelta = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformDirection(delta[0], delta[1]);
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
- const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
- const ratio = (curNativeWidth + localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth;
- if (ratio >= 1) {
- this.layoutDoc.nativeWidth = nativeWidth * ratio;
- this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0];
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
- }
- return false;
- }, emptyFunction, this.toggleSidebar);
- }
-
- sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth();
- @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); }
- @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); }
+ setupMoveUpEvents(
+ this,
+ e,
+ (e, down, delta) => {
+ const localDelta = this.props
+ .ScreenToLocalTransform()
+ .scale(this.props.scaling?.() || 1)
+ .transformDirection(delta[0], delta[1]);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
+ const ratio = (curNativeWidth + localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth;
+ if (ratio >= 1) {
+ this.layoutDoc.nativeWidth = nativeWidth * ratio;
+ this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0];
+ this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+ }
+ return false;
+ },
+ emptyFunction,
+ this.toggleSidebar
+ );
+ };
+ sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
+ @computed get sidebarWidthPercent() {
+ return StrCast(this.layoutDoc._sidebarWidthPercent, '0%');
+ }
+ @computed get sidebarColor() {
+ return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + '-backgroundColor'], '#e4e4e4'));
+ }
/**
* function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted;
@@ -414,7 +431,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
// put temporary cutomized marker on searched location
- this.searchMarkers.forEach((marker) => {
+ this.searchMarkers.forEach(marker => {
marker.setMap(null);
});
this.searchMarkers = [];
@@ -426,7 +443,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
position: place.geometry.location,
})
);
- }
+ };
/**
* Handles toggle of sidebar on click the little comment button
@@ -435,95 +452,99 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
TraceMobx();
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
const color = !annotated ? Colors.WHITE : Colors.BLACK;
- const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props as any, StyleProp.WidgetColor + (annotated ? ":annotated" : ""));
- return (!annotated) ? (null) :
- <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
+ const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this.props.styleProvider?.(this.rootDoc, this.props as any, StyleProp.WidgetColor + (annotated ? ':annotated' : ''));
+ return !annotated ? null : (
+ <div
+ className="formattedTextBox-sidebar-handle"
+ onPointerDown={this.sidebarDown}
style={{
left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 17px))`,
backgroundColor: backgroundColor,
color: color,
- opacity: annotated ? 1 : undefined
- }} >
- <FontAwesomeIcon icon={"comment-alt"} />
- </div>;
+ opacity: annotated ? 1 : undefined,
+ }}>
+ <FontAwesomeIcon icon={'comment-alt'} />
+ </div>
+ );
}
// TODO: Adding highlight box layer to Maps
@action
toggleSidebar = () => {
const prevWidth = this.sidebarWidth();
- this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%";
+ this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%';
this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
- }
+ };
sidebarDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), false);
- }
+ };
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
const bounds = this._ref.current!.getBoundingClientRect();
- this.layoutDoc._sidebarWidthPercent = "" + 100 * Math.max(0, (1 - (e.clientX - bounds.left) / bounds.width)) + "%";
- this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== "0%";
+ this.layoutDoc._sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
+ this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== '0%';
e.preventDefault();
return false;
- }
+ };
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => this._setPreviewCursor = func;
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func);
@action
onMarqueeDown = (e: React.PointerEvent) => {
if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.ActiveTool)) {
- setupMoveUpEvents(this, e, action(e => {
- MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeing = [e.clientX, e.clientY];
- return true;
- }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
+ setupMoveUpEvents(
+ this,
+ e,
+ action(e => {
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
+ this._marqueeing = [e.clientX, e.clientY];
+ return true;
+ }),
+ returnFalse,
+ () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations),
+ false
+ );
}
- }
+ };
@action finishMarquee = (x?: number, y?: number) => {
this._marqueeing = undefined;
this._isAnnotating = false;
x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false, false);
- }
+ };
addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
return this.addDocument(doc, annotationKey);
- }
+ };
pointerEvents = () => {
- return this.props.isContentActive() && this.props.pointerEvents?.() !== "none" && !MarqueeOptionsMenu.Instance.isShown() ?
- "all" :
- SnappingManager.GetIsDragging() ?
- undefined : "none";
- }
+ return this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none';
+ };
@computed get annotationLayer() {
- return <div className="mapBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
- {this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
- <Annotation key={`${anno[Id]}-annotation`} {...this.props}
- fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} />)}
- </div>;
+ return (
+ <div className="mapBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
+ {this.inlineTextAnnotations
+ .sort((a, b) => NumCast(a.y) - NumCast(b.y))
+ .map(anno => (
+ <Annotation key={`${anno[Id]}-annotation`} {...this.props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} />
+ ))}
+ </div>
+ );
}
getAnchor = () => {
- const anchor =
- AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ??
- this.rootDoc;
+ const anchor = AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ?? this.rootDoc;
return anchor;
- }
+ };
/**
* render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker
- * @returns
+ * @returns
*/
private renderMarkers = () => {
return this.allMapMarkers.map(place => (
- <Marker
- key={place[Id]}
- position={{ lat: NumCast(place.lat), lng: NumCast(place.lng) }}
- onLoad={marker => this.markerLoadHandler(marker, place)}
- onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)}
- />
+ <Marker key={place[Id]} position={{ lat: NumCast(place.lat), lng: NumCast(place.lng) }} onLoad={marker => this.markerLoadHandler(marker, place)} onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} />
));
- }
+ };
// TODO: auto center on select a document in the sidebar
private handleMapCenter = (map: google.maps.Map) => {
@@ -531,7 +552,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// if (SelectionManager.Views().lastElement()) {
// console.log(SelectionManager.Views().lastElement());
// }
- }
+ };
panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0);
panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
@@ -543,7 +564,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
savedAnnotations = () => this._savedAnnotations;
render() {
- const renderAnnotations = (docFilters?: () => string[]) => (null);
+ const renderAnnotations = (docFilters?: () => string[]) => null;
// bcz: commmented this out. Otherwise, any documents that are rendered with an InfoWindow of a marker
// will also be rendered as freeform annotations on the map. However, it doesn't seem that rendering
// freeform documents on the map does anything anyway, so getting rid of it for now. Also, since documents
@@ -571,88 +592,88 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// addDocument={this.sidebarAddDocument}
// childPointerEvents={true}
// pointerEvents={CurrentUserUtils.ActiveTool !== InkTool.None || this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
- return <div className="mapBox" ref={this._ref}>
- {/*console.log(apiKey)*/}
- {/* <LoadScript
+ return (
+ <div className="mapBox" ref={this._ref}>
+ {/*console.log(apiKey)*/}
+ {/* <LoadScript
googleMapsApiKey={apiKey!}
libraries={['places', 'drawing']}
> */}
- <div className="mapBox-wrapper"
- onWheel={e => e.stopPropagation()}
- onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}>
-
- <div style={{ mixBlendMode: "multiply" }}>
- {renderAnnotations(this.transparentFilter)}
+ <div className="mapBox-wrapper" onWheel={e => e.stopPropagation()} onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()} style={{ width: `calc(100% - ${this.sidebarWidthPercent})` }}>
+ <div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>
+ {renderAnnotations(this.opaqueFilter)}
+ {SnappingManager.GetIsDragging() ? null : renderAnnotations()}
+ {this.annotationLayer}
+ <GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}>
+ <Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}>
+ <input className="mapBox-input" ref={this.inputRef} type="text" placeholder="Enter location" />
+ </Autocomplete>
+
+ {this.renderMarkers()}
+ {this.allMapMarkers
+ .filter(marker => marker.infoWindowOpen)
+ .map(marker => (
+ <MapBoxInfoWindow
+ key={marker[Id]}
+ {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
+ place={marker}
+ markerMap={this.markerMap}
+ PanelWidth={this.infoWidth}
+ PanelHeight={this.infoHeight}
+ moveDocument={this.moveDocument}
+ isAnyChildContentActive={this.isAnyChildContentActive}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ />
+ ))}
+ {/* {this.handleMapCenter(this._map)} */}
+ </GoogleMap>
+ {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? null : (
+ <MarqueeAnnotator
+ rootDoc={this.rootDoc}
+ anchorMenuClick={this.anchorMenuClick}
+ scrollTop={0}
+ down={this._marqueeing}
+ scaling={returnOne}
+ addDocument={this.addDocumentWrapper}
+ docView={this.props.docViewPath().lastElement()}
+ finishMarquee={this.finishMarquee}
+ savedAnnotations={this.savedAnnotations}
+ annotationLayer={this._annotationLayer.current}
+ mainCont={this._mainCont.current}
+ />
+ )}
</div>
- {renderAnnotations(this.opaqueFilter)}
- {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()}
- {this.annotationLayer}
- <GoogleMap
- mapContainerStyle={mapContainerStyle}
- onZoomChanged={this.zoomChanged}
- onCenterChanged={this.centered}
- onLoad={this.loadHandler}
- options={mapOptions}
- >
- <Autocomplete
- onLoad={this.setSearchBox}
- onPlaceChanged={this.handlePlaceChanged}>
- <input className="mapBox-input" ref={this.inputRef} type="text" placeholder="Enter location" />
- </Autocomplete>
-
- {this.renderMarkers()}
- {this.allMapMarkers.filter(marker => marker.infoWindowOpen).map(marker => <MapBoxInfoWindow key={marker[Id]}
- {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
- place={marker}
- markerMap={this.markerMap}
- PanelWidth={this.infoWidth}
- PanelHeight={this.infoHeight}
- moveDocument={this.moveDocument}
- isAnyChildContentActive={this.isAnyChildContentActive}
+ {/* </LoadScript > */}
+ <div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <SidebarAnnos
+ ref={this._sidebarRef}
+ {...this.props}
+ fieldKey={this.fieldKey}
+ rootDoc={this.rootDoc}
+ layoutDoc={this.layoutDoc}
+ dataDoc={this.dataDoc}
+ showSidebar={this.SidebarShown}
+ nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- />)}
- {this.handleMapCenter(this._map)}
- </GoogleMap>
- {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) :
- <MarqueeAnnotator rootDoc={this.rootDoc}
- anchorMenuClick={this.anchorMenuClick}
- scrollTop={0}
- down={this._marqueeing} scaling={returnOne}
- addDocument={this.addDocumentWrapper}
- docView={this.props.docViewPath().lastElement()}
- finishMarquee={this.finishMarquee}
- savedAnnotations={this.savedAnnotations}
- annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current} />}
- </div>
- {/* </LoadScript > */}
- <div className="mapBox-sidebar"
- style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
- <SidebarAnnos ref={this._sidebarRef}
- {...this.props}
- fieldKey={this.fieldKey}
- rootDoc={this.rootDoc}
- layoutDoc={this.layoutDoc}
- dataDoc={this.dataDoc}
- showSidebar={this.SidebarShown}
- nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- PanelWidth={this.sidebarWidth}
- sidebarAddDocument={this.sidebarAddDocument}
- moveDocument={this.moveDocument}
- removeDocument={this.sidebarRemoveDocument}
- />
- </div>
- <div className="mapBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
- style={{
- display: !this.props.isContentActive() ? "none" : undefined,
- top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
- backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
- }}
- onPointerDown={this.sidebarBtnDown} >
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+ PanelWidth={this.sidebarWidth}
+ sidebarAddDocument={this.sidebarAddDocument}
+ moveDocument={this.moveDocument}
+ removeDocument={this.sidebarRemoveDocument}
+ />
+ </div>
+ <div
+ className="mapBox-overlayButton-sidebar"
+ key="sidebar"
+ title="Toggle Sidebar"
+ style={{
+ display: !this.props.isContentActive() ? 'none' : undefined,
+ top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
+ }}
+ onPointerDown={this.sidebarBtnDown}>
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ </div>
</div>
- </div>;
+ );
}
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 1fb3cef2a..5b9d90780 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,12 +1,12 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
-import { observer } from "mobx-react";
-import * as Pdfjs from "pdfjs-dist";
-import "pdfjs-dist/web/pdf_viewer.css";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { observer } from 'mobx-react';
+import * as Pdfjs from 'pdfjs-dist';
+import 'pdfjs-dist/web/pdf_viewer.css';
+import { Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
-import { ImageField, PdfField } from "../../../fields/URLField";
+import { ImageField, PdfField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, returnOne, setupMoveUpEvents, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
@@ -15,25 +15,27 @@ import { KeyCodes } from '../../util/KeyCodes';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from "../DocComponent";
+import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { Colors } from '../global/globalEnums';
-import { CreateImage } from "../nodes/WebBoxRenderer";
+import { CreateImage } from '../nodes/WebBoxRenderer';
import { AnchorMenu } from '../pdf/AnchorMenu';
-import { PDFViewer } from "../pdf/PDFViewer";
+import { PDFViewer } from '../pdf/PDFViewer';
import { SidebarAnnos } from '../SidebarAnnos';
import { FieldView, FieldViewProps } from './FieldView';
import { ImageBox } from './ImageBox';
-import "./PDFBox.scss";
+import './PDFBox.scss';
import { VideoBox } from './VideoBox';
-import React = require("react");
+import React = require('react');
import { CollectionFreeFormView } from '../collections/collectionFreeForm';
@observer
export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); }
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(PDFBox, fieldKey);
+ }
public static openSidebarWidth = 250;
public static sidebarResizerWidth = 5;
- private _searchString: string = "";
+ private _searchString: string = '';
private _initialScrollTarget: Opt<Doc>;
private _pdfViewer: PDFViewer | undefined;
private _searchRef = React.createRef<HTMLInputElement>();
@@ -44,8 +46,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
@observable private _pageControls = false;
- @computed get pdfUrl() { return Cast(this.dataDoc[this.props.fieldKey], PdfField); }
- @computed get pdfThumb() { return ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumb))?.url; }
+ @computed get pdfUrl() {
+ return Cast(this.dataDoc[this.props.fieldKey], PdfField);
+ }
+ @computed get pdfThumb() {
+ return ImageCast(this.layoutDoc['thumb-frozen'], ImageCast(this.layoutDoc.thumb))?.url;
+ }
constructor(props: any) {
super(props);
@@ -53,8 +59,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
!this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
if (this.pdfUrl) {
- if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href));
- else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => this._pdf = pdf));
+ if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href)));
+ else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf)));
}
}
@@ -65,15 +71,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
}
- if (oldDiv.className === "pdfBox-ui" ||
- oldDiv.className === "pdfViewerDash-overlay-inking") {
- newDiv.style.display = "none";
+ if (oldDiv.className === 'pdfBox-ui' || oldDiv.className === 'pdfViewerDash-overlay-inking') {
+ newDiv.style.display = 'none';
}
- if (newDiv && newDiv.style) newDiv.style.overflow = "hidden";
+ if (newDiv && newDiv.style) newDiv.style.overflow = 'hidden';
if (oldDiv instanceof HTMLCanvasElement) {
const canvas = oldDiv;
const img = document.createElement('img'); // create a Image Element
- img.src = canvas.toDataURL(); //image sourcez
+ img.src = canvas.toDataURL(); //image sourcez
img.style.width = canvas.style.width;
img.style.height = canvas.style.height;
const newCan = newDiv as HTMLCanvasElement;
@@ -81,20 +86,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
parEle.removeChild(newCan);
parEle.appendChild(img);
}
- }
+ };
crop = (region: Doc | undefined, addCrop?: boolean) => {
if (!region) return;
const cropping = Doc.MakeCopy(region, true);
Doc.GetProto(region).lockedPosition = true;
- Doc.GetProto(region).title = "region:" + this.rootDoc.title;
+ Doc.GetProto(region).title = 'region:' + this.rootDoc.title;
Doc.GetProto(region).isPushpin = true;
this.addDocument(region);
const docViewContent = this.props.docViewPath().lastElement().ContentDiv!;
const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
- newDiv.style.width = (this.layoutDoc[WidthSym]()).toString();
- newDiv.style.height = (this.layoutDoc[HeightSym]()).toString();
+ newDiv.style.width = this.layoutDoc[WidthSym]().toString();
+ newDiv.style.height = this.layoutDoc[HeightSym]().toString();
this.replaceCanvases(docViewContent, newDiv);
const htmlString = this._pdfViewer?._mainCont.current && new XMLSerializer().serializeToString(newDiv);
@@ -103,7 +108,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const anchw = cropping[WidthSym]() * (this.props.scaling?.() || 1);
const anchh = cropping[HeightSym]() * (this.props.scaling?.() || 1);
const viewScale = 1;
- cropping.title = "crop: " + this.rootDoc.title;
+ cropping.title = 'crop: ' + this.rootDoc.title;
cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width);
cropping.y = NumCast(this.rootDoc.y);
cropping._width = anchw;
@@ -114,100 +119,113 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
croppingProto.isPrototype = true;
croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
croppingProto.type = DocumentType.IMG;
- croppingProto.layout = ImageBox.LayoutString("data");
- croppingProto.data = new ImageField(Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png"));
- croppingProto["data-nativeWidth"] = anchw;
- croppingProto["data-nativeHeight"] = anchh;
+ croppingProto.layout = ImageBox.LayoutString('data');
+ croppingProto.data = new ImageField(Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png'));
+ croppingProto['data-nativeWidth'] = anchw;
+ croppingProto['data-nativeHeight'] = anchh;
if (addCrop) {
- DocUtils.MakeLink({ doc: region }, { doc: cropping }, "cropped image", "");
+ DocUtils.MakeLink({ doc: region }, { doc: cropping }, 'cropped image', '');
}
this.props.bringToFront(cropping);
CreateImage(
- "",
+ '',
document.styleSheets,
htmlString,
anchw,
anchh,
- NumCast(region.y) * this.props.PanelWidth() / NumCast(this.rootDoc[this.fieldKey + "-nativeWidth"]),
- NumCast(region.x) * this.props.PanelWidth() / NumCast(this.rootDoc[this.fieldKey + "-nativeWidth"]),
+ (NumCast(region.y) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']),
+ (NumCast(region.x) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']),
4
- ).then
- ((data_url: any) => {
- VideoBox.convertDataUri(data_url, region[Id]).then(
- returnedfilename => setTimeout(action(() => {
- croppingProto.data = new ImageField(returnedfilename);
- }), 500));
+ )
+ .then((data_url: any) => {
+ VideoBox.convertDataUri(data_url, region[Id]).then(returnedfilename =>
+ setTimeout(
+ action(() => {
+ croppingProto.data = new ImageField(returnedfilename);
+ }),
+ 500
+ )
+ );
})
.catch(function (error: any) {
console.error('oops, something went wrong!', error);
});
-
return cropping;
- }
+ };
updateIcon = () => {
// currently we render pdf icons as text labels
const docViewContent = this.props.docViewPath().lastElement().ContentDiv!;
- const filename = this.layoutDoc[Id] + "-icon" + (new Date()).getTime();
- this._pdfViewer?._mainCont.current && CollectionFreeFormView.UpdateIcon(
- filename, docViewContent,
- this.layoutDoc[WidthSym](), this.layoutDoc[HeightSym](),
- this.props.PanelWidth(), this.props.PanelHeight(),
- NumCast(this.layoutDoc._scrollTop),
- NumCast(this.rootDoc[this.fieldKey + "-nativeHeight"], 1),
- true,
- this.layoutDoc[Id] + "-icon",
- (iconFile:string, nativeWidth:number, nativeHeight:number) => {
- setTimeout(() => {
- this.dataDoc.icon = new ImageField(iconFile);
- this.dataDoc["icon-nativeWidth"] = nativeWidth;
- this.dataDoc["icon-nativeHeight"] = nativeHeight;
- }, 500);
- });
- }
+ const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime();
+ this._pdfViewer?._mainCont.current &&
+ CollectionFreeFormView.UpdateIcon(
+ filename,
+ docViewContent,
+ this.layoutDoc[WidthSym](),
+ this.layoutDoc[HeightSym](),
+ this.props.PanelWidth(),
+ this.props.PanelHeight(),
+ NumCast(this.layoutDoc._scrollTop),
+ NumCast(this.rootDoc[this.fieldKey + '-nativeHeight'], 1),
+ true,
+ this.layoutDoc[Id] + '-icon',
+ (iconFile: string, nativeWidth: number, nativeHeight: number) => {
+ setTimeout(() => {
+ this.dataDoc.icon = new ImageField(iconFile);
+ this.dataDoc['icon-nativeWidth'] = nativeWidth;
+ this.dataDoc['icon-nativeHeight'] = nativeHeight;
+ }, 500);
+ }
+ );
+ };
- componentWillUnmount() { this._selectReactionDisposer?.(); }
+ componentWillUnmount() {
+ this._selectReactionDisposer?.();
+ }
componentDidMount() {
this.props.setContentView?.(this);
- this._selectReactionDisposer = reaction(() => this.props.isSelected(),
+ this._selectReactionDisposer = reaction(
+ () => this.props.isSelected(),
() => {
- document.removeEventListener("keydown", this.onKeyDown);
- this.props.isSelected(true) && document.addEventListener("keydown", this.onKeyDown);
- }, { fireImmediately: true });
+ document.removeEventListener('keydown', this.onKeyDown);
+ this.props.isSelected(true) && document.addEventListener('keydown', this.onKeyDown);
+ },
+ { fireImmediately: true }
+ );
}
scrollFocus = (doc: Doc, smooth: boolean) => {
let didToggle = false;
- if (DocListCast(this.props.Document[this.fieldKey + "-sidebar"]).includes(doc) && !this.SidebarShown) {
+ if (DocListCast(this.props.Document[this.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
this.toggleSidebar(!smooth);
didToggle = true;
}
if (this._sidebarRef?.current?.makeDocUnfiltered(doc)) return 1;
this._initialScrollTarget = doc;
return this._pdfViewer?.scrollFocus(doc, smooth) ?? (didToggle ? 1 : undefined);
- }
+ };
getAnchor = () => {
const anchor =
this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations()) ??
Docs.Create.TextanchorDocument({
- title: StrCast(this.rootDoc.title + "@" + NumCast(this.layoutDoc._scrollTop)?.toFixed(0)),
+ title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._scrollTop)?.toFixed(0)),
y: NumCast(this.layoutDoc._scrollTop),
- unrendered: true
+ unrendered: true,
});
this.addDocument(anchor);
return anchor;
- }
+ };
@action
loaded = (nw: number, nh: number, np: number) => {
- this.dataDoc[this.props.fieldKey + "-numPages"] = np;
- Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), nw * 96 / 72));
- Doc.SetNativeHeight(this.dataDoc, nh * 96 / 72);
+ this.dataDoc[this.props.fieldKey + '-numPages'] = np;
+ Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), (nw * 96) / 72));
+ Doc.SetNativeHeight(this.dataDoc, (nh * 96) / 72);
this.layoutDoc._height = this.layoutDoc[WidthSym]() / (Doc.NativeAspect(this.dataDoc) || 1);
!this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
- }
+ };
public search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
if (!this._searching && !clear) {
@@ -225,19 +243,23 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
public backPage = () => {
this.Document._curPage = Math.max(1, (NumCast(this.Document._curPage) || 1) - 1);
return true;
- }
+ };
public forwardPage = () => {
- this.Document._curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + "-numPages"]), (NumCast(this.Document._curPage) || 1) + 1);
+ this.Document._curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + '-numPages']), (NumCast(this.Document._curPage) || 1) + 1);
return true;
- }
- public gotoPage = (p: number) => this.Document._curPage = p;
+ };
+ public gotoPage = (p: number) => (this.Document._curPage = p);
@undoBatch
onKeyDown = action((e: KeyboardEvent) => {
let processed = false;
switch (e.key) {
- case "PageDown": processed = this.forwardPage(); break;
- case "PageUp": processed = this.backPage(); break;
+ case 'PageDown':
+ processed = this.forwardPage();
+ break;
+ case 'PageUp':
+ processed = this.backPage();
+ break;
}
if (processed) {
e.stopImmediatePropagation();
@@ -251,131 +273,163 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.scrollFocus(this._initialScrollTarget, false);
this._initialScrollTarget = undefined;
}
- }
- searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => this._searchString = e.currentTarget.value;
+ };
+ searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
// adding external documents; to sidebar key
// if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"-annotation")
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
if (!this.layoutDoc._showSidebar) this.toggleSidebar();
return this.addDocument(doc, sidebarKey);
- }
- sidebarBtnDown = (e: React.PointerEvent, onButton: boolean) => { // onButton determines whether the width of the pdf box changes, or just the ratio of the sidebar to the pdf
- const batch = UndoManager.StartBatch("sidebar");
- setupMoveUpEvents(this, e, (e, down, delta) => {
- const localDelta = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformDirection(delta[0], delta[1]);
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
- const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
- const ratio = (curNativeWidth + (onButton ? 1 : -1) * localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth;
- if (ratio >= 1) {
- this.layoutDoc.nativeWidth = nativeWidth * ratio;
- onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]);
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
- }
- return false;
- }, () => batch.end(), () => this.toggleSidebar());
- }
+ };
+ sidebarBtnDown = (e: React.PointerEvent, onButton: boolean) => {
+ // onButton determines whether the width of the pdf box changes, or just the ratio of the sidebar to the pdf
+ const batch = UndoManager.StartBatch('sidebar');
+ setupMoveUpEvents(
+ this,
+ e,
+ (e, down, delta) => {
+ const localDelta = this.props
+ .ScreenToLocalTransform()
+ .scale(this.props.scaling?.() || 1)
+ .transformDirection(delta[0], delta[1]);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
+ const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this.props.scaling?.() || 1)) / nativeWidth;
+ if (ratio >= 1) {
+ this.layoutDoc.nativeWidth = nativeWidth * ratio;
+ onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]);
+ this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+ }
+ return false;
+ },
+ () => batch.end(),
+ () => this.toggleSidebar()
+ );
+ };
@observable _previewNativeWidth: Opt<number> = undefined;
@observable _previewWidth: Opt<number> = undefined;
toggleSidebar = action((preview: boolean = false) => {
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth + PDFBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth;
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
if (preview) {
this._previewNativeWidth = nativeWidth * sideratio;
- this._previewWidth = this.layoutDoc[WidthSym]() * nativeWidth * sideratio / curNativeWidth;
+ this._previewWidth = (this.layoutDoc[WidthSym]() * nativeWidth * sideratio) / curNativeWidth;
this._showSidebar = true;
- }
- else {
+ } else {
this.layoutDoc.nativeWidth = nativeWidth * pdfratio;
- this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * pdfratio / curNativeWidth;
+ this.layoutDoc._width = (this.layoutDoc[WidthSym]() * nativeWidth * pdfratio) / curNativeWidth;
this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
});
settingsPanel() {
- const pageBtns = <>
- <button className="pdfBox-backBtn" key="back" title="Page Back"
- onPointerDown={e => e.stopPropagation()} onClick={this.backPage} >
- <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-left"} size="sm" />
- </button>
- <button className="pdfBox-fwdBtn" key="fwd" title="Page Forward"
- onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage} >
- <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-right"} size="sm" />
- </button>
- </>;
- const searchTitle = `${!this._searching ? "Open" : "Close"} Search Bar`;
+ const pageBtns = (
+ <>
+ <button className="pdfBox-backBtn" key="back" title="Page Back" onPointerDown={e => e.stopPropagation()} onClick={this.backPage}>
+ <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-left'} size="sm" />
+ </button>
+ <button className="pdfBox-fwdBtn" key="fwd" title="Page Forward" onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}>
+ <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-right'} size="sm" />
+ </button>
+ </>
+ );
+ const searchTitle = `${!this._searching ? 'Open' : 'Close'} Search Bar`;
const curPage = NumCast(this.Document._curPage) || 1;
- return !this.props.isContentActive() || this._pdfViewer?.isAnnotating ? (null) :
- <div className="pdfBox-ui" onKeyDown={e => [KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true}
- onPointerDown={e => e.stopPropagation()} style={{ display: this.props.isContentActive() ? "flex" : "none" }}>
- <div className="pdfBox-overlayCont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
+ return !this.props.isContentActive() || this._pdfViewer?.isAnnotating ? null : (
+ <div
+ className="pdfBox-ui"
+ onKeyDown={e => ([KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true)}
+ onPointerDown={e => e.stopPropagation()}
+ style={{ display: this.props.isContentActive() ? 'flex' : 'none' }}>
+ <div className="pdfBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
<button className="pdfBox-overlayButton" title={searchTitle} />
- <input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged}
+ <input
+ className="pdfBox-searchBar"
+ placeholder="Search"
+ ref={this._searchRef}
+ onChange={this.searchStringChanged}
onKeyDown={e => {
e.stopPropagation();
e.keyCode === KeyCodes.ENTER && this.search(this._searchString, e.shiftKey);
- }} />
+ }}
+ />
<button className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
<FontAwesomeIcon icon="search" size="sm" />
</button>
- <button className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation} >
- <FontAwesomeIcon icon={"arrow-up"} size="lg" />
+ <button className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation}>
+ <FontAwesomeIcon icon={'arrow-up'} size="lg" />
</button>
- <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation} >
- <FontAwesomeIcon icon={"arrow-down"} size="lg" />
+ <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation}>
+ <FontAwesomeIcon icon={'arrow-down'} size="lg" />
</button>
</div>
- <button className="pdfBox-overlayButton" title={searchTitle}
- onClick={action(() => { this._searching = !this._searching; this.search("", true, true); })} >
- <div className="pdfBox-overlayButton-arrow" onPointerDown={(e) => e.stopPropagation()} />
- <div className="pdfBox-overlayButton-iconCont" onPointerDown={(e) => e.stopPropagation()}>
- <FontAwesomeIcon icon={this._searching ? "times" : "search"} size="lg" />
+ <button
+ className="pdfBox-overlayButton"
+ title={searchTitle}
+ onClick={action(() => {
+ this._searching = !this._searching;
+ this.search('', true, true);
+ })}>
+ <div className="pdfBox-overlayButton-arrow" onPointerDown={e => e.stopPropagation()} />
+ <div className="pdfBox-overlayButton-iconCont" onPointerDown={e => e.stopPropagation()}>
+ <FontAwesomeIcon icon={this._searching ? 'times' : 'search'} size="lg" />
</div>
</button>
<div className="pdfBox-pageNums">
- <input value={curPage} style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: "all" }}
- onChange={e => this.Document._curPage = Number(e.currentTarget.value)}
+ <input
+ value={curPage}
+ style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: 'all' }}
+ onChange={e => (this.Document._curPage = Number(e.currentTarget.value))}
onKeyDown={e => e.stopPropagation()}
- onClick={action(() => this._pageControls = !this._pageControls)} />
- {this._pageControls ? pageBtns : (null)}
+ onClick={action(() => (this._pageControls = !this._pageControls))}
+ />
+ {this._pageControls ? pageBtns : null}
</div>
- <div className="pdfBox-sidebarBtn" key="sidebar" title="Toggle Sidebar"
+ <div
+ className="pdfBox-sidebarBtn"
+ key="sidebar"
+ title="Toggle Sidebar"
style={{
- display: !this.props.isContentActive() ? "none" : undefined,
- top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
- backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
+ display: !this.props.isContentActive() ? 'none' : undefined,
+ top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
- onPointerDown={e => this.sidebarBtnDown(e, true)} >
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+ onPointerDown={e => this.sidebarBtnDown(e, true)}>
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
</div>
- </div>;
+ </div>
+ );
}
- sidebarWidth = () => !this.SidebarShown ? 0 :
- PDFBox.sidebarResizerWidth + (this._previewWidth ? PDFBox.openSidebarWidth :
- (NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth() / NumCast(this.layoutDoc.nativeWidth))
+ sidebarWidth = () =>
+ !this.SidebarShown ? 0 : PDFBox.sidebarResizerWidth + (this._previewWidth ? PDFBox.openSidebarWidth : ((NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc)) * this.props.PanelWidth()) / NumCast(this.layoutDoc.nativeWidth));
specificContextMenu = (e: React.MouseEvent): void => {
const funcs: ContextMenuProps[] = [];
- funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(Utils.prepend("") + this.pdfUrl.url.pathname), icon: "expand-arrows-alt" });
- funcs.push({ description: "update icon", event: () => this.pdfUrl && this.updateIcon(), icon: "expand-arrows-alt" });
+ funcs.push({ description: 'Copy path', event: () => this.pdfUrl && Utils.CopyText(Utils.prepend('') + this.pdfUrl.url.pathname), icon: 'expand-arrows-alt' });
+ funcs.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' });
//funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" });
- ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
- }
+ ContextMenu.Instance.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' });
+ };
@computed get renderTitleBox() {
- const classname = "pdfBox" + (this.props.isContentActive() ? "-interactive" : "");
- return <div className={classname} >
- <div className="pdfBox-title-outer">
- <strong className="pdfBox-title" >{this.props.Document.title}</strong>
+ const classname = 'pdfBox' + (this.props.isContentActive() ? '-interactive' : '');
+ return (
+ <div className={classname}>
+ <div className="pdfBox-title-outer">
+ <strong className="pdfBox-title">{StrCast(this.props.Document.title)}</strong>
+ </div>
</div>
- </div>;
+ );
}
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
@observable _showSidebar = false;
- @computed get SidebarShown() { return this._showSidebar || this.layoutDoc._showSidebar ? true : false; }
+ @computed get SidebarShown() {
+ return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ }
contentScaling = () => 1;
isPdfContentActive = () => this.isAnyChildContentActive() || this.props.isSelected();
@@ -383,54 +437,60 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
TraceMobx();
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const scale = previewScale * (this.props.scaling?.() || 1);
- return <div className={"pdfBox"} onContextMenu={this.specificContextMenu}
- style={{
- display: this.props.thumbShown?.() ? "none" : undefined,
- height: this.props.Document._scrollTop && !this.Document._fitWidth && (window.screen.width > 600) ?
- NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined
- }}>
- <div className="pdfBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} />
- <div style={{
- width: `calc(${100 / scale}% - ${this.sidebarWidth() / scale * (this._previewWidth ? scale : 1)}px)`,
- height: `${100 / scale}%`,
- transform: `scale(${scale})`,
- position: "absolute",
- transformOrigin: "top left",
- top: 0,
- }}>
- <PDFViewer {...this.props}
+ return (
+ <div
+ className={'pdfBox'}
+ onContextMenu={this.specificContextMenu}
+ style={{
+ display: this.props.thumbShown?.() ? 'none' : undefined,
+ height: this.props.Document._scrollTop && !this.Document._fitWidth && window.screen.width > 600 ? (NumCast(this.Document._height) * this.props.PanelWidth()) / NumCast(this.Document._width) : undefined,
+ }}>
+ <div className="pdfBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} />
+ <div
+ style={{
+ width: `calc(${100 / scale}% - ${(this.sidebarWidth() / scale) * (this._previewWidth ? scale : 1)}px)`,
+ height: `${100 / scale}%`,
+ transform: `scale(${scale})`,
+ position: 'absolute',
+ transformOrigin: 'top left',
+ top: 0,
+ }}>
+ <PDFViewer
+ {...this.props}
+ rootDoc={this.rootDoc}
+ layoutDoc={this.layoutDoc}
+ dataDoc={this.dataDoc}
+ pdf={this._pdf!}
+ url={this.pdfUrl!.url.pathname}
+ isContentActive={this.isPdfContentActive}
+ anchorMenuClick={this.anchorMenuClick}
+ loaded={!Doc.NativeAspect(this.dataDoc) ? this.loaded : undefined}
+ setPdfViewer={this.setPdfViewer}
+ addDocument={this.addDocument}
+ moveDocument={this.moveDocument}
+ removeDocument={this.removeDocument}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ crop={this.crop}
+ ContentScaling={returnOne}
+ />
+ </div>
+ <SidebarAnnos
+ ref={this._sidebarRef}
+ {...this.props}
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
- pdf={this._pdf!}
- url={this.pdfUrl!.url.pathname}
- isContentActive={this.isPdfContentActive}
- anchorMenuClick={this.anchorMenuClick}
- loaded={!Doc.NativeAspect(this.dataDoc) ? this.loaded : undefined}
- setPdfViewer={this.setPdfViewer}
- addDocument={this.addDocument}
+ setHeight={emptyFunction}
+ nativeWidth={this._previewNativeWidth ?? NumCast(this.layoutDoc._nativeWidth)}
+ showSidebar={this.SidebarShown}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ sidebarAddDocument={this.sidebarAddDocument}
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- crop={this.crop}
- ContentScaling={returnOne}
/>
+ {this.settingsPanel()}
</div>
- <SidebarAnnos ref={this._sidebarRef}
- {...this.props}
- rootDoc={this.rootDoc}
- layoutDoc={this.layoutDoc}
- dataDoc={this.dataDoc}
- setHeight={emptyFunction}
- nativeWidth={this._previewNativeWidth ?? NumCast(this.layoutDoc._nativeWidth)}
- showSidebar={this.SidebarShown}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- sidebarAddDocument={this.sidebarAddDocument}
- moveDocument={this.moveDocument}
- removeDocument={this.removeDocument}
- />
- {this.settingsPanel()}
- </div>;
+ );
}
static pdfcache = new Map<string, Pdfjs.PDFDocumentProxy>();
@@ -446,13 +506,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const href = this.pdfUrl?.url.href;
if (href) {
- if (PDFBox.pdfcache.get(href)) setTimeout(action(() => this._pdf = PDFBox.pdfcache.get(href)));
+ if (PDFBox.pdfcache.get(href)) setTimeout(action(() => (this._pdf = PDFBox.pdfcache.get(href))));
else {
if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise);
- PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, this._pdf = pdf)));
+ PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, (this._pdf = pdf))));
}
}
return this.renderTitleBox;
}
}
-
diff --git a/src/client/views/nodes/formattedText/schema_rts.ts b/src/client/views/nodes/formattedText/schema_rts.ts
index 83561073c..d6e0e6002 100644
--- a/src/client/views/nodes/formattedText/schema_rts.ts
+++ b/src/client/views/nodes/formattedText/schema_rts.ts
@@ -1,8 +1,7 @@
-import { Schema, Slice } from "prosemirror-model";
-
-import { nodes } from "./nodes_rts";
-import { marks } from "./marks_rts";
+import { Schema, Slice } from 'prosemirror-model';
+import { nodes } from './nodes_rts';
+import { marks } from './marks_rts';
// :: Schema
// This schema rougly corresponds to the document schema used by
@@ -20,7 +19,9 @@ const fromJson = schema.nodeFromJSON;
schema.nodeFromJSON = (json: any) => {
const node = fromJson(json);
if (json.type === schema.nodes.summary.name) {
- node.attrs.text = Slice.fromJSON(schema, node.attrs.textslice);
+ // bcz: this is a hacky way to convert the JSON that's serialized for a summary node into the Slice that the summary node wants at run-time.
+ // since attrs are readonly, assigning the text field like this violates the way prosemirror works, but I think we can get away with it.
+ (node.attrs.text as any) = Slice.fromJSON(schema, node.attrs.textslice);
}
return node;
-}; \ No newline at end of file
+};
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 7045d6d5d..91f8d1efc 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,55 +1,57 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import { ColorState, SketchPicker } from "react-color";
+import React = require('react');
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import { ColorState, SketchPicker } from 'react-color';
import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
-import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../../fields/Doc";
-import { InkTool } from "../../../../fields/InkField";
-import { List } from "../../../../fields/List";
-import { PrefetchProxy } from "../../../../fields/Proxy";
-import { listSpec } from "../../../../fields/Schema";
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from "../../../../fields/Types";
+import { Doc, DocListCast, DocListCastAsync, FieldResult } from '../../../../fields/Doc';
+import { InkTool } from '../../../../fields/InkField';
+import { List } from '../../../../fields/List';
+import { PrefetchProxy } from '../../../../fields/Proxy';
+import { listSpec } from '../../../../fields/Schema';
+import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { emptyFunction, returnFalse, returnOne, returnTrue, setupMoveUpEvents } from '../../../../Utils';
-import { Docs } from "../../../documents/Documents";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
-import { DocumentManager } from "../../../util/DocumentManager";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { undoBatch, UndoManager } from "../../../util/UndoManager";
-import { CollectionDockingView } from "../../collections/CollectionDockingView";
-import { MarqueeViewBounds } from "../../collections/collectionFreeForm";
-import { CollectionView, CollectionViewType } from "../../collections/CollectionView";
-import { TabDocView } from "../../collections/TabDocView";
-import { ViewBoxBaseComponent } from "../../DocComponent";
-import { Colors } from "../../global/globalEnums";
-import { LightboxView } from "../../LightboxView";
-import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentView";
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { CurrentUserUtils } from '../../../util/CurrentUserUtils';
+import { DocumentManager } from '../../../util/DocumentManager';
+import { SelectionManager } from '../../../util/SelectionManager';
+import { undoBatch, UndoManager } from '../../../util/UndoManager';
+import { CollectionDockingView } from '../../collections/CollectionDockingView';
+import { MarqueeViewBounds } from '../../collections/collectionFreeForm';
+import { CollectionView, CollectionViewType } from '../../collections/CollectionView';
+import { TabDocView } from '../../collections/TabDocView';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { Colors } from '../../global/globalEnums';
+import { LightboxView } from '../../LightboxView';
+import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
-import "./PresBox.scss";
-import { PresEffect, PresMovement, PresStatus } from "./PresEnums";
-import { ScriptingGlobals } from "../../../util/ScriptingGlobals";
-import { PresElementBox } from ".";
+import './PresBox.scss';
+import { PresEffect, PresMovement, PresStatus } from './PresEnums';
+import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
+import { PresElementBox } from '.';
export interface PinProps {
audioRange?: boolean;
setPosition?: boolean;
hidePresBox?: boolean;
pinWithView?: PinViewProps;
- pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document
- panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area)
- panelHeight?: number
+ pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document
+ panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area)
+ panelHeight?: number;
}
export interface PinViewProps {
- bounds: MarqueeViewBounds;
- scale: number;
+ bounds: MarqueeViewBounds;
+ scale: number;
}
@observer
export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(PresBox, fieldKey);
+ }
/**
* transitions & effects for documents
@@ -67,22 +69,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
};
switch (presDoc.presEffect) {
- case PresEffect.Zoom: return (<Zoom {...effectProps}>{renderDoc}</Zoom>);
- case PresEffect.Fade: return (<Fade {...effectProps}>{renderDoc}</Fade>);
- case PresEffect.Flip: return (<Flip {...effectProps}>{renderDoc}</Flip>);
- case PresEffect.Rotate: return (<Rotate {...effectProps}>{renderDoc}</Rotate>);
- case PresEffect.Bounce: return (<Bounce {...effectProps}>{renderDoc}</Bounce>);
- case PresEffect.Roll: return (<Roll {...effectProps}>{renderDoc}</Roll>);
- case PresEffect.Lightspeed: return (<LightSpeed {...effectProps}>{renderDoc}</LightSpeed>);
+ case PresEffect.Zoom:
+ return <Zoom {...effectProps}>{renderDoc}</Zoom>;
+ case PresEffect.Fade:
+ return <Fade {...effectProps}>{renderDoc}</Fade>;
+ case PresEffect.Flip:
+ return <Flip {...effectProps}>{renderDoc}</Flip>;
+ case PresEffect.Rotate:
+ return <Rotate {...effectProps}>{renderDoc}</Rotate>;
+ case PresEffect.Bounce:
+ return <Bounce {...effectProps}>{renderDoc}</Bounce>;
+ case PresEffect.Roll:
+ return <Roll {...effectProps}>{renderDoc}</Roll>;
+ case PresEffect.Lightspeed:
+ return <LightSpeed {...effectProps}>{renderDoc}</LightSpeed>;
case PresEffect.None:
- default: return renderDoc;
+ default:
+ return renderDoc;
}
}
public static EffectsProvider(layoutDoc: Doc, renderDoc: any) {
- return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ?
- PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex])
- :
- renderDoc;
+ return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ? PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex]) : renderDoc;
}
@observable public static Instance: PresBox;
@@ -107,10 +114,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable private openMovementDropdown: boolean = false;
@observable private openEffectDropdown: boolean = false;
@observable private presentTools: boolean = false;
- @computed get isTreeOrStack() {return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any) }
- @computed get isTree() { return this.layoutDoc._viewType === CollectionViewType.Tree;}
- @computed get presFieldKey() { return StrCast(this.layoutDoc.presFieldKey, "data"); }
- @computed get childDocs() { return DocListCast(this.rootDoc[this.presFieldKey]); }
+ @computed get isTreeOrStack() {
+ return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any);
+ }
+ @computed get isTree() {
+ return this.layoutDoc._viewType === CollectionViewType.Tree;
+ }
+ @computed get presFieldKey() {
+ return StrCast(this.layoutDoc.presFieldKey, 'data');
+ }
+ @computed get childDocs() {
+ return DocListCast(this.rootDoc[this.presFieldKey]);
+ }
@observable _treeViewMap: Map<Doc, number> = new Map();
@computed get tagDocs() {
@@ -121,9 +136,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
return tagDocs;
}
- @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
- @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); }
- @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); }
+ @computed get itemIndex() {
+ return NumCast(this.rootDoc._itemIndex);
+ }
+ @computed get activeItem() {
+ return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null);
+ }
+ @computed get targetDoc() {
+ return Cast(this.activeItem?.presentationTargetDoc, Doc, null);
+ }
@computed get scrollable(): boolean {
if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
else return false;
@@ -134,7 +155,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
constructor(props: any) {
super(props);
- if (CurrentUserUtils.ActivePresentation = this.rootDoc) runInAction(() => PresBox.Instance = this);
+ if ((CurrentUserUtils.ActivePresentation = this.rootDoc)) runInAction(() => (PresBox.Instance = this));
this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
}
@computed get selectedDocumentView() {
@@ -142,21 +163,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc);
}
@computed get isPres(): boolean {
- document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+ document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
if (this.selectedDoc?.type === DocumentType.PRES) {
- document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
- document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
+ document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
+ document.addEventListener('keydown', PresBox.keyEventsWrapper, true);
return true;
}
return false;
}
- @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+ @computed get selectedDoc() {
+ return this.selectedDocumentView?.rootDoc;
+ }
_unmounting = false;
@action
componentWillUnmount() {
this._unmounting = true;
- document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+ document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
this._presKeyEventsActive = false;
this.resetPresentation();
// Turn of progressivize editors
@@ -167,37 +190,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
componentDidMount() {
this._unmounting = false;
- this.rootDoc._forceRenderEngine = "timeline";
+ this.rootDoc._forceRenderEngine = 'timeline';
this.layoutDoc.presStatus = PresStatus.Edit;
this.layoutDoc._gridGap = 0;
this.layoutDoc._yMargin = 0;
this.turnOffEdit(true);
- DocListCastAsync(CurrentUserUtils.MyTrails.data).then(pres =>
- !pres?.includes(this.rootDoc) && Doc.AddDocToList(CurrentUserUtils.MyTrails, "data", this.rootDoc));
- this._disposers.selection = reaction(() => SelectionManager.Views(),
- views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation());
+ DocListCastAsync(CurrentUserUtils.MyTrails.data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(CurrentUserUtils.MyTrails, 'data', this.rootDoc));
+ this._disposers.selection = reaction(
+ () => SelectionManager.Views(),
+ views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation()
+ );
}
@action
updateCurrentPresentation = (pres?: Doc) => {
if (pres) CurrentUserUtils.ActivePresentation = pres;
else CurrentUserUtils.ActivePresentation = this.rootDoc;
- document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
- document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
+ document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
+ document.addEventListener('keydown', PresBox.keyEventsWrapper, true);
this._presKeyEventsActive = true;
PresBox.Instance = this;
- }
+ };
// There are still other internal frames and should go through all frames before going to next slide
nextInternalFrame = (targetDoc: Doc, activeItem: Doc) => {
- const currentFrame = Cast(targetDoc?._currentFrame, "number", null);
+ const currentFrame = Cast(targetDoc?._currentFrame, 'number', null);
const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- targetDoc._viewTransition = "all 1s";
- setTimeout(() => targetDoc._viewTransition = undefined, 1010);
+ targetDoc._viewTransition = 'all 1s';
+ setTimeout(() => (targetDoc._viewTransition = undefined), 1010);
this.nextKeyframe(targetDoc, activeItem);
if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc);
else targetDoc.keyFrameEditing = true;
- }
+ };
_mediaTimer!: [NodeJS.Timeout, Doc];
// 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
@@ -207,7 +231,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.presStartTime), NumCast(activeItem.presStartTime) + duration);
}
- }
+ };
stopTempMedia = (targetDocField: FieldResult) => {
const targetDoc = Cast(targetDocField, Doc, null);
@@ -215,11 +239,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
targMedia?.ComponentView?.Pause?.();
}
- }
+ };
- //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
+ //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
// TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions
- // No more frames in current doc and next slide is defined, therefore move to next slide
+ // No more frames in current doc and next slide is defined, therefore move to next slide
nextSlide = (activeNext: Doc) => {
const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
console.info('nextSlide', activeNext.title, targetNext?.title);
@@ -229,11 +253,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (!this.childDocs[nextSelected].groupWithUp) {
break;
} else {
- console.log("Title: " + this.childDocs[nextSelected].title);
+ console.log('Title: ' + this.childDocs[nextSelected].title);
this.gotoDocument(nextSelected, this.activeItem, true);
}
}
- }
+ };
// Called when the user activates 'next' - to move to the next part of the pres. trail
@action
@@ -241,7 +265,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- const lastFrame = Cast(targetDoc?.lastFrame, "number", null);
+ const lastFrame = Cast(targetDoc?.lastFrame, 'number', null);
const curFrame = NumCast(targetDoc?._currentFrame);
let internalFrames: boolean = false;
if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.scrollProgressivize) internalFrames = true;
@@ -249,13 +273,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Case 1: There are still other frames and should go through all frames before going to next slide
this.nextInternalFrame(targetDoc, activeItem);
} else if (this.childDocs[this.itemIndex + 1] !== undefined) {
- // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
+ // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
this.nextSlide(activeNext);
} else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
// Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
this.gotoDocument(0, this.activeItem);
}
- }
+ };
// Called when the user activates 'back' - to move to the previous part of the pres. trail
@action
@@ -264,7 +288,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null);
const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
- const lastFrame = Cast(targetDoc.lastFrame, "number", null);
+ const lastFrame = Cast(targetDoc.lastFrame, 'number', null);
const curFrame = NumCast(targetDoc._currentFrame);
let prevSelected = this.itemIndex;
// Functionality for group with up
@@ -284,7 +308,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Case 3: Pres loop is on so it should go to the last slide
this.gotoDocument(this.childDocs.length - 1, activeItem);
}
- }
+ };
//The function that is called when a document is clicked or reached through next or back.
//it'll also execute the necessary actions if presentation is playing.
@@ -297,20 +321,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) {
DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia);
}
- if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) {
+ if (from?.mediaStop === 'auto' && this.layoutDoc.presStatus !== PresStatus.Edit) {
this.stopTempMedia(from.presentationTargetDoc);
}
// If next slide is audio / video 'Play automatically' then the next slide should be played
- if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) {
+ if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && activeItem.mediaStart === 'auto') {
this.startTempMedia(targetDoc, activeItem);
}
if (targetDoc) {
- Doc.linkFollowHighlight((targetDoc.annotationOn instanceof Doc) ? [targetDoc, targetDoc.annotationOn] : targetDoc);
- targetDoc && runInAction(() => {
- if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0;
- else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500;
- });
- setTimeout(() => targetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510);
+ Doc.linkFollowHighlight(targetDoc.annotationOn instanceof Doc ? [targetDoc, targetDoc.annotationOn] : targetDoc);
+ targetDoc &&
+ runInAction(() => {
+ if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0;
+ else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500;
+ });
+ setTimeout(() => (targetDoc.focusSpeed = 500), this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510);
}
if (targetDoc?.lastFrame !== undefined) {
targetDoc._currentFrame = 0;
@@ -327,14 +352,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
clearTimeout(this._navTimer);
const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
if (bestTarget) console.log(bestTarget.title, bestTarget.type);
- else console.log("no best target");
- if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem, false);
- }
+ else console.log('no best target');
+ if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem, false);
+ };
// navigates to the bestTarget document by making sure it is on screen,
- // then it applies the view specs stored in activeItem to
+ // then it applies the view specs stored in activeItem to
@action
- static navigateToDoc(bestTarget:Doc, activeItem:Doc, jumpToDoc:boolean) {
+ static navigateToDoc(bestTarget: Doc, activeItem: Doc, jumpToDoc: boolean) {
if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) {
bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
bestTarget._scrollTop = activeItem.presPinViewScroll;
@@ -343,32 +368,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
} else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) {
bestTarget._currentTimecode = activeItem.presStartTime;
} else {
- const contentBounds= Cast(activeItem.contentBounds, listSpec("number"));
+ const contentBounds = Cast(activeItem.contentBounds, listSpec('number'));
bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
if (contentBounds) {
- bestTarget._panX = (contentBounds[0] + contentBounds[2])/2;
- bestTarget._panY = (contentBounds[1] + contentBounds[3])/2;
+ bestTarget._panX = (contentBounds[0] + contentBounds[2]) / 2;
+ bestTarget._panY = (contentBounds[1] + contentBounds[3]) / 2;
const dv = DocumentManager.Instance.getDocumentView(bestTarget);
if (dv) {
- bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]),
- dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0]));
- };
+ bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), dv.props.PanelWidth() / (contentBounds[2] - contentBounds[0]));
+ }
} else {
bestTarget._panX = activeItem.presPinViewX;
bestTarget._panY = activeItem.presPinViewY;
bestTarget._viewScale = activeItem.presPinViewScale;
}
}
- return setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
+ return setTimeout(() => (bestTarget._viewTransition = undefined), activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
}
/**
* This method makes sure that cursor navigates to the element that
- * has the option open and last in the group.
- * Design choice: If the next document is not in presCollection or
+ * has the option open and last in the group.
+ * Design choice: If the next document is not in presCollection or
* presCollection itself then if there is a presCollection it will add
* a new tab. If presCollection is undefined it will open the document
- * on the right.
+ * on the right.
*/
navigateToElement = async (curDoc: Doc) => {
const activeItem: Doc = this.activeItem;
@@ -401,7 +425,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
});
const openInTab = (doc: Doc, finished?: () => void) => {
- collectionDocView ? collectionDocView.props.addDocTab(doc, "") : this.props.addDocTab(doc, "");
+ collectionDocView ? collectionDocView.props.addDocTab(doc, '') : this.props.addDocTab(doc, '');
this.layoutDoc.presCollection = targetDoc;
// this still needs some fixing
setTimeout(resetSelection, 500);
@@ -417,21 +441,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// openInTab(targetDoc);
} else if (curDoc.presMovement === PresMovement.Pan && targetDoc) {
LightboxView.SetLightboxDoc(undefined);
- await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext ? [srcContext]:[], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right
+ await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right
} else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
LightboxView.SetLightboxDoc(undefined);
- //awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext ? [srcContext]:[], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right
+ //awaiting jump so that new scale can be found, since jumping is async
+ await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right
}
// After navigating to the document, if it is added as a presPinView then it will
// adjust the pan and scale to that of the pinView when it was added.
if (activeItem.presPinView) {
console.log(targetDoc.title);
- console.log("presPinView in PresBox.tsx:420");
+ console.log('presPinView in PresBox.tsx:420');
// if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target
this.navigateToView(targetDoc, activeItem);
}
- }
+ };
/**
* Uses the viewfinder to progressivize through the different views of a single collection.
@@ -441,10 +465,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
const srcContext = Cast(targetDoc?.context, Doc, null);
const docView = DocumentManager.Instance.getDocumentView(targetDoc);
- const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
- const vfWidth = this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
- const vfTop = this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
- const vfHeight = this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
+ const vfLeft = this.checkList(targetDoc, activeItem['viewfinder-left-indexed']);
+ const vfWidth = this.checkList(targetDoc, activeItem['viewfinder-width-indexed']);
+ const vfTop = this.checkList(targetDoc, activeItem['viewfinder-top-indexed']);
+ const vfHeight = this.checkList(targetDoc, activeItem['viewfinder-height-indexed']);
// Case 1: document that is not a Golden Layout tab
if (srcContext) {
const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
@@ -455,8 +479,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2;
const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2;
const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
- srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
- srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
+ srcContext._panX = newPanX + (vfLeft + vfWidth / 2);
+ srcContext._panY = newPanY + (vfTop + vfHeight / 2);
srcContext._viewScale = newScale;
}
}
@@ -465,8 +489,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const panelWidth: number = docView.props.PanelWidth();
const panelHeight: number = docView.props.PanelHeight();
const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
- targetDoc._panX = vfLeft + (vfWidth / 2);
- targetDoc._panY = vfTop + (vfWidth / 2);
+ targetDoc._panX = vfLeft + vfWidth / 2;
+ targetDoc._panY = vfTop + vfWidth / 2;
targetDoc._viewScale = newScale;
}
const resize = document.getElementById('resizable');
@@ -476,7 +500,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
resize.style.top = vfTop + 'px';
resize.style.left = vfLeft + 'px';
}
- }
+ };
/**
* For 'Hide Before' and 'Hide After' buttons making sure that
@@ -490,18 +514,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (tagDoc) tagDoc.opacity = 1;
const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
const curInd: number = itemIndexes.indexOf(index);
- if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1; }
- else {
- if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { }
- else if (curDoc.presHideBefore) {
+ if (tagDoc === this.layoutDoc.presCollection) {
+ tagDoc.opacity = 1;
+ } else {
+ if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) {
+ } else if (curDoc.presHideBefore) {
if (index > this.itemIndex) {
tagDoc.opacity = 0;
} else if (!curDoc.presHideAfter) {
tagDoc.opacity = 1;
}
}
- if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== (itemIndexes.length - 1)) { }
- else if (curDoc.presHideAfter) {
+ if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== itemIndexes.length - 1) {
+ } else if (curDoc.presHideAfter) {
if (index < this.itemIndex) {
tagDoc.opacity = 0;
} else if (!curDoc.presHideBefore) {
@@ -510,9 +535,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
});
- }
-
-
+ };
//The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
@action
@@ -521,13 +544,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
let activeItem: Doc = this.activeItem;
let targetDoc: Doc = this.targetDoc;
let duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
- const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
- const load = async () => { // Wrap the loop into an async function for this to work
+ const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms)));
+ const load = async () => {
+ // Wrap the loop into an async function for this to work
for (var i = startSlide; i < this.childDocs.length; i++) {
activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
- if (duration < 100) { duration = 2500; }
+ if (duration < 100) {
+ duration = 2500;
+ }
if (NumCast(targetDoc.lastFrame) > 0) {
for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) {
await timer(duration / NumCast(targetDoc.lastFrame));
@@ -535,7 +561,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
- await timer(duration); this.next(); // then the created Promise can be awaited
+ await timer(duration);
+ this.next(); // then the created Promise can be awaited
if (i === this.childDocs.length - 1) {
setTimeout(() => {
clearTimeout(this._presTimer);
@@ -549,7 +576,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.startPresentation(startSlide);
this.gotoDocument(startSlide, activeItem);
load();
- }
+ };
// The function pauses the auto presentation
@action
@@ -560,20 +587,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.layoutDoc.presLoop = false;
this.childDocs.forEach(this.stopTempMedia);
}
- }
+ };
//The function that resets the presentation by removing every action done by it. It also
//stops the presentaton.
resetPresentation = () => {
this.rootDoc._itemIndex = 0;
- this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => {
- try {
- doc.opacity = 1;
- } catch (e) {
- console.log("Reset presentation error: ", e);
- }
- });
- }
+ this.childDocs
+ .map(doc => Cast(doc.presentationTargetDoc, Doc, null))
+ .filter(doc => doc instanceof Doc)
+ .forEach(doc => {
+ try {
+ doc.opacity = 1;
+ } catch (e) {
+ console.log('Reset presentation error: ', e);
+ }
+ });
+ };
// The function allows for viewing the pres path on toggle
@action togglePath = (srcContext: Doc, off?: boolean) => {
@@ -581,19 +611,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._pathBoolean = false;
srcContext.presPathView = false;
} else {
- runInAction(() => this._pathBoolean = !this._pathBoolean);
+ runInAction(() => (this._pathBoolean = !this._pathBoolean));
srcContext.presPathView = this._pathBoolean;
}
- }
+ };
// The function allows for expanding the view of pres on toggle
@action toggleExpandMode = () => {
- runInAction(() => this._expandBoolean = !this._expandBoolean);
+ runInAction(() => (this._expandBoolean = !this._expandBoolean));
this.rootDoc.expandBoolean = this._expandBoolean;
- this.childDocs.forEach((doc) => {
+ this.childDocs.forEach(doc => {
doc.presExpandInlineButton = this._expandBoolean;
});
- }
+ };
/**
* The function that starts the presentation at the given index, also checking if actions should be applied
@@ -611,7 +641,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
tagDoc.opacity = 0;
}
});
- }
+ };
/**
* The method called to open the presentation as a minimized view
@@ -621,7 +651,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) {
this.layoutDoc.presStatus = PresStatus.Edit;
Doc.RemoveDocFromList(CurrentUserUtils.MyOverlayDocs, undefined, this.rootDoc);
- CollectionDockingView.AddSplit(this.rootDoc, "right");
+ CollectionDockingView.AddSplit(this.rootDoc, 'right');
} else {
this.layoutDoc.presStatus = PresStatus.Edit;
clearTimeout(this._presTimer);
@@ -633,7 +663,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Doc.AddDocToList(CurrentUserUtils.MyOverlayDocs, undefined, this.rootDoc);
this.props.removeDocument?.(this.layoutDoc);
}
- }
+ };
/**
* Called when the user changes the view type
@@ -643,7 +673,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
viewChanged = action((e: React.ChangeEvent) => {
//@ts-ignore
const viewType = e.target.selectedOptions[0].value as CollectionViewType;
- this.layoutDoc.presFieldKey = this.fieldKey+(viewType === CollectionViewType.Tree ?"-linearized":"");
+ this.layoutDoc.presFieldKey = this.fieldKey + (viewType === CollectionViewType.Tree ? '-linearized' : '');
// pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
[CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType) && (this.rootDoc._pivotField = undefined);
this.rootDoc._viewType = viewType;
@@ -677,20 +707,30 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
});
-
setMovementName = action((movement: any, activeItem: Doc): string => {
let output: string = 'none';
switch (movement) {
- case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom
- case PresMovement.Pan: output = 'Pan'; break; //Pan
- case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut
- case PresMovement.None: output = 'None'; break; //None
- default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom
+ case PresMovement.Zoom:
+ output = 'Pan & Zoom';
+ break; //Pan and zoom
+ case PresMovement.Pan:
+ output = 'Pan';
+ break; //Pan
+ case PresMovement.Jump:
+ output = 'Jump cut';
+ break; //Jump Cut
+ case PresMovement.None:
+ output = 'None';
+ break; //None
+ default:
+ output = 'Zoom';
+ activeItem.presMovement = 'zoom';
+ break; //default set as zoom
}
return output;
});
- whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isChildActive = isActive));
+ whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged((this._isChildActive = isActive)));
// For dragging documents into the presentation trail
addDocumentFilter = (docs: Doc[]) => {
docs.forEach((doc, i) => {
@@ -698,8 +738,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (doc.type === DocumentType.LABEL) {
const audio = Cast(doc.annotationOn, Doc, null);
if (audio) {
- audio.mediaStart = "manual";
- audio.mediaStop = "manual";
+ audio.mediaStart = 'manual';
+ audio.mediaStop = 'manual';
audio.presStartTime = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */));
audio.presEndTime = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */));
audio.presDuration = audio.presStartTime - audio.presEndTime;
@@ -714,7 +754,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
setTimeout(() => this.removeDocument(doc), 0);
return false;
} else {
- if (!doc.presentationTargetDoc) doc.title = doc.title + " - Slide";
+ if (!doc.presentationTargetDoc) doc.title = doc.title + ' - Slide';
doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
doc.presMovement = PresMovement.Zoom;
if (this._expandBoolean) doc.presExpandInlineButton = true;
@@ -722,13 +762,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
});
return true;
- }
- childLayoutTemplate = () => !this.isTreeOrStack ? undefined : DocCast(Doc.UserDoc().presElement);
+ };
+ childLayoutTemplate = () => (!this.isTreeOrStack ? undefined : DocCast(Doc.UserDoc().presElement));
removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.rootDoc, this.fieldKey, doc);
- getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
+ getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight
panelHeight = () => this.props.PanelHeight() - 40;
- isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.ActiveTool === InkTool.None && !this.layoutDoc._lockedPosition) &&
- (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
+ isContentActive = (outsideReaction?: boolean) =>
+ CurrentUserUtils.ActiveTool === InkTool.None && !this.layoutDoc._lockedPosition && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false;
/**
* For sorting the array so that the order is maintained when it is dropped.
@@ -736,7 +776,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
sortArray = (): Doc[] => {
return this.childDocs.filter(doc => this._selectedArray.has(doc));
- }
+ };
/**
* Method to get the list of selected items in the order in which they have been selected
@@ -745,9 +785,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => {
const curDoc = Cast(doc, Doc, null);
const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
- if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div>;
- else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>;
- else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>;
+ if (curDoc && curDoc === this.activeItem)
+ return (
+ <div key={index} className="selectedList-items">
+ <b>
+ {index + 1}. {curDoc.title}
+ </b>
+ </div>
+ );
+ else if (tagDoc)
+ return (
+ <div key={index} className="selectedList-items">
+ {index + 1}. {curDoc.title}
+ </div>
+ );
+ else if (curDoc)
+ return (
+ <div key={index} className="selectedList-items">
+ {index + 1}. {curDoc.title}
+ </div>
+ );
});
return list;
}
@@ -756,7 +813,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
selectPres = () => {
const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
presDocView && SelectionManager.SelectView(presDocView, false);
- }
+ };
//Regular click
@action
@@ -766,12 +823,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0);
else this.updateCurrentPresentation(context);
- if (this.activeItem.setPosition &&
- this.activeItem.y !== undefined &&
- this.activeItem.x !== undefined &&
- this.targetDoc.x !== undefined &&
- this.targetDoc.y !== undefined) {
- const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
+ if (this.activeItem.setPosition && this.activeItem.y !== undefined && this.activeItem.x !== undefined && this.targetDoc.x !== undefined && this.targetDoc.y !== undefined) {
+ const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms)));
const time = 10;
const ydiff = NumCast(this.activeItem.y) - NumCast(this.targetDoc.y);
const xdiff = NumCast(this.activeItem.x) - NumCast(this.targetDoc.x);
@@ -782,7 +835,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
await timer(0.1);
}
}
- }
+ };
//Command click
@action
@@ -797,13 +850,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.removeFromArray(this._dragArray, doc);
}
this.selectPres();
- }
+ };
removeFromArray = (arr: any[], val: any) => {
const index: number = arr.indexOf(val);
const ret: any[] = arr.splice(index, 1);
arr = ret;
- }
+ };
//Shift click
@action
@@ -818,7 +871,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
this.selectPres();
- }
+ };
//regular click
@action
@@ -829,17 +882,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._dragArray.splice(0, this._dragArray.length, drag);
focus && this.selectElement(doc);
selectPres && this.selectPres();
- }
+ };
modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => {
if (cmdClick) this.multiSelect(doc, ref, drag);
else if (shiftClick) this.shiftSelect(doc, ref, drag);
else this.regularSelect(doc, ref, drag, focus);
- }
+ };
static keyEventsWrapper = (e: KeyboardEvent) => {
PresBox.Instance.keyEvents(e);
- }
+ };
// Key for when the presentaiton is active
@action
@@ -847,57 +900,75 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (e.target instanceof HTMLInputElement) return;
let handled = false;
const anchorNode = document.activeElement as HTMLDivElement;
- if (anchorNode && anchorNode.className?.includes("lm_title")) return;
+ if (anchorNode && anchorNode.className?.includes('lm_title')) return;
switch (e.key) {
- case "Backspace":
- if (this.layoutDoc.presStatus === "edit") {
- undoBatch(action(() => {
- for (const doc of Array.from(this._selectedArray.keys())) {
- this.removeDocument(doc);
- }
- this._selectedArray.clear();
- this._eleArray.length = 0;
- this._dragArray.length = 0;
- }))();
+ case 'Backspace':
+ if (this.layoutDoc.presStatus === 'edit') {
+ undoBatch(
+ action(() => {
+ for (const doc of Array.from(this._selectedArray.keys())) {
+ this.removeDocument(doc);
+ }
+ this._selectedArray.clear();
+ this._eleArray.length = 0;
+ this._dragArray.length = 0;
+ })
+ )();
handled = true;
}
break;
- case "Escape":
- if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) { this.updateMinimize(); }
- else if (this.layoutDoc.presStatus === "edit") { this._selectedArray.clear(); this._eleArray.length = this._dragArray.length = 0; }
- else this.layoutDoc.presStatus = "edit";
+ case 'Escape':
+ if (DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc)) {
+ this.updateMinimize();
+ } else if (this.layoutDoc.presStatus === 'edit') {
+ this._selectedArray.clear();
+ this._eleArray.length = this._dragArray.length = 0;
+ } else this.layoutDoc.presStatus = 'edit';
if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
break;
- case "Down": case "ArrowDown":
- case "Right": case "ArrowRight":
- if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { // TODO: update to work properly
+ case 'Down':
+ case 'ArrowDown':
+ case 'Right':
+ case 'ArrowRight':
+ if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) {
+ // TODO: update to work properly
this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1;
this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
} else {
this.next();
- if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
}
handled = true;
break;
- case "Up": case "ArrowUp":
- case "Left": case "ArrowLeft":
- if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly
+ case 'Up':
+ case 'ArrowUp':
+ case 'Left':
+ case 'ArrowLeft':
+ if (e.shiftKey && this.itemIndex !== 0) {
+ // TODO: update to work properly
this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1;
this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
} else {
this.back();
- if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
}
handled = true;
break;
- case "Spacebar": case " ":
+ case 'Spacebar':
+ case ' ':
if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex);
else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
break;
- case "a":
- if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === "edit") {
+ case 'a':
+ if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === 'edit') {
this._selectedArray.clear();
this.childDocs.forEach(doc => this._selectedArray.set(doc, undefined));
handled = true;
@@ -909,10 +980,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
e.stopPropagation();
e.preventDefault();
}
- }
+ };
/**
- *
+ *
*/
@action
viewPaths = () => {
@@ -920,7 +991,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (srcContext) {
this.togglePath(srcContext);
}
- }
+ };
getAllIndexes = (arr: Doc[], val: Doc): number[] => {
const indexes = [];
@@ -928,7 +999,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
arr[i] === val && indexes.push(i);
}
return indexes;
- }
+ };
// Adds the index in the pres path graphically
@computed get order() {
@@ -936,61 +1007,64 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const docs: Doc[] = [];
const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
const dv = DocumentManager.Instance.getDocumentView(presCollection);
- this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => {
- const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
- const srcContext = Cast(tagDoc.context, Doc, null);
- const width = NumCast(tagDoc._width) / 10;
- const height = Math.max(NumCast(tagDoc._height) / 10, 15);
- const edge = Math.max(width, height);
- const fontSize = edge * 0.8;
- const gap = 2;
- if (presCollection === srcContext) {
- // Case A: Document is contained within the collection
- if (docs.includes(tagDoc)) {
- const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length;
- docs.push(tagDoc);
- order.push(
- <div className="pathOrder"
- key={tagDoc.id + 'pres' + index}
- style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - (edge / 2)), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
- onClick={() => this.selectElement(doc)}>
- <div className="pathOrder-frame">{index + 1}</div>
- </div>);
- } else {
+ this.childDocs
+ .filter(doc => Cast(doc.presentationTargetDoc, Doc, null))
+ .forEach((doc, index) => {
+ const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+ const srcContext = Cast(tagDoc.context, Doc, null);
+ const width = NumCast(tagDoc._width) / 10;
+ const height = Math.max(NumCast(tagDoc._height) / 10, 15);
+ const edge = Math.max(width, height);
+ const fontSize = edge * 0.8;
+ const gap = 2;
+ if (presCollection === srcContext) {
+ // Case A: Document is contained within the collection
+ if (docs.includes(tagDoc)) {
+ const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length;
+ docs.push(tagDoc);
+ order.push(
+ <div
+ className="pathOrder"
+ key={tagDoc.id + 'pres' + index}
+ style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - edge / 2), left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }}
+ onClick={() => this.selectElement(doc)}>
+ <div className="pathOrder-frame">{index + 1}</div>
+ </div>
+ );
+ } else {
+ docs.push(tagDoc);
+ order.push(
+ <div
+ className="pathOrder"
+ key={tagDoc.id + 'pres' + index}
+ style={{ top: NumCast(tagDoc.y) - edge / 2, left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }}
+ onClick={() => this.selectElement(doc)}>
+ <div className="pathOrder-frame">{index + 1}</div>
+ </div>
+ );
+ }
+ } else if (doc.presPinView && presCollection === tagDoc && dv) {
+ // Case B: Document is presPinView and is presCollection
+ const scale: number = 1 / NumCast(doc.presPinViewScale);
+ const height: number = dv.props.PanelHeight() * scale;
+ const width: number = dv.props.PanelWidth() * scale;
+ const indWidth = width / 10;
+ const indHeight = Math.max(height / 10, 15);
+ const indEdge = Math.max(indWidth, indHeight);
+ const indFontSize = indEdge * 0.8;
+ const xLoc: number = NumCast(doc.presPinViewX) - width / 2;
+ const yLoc: number = NumCast(doc.presPinViewY) - height / 2;
docs.push(tagDoc);
order.push(
- <div className="pathOrder"
- key={tagDoc.id + 'pres' + index}
- style={{ top: NumCast(tagDoc.y) - (edge / 2), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
- onClick={() => this.selectElement(doc)}>
- <div className="pathOrder-frame">{index + 1}</div>
- </div>);
+ <>
+ <div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ top: yLoc - indEdge / 2, left: xLoc - indEdge / 2, width: indEdge, height: indEdge, fontSize: indFontSize }} onClick={() => this.selectElement(doc)}>
+ <div className="pathOrder-frame">{index + 1}</div>
+ </div>
+ <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div>
+ </>
+ );
}
- } else if (doc.presPinView && presCollection === tagDoc && dv) {
- // Case B: Document is presPinView and is presCollection
- const scale: number = 1 / NumCast(doc.presPinViewScale);
- const height: number = dv.props.PanelHeight() * scale;
- const width: number = dv.props.PanelWidth() * scale;
- const indWidth = width / 10;
- const indHeight = Math.max(height / 10, 15);
- const indEdge = Math.max(indWidth, indHeight);
- const indFontSize = indEdge * 0.8;
- const xLoc: number = NumCast(doc.presPinViewX) - (width / 2);
- const yLoc: number = NumCast(doc.presPinViewY) - (height / 2);
- docs.push(tagDoc);
- order.push(
- <>
- <div className="pathOrder"
- key={tagDoc.id + 'pres' + index}
- style={{ top: yLoc - (indEdge / 2), left: xLoc - (indEdge / 2), width: indEdge, height: indEdge, fontSize: indFontSize }}
- onClick={() => this.selectElement(doc)}
- >
- <div className="pathOrder-frame">{index + 1}</div>
- </div>
- <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div>
- </>);
- }
- });
+ });
return order;
}
@@ -1003,37 +1077,39 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
* collection)
*/
@computed get paths() {
- let pathPoints = "";
+ let pathPoints = '';
const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
this.childDocs.forEach((doc, index) => {
const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
const srcContext = Cast(tagDoc?.context, Doc, null);
if (tagDoc && presCollection === srcContext) {
- const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2);
- const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2);
- if (index = 0) pathPoints = n1x + "," + n1y;
- else pathPoints = pathPoints + " " + n1x + "," + n1y;
+ const n1x = NumCast(tagDoc.x) + NumCast(tagDoc._width) / 2;
+ const n1y = NumCast(tagDoc.y) + NumCast(tagDoc._height) / 2;
+ if ((index = 0)) pathPoints = n1x + ',' + n1y;
+ else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
} else if (doc.presPinView && presCollection === tagDoc) {
const n1x = NumCast(doc.presPinViewX);
const n1y = NumCast(doc.presPinViewY);
- if (index = 0) pathPoints = n1x + "," + n1y;
- else pathPoints = pathPoints + " " + n1x + "," + n1y;
+ if ((index = 0)) pathPoints = n1x + ',' + n1y;
+ else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
}
});
- return (<polyline
- points={pathPoints}
- style={{
- opacity: 1,
- stroke: "#69a6db",
- strokeWidth: 5,
- strokeDasharray: '10 5',
- boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
- }}
- fill="none"
- markerStart="url(#markerArrow)"
- markerMid="url(#markerSquare)"
- markerEnd="url(#markerSquareFilled)"
- />);
+ return (
+ <polyline
+ points={pathPoints}
+ style={{
+ opacity: 1,
+ stroke: '#69a6db',
+ strokeWidth: 5,
+ strokeDasharray: '10 5',
+ boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
+ }}
+ fill="none"
+ markerStart="url(#markerArrow)"
+ markerMid="url(#markerSquare)"
+ markerEnd="url(#markerSquareFilled)"
+ />
+ );
}
// Converts seconds to ms and updates presTransition
@@ -1042,8 +1118,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (change) timeInMS += change;
if (timeInMS < 100) timeInMS = 100;
if (timeInMS > 10000) timeInMS = 10000;
- Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS);
- }
+ Array.from(this._selectedArray.keys()).forEach(doc => (doc.presTransition = timeInMS));
+ };
// Converts seconds to ms and updates presTransition
setZoom = (number: String, change?: number) => {
@@ -1051,8 +1127,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (change) scale += change;
if (scale < 0.01) scale = 0.01;
if (scale > 1.5) scale = 1.5;
- Array.from(this._selectedArray.keys()).forEach((doc) => doc.presZoom = scale);
- }
+ Array.from(this._selectedArray.keys()).forEach(doc => (doc.presZoom = scale));
+ };
// Converts seconds to ms and updates presDuration
setDurationTime = (number: String, change?: number) => {
@@ -1060,8 +1136,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (change) timeInMS += change;
if (timeInMS < 100) timeInMS = 100;
if (timeInMS > 20000) timeInMS = 20000;
- Array.from(this._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS);
- }
+ Array.from(this._selectedArray.keys()).forEach(doc => (doc.presDuration = timeInMS));
+ };
/**
* When the movement dropdown is changes
@@ -1069,7 +1145,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
updateMovement = action((movement: any, all?: boolean) => {
const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
- array.forEach((doc) => {
+ array.forEach(doc => {
switch (movement) {
case PresMovement.Zoom: //Pan and zoom
doc.presMovement = PresMovement.Zoom;
@@ -1081,7 +1157,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
doc.presJump = true;
doc.presMovement = PresMovement.Jump;
break;
- case PresMovement.None: default:
+ case PresMovement.None:
+ default:
doc.presMovement = PresMovement.None;
break;
}
@@ -1092,31 +1169,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
updateHideBefore = (activeItem: Doc) => {
activeItem.presHideBefore = !activeItem.presHideBefore;
- Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore);
- }
+ Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideBefore = activeItem.presHideBefore));
+ };
@undoBatch
@action
updateHideAfter = (activeItem: Doc) => {
activeItem.presHideAfter = !activeItem.presHideAfter;
- Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter);
- }
+ Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideAfter = activeItem.presHideAfter));
+ };
@undoBatch
@action
updateOpenDoc = (activeItem: Doc) => {
activeItem.openDocument = !activeItem.openDocument;
- Array.from(this._selectedArray.keys()).forEach((doc) => {
+ Array.from(this._selectedArray.keys()).forEach(doc => {
doc.openDocument = activeItem.openDocument;
});
- }
+ };
@undoBatch
@action
updateEffectDirection = (effect: any, all?: boolean) => {
const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
- array.forEach((doc) => {
- const tagDoc = doc;// Cast(doc.presentationTargetDoc, Doc, null);
+ array.forEach(doc => {
+ const tagDoc = doc; // Cast(doc.presentationTargetDoc, Doc, null);
switch (effect) {
case PresEffect.Left:
tagDoc.presEffectDirection = PresEffect.Left;
@@ -1130,19 +1207,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
case PresEffect.Bottom:
tagDoc.presEffectDirection = PresEffect.Bottom;
break;
- case PresEffect.Center: default:
+ case PresEffect.Center:
+ default:
tagDoc.presEffectDirection = PresEffect.Center;
break;
}
});
- }
+ };
@undoBatch
@action
updateEffect = (effect: any, all?: boolean) => {
const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
- array.forEach((doc) => {
- const tagDoc = doc;//Cast(doc.presentationTargetDoc, Doc, null);
+ array.forEach(doc => {
+ const tagDoc = doc; //Cast(doc.presentationTargetDoc, Doc, null);
switch (effect) {
case PresEffect.Bounce:
tagDoc.presEffect = PresEffect.Bounce;
@@ -1159,19 +1237,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
case PresEffect.Rotate:
tagDoc.presEffect = PresEffect.Rotate;
break;
- case PresEffect.None: default:
+ case PresEffect.None:
+ default:
tagDoc.presEffect = PresEffect.None;
break;
}
});
- }
+ };
_batch: UndoManager.Batch | undefined = undefined;
@computed get transitionDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection);
+ const isPresCollection: boolean = targetDoc === this.layoutDoc.presCollection;
const isPinWithView: boolean = BoolCast(activeItem.presPinView);
if (activeItem && targetDoc) {
const type = targetDoc.type;
@@ -1182,155 +1261,301 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const effect = this.activeItem.presEffect ? this.activeItem.presEffect : 'None';
activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
return (
- <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
+ <div
+ className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? 'active' : ''}`}
+ onPointerDown={e => e.stopPropagation()}
+ onPointerUp={e => e.stopPropagation()}
+ onClick={action(e => {
+ e.stopPropagation();
+ this.openMovementDropdown = false;
+ this.openEffectDropdown = false;
+ })}>
<div className="ribbon-box">
Movement
- {isPresCollection || (isPresCollection && isPinWithView) ?
+ {isPresCollection || (isPresCollection && isPinWithView) ? (
<div className="ribbon-property" style={{ marginLeft: 0, height: 25, textAlign: 'left', paddingLeft: 5, paddingRight: 5, fontSize: 10 }}>
- {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"}
+ {this.scrollable ? 'Scroll to pinned view' : !isPinWithView ? 'No movement' : 'Pan & Zoom to pinned view'}
</div>
- :
- <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
+ ) : (
+ <div
+ className="presBox-dropdown"
+ onClick={action(e => {
+ e.stopPropagation();
+ this.openMovementDropdown = !this.openMovementDropdown;
+ })}
+ style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
{this.setMovementName(activeItem.presMovement, activeItem)}
- <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} />
- <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}>
- <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None</div>
- <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom</div>
- <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan</div>
- <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut</div>
+ <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this.openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? 'grid' : 'none' }}>
+ <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>
+ None
+ </div>
+ <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>
+ Pan {'&'} Zoom
+ </div>
+ <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>
+ Pan
+ </div>
+ <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>
+ Jump cut
+ </div>
</div>
</div>
- }
- <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}>
+ )}
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
<div className="presBox-subheading">Zoom (% screen filled)</div>
<div className="ribbon-property">
- <input className="presBox-input"
- type="number" value={zoom}
- onChange={action((e) => this.setZoom(e.target.value))} />%
+ <input className="presBox-input" type="number" value={zoom} onChange={action(e => this.setZoom(e.target.value))} />%
</div>
<div className="ribbon-propertyUpDown">
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
- <FontAwesomeIcon icon={"caret-up"} />
+ <FontAwesomeIcon icon={'caret-up'} />
</div>
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
- <FontAwesomeIcon icon={"caret-down"} />
+ <FontAwesomeIcon icon={'caret-down'} />
</div>
</div>
</div>
- <input type="range" step="1" min="0" max="150" value={zoom}
- className={`toolbar-slider ${activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}
+ <input
+ type="range"
+ step="1"
+ min="0"
+ max="150"
+ value={zoom}
+ className={`toolbar-slider ${activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}
id="toolbar-slider"
- onPointerDown={() => this._batch = UndoManager.StartBatch("presZoom")}
+ onPointerDown={() => (this._batch = UndoManager.StartBatch('presZoom'))}
onPointerUp={() => this._batch?.end()}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
this.setZoom(e.target.value);
- }} />
- <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}>
+ }}
+ />
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
<div className="presBox-subheading">Movement Speed</div>
<div className="ribbon-property">
- <input className="presBox-input"
- type="number" value={transitionSpeed}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e) => this.setTransitionTime(e.target.value))} /> s
+ <input className="presBox-input" type="number" value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.setTransitionTime(e.target.value))} /> s
</div>
<div className="ribbon-propertyUpDown">
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), 1000))}>
- <FontAwesomeIcon icon={"caret-up"} />
+ <FontAwesomeIcon icon={'caret-up'} />
</div>
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), -1000))}>
- <FontAwesomeIcon icon={"caret-down"} />
+ <FontAwesomeIcon icon={'caret-down'} />
</div>
</div>
</div>
- <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed}
- className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}
+ <input
+ type="range"
+ step="0.1"
+ min="0.1"
+ max="10"
+ value={transitionSpeed}
+ className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}
id="toolbar-slider"
- onPointerDown={() => this._batch = UndoManager.StartBatch("presTransition")}
+ onPointerDown={() => (this._batch = UndoManager.StartBatch('presTransition'))}
onPointerUp={() => this._batch?.end()}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
this.setTransitionTime(e.target.value);
- }} />
- <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
+ }}
+ />
+ <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}>
<div className="slider-text">Fast</div>
<div className="slider-text">Medium</div>
<div className="slider-text">Slow</div>
</div>
</div>
<div className="ribbon-box">
- Visibility {"&"} Duration
+ Visibility {'&'} Duration
<div className="ribbon-doubleButton">
- {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide before presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideBefore ? "active" : ""}`} onClick={() => this.updateHideBefore(activeItem)}>Hide before</div></Tooltip>}
- {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide after presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideAfter ? "active" : ""}`} onClick={() => this.updateHideAfter(activeItem)}>Hide after</div></Tooltip>}
- <Tooltip title={<><div className="dash-tooltip">{"Open in lightbox view"}</div></>}><div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? Colors.LIGHT_BLUE : "" }} onClick={() => this.updateOpenDoc(activeItem)}>Lightbox</div></Tooltip>
+ {isPresCollection ? null : (
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Hide before presented'}</div>
+ </>
+ }>
+ <div className={`ribbon-toggle ${activeItem.presHideBefore ? 'active' : ''}`} onClick={() => this.updateHideBefore(activeItem)}>
+ Hide before
+ </div>
+ </Tooltip>
+ )}
+ {isPresCollection ? null : (
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Hide after presented'}</div>
+ </>
+ }>
+ <div className={`ribbon-toggle ${activeItem.presHideAfter ? 'active' : ''}`} onClick={() => this.updateHideAfter(activeItem)}>
+ Hide after
+ </div>
+ </Tooltip>
+ )}
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Open in lightbox view'}</div>
+ </>
+ }>
+ <div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? Colors.LIGHT_BLUE : '' }} onClick={() => this.updateOpenDoc(activeItem)}>
+ Lightbox
+ </div>
+ </Tooltip>
</div>
- {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <>
- <div className="ribbon-doubleButton" >
- <div className="presBox-subheading">Slide Duration</div>
- <div className="ribbon-property">
- <input className="presBox-input"
- type="number" value={duration}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e) => this.setDurationTime(e.target.value))} /> s
+ {type === DocumentType.AUDIO || type === DocumentType.VID ? null : (
+ <>
+ <div className="ribbon-doubleButton">
+ <div className="presBox-subheading">Slide Duration</div>
+ <div className="ribbon-property">
+ <input className="presBox-input" type="number" value={duration} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.setDurationTime(e.target.value))} /> s
+ </div>
+ <div className="ribbon-propertyUpDown">
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}>
+ <FontAwesomeIcon icon={'caret-up'} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}>
+ <FontAwesomeIcon icon={'caret-down'} />
+ </div>
+ </div>
+ </div>
+ <input
+ type="range"
+ step="0.1"
+ min="0.1"
+ max="20"
+ value={duration}
+ style={{ display: targetDoc.type === DocumentType.AUDIO ? 'none' : 'block' }}
+ className={'toolbar-slider'}
+ id="duration-slider"
+ onPointerDown={() => {
+ this._batch = UndoManager.StartBatch('presDuration');
+ }}
+ onPointerUp={() => {
+ if (this._batch) this._batch.end();
+ }}
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+ e.stopPropagation();
+ this.setDurationTime(e.target.value);
+ }}
+ />
+ <div className={'slider-headers'} style={{ display: targetDoc.type === DocumentType.AUDIO ? 'none' : 'grid' }}>
+ <div className="slider-text">Short</div>
+ <div className="slider-text">Medium</div>
+ <div className="slider-text">Long</div>
</div>
- <div className="ribbon-propertyUpDown">
- <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}>
- <FontAwesomeIcon icon={"caret-up"} />
+ </>
+ )}
+ </div>
+ {isPresCollection ? null : (
+ <div className="ribbon-box">
+ Effects
+ <div
+ className="presBox-dropdown"
+ onClick={action(e => {
+ e.stopPropagation();
+ this.openEffectDropdown = !this.openEffectDropdown;
+ })}
+ style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
+ {effect.toString()}
+ <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? 'grid' : 'none' }} onPointerDown={e => e.stopPropagation()}>
+ <div
+ className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.None || !this.activeItem.presEffect ? 'active' : ''}`}
+ onPointerDown={e => e.stopPropagation()}
+ onClick={() => this.updateEffect(PresEffect.None)}>
+ None
</div>
- <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}>
- <FontAwesomeIcon icon={"caret-down"} />
+ <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Fade ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>
+ Fade In
+ </div>
+ <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Flip ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>
+ Flip
+ </div>
+ <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Rotate ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>
+ Rotate
+ </div>
+ <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Bounce ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>
+ Bounce
+ </div>
+ <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Roll ? 'active' : ''}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>
+ Roll
</div>
</div>
</div>
- <input type="range" step="0.1" min="0.1" max="20" value={duration}
- style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }}
- className={"toolbar-slider"} id="duration-slider"
- onPointerDown={() => { this._batch = UndoManager.StartBatch("presDuration"); }}
- onPointerUp={() => { if (this._batch) this._batch.end(); }}
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }}
- />
- <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}>
- <div className="slider-text">Short</div>
- <div className="slider-text">Medium</div>
- <div className="slider-text">Long</div>
+ <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? 'none' : 'inline-flex' }}>
+ <div className="presBox-subheading">Effect direction</div>
+ <div className="ribbon-property">{this.effectDirection}</div>
</div>
- </>}
- </div>
- {isPresCollection ? (null) : <div className="ribbon-box">
- Effects
- <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
- {effect}
- <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} />
- <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.None || !this.activeItem.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div>
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div>
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}>
- <div className="presBox-subheading" >Effect direction</div>
- <div className="ribbon-property">
- {this.effectDirection}
+ <div className="effectDirection" style={{ display: effect === 'None' ? 'none' : 'grid', width: 40 }}>
+ <Tooltip title={<div className="dash-tooltip">{'Enter from left'}</div>}>
+ <div
+ style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }}
+ onClick={() => this.updateEffectDirection(PresEffect.Left)}>
+ <FontAwesomeIcon icon={'angle-right'} />
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">{'Enter from right'}</div>}>
+ <div
+ style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }}
+ onClick={() => this.updateEffectDirection(PresEffect.Right)}>
+ <FontAwesomeIcon icon={'angle-left'} />
+ </div>
+ </Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Enter from top'}</div>
+ </>
+ }>
+ <div
+ style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }}
+ onClick={() => this.updateEffectDirection(PresEffect.Top)}>
+ <FontAwesomeIcon icon={'angle-down'} />
+ </div>
+ </Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Enter from bottom'}</div>
+ </>
+ }>
+ <div
+ style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : 'black', cursor: 'pointer' }}
+ onClick={() => this.updateEffectDirection(PresEffect.Bottom)}>
+ <FontAwesomeIcon icon={'angle-up'} />
+ </div>
+ </Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Enter from center'}</div>
+ </>
+ }>
+ <div
+ style={{
+ gridColumn: 2,
+ gridRow: 2,
+ width: 10,
+ height: 10,
+ alignSelf: 'center',
+ justifySelf: 'center',
+ border: this.activeItem.presEffectDirection === PresEffect.Center || !this.activeItem.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : 'solid 2px black',
+ borderRadius: '100%',
+ cursor: 'pointer',
+ }}
+ onClick={() => this.updateEffectDirection(PresEffect.Center)}></div>
+ </Tooltip>
</div>
</div>
- <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
- <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: this.activeItem.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: this.activeItem.presEffectDirection === PresEffect.Center || !this.activeItem.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip>
- </div>
- </div>}
+ )}
<div className="ribbon-final-box">
<div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
Apply to all
</div>
</div>
- </div >
+ </div>
);
}
}
@@ -1338,11 +1563,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get effectDirection(): string {
let effect = '';
switch (this.activeItem.presEffectDirection) {
- case 'left': effect = "Enter from left"; break;
- case 'right': effect = "Enter from right"; break;
- case 'top': effect = "Enter from top"; break;
- case 'bottom': effect = "Enter from bottom"; break;
- default: effect = "Enter from center"; break;
+ case 'left':
+ effect = 'Enter from left';
+ break;
+ case 'right':
+ effect = 'Enter from right';
+ break;
+ case 'top':
+ effect = 'Enter from top';
+ break;
+ case 'bottom':
+ effect = 'Enter from bottom';
+ break;
+ default:
+ effect = 'Enter from center';
+ break;
}
return effect;
}
@@ -1355,7 +1590,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.updateMovement(activeItem.presMovement, true);
this.updateEffect(activeItem.presEffect, true);
this.updateEffectDirection(activeItem.presEffectDirection, true);
- array.forEach((doc) => {
+ array.forEach(doc => {
const curDoc = Cast(doc, Doc, null);
const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
if (tagDoc && targetDoc) {
@@ -1365,63 +1600,86 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
curDoc.presHideAfter = activeItem.presHideAfter;
}
});
- }
+ };
@computed get presPinViewOptionsDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 16, filter: 'invert(1)' }} />;
+ const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 16, filter: 'invert(1)' }} />;
return (
<>
- {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)}
+ {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : null}
<div className="ribbon-doubleButton">
- <Tooltip title={<><div className="dash-tooltip">{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}</div></>}><div className="ribbon-toggle" style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : "" }}
- onClick={() => {
- activeItem.presPinView = !activeItem.presPinView;
- targetDoc.presPinView = activeItem.presPinView;
- if (activeItem.presPinView) {
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
- const scroll = targetDoc._scrollTop;
- activeItem.presPinView = true;
- activeItem.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeItem.presStartTime = targetDoc._currentTimecode;
- activeItem.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeItem.presPinView = true;
- activeItem.presPinViewX = x;
- activeItem.presPinViewY = y;
- activeItem.presPinViewScale = scale;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const width = targetDoc._clipWidth;
- activeItem.presPinClipWidth = width;
- activeItem.presPinView = true;
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{activeItem.presPinView ? 'Turn off pin with view' : 'Turn on pin with view'}</div>
+ </>
+ }>
+ <div
+ className="ribbon-toggle"
+ style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : '' }}
+ onClick={() => {
+ activeItem.presPinView = !activeItem.presPinView;
+ targetDoc.presPinView = activeItem.presPinView;
+ if (activeItem.presPinView) {
+ if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
+ const scroll = targetDoc._scrollTop;
+ activeItem.presPinView = true;
+ activeItem.presPinViewScroll = scroll;
+ } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
+ activeItem.presStartTime = targetDoc._currentTimecode;
+ activeItem.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
+ } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
+ const x = targetDoc._panX;
+ const y = targetDoc._panY;
+ const scale = targetDoc._viewScale;
+ activeItem.presPinView = true;
+ activeItem.presPinViewX = x;
+ activeItem.presPinViewY = y;
+ activeItem.presPinViewScale = scale;
+ } else if (targetDoc.type === DocumentType.COMPARISON) {
+ const width = targetDoc._clipWidth;
+ activeItem.presPinClipWidth = width;
+ activeItem.presPinView = true;
+ }
}
- }
- }}>{presPinWithViewIcon}</div></Tooltip>
- {activeItem.presPinView ? <Tooltip title={<><div className="dash-tooltip">{"Update the pinned view with the view of the selected document"}</div></>}><div className="ribbon-button"
- onClick={() => {
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
- const scroll = targetDoc._scrollTop;
- activeItem.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeItem.presStartTime = targetDoc._currentTimecode;
- activeItem.presStartTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const clipWidth = targetDoc._clipWidth;
- activeItem.presPinClipWidth = clipWidth;
- } else {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeItem.presPinViewX = x;
- activeItem.presPinViewY = y;
- activeItem.presPinViewScale = scale;
- }
- }}>Update</div></Tooltip> : (null)}
+ }}>
+ {presPinWithViewIcon}
+ </div>
+ </Tooltip>
+ {activeItem.presPinView ? (
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Update the pinned view with the view of the selected document'}</div>
+ </>
+ }>
+ <div
+ className="ribbon-button"
+ onClick={() => {
+ if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
+ const scroll = targetDoc._scrollTop;
+ activeItem.presPinViewScroll = scroll;
+ } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
+ activeItem.presStartTime = targetDoc._currentTimecode;
+ activeItem.presStartTime = NumCast(targetDoc._currentTimecode) + 0.1;
+ } else if (targetDoc.type === DocumentType.COMPARISON) {
+ const clipWidth = targetDoc._clipWidth;
+ activeItem.presPinClipWidth = clipWidth;
+ } else {
+ const x = targetDoc._panX;
+ const y = targetDoc._panY;
+ const scale = targetDoc._viewScale;
+ activeItem.presPinViewX = x;
+ activeItem.presPinViewY = y;
+ activeItem.presPinViewScale = scale;
+ }
+ }}>
+ Update
+ </div>
+ </Tooltip>
+ ) : null}
</div>
</>
);
@@ -1432,38 +1690,58 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
return (
<>
- {this.panable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Pan X</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number" value={NumCast(activeItem.presPinViewX)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} />
+ {this.panable ? (
+ <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}>
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Pan X</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input
+ className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number"
+ value={NumCast(activeItem.presPinViewX)}
+ onKeyDown={e => e.stopPropagation()}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ const val = e.target.value;
+ activeItem.presPinViewX = Number(val);
+ })}
+ />
+ </div>
</div>
- </div>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Pan Y</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number" value={NumCast(activeItem.presPinViewY)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} />
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Pan Y</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input
+ className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number"
+ value={NumCast(activeItem.presPinViewY)}
+ onKeyDown={e => e.stopPropagation()}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ const val = e.target.value;
+ activeItem.presPinViewY = Number(val);
+ })}
+ />
+ </div>
</div>
- </div>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Scale</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number" value={NumCast(activeItem.presPinViewScale)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} />
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Scale</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input
+ className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number"
+ value={NumCast(activeItem.presPinViewScale)}
+ onKeyDown={e => e.stopPropagation()}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ const val = e.target.value;
+ activeItem.presPinViewScale = Number(val);
+ })}
+ />
+ </div>
</div>
</div>
- </div> : (null)}
+ ) : null}
</>
);
}
@@ -1473,18 +1751,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
return (
<>
- {this.scrollable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Scroll</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number" value={NumCast(activeItem.presPinViewScroll)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} />
+ {this.scrollable ? (
+ <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}>
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Scroll</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input
+ className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number"
+ value={NumCast(activeItem.presPinViewScroll)}
+ onKeyDown={e => e.stopPropagation()}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ const val = e.target.value;
+ activeItem.presPinViewScroll = Number(val);
+ })}
+ />
+ </div>
</div>
</div>
- </div> : (null)}
+ ) : null}
</>
);
}
@@ -1494,13 +1780,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const list = this.childDocs.map((doc, i) => {
if (i > this.itemIndex) {
return (
- <option>{i + 1}. {doc.title}</option>
+ <option>
+ {i + 1}. {StrCast(doc.title)}
+ </option>
);
}
});
- return (
- list
- );
+ return list;
}
@computed get mediaOptionsDropdown() {
@@ -1510,25 +1796,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const clipEnd: number = NumCast(activeItem.clipEnd);
const duration = Math.round(NumCast(activeItem[`${Doc.LayoutFieldKey(activeItem)}-duration`]) * 10);
const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc);
- const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + ". " + this.childDocs[mediaStopDocInd - 1].title : "";
+ const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + '. ' + this.childDocs[mediaStopDocInd - 1].title : '';
if (activeItem && targetDoc) {
return (
<div>
<div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div>
<div className="ribbon-box">
- Start {"&"} End Time
- <div className={"slider-headers"}>
- <div className="slider-block" >
+ Start {'&'} End Time
+ <div className={'slider-headers'}>
+ <div className="slider-block">
<div className="slider-text" style={{ fontWeight: 500 }}>
Start time (s)
</div>
- <div id={"startTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
- <input className="presBox-input"
+ <div id={'startTime'} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
+ <input
+ className="presBox-input"
style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
- type="number" value={NumCast(activeItem.presStartTime)}
+ type="number"
+ value={NumCast(activeItem.presStartTime)}
onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presStartTime = Number(e.target.value); })}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ activeItem.presStartTime = Number(e.target.value);
+ })}
/>
</div>
</div>
@@ -1544,24 +1834,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="slider-text" style={{ fontWeight: 500 }}>
End time (s)
</div>
- <div id={"endTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
- <input className="presBox-input"
+ <div id={'endTime'} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
+ <input
+ className="presBox-input"
onKeyDown={e => e.stopPropagation()}
style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
- type="number" value={NumCast(activeItem.presEndTime)}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presEndTime = Number(e.target.value); })}
+ type="number"
+ value={NumCast(activeItem.presEndTime)}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
+ activeItem.presEndTime = Number(e.target.value);
+ })}
/>
</div>
</div>
</div>
<div className="multiThumb-slider">
- <input type="range" step="0.1" min={clipStart} max={clipEnd} value={NumCast(activeItem.presEndTime)}
+ <input
+ type="range"
+ step="0.1"
+ min={clipStart}
+ max={clipEnd}
+ value={NumCast(activeItem.presEndTime)}
style={{ gridColumn: 1, gridRow: 1 }}
- className={`toolbar-slider ${"end"}`}
+ className={`toolbar-slider ${'end'}`}
id="toolbar-slider"
onPointerDown={() => {
- this._batch = UndoManager.StartBatch("presEndTime");
- const endBlock = document.getElementById("endTime");
+ this._batch = UndoManager.StartBatch('presEndTime');
+ const endBlock = document.getElementById('endTime');
if (endBlock) {
endBlock.style.color = Colors.LIGHT_GRAY;
endBlock.style.backgroundColor = Colors.MEDIUM_BLUE;
@@ -1569,7 +1868,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}}
onPointerUp={() => {
this._batch?.end();
- const endBlock = document.getElementById("endTime");
+ const endBlock = document.getElementById('endTime');
if (endBlock) {
endBlock.style.color = Colors.BLACK;
endBlock.style.backgroundColor = Colors.LIGHT_GRAY;
@@ -1578,14 +1877,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
activeItem.presEndTime = Number(e.target.value);
- }} />
- <input type="range" step="0.1" min={clipStart} max={clipEnd} value={NumCast(activeItem.presStartTime)}
+ }}
+ />
+ <input
+ type="range"
+ step="0.1"
+ min={clipStart}
+ max={clipEnd}
+ value={NumCast(activeItem.presStartTime)}
style={{ gridColumn: 1, gridRow: 1 }}
- className={`toolbar-slider ${"start"}`}
+ className={`toolbar-slider ${'start'}`}
id="toolbar-slider"
onPointerDown={() => {
- this._batch = UndoManager.StartBatch("presStartTime");
- const startBlock = document.getElementById("startTime");
+ this._batch = UndoManager.StartBatch('presStartTime');
+ const startBlock = document.getElementById('startTime');
if (startBlock) {
startBlock.style.color = Colors.LIGHT_GRAY;
startBlock.style.backgroundColor = Colors.MEDIUM_BLUE;
@@ -1593,7 +1898,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}}
onPointerUp={() => {
this._batch?.end();
- const startBlock = document.getElementById("startTime");
+ const startBlock = document.getElementById('startTime');
if (startBlock) {
startBlock.style.color = Colors.BLACK;
startBlock.style.backgroundColor = Colors.LIGHT_GRAY;
@@ -1602,9 +1907,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
activeItem.presStartTime = Number(e.target.value);
- }} />
+ }}
+ />
</div>
- <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
+ <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}>
<div className="slider-text">{clipStart} s</div>
<div className="slider-text"></div>
<div className="slider-text">{clipEnd} s</div>
@@ -1615,38 +1921,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="presBox-subheading">Start playing:</div>
<div className="presBox-radioButtons">
<div className="checkbox-container">
- <input className="presBox-checkbox"
- type="checkbox"
- onChange={() => activeItem.mediaStart = "manual"}
- checked={activeItem.mediaStart === "manual"}
- />
+ <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStart = 'manual')} checked={activeItem.mediaStart === 'manual'} />
<div>On click</div>
</div>
<div className="checkbox-container">
- <input className="presBox-checkbox"
- type="checkbox"
- onChange={() => activeItem.mediaStart = "auto"}
- checked={activeItem.mediaStart === "auto"}
- />
+ <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStart = 'auto')} checked={activeItem.mediaStart === 'auto'} />
<div>Automatically</div>
</div>
</div>
<div className="presBox-subheading">Stop playing:</div>
<div className="presBox-radioButtons">
<div className="checkbox-container">
- <input className="presBox-checkbox"
- type="checkbox"
- onChange={() => activeItem.mediaStop = "manual"}
- checked={activeItem.mediaStop === "manual"}
- />
+ <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStop = 'manual')} checked={activeItem.mediaStop === 'manual'} />
<div>At audio end time</div>
</div>
<div className="checkbox-container">
- <input className="presBox-checkbox"
- type="checkbox"
- onChange={() => activeItem.mediaStop = "auto"}
- checked={activeItem.mediaStop === "auto"}
- />
+ <input className="presBox-checkbox" type="checkbox" onChange={() => (activeItem.mediaStop = 'auto')} checked={activeItem.mediaStop === 'auto'} />
<div>On slide change</div>
</div>
{/* <div className="checkbox-container">
@@ -1670,7 +1960,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
</div>
- </div >
+ </div>
);
}
}
@@ -1678,84 +1968,137 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get newDocumentToolbarDropdown() {
return (
<div>
- <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div
+ className={'presBox-toolbar-dropdown'}
+ style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === 'edit' ? 'inline-flex' : 'none' }}
+ onClick={e => e.stopPropagation()}
+ onPointerUp={e => e.stopPropagation()}
+ onPointerDown={e => e.stopPropagation()}>
<div className="layout-container" style={{ height: 'max-content' }}>
- <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
- <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'blank';
+ this.createNewSlide(this.layout);
+ })}
+ />
+ <div
+ className="layout"
+ style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'title';
+ this.createNewSlide(this.layout);
+ })}>
<div className="title">Title</div>
<div className="subtitle">Subtitle</div>
</div>
- <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
- <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'header';
+ this.createNewSlide(this.layout);
+ })}>
+ <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>
+ Section header
+ </div>
</div>
- <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
- <div className="title" style={{ alignSelf: 'center' }}>Title</div>
+ <div
+ className="layout"
+ style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }}
+ onClick={action(() => {
+ this.layout = 'content';
+ this.createNewSlide(this.layout);
+ })}>
+ <div className="title" style={{ alignSelf: 'center' }}>
+ Title
+ </div>
<div className="content">Text goes here</div>
</div>
</div>
</div>
- </div >
+ </div>
);
}
@observable openLayouts: boolean = false;
@observable addFreeform: boolean = true;
- @observable layout: string = "";
- @observable title: string = "";
+ @observable layout: string = '';
+ @observable title: string = '';
@computed get newDocumentDropdown() {
return (
<div>
- <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div className="ribbon-box">
Slide Title: <br></br>
- <input className="ribbon-textInput" placeholder="..." type="text" name="fname"
- onChange={(e) => {
+ <input
+ className="ribbon-textInput"
+ placeholder="..."
+ type="text"
+ name="fname"
+ onChange={e => {
e.stopPropagation();
e.preventDefault();
- runInAction(() => this.title = e.target.value);
- }}>
- </input>
+ runInAction(() => (this.title = e.target.value));
+ }}></input>
</div>
<div className="ribbon-box">
Choose type:
<div className="ribbon-doubleButton">
- <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? "" : Colors.LIGHT_BLUE }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Text</div>
- <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : "" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Freeform</div>
+ <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? '' : Colors.LIGHT_BLUE }} onClick={action(() => (this.addFreeform = !this.addFreeform))}>
+ Text
+ </div>
+ <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : '' }} onClick={action(() => (this.addFreeform = !this.addFreeform))}>
+ Freeform
+ </div>
</div>
</div>
- <div className="ribbon-box" style={{ display: this.addFreeform ? "grid" : "none" }}>
+ <div className="ribbon-box" style={{ display: this.addFreeform ? 'grid' : 'none' }}>
Preset layouts:
<div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
- <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'blank')} />
- <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'title')}>
+ <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'blank'))} />
+ <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'title'))}>
<div className="title">Title</div>
<div className="subtitle">Subtitle</div>
</div>
- <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'header')}>
- <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
+ <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'header'))}>
+ <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>
+ Section header
+ </div>
</div>
- <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'content')}>
- <div className="title" style={{ alignSelf: 'center' }}>Title</div>
+ <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'content'))}>
+ <div className="title" style={{ alignSelf: 'center' }}>
+ Title
+ </div>
<div className="content">Text goes here</div>
</div>
- <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'twoColumns')}>
- <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
- <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
- <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
+ <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => (this.layout = 'twoColumns'))}>
+ <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>
+ Title
+ </div>
+ <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>
+ Column one text
+ </div>
+ <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>
+ Column two text
+ </div>
</div>
</div>
- <div className="open-layout" onClick={action(() => this.openLayouts = !this.openLayouts)}>
- <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} />
+ <div className="open-layout" onClick={action(() => (this.openLayouts = !this.openLayouts))}>
+ <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'caret-down'} size={'lg'} />
</div>
</div>
<div className="ribbon-final-box">
- <div className={this.title !== "" && (this.addFreeform && this.layout !== "" || !this.addFreeform) ? "ribbon-final-button-hidden" : "ribbon-final-button"} onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}>
+ <div
+ className={this.title !== '' && ((this.addFreeform && this.layout !== '') || !this.addFreeform) ? 'ribbon-final-button-hidden' : 'ribbon-final-button'}
+ onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}>
Create New Slide
</div>
</div>
</div>
- </div >
+ </div>
);
}
@@ -1763,7 +2106,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
let doc = undefined;
if (layout) doc = this.createTemplate(layout);
if (freeform && layout) doc = this.createTemplate(layout, title);
- if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
+ if (!freeform && !layout) doc = Docs.Create.TextDocument('', { _nativeWidth: 400, _width: 225, title: title });
if (doc) {
const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
const data = Cast(presCollection?.data, listSpec(Doc));
@@ -1773,10 +2116,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
TabDocView.PinDoc(doc);
this.gotoDocument(this.childDocs.length, this.activeItem);
} else {
- this.props.addDocTab(doc, "add:right");
+ this.props.addDocTab(doc, 'add:right');
}
}
- }
+ };
createTemplate = (layout: string, input?: string) => {
const activeItem: Doc = this.activeItem;
@@ -1788,43 +2131,59 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20;
}
let doc = undefined;
- const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", });
- const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" });
- const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" });
- const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" });
- const content = Docs.Create.TextDocument("Click to change text", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
- const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" });
- const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
+ const title = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 58, _fontSize: '24pt' });
+ const subtitle = Docs.Create.TextDocument('Click to change subtitle', { title: 'Slide subtitle', _width: 380, _height: 50, x: 10, y: 118, _fontSize: '16pt' });
+ const header = Docs.Create.TextDocument('Click to change header', { title: 'Slide header', _width: 380, _height: 65, x: 10, y: 80, _fontSize: '20pt' });
+ const contentTitle = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 10, _fontSize: '24pt' });
+ const content = Docs.Create.TextDocument('Click to change text', { title: 'Slide text', _width: 380, _height: 145, x: 10, y: 70, _fontSize: '14pt' });
+ const content1 = Docs.Create.TextDocument('Click to change text', { title: 'Column 1', _width: 185, _height: 140, x: 10, y: 80, _fontSize: '14pt' });
+ const content2 = Docs.Create.TextDocument('Click to change text', { title: 'Column 2', _width: 185, _height: 140, x: 205, y: 80, _fontSize: '14pt' });
switch (layout) {
case 'blank':
- doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y });
+ doc = Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x: x, y: y });
break;
case 'title':
- doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
+ doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : 'Title slide', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
break;
case 'header':
- doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
+ doc = Docs.Create.FreeformDocument([header], { title: input ? input : 'Section header', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
break;
case 'content':
- doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
+ doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : 'Title and content', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
break;
case 'twoColumns':
- doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
+ doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
break;
default:
break;
}
return doc;
- }
+ };
// Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
@computed get presentDropdown() {
return (
- <div className={`dropdown-play ${this.presentTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
- <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.updateMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
+ <div className={`dropdown-play ${this.presentTools ? 'active' : ''}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div
+ className="dropdown-play-button"
+ onClick={undoBatch(
+ action(() => {
+ this.updateMinimize();
+ this.turnOffEdit(true);
+ this.gotoDocument(this.itemIndex, this.activeItem);
+ })
+ )}>
Mini-player
</div>
- <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
+ <div
+ className="dropdown-play-button"
+ onClick={undoBatch(
+ action(() => {
+ this.layoutDoc.presStatus = 'manual';
+ this.turnOffEdit(true);
+ this.gotoDocument(this.itemIndex, this.activeItem);
+ })
+ )}>
Sidebar player
</div>
</div>
@@ -1835,7 +2194,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => {
const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
- const currentFrame = Cast(tagDoc._currentFrame, "number", null);
+ const currentFrame = Cast(tagDoc._currentFrame, 'number', null);
if (currentFrame === undefined) {
tagDoc._currentFrame = 0;
// CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
@@ -1845,19 +2204,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc);
tagDoc._currentFrame = Math.max(0, (currentFrame || 0) + 1);
tagDoc.lastFrame = Math.max(NumCast(tagDoc._currentFrame), NumCast(tagDoc.lastFrame));
- }
+ };
@action
prevKeyframe = (tagDoc: Doc, actItem: Doc): void => {
const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
- const currentFrame = Cast(tagDoc._currentFrame, "number", null);
+ const currentFrame = Cast(tagDoc._currentFrame, 'number', null);
if (currentFrame === undefined) {
tagDoc._currentFrame = 0;
// CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
}
CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
tagDoc._currentFrame = Math.max(0, (currentFrame || 0) - 1);
- }
+ };
/**
* Returns the collection type as a string for headers
@@ -1868,15 +2227,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
let type: string = '';
if (activeItem) {
switch (targetDoc.type) {
- case DocumentType.PDF: type = "PDF"; break;
- case DocumentType.RTF: type = "Text node"; break;
- case DocumentType.COL: type = "Collection"; break;
- case DocumentType.AUDIO: type = "Audio"; break;
- case DocumentType.VID: type = "Video"; break;
- case DocumentType.IMG: type = "Image"; break;
- case DocumentType.WEB: type = "Web page"; break;
- case DocumentType.MAP: type = "Map"; break;
- default: type = "Other node"; break;
+ case DocumentType.PDF:
+ type = 'PDF';
+ break;
+ case DocumentType.RTF:
+ type = 'Text node';
+ break;
+ case DocumentType.COL:
+ type = 'Collection';
+ break;
+ case DocumentType.AUDIO:
+ type = 'Audio';
+ break;
+ case DocumentType.VID:
+ type = 'Video';
+ break;
+ case DocumentType.IMG:
+ type = 'Image';
+ break;
+ case DocumentType.WEB:
+ type = 'Web page';
+ break;
+ case DocumentType.MAP:
+ type = 'Map';
+ break;
+ default:
+ type = 'Other node';
+ break;
}
}
return type;
@@ -1885,66 +2262,122 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable private openActiveColorPicker: boolean = false;
@observable private openViewedColorPicker: boolean = false;
-
-
@computed get progressivizeDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
if (activeItem && targetDoc) {
- const activeFontColor = targetDoc["pres-text-color"] ? StrCast(targetDoc["pres-text-color"]) : "Black";
- const viewedFontColor = targetDoc["pres-text-viewed-color"] ? StrCast(targetDoc["pres-text-viewed-color"]) : "Black";
+ const activeFontColor = targetDoc['pres-text-color'] ? StrCast(targetDoc['pres-text-color']) : 'Black';
+ const viewedFontColor = targetDoc['pres-text-viewed-color'] ? StrCast(targetDoc['pres-text-viewed-color']) : 'Black';
return (
<div>
- <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div
+ className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === 'edit' ? 'active' : ''}`}
+ onClick={e => e.stopPropagation()}
+ onPointerUp={e => e.stopPropagation()}
+ onPointerDown={e => e.stopPropagation()}>
<div className="ribbon-box">
{this.stringType} selected
- <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeChild}>Contents</div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editProgressivize}>Edit</div>
+ <div
+ className="ribbon-doubleButton"
+ style={{
+ borderTop: 'solid 1px darkgrey',
+ display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none',
+ }}>
+ <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeChild}>
+ Contents
+ </div>
+ <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editProgressivize}>
+ Edit
+ </div>
</div>
- <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}>
<div className="presBox-subheading">Active text color</div>
- <div className="ribbon-colorBox" style={{ backgroundColor: activeFontColor, height: 15, width: 15 }} onClick={action(() => { this.openActiveColorPicker = !this.openActiveColorPicker; })}>
- </div>
+ <div
+ className="ribbon-colorBox"
+ style={{ backgroundColor: activeFontColor, height: 15, width: 15 }}
+ onClick={action(() => {
+ this.openActiveColorPicker = !this.openActiveColorPicker;
+ })}></div>
</div>
{this.activeColorPicker}
- <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}>
<div className="presBox-subheading">Viewed font color</div>
- <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => this.openViewedColorPicker = !this.openViewedColorPicker)}>
- </div>
+ <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => (this.openViewedColorPicker = !this.openViewedColorPicker))}></div>
</div>
{this.viewedColorPicker}
- <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeZoom}>Zoom</div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editZoomProgressivize}>Edit</div>
+ <div
+ className="ribbon-doubleButton"
+ style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? 'inline-flex' : 'none' }}>
+ <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeZoom}>
+ Zoom
+ </div>
+ <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editZoomProgressivize}>
+ Edit
+ </div>
</div>
- <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeScroll}>Scroll</div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editScrollProgressivize}>Edit</div>
+ <div
+ className="ribbon-doubleButton"
+ style={{
+ borderTop: 'solid 1px darkgrey',
+ display: targetDoc._viewType === 'stacking' || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none',
+ }}>
+ <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeScroll}>
+ Scroll
+ </div>
+ <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editScrollProgressivize}>
+ Edit
+ </div>
</div>
</div>
<div className="ribbon-final-box">
Frames
<div className="ribbon-doubleButton">
<div className="ribbon-frameSelector">
- <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc, activeItem); }}>
- <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+ <div
+ key="back"
+ title="back frame"
+ className="backKeyframe"
+ onClick={e => {
+ e.stopPropagation();
+ this.prevKeyframe(targetDoc, activeItem);
+ }}>
+ <FontAwesomeIcon icon={'caret-left'} size={'lg'} />
</div>
- <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.keyFrameEditing ? "white" : "black", backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }}
- onClick={action(() => targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing)} >
+ <div
+ key="num"
+ title="toggle view all"
+ className="numKeyframe"
+ style={{ color: targetDoc.keyFrameEditing ? 'white' : 'black', backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }}
+ onClick={action(() => (targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing))}>
{NumCast(targetDoc._currentFrame)}
</div>
- <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc, activeItem); }}>
- <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+ <div
+ key="fwd"
+ title="forward frame"
+ className="fwdKeyframe"
+ onClick={e => {
+ e.stopPropagation();
+ this.nextKeyframe(targetDoc, activeItem);
+ }}>
+ <FontAwesomeIcon icon={'caret-right'} size={'lg'} />
</div>
</div>
- <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Last frame'}</div>
+ </>
+ }>
+ <div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div>
+ </Tooltip>
</div>
<div className="ribbon-frameList">
{this.frameListHeader}
{this.frameList}
</div>
- <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(" TODO: play frames")}>Play</div>
+ <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(' TODO: play frames')}>
+ Play
+ </div>
</div>
</div>
</div>
@@ -1958,37 +2391,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
const val = String(color.hex);
- targetDoc["pres-text-color"] = val;
+ targetDoc['pres-text-color'] = val;
return true;
- }
+ };
@undoBatch
@action
switchPresented = (color: ColorState) => {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
const val = String(color.hex);
- targetDoc["pres-text-viewed-color"] = val;
+ targetDoc['pres-text-viewed-color'] = val;
return true;
- }
+ };
@computed get activeColorPicker() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- return !this.openActiveColorPicker ? (null) : <SketchPicker onChange={this.switchActive}
- presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
- '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
- '#FFFFFF', '#f1efeb', 'transparent']}
- color={StrCast(targetDoc["pres-text-color"])} />;
+ return !this.openActiveColorPicker ? null : (
+ <SketchPicker
+ onChange={this.switchActive}
+ presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+ color={StrCast(targetDoc['pres-text-color'])}
+ />
+ );
}
@computed get viewedColorPicker() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- return !this.openViewedColorPicker ? (null) : <SketchPicker onChange={this.switchPresented}
- presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
- '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
- '#FFFFFF', '#f1efeb', 'transparent']}
- color={StrCast(targetDoc["pres-text-viewed-color"])} />;
+ return !this.openViewedColorPicker ? null : (
+ <SketchPicker
+ onChange={this.switchPresented}
+ presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+ color={StrCast(targetDoc['pres-text-viewed-color'])}
+ />
+ );
}
@action
@@ -1999,7 +2436,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (srcContext) this.togglePath(srcContext, true);
}
// Turn off the progressivize editors for each document
- this.childDocs.forEach((doc) => {
+ this.childDocs.forEach(doc => {
doc.editSnapZoomProgressivize = false;
doc.editZoomProgressivize = false;
const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
@@ -2008,7 +2445,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// targetDoc.editScrollProgressivize = false;
}
});
- }
+ };
//Toggle whether the user edits or not
@action
@@ -2016,14 +2453,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
if (!targetDoc.editZoomProgressivize) {
- if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true;
+ if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true;
+ targetDoc.zoomProgressivize = true;
targetDoc.editZoomProgressivize = true;
activeItem.editZoomProgressivize = true;
} else {
targetDoc.editZoomProgressivize = false;
activeItem.editZoomProgressivize = false;
}
- }
+ };
//Toggle whether the user edits or not
@action
@@ -2031,12 +2469,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
if (!targetDoc.editScrollProgressivize) {
- if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; }
+ if (!targetDoc.scrollProgressivize) {
+ targetDoc.scrollProgressivize = true;
+ activeItem.scrollProgressivize = true;
+ }
targetDoc.editScrollProgressivize = true;
} else {
targetDoc.editScrollProgressivize = false;
}
- }
+ };
//Progressivize Zoom
@action
@@ -2052,7 +2493,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
targetDoc._currentFrame = 0;
targetDoc.lastFrame = 0;
}
- }
+ };
//Progressivize Zoom
@action
@@ -2068,7 +2509,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
targetDoc._currentFrame = 0;
targetDoc.lastFrame = 0;
}
- }
+ };
//Progressivize Child Docs
@action
@@ -2077,12 +2518,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
targetDoc._currentFrame = targetDoc.lastFrame;
if (!targetDoc.editProgressivize) {
- if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; }
+ if (!activeItem.presProgressivize) {
+ activeItem.presProgressivize = true;
+ targetDoc.presProgressivize = true;
+ }
targetDoc.editProgressivize = true;
} else {
targetDoc.editProgressivize = false;
}
- }
+ };
@action
progressivizeChild = (e: React.MouseEvent) => {
@@ -2104,40 +2548,48 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
targetDoc._currentFrame = 0;
targetDoc.keyFrameEditing = true;
}
- }
+ };
@action
checkMovementLists = (doc: Doc, xlist: any, ylist: any) => {
const x: List<number> = xlist;
const y: List<number> = ylist;
const tags: JSX.Element[] = [];
- let pathPoints = ""; //List of all of the pathpoints that need to be added
+ let pathPoints = ''; //List of all of the pathpoints that need to be added
for (let i = 0; i < x.length - 1; i++) {
if (y[i] || x[i]) {
- if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33);
- else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33);
- tags.push(<div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>{i}</div>);
+ if (i === 0) pathPoints = x[i] - 11 + ',' + (y[i] + 33);
+ else pathPoints = pathPoints + ' ' + (x[i] - 11) + ',' + (y[i] + 33);
+ tags.push(
+ <div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>
+ {i}
+ </div>
+ );
}
}
- tags.push(<svg style={{ overflow: 'visible', position: 'absolute' }}><polyline
- points={pathPoints}
- style={{
- position: 'absolute',
- opacity: 1,
- stroke: "#000000",
- strokeWidth: 2,
- strokeDasharray: '10 5',
- }}
- fill="none"
- /></svg>);
+ tags.push(
+ <svg style={{ overflow: 'visible', position: 'absolute' }}>
+ <polyline
+ points={pathPoints}
+ style={{
+ position: 'absolute',
+ opacity: 1,
+ stroke: '#000000',
+ strokeWidth: 2,
+ strokeDasharray: '10 5',
+ }}
+ fill="none"
+ />
+ </svg>
+ );
return tags;
- }
+ };
@observable
toggleDisplayMovement = (doc: Doc) => {
if (doc.displayMovement) doc.displayMovement = false;
else doc.displayMovement = true;
- }
+ };
@action
checkList = (doc: Doc, list: any): number => {
@@ -2149,22 +2601,54 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
x[NumCast(doc._currentFrame)] = x[NumCast(doc._currentFrame) - 1];
return x[NumCast(doc._currentFrame)];
} else return 100;
- }
+ };
@computed get progressivizeChildDocs() {
const targetDoc: Doc = this.targetDoc;
const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
const tags: JSX.Element[] = [];
docs.forEach((doc, index) => {
- if (doc["x-indexed"] && doc["y-indexed"]) {
- tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? "block" : "none" }}>{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}</div>);
+ if (doc['x-indexed'] && doc['y-indexed']) {
+ tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? 'block' : 'none' }}>{this.checkMovementLists(doc, doc['x-indexed'], doc['y-indexed'])}</div>);
}
tags.push(
- <div className="progressivizeButton" key={index} onPointerLeave={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
- <div className="progressivizeButton-prev"><FontAwesomeIcon icon={"caret-left"} size={"lg"} onClick={e => { e.stopPropagation(); this.prevAppearFrame(doc, index); }} /></div>
- <div className="progressivizeButton-frame">{doc.appearFrame}</div>
- <div className="progressivizeButton-next"><FontAwesomeIcon icon={"caret-right"} size={"lg"} onClick={e => { e.stopPropagation(); this.nextAppearFrame(doc, index); }} /></div>
- </div>);
+ <div
+ className="progressivizeButton"
+ key={index}
+ onPointerLeave={() => {
+ if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0;
+ }}
+ onPointerOver={() => {
+ if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5;
+ }}
+ onClick={e => {
+ this.toggleDisplayMovement(doc);
+ e.stopPropagation();
+ }}
+ style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : '#c8c8c8', top: NumCast(doc.y), left: NumCast(doc.x) }}>
+ <div className="progressivizeButton-prev">
+ <FontAwesomeIcon
+ icon={'caret-left'}
+ size={'lg'}
+ onClick={e => {
+ e.stopPropagation();
+ this.prevAppearFrame(doc, index);
+ }}
+ />
+ </div>
+ <div className="progressivizeButton-frame">{NumCast(doc.appearFrame)}</div>
+ <div className="progressivizeButton-next">
+ <FontAwesomeIcon
+ icon={'caret-right'}
+ size={'lg'}
+ onClick={e => {
+ e.stopPropagation();
+ this.nextAppearFrame(doc, index);
+ }}
+ />
+ </div>
+ </div>
+ );
});
return tags;
}
@@ -2173,25 +2657,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
nextAppearFrame = (doc: Doc, i: number): void => {
// const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
// const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
- const appearFrame = Cast(doc.appearFrame, "number", null);
+ const appearFrame = Cast(doc.appearFrame, 'number', null);
if (appearFrame === undefined) {
doc.appearFrame = 0;
}
doc.appearFrame = appearFrame + 1;
- this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
- }
+ this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame));
+ };
@action
prevAppearFrame = (doc: Doc, i: number): void => {
// const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
// const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
- const appearFrame = Cast(doc.appearFrame, "number", null);
+ const appearFrame = Cast(doc.appearFrame, 'number', null);
if (appearFrame === undefined) {
doc.appearFrame = 0;
}
doc.appearFrame = Math.max(0, appearFrame - 1);
- this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
- }
+ this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame));
+ };
@action
updateOpacityList = (list: any, frame: number) => {
@@ -2216,10 +2700,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
list = x;
}
- }
+ };
@computed get moreInfoDropdown() {
- return (<div></div>);
+ return <div></div>;
}
@computed
@@ -2235,28 +2719,36 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
} else {
CurrentUserUtils.propertiesWidth = 250;
}
- }
+ };
@computed get toolbar() {
- const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left";
- const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Presentation Panel" : "Open Presentation Panel";
+ const propIcon = CurrentUserUtils.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
+ const propTitle = CurrentUserUtils.propertiesWidth > 0 ? 'Close Presentation Panel' : 'Open Presentation Panel';
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
- const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation);
+ const presKeyEvents: boolean = this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation;
const activeColor = Colors.LIGHT_BLUE;
const inactiveColor = Colors.WHITE;
- return (mode === CollectionViewType.Carousel3D) ? (null) : (
+ return mode === CollectionViewType.Carousel3D ? null : (
<div id="toolbarContainer" className={'presBox-toolbar'}>
{/* <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
<FontAwesomeIcon icon={"plus"} />
<FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
</div></Tooltip> */}
- <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}>
- <div style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
- <FontAwesomeIcon icon={"exchange-alt"} />
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'View paths'}</div>
+ </>
+ }>
+ <div
+ style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? '100%' : undefined }}
+ className={'toolbar-button'}
+ onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
+ <FontAwesomeIcon icon={'exchange-alt'} />
</div>
</Tooltip>
- {isMini ? (null) :
+ {isMini ? null : (
<>
<div className="toolbar-divider" />
{/* <Tooltip title={<><div className="dash-tooltip">{this._expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
@@ -2267,18 +2759,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</Tooltip>
<div className="toolbar-divider" /> */}
- <Tooltip title={<><div className="dash-tooltip">{presKeyEvents ? "Keys are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}</div></>}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{presKeyEvents ? 'Keys are active' : 'Keys are not active - click anywhere on the presentation trail to activate keys'}</div>
+ </>
+ }>
<div className="toolbar-button" style={{ cursor: presKeyEvents ? 'default' : 'pointer', position: 'absolute', right: 30, fontSize: 16 }}>
- <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"keyboard"} style={{ color: presKeyEvents ? activeColor : inactiveColor }} />
+ <FontAwesomeIcon className={'toolbar-thumbtack'} icon={'keyboard'} style={{ color: presKeyEvents ? activeColor : inactiveColor }} />
</div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{propTitle}</div></>}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{propTitle}</div>
+ </>
+ }>
<div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}>
- <FontAwesomeIcon className={"toolbar-thumbtack"} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? activeColor : inactiveColor }} />
+ <FontAwesomeIcon className={'toolbar-thumbtack'} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? activeColor : inactiveColor }} />
</div>
</Tooltip>
</>
- }
+ )}
</div>
);
}
@@ -2292,35 +2794,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
return (
- <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? "none" : undefined }}>
- {isMini ? (null) : <select className="presBox-viewPicker"
- style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
- onPointerDown={e => e.stopPropagation()}
- onChange={this.viewChanged}
- value={mode}>
- <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
- <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Tree}>Tree</option>
- {Doc.noviceMode ? (null) : <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}>3D Carousel</option>}
- </select>}
+ <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
+ {isMini ? null : (
+ <select className="presBox-viewPicker" style={{ display: this.layoutDoc.presStatus === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}>
+ <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>
+ List
+ </option>
+ <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Tree}>
+ Tree
+ </option>
+ {Doc.noviceMode ? null : (
+ <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}>
+ 3D Carousel
+ </option>
+ )}
+ </select>
+ )}
<div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
- <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
- <div className="presBox-button-left"
+ <span className={`presBox-button ${this.layoutDoc.presStatus === 'edit' ? 'present' : ''}`}>
+ <div
+ className="presBox-button-left"
onClick={undoBatch(() => {
if (this.childDocs.length) {
- this.layoutDoc.presStatus = "manual";
+ this.layoutDoc.presStatus = 'manual';
this.gotoDocument(this.itemIndex, this.activeItem);
}
})}>
- <FontAwesomeIcon icon={"play-circle"} />
- <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
+ <FontAwesomeIcon icon={'play-circle'} />
+ <div style={{ display: this.props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}>&nbsp; Present</div>
</div>
- {(mode === CollectionViewType.Carousel3D || isMini) ? (null) : <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`}
- onClick={(action(() => {
- if (this.childDocs.length) this.presentTools = !this.presentTools;
- }))}>
- <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
- {this.presentDropdown}
- </div>}
+ {mode === CollectionViewType.Carousel3D || isMini ? null : (
+ <div
+ className={`presBox-button-right ${this.presentTools ? 'active' : ''}`}
+ onClick={action(() => {
+ if (this.childDocs.length) this.presentTools = !this.presentTools;
+ })}>
+ <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={'angle-down'} />
+ {this.presentDropdown}
+ </div>
+ )}
</span>
{this.playButtons}
</div>
@@ -2332,7 +2844,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
getList = (list: any): List<number> => {
const x: List<number> = list;
return x;
- }
+ };
@action
updateList = (list: any): List<number> => {
@@ -2341,7 +2853,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
x.length + 1;
x[x.length - 1] = NumCast(targetDoc._scrollY);
return x;
- }
+ };
@action
newFrame = () => {
@@ -2350,7 +2862,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const type: string = StrCast(targetDoc.type);
if (!activeItem.frameList) activeItem.frameList = new List<number>();
switch (type) {
- case (DocumentType.PDF || DocumentType.RTF || DocumentType.WEB):
+ case DocumentType.PDF || DocumentType.RTF || DocumentType.WEB:
this.updateList(activeItem.frameList);
break;
case DocumentType.COL:
@@ -2358,20 +2870,46 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
default:
break;
}
- }
+ };
@computed get frameListHeader() {
- return (<div className="frameList-header">
- &nbsp; Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : (null)}
- <div className={"frameList-headerButtons"}>
- <Tooltip title={<><div className="dash-tooltip">{"Add frame by example"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); this.newFrame(); }}>
- <FontAwesomeIcon icon={"plus"} onPointerDown={e => e.stopPropagation()} />
- </div></Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Edit in collection"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); console.log('New frame'); }}>
- <FontAwesomeIcon icon={"edit"} onPointerDown={e => e.stopPropagation()} />
- </div></Tooltip>
+ return (
+ <div className="frameList-header">
+ &nbsp; Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : null}
+ <div className={'frameList-headerButtons'}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Add frame by example'}</div>
+ </>
+ }>
+ <div
+ className={'headerButton'}
+ onClick={e => {
+ e.stopPropagation();
+ this.newFrame();
+ }}>
+ <FontAwesomeIcon icon={'plus'} onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Edit in collection'}</div>
+ </>
+ }>
+ <div
+ className={'headerButton'}
+ onClick={e => {
+ e.stopPropagation();
+ console.log('New frame');
+ }}>
+ <FontAwesomeIcon icon={'edit'} onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip>
+ </div>
</div>
- </div>);
+ );
}
@computed get frameList() {
@@ -2379,66 +2917,118 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const targetDoc: Doc = this.targetDoc;
const frameList: List<number> = this.getList(activeItem.frameList);
if (frameList) {
- const frameItems = frameList.map((value) =>
- <div className="framList-item">
-
- </div>
- );
- return (
-
- <div className="frameList-container">
- {frameItems}
- </div>
- );
- } else return (null);
-
+ const frameItems = frameList.map(value => <div className="framList-item"></div>);
+ return <div className="frameList-container">{frameItems}</div>;
+ } else return null;
}
@computed get playButtonFrames() {
const targetDoc: Doc = this.targetDoc;
return (
<>
- {this.targetDoc ? <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
- <div>{targetDoc._currentFrame}</div>
- <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
- <div>{targetDoc.lastFrame}</div>
- </div> : null}
+ {this.targetDoc ? (
+ <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? 'inline-flex' : 'none' }}>
+ <div>{NumCast(targetDoc._currentFrame)}</div>
+ <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
+ <div>{NumCast(targetDoc.lastFrame)}</div>
+ </div>
+ ) : null}
</>
);
}
@computed get playButtons() {
- const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
- const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
+ const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
+ const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
// Case 1: There are still other frames and should go through all frames before going to next slide
- return (<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
- <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
- <div className="presPanel-divider"></div>
- <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div>
- <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? "pause" : "play"} /></div></Tooltip>
- <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
- <div className="presPanel-divider"></div>
- <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip>
- <div
- className="presPanel-button-text"
- onClick={() => this.gotoDocument(0, this.activeItem)}
- style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
- Slide {this.itemIndex + 1} / {this.childDocs.length}
- {this.playButtonFrames}
+ return (
+ <div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== 'edit' ? 'inline-flex' : 'none' }}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Loop'}</div>
+ </>
+ }>
+ <div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop)}>
+ <FontAwesomeIcon icon={'redo-alt'} />
+ </div>
+ </Tooltip>
+ <div className="presPanel-divider"></div>
+ <div
+ className="presPanel-button"
+ style={{ opacity: presStart ? 0.4 : 1 }}
+ onClick={() => {
+ this.back();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ }}>
+ <FontAwesomeIcon icon={'arrow-left'} />
+ </div>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>
+ </>
+ }>
+ <div className="presPanel-button" onClick={this.startOrPause}>
+ <FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} />
+ </div>
+ </Tooltip>
+ <div
+ className="presPanel-button"
+ style={{ opacity: presEnd ? 0.4 : 1 }}
+ onClick={() => {
+ this.next();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ }}>
+ <FontAwesomeIcon icon={'arrow-right'} />
+ </div>
+ <div className="presPanel-divider"></div>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Click to return to 1st slide'}</div>
+ </>
+ }>
+ <div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}>
+ <b>1</b>
+ </div>
+ </Tooltip>
+ <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}>
+ Slide {this.itemIndex + 1} / {this.childDocs.length}
+ {this.playButtonFrames}
+ </div>
+ <div className="presPanel-divider"></div>
+ {this.props.PanelWidth() > 250 ? (
+ <div
+ className="presPanel-button-text"
+ onClick={undoBatch(
+ action(() => {
+ this.layoutDoc.presStatus = 'edit';
+ clearTimeout(this._presTimer);
+ })
+ )}>
+ EXIT
+ </div>
+ ) : (
+ <div className="presPanel-button" onClick={undoBatch(action(() => (this.layoutDoc.presStatus = 'edit')))}>
+ <FontAwesomeIcon icon={'times'} />
+ </div>
+ )}
</div>
- <div className="presPanel-divider"></div>
- {this.props.PanelWidth() > 250 ? <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT</div>
- : <div className="presPanel-button" onClick={undoBatch(action(() => this.layoutDoc.presStatus = "edit"))}>
- <FontAwesomeIcon icon={"times"} />
- </div>}
- </div>);
+ );
}
@action
startOrPause = () => {
if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
else this.pauseAutoPres();
- }
+ };
@action
prevClicked = (e: PointerEvent) => {
@@ -2447,7 +3037,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
clearTimeout(this._presTimer);
this.layoutDoc.presStatus = PresStatus.Manual;
}
- }
+ };
@action
nextClicked = (e: PointerEvent) => {
@@ -2456,35 +3046,35 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
clearTimeout(this._presTimer);
this.layoutDoc.presStatus = PresStatus.Manual;
}
- }
+ };
@undoBatch
@action
exitClicked = (e: PointerEvent) => {
this.updateMinimize();
this.layoutDoc.presStatus = PresStatus.Edit;
clearTimeout(this._presTimer);
- }
+ };
@action
startMarqueeCreateSlide = () => {
PresBox.startMarquee = true;
- }
+ };
AddToMap = (treeViewDoc: Doc, index: number[]): Doc[] => {
var indexNum = 0;
for (let i = 0; i < index.length; i++) {
- indexNum += (index[i] * (10 ** (-i)));
+ indexNum += index[i] * 10 ** -i;
}
if (this._treeViewMap.get(treeViewDoc) !== indexNum) {
this._treeViewMap.set(treeViewDoc, indexNum);
const sorted = this.sort(this._treeViewMap);
const curList = DocListCast(this.dataDoc[this.presFieldKey]);
- if (sorted.length !== curList.length || sorted.some((doc,ind) => doc !== curList[ind])) {
+ if (sorted.length !== curList.length || sorted.some((doc, ind) => doc !== curList[ind])) {
this.dataDoc[this.presFieldKey] = new List<Doc>(sorted); // this is a flat array of Docs
}
}
return this.childDocs;
- }
+ };
RemFromMap = (treeViewDoc: Doc, index: number[]): Doc[] => {
if (!this._unmounting && this.isTree) {
@@ -2492,10 +3082,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.dataDoc[this.presFieldKey] = new List<Doc>(this.sort(this._treeViewMap));
}
return this.childDocs;
- }
+ };
// TODO: [AL] implement sort function for an array of numbers (e.g. arr[1,2,4] v arr[1,2,1])
- sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0).map(kv => kv[0]);
+ sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]);
render() {
// calling this method for keyEvents
@@ -2503,42 +3093,73 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// needed to ensure that the childDocs are loaded for looking up fields
this.childDocs.slice();
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
- const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation);
- const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
- const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
- return DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.rootDoc) ?
+ const presKeyEvents: boolean = this.isPres && this._presKeyEventsActive && this.rootDoc === CurrentUserUtils.ActivePresentation;
+ const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
+ const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ return DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.rootDoc) ? (
<div className="miniPres" onClick={e => e.stopPropagation()}>
- <div className="presPanelOverlay" style={{ display: "inline-flex", height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
- <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.layoutDoc.presLoop = !this.layoutDoc.presLoop, false, false)}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
+ <div className="presPanelOverlay" style={{ display: 'inline-flex', height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Loop'}</div>
+ </>
+ }>
+ <div
+ className="presPanel-button"
+ style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }}
+ onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}>
+ <FontAwesomeIcon icon={'redo-alt'} />
+ </div>
+ </Tooltip>
<div className="presPanel-divider"></div>
- <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.prevClicked, false, false)}><FontAwesomeIcon icon={"arrow-left"} /></div>
- <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button"
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.startOrPause, false, false)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div></Tooltip>
- <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.nextClicked, false, false)}><FontAwesomeIcon icon={"arrow-right"} /></div>
+ <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.prevClicked, false, false)}>
+ <FontAwesomeIcon icon={'arrow-left'} />
+ </div>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>
+ </>
+ }>
+ <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.startOrPause, false, false)}>
+ <FontAwesomeIcon icon={this.layoutDoc.presStatus === 'auto' ? 'pause' : 'play'} />
+ </div>
+ </Tooltip>
+ <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.nextClicked, false, false)}>
+ <FontAwesomeIcon icon={'arrow-right'} />
+ </div>
<div className="presPanel-divider"></div>
- <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }}
- onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.gotoDocument(0, this.activeItem), false, false)}><b>1</b></div></Tooltip>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{'Click to return to 1st slide'}</div>
+ </>
+ }>
+ <div className="presPanel-button" style={{ border: 'solid 1px white' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.gotoDocument(0, this.activeItem), false, false)}>
+ <b>1</b>
+ </div>
+ </Tooltip>
<div className="presPanel-button-text">
Slide {this.itemIndex + 1} / {this.childDocs.length}
{this.playButtonFrames}
</div>
<div className="presPanel-divider" />
- <div className="presPanel-button-text" onPointerDown={e =>
- setupMoveUpEvents(this, e, returnFalse, returnFalse, this.exitClicked, false, false)}>EXIT</div>
+ <div className="presPanel-button-text" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.exitClicked, false, false)}>
+ EXIT
+ </div>
</div>
- </div >
- :
- <div className="presBox-cont" style={{ minWidth: DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }} >
+ </div>
+ ) : (
+ <div className="presBox-cont" style={{ minWidth: DocListCast(CurrentUserUtils.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }}>
{this.topPanel}
{this.toolbar}
{this.newDocumentToolbarDropdown}
<div className="presBox-listCont">
<div className="Slide" style={{ height: `calc(100% - 30px)` }}>
- {mode !== CollectionViewType.Invalid ?
- <CollectionView {...this.props}
+ {mode !== CollectionViewType.Invalid ? (
+ <CollectionView
+ {...this.props}
ContainingCollectionDoc={this.props.Document}
PanelWidth={this.props.PanelWidth}
PanelHeight={this.panelHeight}
@@ -2556,25 +3177,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
AddToMap={this.AddToMap}
RemFromMap={this.RemFromMap}
hierarchyIndex={[]}
- /> : (null)
- }
+ />
+ ) : null}
</div>
- { // if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack
- <Tooltip title={<div className="dash-tooltip">{"Click on document to pin to presentaiton or make a marquee selection to pin your desired view"}</div>}>
+ {
+ // if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack
+ <Tooltip title={<div className="dash-tooltip">{'Click on document to pin to presentaiton or make a marquee selection to pin your desired view'}</div>}>
<button className="add-slide-button" onPointerDown={this.startMarqueeCreateSlide}>
+ NEW SLIDE
</button>
</Tooltip>
}
</div>
- </div>;
+ </div>
+ );
}
}
-ScriptingGlobals.add(function navigateToDoc(bestTarget:Doc, activeItem:Doc) {
+ScriptingGlobals.add(function navigateToDoc(bestTarget: Doc, activeItem: Doc) {
const srcContext = Cast(bestTarget.context, Doc, null) ?? Cast(Cast(bestTarget.annotationOn, Doc, null)?.context, Doc, null);
- const openInTab = (doc: Doc, finished?: () => void) => {CollectionDockingView.AddSplit(doc, "right"); finished?.(); };
- DocumentManager.Instance.jumpToDocument(bestTarget, true, openInTab, srcContext ? [srcContext]:[],
- undefined, undefined, undefined, () => PresBox.navigateToDoc(bestTarget, activeItem, true), undefined, true, NumCast(activeItem.presZoom));
-}); \ No newline at end of file
+ const openInTab = (doc: Doc, finished?: () => void) => {
+ CollectionDockingView.AddSplit(doc, 'right');
+ finished?.();
+ };
+ DocumentManager.Instance.jumpToDocument(bestTarget, true, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, () => PresBox.navigateToDoc(bestTarget, activeItem, true), undefined, true, NumCast(activeItem.presZoom));
+});