aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
authormehekj <mehek.jethani@gmail.com>2023-01-28 22:39:23 -0500
committermehekj <mehek.jethani@gmail.com>2023-01-28 22:39:23 -0500
commit9f139c7f0f571bdfea8ce99fc0a507724eb8fd74 (patch)
tree4de6642112f9c6c2df1a85cf8fa9ed700bb94cbd /src/client/views/nodes
parent9d2af1180f0dd5af5ab86b922cd8b0cdfcf4ea09 (diff)
parent95b8a5a2b470d3118b6eeac484a45b23df2830b4 (diff)
Merge branch 'master' into schema-mehek
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/AudioBox.tsx7
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx31
-rw-r--r--src/client/views/nodes/FilterBox.tsx2
-rw-r--r--src/client/views/nodes/FunctionPlotBox.tsx7
-rw-r--r--src/client/views/nodes/ImageBox.tsx8
-rw-r--r--src/client/views/nodes/LabelBox.tsx4
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx73
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx5
-rw-r--r--src/client/views/nodes/PDFBox.tsx9
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx4
-rw-r--r--src/client/views/nodes/VideoBox.tsx11
-rw-r--r--src/client/views/nodes/WebBox.tsx6
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx6
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx50
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts2
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts2
-rw-r--r--src/client/views/nodes/trails/PresBox.scss26
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx543
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx22
21 files changed, 457 insertions, 369 deletions
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index a5b5ea664..aa9d648bf 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -137,7 +137,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return { la1, la2, linkTime };
}
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
return (
CollectionStackedTimeline.createAnchor(
this.rootDoc,
@@ -145,7 +145,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this.annotationKey,
'_timecodeToShow' /* audioStart */,
'_timecodeToHide' /* audioEnd */,
- this._ele?.currentTime || Cast(this.props.Document._currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined)
+ this._ele?.currentTime || Cast(this.props.Document._currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined),
+ undefined,
+ undefined,
+ addAsAnnotation
) || this.rootDoc
);
};
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 6f3152981..a39e0f65f 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -135,7 +135,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
DocumentLinksButton.AnnotationId = undefined;
} else if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View.props.Document) {
const sourceDoc = DocumentLinksButton.StartLink;
- const targetDoc = this.props.View.ComponentView?.getAnchor?.() || this.props.View.Document;
+ const targetDoc = this.props.View.ComponentView?.getAnchor?.(true) || this.props.View.Document;
const linkDoc = DocUtils.MakeLink({ doc: sourceDoc }, { doc: targetDoc }, 'links'); //why is long drag here when this is used for completing links by clicking?
LinkManager.currentLink = linkDoc;
@@ -183,8 +183,8 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
DocumentLinksButton.AnnotationUri = undefined;
//!this.props.StartLink
} else if (startLink !== endLink) {
- endLink = endLinkView?.docView?._componentView?.getAnchor?.() || endLink;
- startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.() || startLink;
+ endLink = endLinkView?.docView?._componentView?.getAnchor?.(true) || endLink;
+ startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.(true) || startLink;
const linkDoc = DocUtils.MakeLink({ doc: startLink }, { doc: endLink }, DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined, undefined, undefined, true);
LinkManager.currentLink = linkDoc;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 95cf08289..b94db2c6b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -121,7 +121,7 @@ export type DocFocusFunc = (doc: Doc, options: DocFocusOptions) => void;
export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => any;
export interface DocComponentView {
updateIcon?: () => void; // updates the icon representation of the document
- getAnchor?: () => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
+ getAnchor?: (addAsAnnotation: boolean) => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
scrollFocus?: (doc: Doc, options: DocFocusOptions) => Opt<number>; // returns the duration of the focus
brushView?: (view: { width: number; height: number; panX: number; panY: number }) => void;
setViewSpec?: (anchor: Doc, preview: boolean) => void; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
@@ -696,6 +696,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
});
+ @action
onPointerDown = (e: React.PointerEvent): void => {
if (this.rootDoc.type === DocumentType.INK && Doc.ActiveTool === InkTool.Eraser) return;
// continue if the event hasn't been canceled AND we are using a mouse or this has an onClick or onDragStart function (meaning it is a button document)
@@ -736,6 +737,9 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
document.removeEventListener('pointerup', this.onPointerUp);
document.addEventListener('pointerup', this.onPointerUp);
+ } else {
+ this._cursorTimer && clearTimeout(this._cursorTimer);
+ this._cursorPress = false;
}
};
@@ -783,9 +787,9 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch
@action
- toggleFollowLink = (location: Opt<string>, zoom?: boolean, setPushpin?: boolean): void => {
+ toggleFollowLink = (location: Opt<string>, zoom?: boolean, setTargetToggle?: boolean): void => {
this.Document.ignoreClick = false;
- if (setPushpin) {
+ if (setTargetToggle) {
this.Document.followLinkToggle = !this.Document.followLinkToggle;
this.Document._isLinkButton = this.Document.followLinkToggle || this.Document._isLinkButton;
} else {
@@ -854,7 +858,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
de.complete.annoDragData.dropDocument = de.complete.annoDragData.dropDocCreator(undefined);
}
if (de.complete.annoDragData || this.rootDoc !== linkdrag.linkSourceDoc.context) {
- const dropDoc = de.complete.annoDragData?.dropDocument ?? this._componentView?.getAnchor?.() ?? this.props.Document;
+ const dropDoc = de.complete.annoDragData?.dropDocument ?? this._componentView?.getAnchor?.(true) ?? this.props.Document;
de.complete.linkDocument = DocUtils.MakeLink({ doc: linkdrag.linkSourceDoc }, { doc: dropDoc }, undefined, undefined, undefined, undefined, [de.x, de.y - 50]);
}
}
@@ -979,7 +983,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
onClicks.push({ description: this.Document.isLinkButton ? 'Remove Follow Behavior' : 'Follow Link in Place', event: () => this.toggleFollowLink('inPlace', false, false), icon: 'link' });
!this.Document.isLinkButton && onClicks.push({ description: 'Follow Link on Right', event: () => this.toggleFollowLink('add:right', false, false), icon: 'link' });
onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(undefined, false, false), icon: 'link' });
- onClicks.push({ description: (this.Document.followLinkToggle ? 'Remove' : 'Make') + ' Pushpin', event: () => this.toggleFollowLink(undefined, false, true), icon: 'map-pin' });
+ onClicks.push({ description: (this.Document.followLinkToggle ? 'Remove' : 'Make') + ' Target Visibility Toggle', event: () => this.toggleFollowLink(undefined, false, true), icon: 'map-pin' });
onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
!existingOnClick && cm.addItem({ description: 'OnClick...', addDivider: true, noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
} else if (DocListCast(this.Document.links).length) {
@@ -1091,7 +1095,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin);
onClickFunc = () => this.onClickHandler;
setHeight = (height: number) => (this.layoutDoc._height = height);
- setContentView = action((view: { getAnchor?: () => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view));
+ setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view));
isContentActive = (outsideReaction?: boolean) => {
return this.props.isContentActive() === false
? false
@@ -1264,7 +1268,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
playAnnotation = () => {
const self = this;
const audioAnnos = Cast(this.dataDoc[this.LayoutFieldKey + '-audioAnnotations'], listSpec(AudioField), null);
- const anno = audioAnnos.lastElement();
+ const anno = audioAnnos?.lastElement();
if (anno instanceof AudioField && this.audioAnnoState === 'stopped') {
new Howl({
src: [anno.url.href],
@@ -1690,7 +1694,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.props.PanelHeight();
}
@computed get Xshift() {
- return this.effectiveNativeWidth ? (this.props.PanelWidth() - this.effectiveNativeWidth * this.nativeScaling) / 2 : 0;
+ return this.effectiveNativeWidth ? Math.max(0, (this.props.PanelWidth() - this.effectiveNativeWidth * this.nativeScaling) / 2) : 0;
}
@computed get Yshift() {
return this.effectiveNativeWidth && this.effectiveNativeHeight && Math.abs(this.Xshift) < 0.001 && (!this.layoutDoc.nativeHeightUnfrozen || (!this.fitWidth && this.effectiveNativeHeight * this.nativeScaling <= this.props.PanelHeight()))
@@ -1707,10 +1711,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.NativeDimScaling, this.props.PanelWidth(), this.props.PanelHeight());
focus = (doc: Doc, options: DocFocusOptions) => this.docView?.focus(doc, options);
getBounds = () => {
- if (!this.docView || !this.docView.ContentDiv || this.props.Document.presBox || this.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
+ if (!this.docView || !this.docView.ContentDiv || this.props.Document.type === DocumentType.PRES || this.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
return undefined;
}
- const xf = this.docView?.props.ScreenToLocalTransform().scale(this.nativeScaling).inverse();
+ const xf = this.docView?.props
+ .ScreenToLocalTransform()
+ .scale(this.trueNativeWidth() ? this.nativeScaling : 1)
+ .inverse();
const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)];
if (this.docView.props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
const docuBox = this.docView.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
@@ -1781,11 +1788,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
PanelHeight = () => this.panelHeight;
NativeDimScaling = () => this.nativeScaling;
selfView = () => this;
+ trueNativeWidth = () => returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, false));
screenToLocalTransform = () =>
this.props
.ScreenToLocalTransform()
.translate(-this.centeringX, -this.centeringY)
- .scale(1 / this.nativeScaling);
+ .scale(this.trueNativeWidth() ? 1 / this.nativeScaling : 1);
componentDidMount() {
this._disposers.reactionScript = reaction(
() => ScriptCast(this.rootDoc.reactionScript)?.script?.run({ this: this.props.Document, self: Cast(this.rootDoc, Doc, null) || this.props.Document }).result,
@@ -1831,6 +1839,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
const xshift = Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined;
const yshift = Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined;
const isButton = this.props.Document.type === DocumentType.FONTICON || this.props.Document._viewType === CollectionViewType.Linear;
+
return (
<div
className="contentFittingDocumentView"
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index 04d252abe..78ba499ec 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -33,7 +33,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps>() {
constructor(props: Readonly<FieldViewProps>) {
super(props);
const targetDoc = FilterBox.targetDoc;
- if (targetDoc && !targetDoc.currentFilter) targetDoc.currentFilter = FilterBox.createFilterDoc();
+ if (targetDoc && !targetDoc.currentFilter) runInAction(() => (targetDoc.currentFilter = FilterBox.createFilterDoc()));
}
/// creates a new, empty filter doc
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index 24562ccbd..5c0005dae 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -12,7 +12,7 @@ import { TraceMobx } from '../../../fields/util';
import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
-import { ViewBoxBaseComponent } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { DocFocusOptions } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
@@ -22,7 +22,7 @@ type EquationDocument = makeInterface<[typeof EquationSchema, typeof documentSch
const EquationDocument = makeInterface(EquationSchema, documentSchema);
@observer
-export class FunctionPlotBox extends ViewBoxBaseComponent<FieldViewProps>() {
+export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(FunctionPlotBox, fieldKey);
}
@@ -41,10 +41,11 @@ export class FunctionPlotBox extends ViewBoxBaseComponent<FieldViewProps>() {
() => this.createGraph()
);
}
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
const anchor = Docs.Create.TextanchorDocument({ annotationOn: this.rootDoc });
anchor.xRange = new List<number>(Array.from(this._plot.options.xAxis.domain));
anchor.yRange = new List<number>(Array.from(this._plot.options.yAxis.domain));
+ if (addAsAnnotation) this.addDocument(anchor);
return anchor;
};
@action
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index ac953d13b..e2ecca0b6 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -52,7 +52,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
private _dropDisposer?: DragManager.DragDropDisposer;
private _disposers: { [name: string]: IReactionDisposer } = {};
- private _getAnchor: (savedAnnotations?: ObservableMap<number, HTMLDivElement[]>) => Opt<Doc> = () => undefined;
+ private _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
@observable _curSuffix = '';
@observable _uploadIcon = uploadIcons.idle;
@@ -86,13 +86,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
: undefined;
}; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
const anchor =
- this._getAnchor?.(this._savedAnnotations) ?? // use marquee anchor, otherwise, save zoom/pan as anchor
+ this._getAnchor?.(this._savedAnnotations, false) ?? // use marquee anchor, otherwise, save zoom/pan as anchor
Docs.Create.ImageanchorDocument({ presTransition: 1000, unrendered: true, annotationOn: this.rootDoc });
if (anchor) {
PresBox.pinDocView(anchor, { pinData: { pannable: true, dataview: true, dataannos: true } }, this.rootDoc);
- this.addDocument(anchor);
+ addAsAnnotation && this.addDocument(anchor);
return anchor;
}
return this.rootDoc;
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 10897b48f..a2143f629 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -36,9 +36,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
this._timeout && clearTimeout(this._timeout);
}
- getAnchor = () => {
- return this.rootDoc;
- };
+ getAnchor = (addAsAnnotation: boolean) => this.rootDoc;
getTitle() {
return this.rootDoc['title-custom'] ? StrCast(this.rootDoc.title) : this.props.label ? this.props.label : typeof this.rootDoc[this.fieldKey] === 'string' ? StrCast(this.rootDoc[this.fieldKey]) : StrCast(this.rootDoc.title);
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index b2fdd93fc..1eab06381 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -4,7 +4,7 @@ import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import wiki from 'wikijs';
import { Doc, DocCastAsync, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
import { DocServer } from '../../DocServer';
import { Docs, DocUtils } from '../../documents/Documents';
@@ -17,7 +17,8 @@ import { Transform } from '../../util/Transform';
import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
import './LinkDocPreview.scss';
import React = require('react');
-import { SelectionManager } from '../../util/SelectionManager';
+import { SearchUtil } from '../../util/SearchUtil';
+import { SearchBox } from '../search/SearchBox';
interface LinkDocPreviewProps {
linkDoc?: Doc;
@@ -37,6 +38,8 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info);
}
+ static _instance: Opt<LinkDocPreview>;
+
_infoRef = React.createRef<HTMLDivElement>();
_linkDocRef = React.createRef<HTMLDivElement>();
@observable public static LinkInfo: Opt<LinkDocPreviewProps>;
@@ -47,6 +50,11 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
@observable _toolTipText = '';
@observable _hrefInd = 0;
+ constructor(props: any) {
+ super(props);
+ LinkDocPreview._instance = this;
+ }
+
@action init() {
var linkTarget = this.props.linkDoc;
this._linkSrc = this.props.linkSrc;
@@ -63,6 +71,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
this._markerTargetDoc = this._targetDoc = linkTarget;
}
this._toolTipText = '';
+ this.updateHref();
}
componentDidUpdate(props: any) {
if (props.linkSrc !== this.props.linkSrc || props.linkDoc !== this.props.linkDoc || props.hrefs !== this.props.hrefs) this.init();
@@ -72,6 +81,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
document.addEventListener('pointerdown', this.onPointerDown, true);
}
+ @action
componentWillUnmount() {
LinkDocPreview.SetLinkInfo(undefined);
document.removeEventListener('pointerdown', this.onPointerDown, true);
@@ -81,7 +91,8 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
!this._linkDocRef.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() {
+ @action
+ updateHref() {
if (this.props.hrefs?.length) {
const href = this.props.hrefs[this._hrefInd];
if (href.indexOf(Doc.localServerPath()) !== 0) {
@@ -91,33 +102,33 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
.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)));
+ 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._markerTargetDoc = this._targetDoc = linkTarget;
- } else {
- this._linkSrc = anchor;
- const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
- this._markerTargetDoc = linkTarget;
- this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
- }
- this._toolTipText = '';
- if (LinkDocPreview.LinkInfo?.noPreview) this.followLink();
+ const anchorDocId = href.replace(Doc.localServerPath(), '').split('?')[0];
+ const anchorDoc = anchorDocId ? PromiseValue(DocCast(DocServer.GetCachedRefField(anchorDocId) ?? DocServer.GetRefField(anchorDocId))) : undefined;
+ 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._markerTargetDoc = this._targetDoc = linkTarget;
+ } else {
+ this._linkSrc = anchor;
+ const linkTarget = LinkManager.getOppositeAnchor(this._linkDoc, this._linkSrc);
+ this._markerTargetDoc = linkTarget;
+ this._targetDoc = /*linkTarget?.type === DocumentType.MARKER &&*/ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
}
- })
- );
+ this._toolTipText = 'link to ' + this._targetDoc?.title;
+ if (LinkDocPreview.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink();
+ }
+ })
+ );
}
return href;
}
@@ -159,11 +170,14 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
};
followLink = () => {
+ LinkDocPreview.Clear();
if (this._linkDoc && this._linkSrc) {
- LinkDocPreview.Clear();
LinkFollower.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 }), OpenWhere.addRight);
+ const webDoc =
+ Array.from(SearchBox.staticSearchCollection(Doc.MyFilesystem, this.props.hrefs[0]).keys()).lastElement() ??
+ Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true });
+ this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
}
};
@@ -209,7 +223,6 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
}
@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 : (
<div className="linkDocPreview-inner">
{!this.props.showHeader ? null : this.previewHeader}
@@ -286,7 +299,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
className="linkDocPreview"
ref={this._linkDocRef}
onPointerDown={this.followLinkPointerDown}
- style={{ left: this.props.location[0], top: this.props.location[1], width: this.width() + borders, height: this.height() + borders + (this.props.showHeader ? 37 : 0) }}>
+ style={{ display: !this._toolTipText ? 'none' : undefined, 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>
);
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index c8d5b0154..95cb49037 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -522,10 +522,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
- getAnchor = () => {
- const anchor = AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ?? this.rootDoc;
- return anchor;
- };
+ getAnchor = (addAsAnnotation: boolean) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.rootDoc;
/**
* render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index e22ee5021..b88ac113e 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -212,7 +212,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
PresBox.restoreTargetDocView(this.props.DocumentView?.(), {}, doc, options.zoomTime ?? 500, { pannable: doc.presPinData ? true : false });
return this._pdfViewer?.scrollFocus(doc, NumCast(doc.presPinViewScroll, NumCast(doc.y)), options) ?? (didToggle ? 1 : undefined);
};
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
let ele: Opt<HTMLDivElement> = undefined;
if (this._pdfViewer?.selectionContent()) {
ele = document.createElement('div');
@@ -226,10 +226,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
PresBox.pinDocView(anchor, { pinData: { scrollable: true, pannable: true } }, this.rootDoc);
return anchor;
};
- const anchor = this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations()) ?? docAnchor();
+ const annoAnchor = this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations(), true);
+ const anchor = annoAnchor ?? docAnchor();
anchor.text = ele?.textContent ?? '';
anchor.textHtml = ele?.innerHTML;
- this.addDocument(anchor);
+ if (addAsAnnotation || annoAnchor) {
+ this.addDocument(anchor);
+ }
return anchor;
};
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 76a24d831..f94996c66 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -128,9 +128,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
this.setupDictation();
}
}
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
const startTime = Cast(this.layoutDoc._currentTimecode, 'number', null) || (this._videoRec ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined);
- return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, '_timecodeToShow', '_timecodeToHide', startTime, startTime === undefined ? undefined : startTime + 3) || this.rootDoc;
+ return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, '_timecodeToShow', '_timecodeToHide', startTime, startTime === undefined ? undefined : startTime + 3, undefined, addAsAnnotation) || this.rootDoc;
};
videoLoad = () => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index a8f78edd5..1dfa55c64 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -385,15 +385,18 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
Doc.SetNativeWidth(Doc.GetProto(imageSummary), Doc.NativeWidth(this.layoutDoc));
Doc.SetNativeHeight(Doc.GetProto(imageSummary), Doc.NativeHeight(this.layoutDoc));
this.props.addDocument?.(imageSummary);
- const link = DocUtils.MakeLink({ doc: imageSummary }, { doc: this.getAnchor() }, 'video snapshot');
+ const link = DocUtils.MakeLink({ doc: imageSummary }, { doc: this.getAnchor(true) }, 'video snapshot');
link && (Doc.GetProto(link.anchor2 as Doc).timecodeToHide = NumCast((link.anchor2 as Doc).timecodeToShow) + 3);
setTimeout(() => downX !== undefined && downY !== undefined && DocumentManager.Instance.getFirstDocumentView(imageSummary)?.startDragging(downX, downY, 'move', true));
};
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
const timecode = Cast(this.layoutDoc._currentTimecode, 'number', null);
- const marquee = AnchorMenu.Instance.GetAnchor?.();
- return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, '_timecodeToShow' /* videoStart */, '_timecodeToHide' /* videoEnd */, timecode ? timecode : undefined, undefined, marquee) || this.rootDoc;
+ const marquee = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation);
+ return (
+ CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, '_timecodeToShow' /* videoStart */, '_timecodeToHide' /* videoEnd */, timecode ? timecode : undefined, undefined, marquee, addAsAnnotation) ||
+ this.rootDoc
+ );
};
// sets video info on load
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 8be4884ce..acf4fe4b0 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -307,7 +307,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return undefined;
};
- getAnchor = () => {
+ getAnchor = (addAsAnnotation: boolean) => {
let ele: Opt<HTMLDivElement> = undefined;
try {
const contents = this._iframe?.contentWindow?.getSelection()?.getRangeAt(0).cloneContents();
@@ -317,7 +317,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
} catch (e) {}
const anchor =
- this._getAnchor(this._savedAnnotations) ??
+ this._getAnchor(this._savedAnnotations, false) ??
Docs.Create.WebanchorDocument(this._url, {
title: StrCast(this.rootDoc.title + ' ' + this.layoutDoc._scrollTop),
y: NumCast(this.layoutDoc._scrollTop),
@@ -325,7 +325,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
anchor.text = ele?.textContent ?? '';
anchor.textHtml = ele?.innerHTML;
- this.addDocumentWrapper(anchor);
+ addAsAnnotation && this.addDocumentWrapper(anchor);
return anchor;
};
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index e477d7ae2..1de29f806 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -161,7 +161,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
</div>
);
return (
- <div className={`menuButton ${this.type} ${numBtnType}`} onClick={action(() => (this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen))}>
+ <div className={`menuButton ${this.type} ${numBtnType}`} onPointerDown={e => e.stopPropagation()} onClick={action(() => (this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen))}>
{checkResult}
{label}
{this.rootDoc.dropDownOpen ? dropdown : null}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 63347015b..39005a18b 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -287,12 +287,12 @@ export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
document.addEventListener('pointerdown', hideMenu, true);
};
render() {
- return this.getElement([
+ return this.getElement(
<Tooltip key="trash" title={<div className="dash-tooltip">{`Show Pivot Viewer for '${this._fieldKey}'`}</div>}>
<button className="antimodeMenu-button" onPointerDown={this.showFields}>
<FontAwesomeIcon icon="eye" size="lg" />
</button>
- </Tooltip>,
- ]);
+ </Tooltip>
+ );
}
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b895043de..8407eee96 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -231,7 +231,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
}
- getAnchor = () => this.makeLinkAnchor(undefined, 'add:right', undefined, 'Anchored Selection', false);
+ getAnchor = (addAsAnnotation: boolean) => this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', false, addAsAnnotation);
@action
setupAnchorMenu = () => {
@@ -239,23 +239,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
AnchorMenu.Instance.OnClick = (e: PointerEvent) => {
!this.layoutDoc.showSidebar && this.toggleSidebar();
- setTimeout(() => this._sidebarRef.current?.anchorMenuClick(this.makeLinkAnchor(undefined, 'add:right', undefined, 'Anchored Selection', true))); // give time for sidebarRef to be created
+ setTimeout(() => this._sidebarRef.current?.anchorMenuClick(this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true))); // give time for sidebarRef to be created
};
AnchorMenu.Instance.OnAudio = (e: PointerEvent) => {
!this.layoutDoc.showSidebar && this.toggleSidebar();
- const anchor = this.getAnchor();
- const target = this._sidebarRef.current?.anchorMenuClick(anchor);
- if (target) {
- anchor.followLinkAudio = true;
- DocumentViewInternal.recordAudioAnnotation(Doc.GetProto(target), Doc.LayoutFieldKey(target));
- target.title = ComputedField.MakeFunction(`self["text-audioAnnotations-text"].lastElement()`);
- }
+ const anchor = this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true, true);
+ setTimeout(() => {
+ const target = this._sidebarRef.current?.anchorMenuClick(anchor);
+ if (target) {
+ anchor.followLinkAudio = true;
+ DocumentViewInternal.recordAudioAnnotation(Doc.GetProto(target), Doc.LayoutFieldKey(target));
+ target.title = ComputedField.MakeFunction(`self["text-audioAnnotations-text"].lastElement()`);
+ }
+ });
};
AnchorMenu.Instance.Highlight = action((color: string, isLinkButton: boolean) => {
this._editorView?.state && RichTextMenu.Instance.setHighlight(color, this._editorView, this._editorView?.dispatch);
return undefined;
});
- AnchorMenu.Instance.onMakeAnchor = this.getAnchor;
+ AnchorMenu.Instance.onMakeAnchor = () => this.getAnchor(true);
AnchorMenu.Instance.StartCropDrag = unimplementedFunction;
/**
* This function is used by the PDFmenu to create an anchor highlight and a new linked text annotation.
@@ -270,7 +272,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return target;
};
- DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docViewPath().lastElement(), this.getAnchor, targetCreator), e.pageX, e.pageY);
+ DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
});
const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
@@ -518,7 +520,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
- if (de.complete.annoDragData) de.complete.annoDragData.dropDocCreator = this.getAnchor;
+ if (de.complete.annoDragData) de.complete.annoDragData.dropDocCreator = () => this.getAnchor(true);
const dragData = de.complete.docDragData;
if (dragData) {
const draggedDoc = dragData.draggedDocuments.length && dragData.draggedDocuments[0];
@@ -689,9 +691,18 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
pinToPres = (anchor: Doc) => this.props.pinToPres(anchor, {});
@undoBatch
- makePushpin = (anchor: Doc) => (anchor.followLinkToggle = !anchor.followLinkToggle);
+ makeTargetToggle = (anchor: Doc) => (anchor.followLinkToggle = !anchor.followLinkToggle);
+
+ @undoBatch
+ showTargetTrail = (anchor: Doc) => {
+ const trail = DocCast(anchor.presTrail);
+ if (trail) {
+ Doc.ActivePresentation = trail;
+ this.props.addDocTab(trail, OpenWhere.replaceRight);
+ }
+ };
- isPushpin = (anchor: Doc) => BoolCast(anchor.followLinkToggle);
+ isTargetToggler = (anchor: Doc) => BoolCast(anchor.followLinkToggle);
specificContextMenu = (e: React.MouseEvent): void => {
const cm = ContextMenu.Instance;
@@ -714,8 +725,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
AnchorMenu.Instance.Delete = () => this.deleteAnnotation(anchor as Doc);
AnchorMenu.Instance.Pinned = false;
AnchorMenu.Instance.PinToPres = () => this.pinToPres(anchor as Doc);
- AnchorMenu.Instance.MakePushpin = () => this.makePushpin(anchor as Doc);
- AnchorMenu.Instance.IsPushpin = () => this.isPushpin(anchor as Doc);
+ AnchorMenu.Instance.MakeTargetToggle = () => this.makeTargetToggle(anchor as Doc);
+ AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(anchor as Doc);
+ AnchorMenu.Instance.IsTargetToggler = () => this.isTargetToggler(anchor as Doc);
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
})
);
@@ -891,7 +903,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
// TODO: nda -- Look at how link anchors are added
- makeLinkAnchor(anchorDoc?: Doc, location?: string, targetHref?: string, title?: string, noPreview?: boolean) {
+ makeLinkAnchor(anchorDoc?: Doc, location?: string, targetHref?: string, title?: string, noPreview?: boolean, addAsAnnotation?: boolean) {
const state = this._editorView?.state;
if (state) {
let selectedText = '';
@@ -901,7 +913,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (sel.from !== sel.to) {
const anchor = anchorDoc ?? Docs.Create.TextanchorDocument({ title: '#' + this._editorView?.state.doc.textBetween(sel.from, sel.to), annotationOn: this.dataDoc, unrendered: true });
const href = targetHref ?? Doc.localServerPath(anchor);
- if (anchor !== anchorDoc) this.addDocument(anchor);
+ if (anchor !== anchorDoc && addAsAnnotation) this.addDocument(anchor);
tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => {
if (node.firstChild === null && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) {
const allAnchors = [{ href, title, anchorId: anchor[Id] }];
@@ -1469,7 +1481,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (!this._editorView?.state.selection.empty && !(this._editorView?.state.selection instanceof NodeSelection) && FormattedTextBox._canAnnotate && !(e.nativeEvent as any).dash) this.setupAnchorMenu();
if (!this._downEvent) return;
this._downEvent = false;
- if (this.props.isContentActive(true) && !(e.nativeEvent as any).dash) {
+ if (this._editorView?.state.selection.empty && this.props.isContentActive(true) && !(e.nativeEvent as any).dash) {
const editor = this._editorView!;
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
!this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index e3c67ad2e..5675776fb 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -259,7 +259,7 @@ export class RichTextRules {
this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
}
const target = (docx instanceof Doc && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500 }, docid);
- DocUtils.MakeLink({ doc: this.TextBox.getAnchor() }, { doc: target }, 'portal to:portal from', undefined);
+ DocUtils.MakeLink({ doc: this.TextBox.getAnchor(true) }, { doc: target }, 'portal to:portal from', undefined);
const fstate = this.TextBox.EditorView?.state;
if (fstate && selection) {
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 8d43c33f0..3898490d3 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -108,7 +108,7 @@ export const marks: { [index: string]: MarkSpec } = {
node.attrs.title,
],
]
- : ['a', { class: anchorids, 'data-targethrefs': targethrefs, title: node.attrs.title, 'data-noPreview': node.attrs.noPreview, location: node.attrs.location, style: `text-decoration: underline` }, 0];
+ : ['a', { class: anchorids, 'data-targethrefs': targethrefs, title: node.attrs.title, 'data-noPreview': node.attrs.noPreview, location: node.attrs.location, style: `text-decoration: underline; cursor: default` }, 0];
},
},
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index 4d60a02f1..fd202590e 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -938,14 +938,19 @@
min-width: 15px;
max-width: 100px;
left: 8px;
+ margin: auto;
+ margin-left: unset;
+ height: 100%;
}
.presBox-presentPanel {
display: flex;
justify-self: end;
width: 100%;
- max-width: 300px;
- min-width: 150px;
+ margin: auto;
+ margin-right: unset;
+ height: 100%;
+ position: relative;
}
select {
@@ -955,7 +960,7 @@
.presBox-button {
cursor: pointer;
- height: 25px;
+ //height: 100%;
border-radius: 5px;
display: none;
justify-content: center;
@@ -986,6 +991,9 @@
width: max-content;
position: absolute;
right: 10px;
+ margin: auto;
+ margin-right: unset;
+ height: 100%;
.present-icon {
margin-right: 7px;
@@ -999,9 +1007,16 @@
position: relative;
display: inline-block;
left: 8px;
+ margin: auto;
+ margin-left: unset;
}
}
+.presBox-buttons.inOverlay {
+ padding-top: unset;
+ padding-bottom: unset;
+}
+
.presBox-backward,
.presBox-forward {
width: 25px;
@@ -1052,6 +1067,8 @@
font-size: 30px;
position: absolute;
min-width: 50px;
+ margin: auto;
+ margin-left: unset;
}
}
@@ -1087,13 +1104,12 @@
color: $white;
border-radius: 5px;
grid-template-rows: 100%;
- height: 25;
+ height: 100%;
width: max-content;
min-width: max-content;
justify-content: space-evenly;
align-items: center;
display: flex;
- position: absolute;
transition: all 0.2s;
.presPanel-button-text {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 6f3dc5e82..ff05dcdcb 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -12,7 +12,7 @@ import { ObjectField } from '../../../../fields/ObjectField';
import { listSpec } from '../../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { AudioField } from '../../../../fields/URLField';
-import { emptyPath, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
@@ -104,7 +104,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return NumCast(this.rootDoc._itemIndex);
}
@computed get activeItem() {
- return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null);
+ return DocCast(this.childDocs[NumCast(this.rootDoc._itemIndex)]);
}
@computed get targetDoc() {
return Cast(this.activeItem?.presentationTargetDoc, Doc, null);
@@ -129,13 +129,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
isActiveItemTarget = (layoutDoc: Doc) => this.activeItem?.presentationTargetDoc === layoutDoc;
clearSelectedArray = () => this.selectedArray.clear();
- addToSelectedArray = (doc: Doc) => this.selectedArray.add(doc);
- removeFromSelectedArray = (doc: Doc) => this.selectedArray.delete(doc);
+ addToSelectedArray = action((doc: Doc) => this.selectedArray.add(doc));
+ removeFromSelectedArray = action((doc: Doc) => this.selectedArray.delete(doc));
_unmounting = false;
@action
componentWillUnmount() {
this._unmounting = true;
+ if (this._presTimer) clearTimeout(this._presTimer);
document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
this.resetPresentation();
// Turn of progressivize editors
@@ -143,7 +144,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Object.values(this._disposers).forEach(disposer => disposer?.());
}
- @action
componentDidMount() {
this._disposers.keyboard = reaction(
() => this.selectedDoc,
@@ -167,10 +167,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
this.props.setContentView?.(this);
this._unmounting = false;
- this.rootDoc._forceRenderEngine = computeTimelineLayout.name;
- this.layoutDoc.presStatus = PresStatus.Edit;
- this.layoutDoc._gridGap = 0;
- this.layoutDoc._yMargin = 0;
+ if (this.props.renderDepth > 0) {
+ runInAction(() => {
+ this.rootDoc._forceRenderEngine = computeTimelineLayout.name;
+ this.layoutDoc._gridGap = 0;
+ this.layoutDoc._yMargin = 0;
+ });
+ }
this.turnOffEdit(true);
this._disposers.selection = reaction(
() => SelectionManager.Views(),
@@ -208,12 +211,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
nextSlide = (slideNum?: number) => {
const nextSlideInd = slideNum ?? this.itemIndex + 1;
let curSlideInd = nextSlideInd;
- const resetSelection = action(() => {
- this.clearSelectedArray();
- for (let i = nextSlideInd; i <= curSlideInd; i++) {
- this.addToSelectedArray(this.childDocs[i]);
- }
- });
CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => DocumentManager.Instance.getDocumentView(clip)?.ComponentView?.Pause?.());
this.clearSelectedArray();
const doGroupWithUp =
@@ -221,6 +218,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
() => {
if (nextSelected < this.childDocs.length) {
if (force || this.childDocs[nextSelected].groupWithUp) {
+ this.addToSelectedArray(this.childDocs[nextSelected]);
const serial = nextSelected + 1 < this.childDocs.length && NumCast(this.childDocs[nextSelected + 1].groupWithUp) > 1;
if (serial) {
this.gotoDocument(nextSelected, this.activeItem, true, async () => {
@@ -229,7 +227,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
doGroupWithUp(nextSelected + 1)();
});
} else {
- this.gotoDocument(nextSelected, this.activeItem, undefined, resetSelection);
+ this.gotoDocument(nextSelected, this.activeItem, true);
curSlideInd = this.itemIndex;
doGroupWithUp(nextSelected + 1)();
}
@@ -247,9 +245,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]);
const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex;
this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1);
- } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
- // Case 2: Last slide and presLoop is toggled ON or it is in Edit mode
- this.nextSlide(0);
+ } else {
+ if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
+ // Case 2: Last slide and presLoop is toggled ON or it is in Edit mode
+ this.nextSlide(0);
+ }
+ return 0;
}
return this.itemIndex;
};
@@ -446,7 +447,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
pinDoc.presWidth = NumCast(targetDoc.width);
pinDoc.presHeight = NumCast(targetDoc.height);
}
- if (pinProps.pinAudioPlay) pinDoc.followLinkAudio = true;
+ if (pinProps.pinAudioPlay) pinDoc.presPlayAudio = true;
if (pinProps.pinData) {
pinDoc.presPinData =
pinProps.pinData.scrollable ||
@@ -507,46 +508,44 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
console.log('Finish Slide Nav: ' + targetDoc.title);
targetDoc[AnimationSym] = undefined;
};
- const srcContext = Cast(targetDoc.context, Doc, null) ?? Cast(Cast(targetDoc.annotationOn, Doc, null)?.context, Doc, null);
- const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
- const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
- const includesDoc: boolean = DocumentManager.Instance.getDocumentView(targetDoc) ? true : false; // DocListCast(presCollection?.data).includes(targetDoc);
- const tabMap = CollectionDockingView.Instance?.tabMap;
- const tab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc === srcContext || tab.DashDoc === targetDoc);
- // Handles the setting of presCollection
- if (includesDoc) {
- //Case 1: Pres collection should not change as it is already the same
- } else if (tab !== undefined) {
- // Case 2: Pres collection should update
- this.layoutDoc.presCollection = srcContext;
- }
- const presStatus = this.rootDoc.presStatus;
const selViewCache = Array.from(this.selectedArray);
const dragViewCache = Array.from(this._dragArray);
const eleViewCache = Array.from(this._eleArray);
const resetSelection = action(() => {
- const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
- if (presDocView) SelectionManager.SelectView(presDocView, false);
- this.rootDoc.presStatus = presStatus;
- this.clearSelectedArray();
- selViewCache.forEach(doc => this.addToSelectedArray(doc));
- this._dragArray.splice(0, this._dragArray.length, ...dragViewCache);
- this._eleArray.splice(0, this._eleArray.length, ...eleViewCache);
+ if (!this.props.isSelected()) {
+ const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
+ if (presDocView) SelectionManager.SelectView(presDocView, false);
+ this.clearSelectedArray();
+ selViewCache.forEach(doc => this.addToSelectedArray(doc));
+ this._dragArray.splice(0, this._dragArray.length, ...dragViewCache);
+ this._eleArray.splice(0, this._eleArray.length, ...eleViewCache);
+ }
finished();
});
const createDocView = (doc: Doc, finished?: () => void) => {
DocumentManager.Instance.AddViewRenderedCb(doc, () => finished?.());
- (collectionDocView ?? this).props.addDocTab(doc, OpenWhere.lightbox);
- this.layoutDoc.presCollection = targetDoc;
+ LightboxView.AddDocTab(doc, OpenWhere.lightbox);
};
- PresBox.NavigateToTarget(targetDoc, activeItem, createDocView, srcContext, includesDoc || tab ? finished : resetSelection);
+ PresBox.NavigateToTarget(targetDoc, activeItem, createDocView, resetSelection);
};
- static NavigateToTarget(targetDoc: Doc, activeItem: Doc, createDocView: any, srcContext: Doc, finished?: () => void) {
+ static NavigateToTarget(targetDoc: Doc, activeItem: Doc, createDocView: any, finished?: () => void) {
if (activeItem.presMovement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) {
(DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
return;
}
+ const options: DocFocusOptions = {
+ willPan: activeItem.presMovement !== PresMovement.None,
+ willPanZoom: activeItem.presMovement === PresMovement.Zoom || activeItem.presMovement === PresMovement.Jump || activeItem.presMovement === PresMovement.Center,
+ zoomScale: activeItem.presMovement === PresMovement.Center ? 0 : NumCast(activeItem.presZoom, 1),
+ zoomTime: activeItem.presMovement === PresMovement.Jump ? 0 : NumCast(activeItem.presTransition, 500),
+ effect: activeItem,
+ noSelect: true,
+ originatingDoc: activeItem,
+ easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
+ zoomTextSelections: BoolCast(activeItem.presZoomText),
+ playAudio: BoolCast(activeItem.presPlayAudio),
+ };
const restoreLayout = () => {
// 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.
@@ -556,34 +555,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
PresBox.restoreTargetDocView(DocumentManager.Instance.getFirstDocumentView(targetDoc), { pinDocLayout }, activeItem, NumCast(activeItem.presTransition, 500));
}
};
- // If openDocument is selected then it should open the document for the user
- if (activeItem.openDocument) {
- LightboxView.SetLightboxDoc(targetDoc); // openInTab(targetDoc);
- setTimeout(restoreLayout);
- } else {
- if (targetDoc) {
- LightboxView.SetLightboxDoc(undefined);
- const options: DocFocusOptions = {
- willPan: activeItem.presMovement !== PresMovement.None,
- willPanZoom: activeItem.presMovement === PresMovement.Zoom || activeItem.presMovement === PresMovement.Jump || activeItem.presMovement === PresMovement.Center,
- zoomScale: activeItem.presMovement === PresMovement.Center ? 0 : NumCast(activeItem.presZoom, 1),
- zoomTime: activeItem.presMovement === PresMovement.Jump ? 0 : NumCast(activeItem.presTransition, 500),
- effect: activeItem,
- noSelect: true,
- originatingDoc: activeItem,
- easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
- zoomTextSelections: true
- };
- if (activeItem.presentationTargetDoc instanceof Doc) activeItem.presentationTargetDoc[AnimationSym] = undefined;
- var containerDocContext = srcContext ? [srcContext] : [];
- while (containerDocContext.length && !DocumentManager.Instance.getDocumentView(containerDocContext[0]) && containerDocContext[0].context) {
- containerDocContext = [Cast(containerDocContext[0].context, Doc, null), ...containerDocContext];
- }
+ const finishAndRestoreLayout = () => {
+ finished?.();
+ restoreLayout();
+ };
+ const containerDocContext = DocumentManager.GetContextPath(targetDoc);
- DocumentManager.Instance.jumpToDocument(targetDoc, options, createDocView, containerDocContext, finished);
+ let context = containerDocContext.length ? containerDocContext[0] : targetDoc;
+ if (activeItem.presOpenInLightbox) {
+ if (!DocumentManager.Instance.getLightboxDocumentView(DocCast(DocCast(targetDoc.annotationOn) ?? targetDoc))) {
+ context = DocCast(targetDoc.annotationOn) ?? targetDoc;
+ LightboxView.SetLightboxDoc(context); // openInTab(targetDoc);
}
- restoreLayout();
}
+ if (targetDoc) {
+ if (activeItem.presentationTargetDoc instanceof Doc) activeItem.presentationTargetDoc[AnimationSym] = undefined;
+
+ DocumentManager.Instance.AddViewRenderedCb(LightboxView.LightboxDoc, dv => {
+ if (!DocumentManager.Instance.getLightboxDocumentView(DocCast(context.annotationOn) ?? context)) {
+ LightboxView.SetLightboxDoc(undefined);
+ }
+ DocumentManager.Instance.jumpToDocument(targetDoc, options, createDocView, containerDocContext, finishAndRestoreLayout);
+ });
+ } else finishAndRestoreLayout();
}
/**
@@ -596,58 +590,56 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const curDoc = Cast(doc, Doc, null);
const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
- if (tagDoc === this.layoutDoc.presCollection) {
- tagDoc.opacity = 1;
- } else {
- if (curDoc.presHide) {
- if (index !== this.itemIndex) {
- tagDoc.opacity = 1;
- }
+ if (curDoc.presHide) {
+ if (index !== this.itemIndex) {
+ tagDoc.opacity = 1;
}
- const hidingIndBef = itemIndexes.find(item => item >= this.itemIndex);
- if (curDoc.presHideBefore && index === hidingIndBef) {
- if (index > this.itemIndex) {
- tagDoc.opacity = 0;
- } else if (index === this.itemIndex || !curDoc.presHideAfter) {
- tagDoc.opacity = 1;
- }
+ }
+ const hidingIndBef = itemIndexes.find(item => item >= this.itemIndex);
+ if (curDoc.presHideBefore && index === hidingIndBef) {
+ if (index > this.itemIndex) {
+ tagDoc.opacity = 0;
+ } else if (index === this.itemIndex || !curDoc.presHideAfter) {
+ tagDoc.opacity = 1;
}
- const hidingIndAft = itemIndexes
- .slice()
- .reverse()
- .find(item => item < this.itemIndex);
- if (curDoc.presHideAfter && index === hidingIndAft) {
- if (index < this.itemIndex) {
- tagDoc.opacity = 0;
- } else if (index === this.itemIndex || !curDoc.presHideBefore) {
- tagDoc.opacity = 1;
- }
+ }
+ const hidingIndAft = itemIndexes
+ .slice()
+ .reverse()
+ .find(item => item < this.itemIndex);
+ if (curDoc.presHideAfter && index === hidingIndAft) {
+ if (index < this.itemIndex) {
+ tagDoc.opacity = 0;
+ } else if (index === this.itemIndex || !curDoc.presHideBefore) {
+ tagDoc.opacity = 1;
}
- const hidingInd = itemIndexes.find(item => item === this.itemIndex);
- if (curDoc.presHide && index === hidingInd) {
- if (index === this.itemIndex) {
- tagDoc.opacity = 0;
- }
+ }
+ const hidingInd = itemIndexes.find(item => item === this.itemIndex);
+ if (curDoc.presHide && index === hidingInd) {
+ if (index === this.itemIndex) {
+ tagDoc.opacity = 0;
}
}
});
};
- //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
- @action
- startAutoPres = async (startSlide: number) => {
- if (!this.childDocs.length) return;
- this.layoutDoc.presStatus = PresStatus.Autoplay;
- this.startPresentation(startSlide + 1 === this.childDocs.length ? 0 : startSlide);
- clearTimeout(this._presTimer);
- const func = (itemIndex: number) => {
- if (itemIndex === this.next()) this.layoutDoc.presStatus = PresStatus.Manual;
- this._presTimer = setTimeout(
- () => this.layoutDoc.presStatus !== PresStatus.Manual && func(this.itemIndex),
- NumCast(this.activeItem.presDuration, this.activeItem.type === DocumentType.SCRIPTING ? 0 : 2500) + NumCast(this.activeItem.presTransition)
- );
+ _exitTrail: Opt<() => void>;
+ PlayTrail = (docs: Doc[]) => {
+ const savedStates = docs.map(doc => (doc._viewType !== CollectionViewType.Freeform ? undefined : { c: doc, x: NumCast(doc.panX), y: NumCast(doc.panY), s: NumCast(doc.viewScale) }));
+ this.startPresentation(0);
+ this._exitTrail = () => {
+ savedStates
+ .filter(savedState => savedState)
+ .map(savedState => {
+ const { x, y, s, c } = savedState!;
+ c._panX = x;
+ c._panY = y;
+ c._viewScale = s;
+ });
+ LightboxView.SetLightboxDoc(undefined);
+ Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, this.rootDoc);
+ return PresStatus.Edit;
};
- func(this.itemIndex);
};
// The function pauses the auto presentation
@@ -696,40 +688,54 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
* @param startIndex: index that the presentation will start at
*/
startPresentation = (startIndex: number) => {
- this.childDocs.forEach(doc => {
- const tagDoc = doc.presentationTargetDoc as Doc;
- if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) {
- tagDoc.opacity = 0;
- }
- if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) {
- tagDoc.opacity = 0;
- }
- });
- this.gotoDocument(startIndex, this.activeItem);
+ clearTimeout(this._presTimer);
+ if (this.childDocs.length) {
+ this.layoutDoc.presStatus = PresStatus.Autoplay;
+ this.childDocs.forEach(doc => {
+ const tagDoc = doc.presentationTargetDoc as Doc;
+ if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) tagDoc.opacity = 0;
+ if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) tagDoc.opacity = 0;
+ // if (doc.presHide && this.childDocs.indexOf(doc) === startIndex) tagDoc.opacity = 0;
+ });
+ const func = () => {
+ const delay = NumCast(this.activeItem.presDuration, this.activeItem.type === DocumentType.SCRIPTING ? 0 : 2500) + NumCast(this.activeItem.presTransition);
+ this._presTimer = setTimeout(() => {
+ if (!this.next()) this.layoutDoc.presStatus = this._exitTrail?.() ?? PresStatus.Manual;
+ this.layoutDoc.presStatus === PresStatus.Autoplay && func();
+ }, delay);
+ };
+ this.gotoDocument(startIndex, this.activeItem, undefined, func);
+ }
};
/**
* The method called to open the presentation as a minimized view
*/
@action
- updateMinimize = async () => {
+ enterMinimize = () => {
+ clearTimeout(this._presTimer);
+ const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ this.props.removeDocument?.(this.layoutDoc);
+ return PresBox.OpenPresMinimized(this.rootDoc, [pt[0] + (this.props.PanelWidth() - 250), pt[1] + 10]);
+ };
+ exitMinimize = () => {
if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc)) {
- this.layoutDoc.presStatus = PresStatus.Edit;
Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, this.rootDoc);
CollectionDockingView.AddSplit(this.rootDoc, OpenWhereMod.right);
- } else {
- this.layoutDoc.presStatus = PresStatus.Edit;
- clearTimeout(this._presTimer);
- const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
- this.rootDoc.overlayX = pt[0] + (this.props.PanelWidth() - 250);
- this.rootDoc.overlayY = pt[1] + 10;
- this.rootDoc._height = 30;
- this.rootDoc._width = 248;
- Doc.AddDocToList(Doc.MyOverlayDocs, undefined, this.rootDoc);
- this.props.removeDocument?.(this.layoutDoc);
}
+ return PresStatus.Edit;
};
+ public static minimizedWidth = 198;
+ public static OpenPresMinimized(doc: Doc, pt: number[]) {
+ doc.overlayX = pt[0];
+ doc.overlayY = pt[1];
+ doc._height = 30;
+ doc._width = PresBox.minimizedWidth;
+ Doc.AddDocToList(Doc.MyOverlayDocs, undefined, doc);
+ return (doc.presStatus = PresStatus.Manual);
+ }
+
/**
* Called when the user changes the view type
* Either 'List' (stacking) or 'Slides' (carousel)
@@ -863,8 +869,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
selectElement = async (doc: Doc) => {
CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => DocumentManager.Instance.getDocumentView(clip)?.ComponentView?.Pause?.());
this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem);
- if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(DocCast(doc.context)), 0);
- else this.updateCurrentPresentation(DocCast(doc.context));
+ // if (doc.presPinView) setTimeout(() => this.updateCurrentPresentation(DocCast(doc.context)), 0);
+ // else
+ this.updateCurrentPresentation(DocCast(doc.context));
};
//Command click
@@ -941,11 +948,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
break;
case 'Escape':
if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc)) {
- this.updateMinimize();
- } else if (this.layoutDoc.presStatus === 'edit') {
+ this.exitClicked();
+ } else if (this.layoutDoc.presStatus === PresStatus.Edit) {
this.clearSelectedArray();
this._eleArray.length = this._dragArray.length = 0;
- } else this.layoutDoc.presStatus = 'edit';
+ } else {
+ this.layoutDoc.presStatus = PresStatus.Edit;
+ }
if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
break;
@@ -1010,7 +1019,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get order() {
const order: JSX.Element[] = [];
const docs: Doc[] = [];
- const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
+ const presCollection = DocumentManager.GetContextPath(this.activeItem).reverse().lastElement();
const dv = DocumentManager.Instance.getDocumentView(presCollection);
this.childDocs
.filter(doc => Cast(doc.presentationTargetDoc, Doc, null))
@@ -1176,8 +1185,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
@action
updateOpenDoc = (activeItem: Doc) => {
- activeItem.openDocument = !activeItem.openDocument;
- this.selectedArray.forEach(doc => (doc.openDocument = activeItem.openDocument));
+ activeItem.presOpenInLightbox = !activeItem.presOpenInLightbox;
+ this.selectedArray.forEach(doc => (doc.presOpenInLightbox = activeItem.presOpenInLightbox));
};
@undoBatch
@action
@@ -1222,8 +1231,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get transitionDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- const isPresCollection: boolean = targetDoc === this.layoutDoc.presCollection;
- const isPinWithView: boolean = BoolCast(activeItem.presPinView);
const presEffect = (effect: PresEffect) => (
<div className={`presBox-dropdownOption ${activeItem.presEffect === effect || (effect === PresEffect.None && !activeItem.presEffect) ? 'active' : ''}`} onPointerDown={StopEvent} onClick={() => this.updateEffect(effect)}>
{effect}
@@ -1250,7 +1257,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const type = targetDoc.type;
const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
const zoom = NumCast(activeItem.presZoom, 1) * 100;
- let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
+ let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 0;
if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
const effect = activeItem.presEffect ? activeItem.presEffect : PresMovement.None;
// activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : PresMovement.Zoom;
@@ -1276,11 +1283,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{this.movementName(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={StopEvent} style={{ display: this._openMovementDropdown ? 'grid' : 'none' }}>
- {isPresCollection || (isPresCollection && isPinWithView) ? null : presMovement(PresMovement.None)}
+ {presMovement(PresMovement.None)}
{presMovement(PresMovement.Center)}
{presMovement(PresMovement.Zoom)}
{presMovement(PresMovement.Pan)}
- {isPresCollection || (isPresCollection && isPinWithView) ? null : presMovement(PresMovement.Jump)}
+ {presMovement(PresMovement.Jump)}
</div>
</div>
<div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
@@ -1322,29 +1329,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="ribbon-box">
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 while presented'}</div>}>
- <div className={`ribbon-toggle ${activeItem.presHide ? 'active' : ''}`} onClick={() => this.updateHide(activeItem)}>
- Hide
- </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">{'Hide before presented'}</div>}>
+ <div className={`ribbon-toggle ${activeItem.presHideBefore ? 'active' : ''}`} onClick={() => this.updateHideBefore(activeItem)}>
+ Hide before
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">{'Hide while presented'}</div>}>
+ <div className={`ribbon-toggle ${activeItem.presHide ? 'active' : ''}`} onClick={() => this.updateHide(activeItem)}>
+ Hide
+ </div>
+ </Tooltip>
+
+ <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)}>
+ <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presOpenInLightbox ? Colors.LIGHT_BLUE : '' }} onClick={() => this.updateOpenDoc(activeItem)}>
Lightbox
</div>
</Tooltip>
@@ -1379,44 +1382,46 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</>
)}
</div>
- {isPresCollection ? null : (
- <div className="ribbon-box">
- Effects
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Play Audio Annotation</div>
- <input className="presBox-checkbox" style={{ margin: 10 }} type="checkbox" onChange={() => (activeItem.followLinkAudio = !BoolCast(activeItem.followLinkAudio))} checked={BoolCast(activeItem.followLinkAudio)} />
- </div>
- <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()}>
- {presEffect(PresEffect.None)}
- {presEffect(PresEffect.Fade)}
- {presEffect(PresEffect.Flip)}
- {presEffect(PresEffect.Rotate)}
- {presEffect(PresEffect.Bounce)}
- {presEffect(PresEffect.Roll)}
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
- <div className="presBox-subheading">Effect direction</div>
- <div className="ribbon-property">{StrCast(this.activeItem.presEffectDirection)}</div>
- </div>
- <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
- {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
- {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
- {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
- {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
- {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+ <div className="ribbon-box">
+ Effects
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Play Audio Annotation</div>
+ <input className="presBox-checkbox" style={{ margin: 10 }} type="checkbox" onChange={() => (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))} checked={BoolCast(activeItem.presPlayAudio)} />
+ </div>
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Zoom Text Selections</div>
+ <input className="presBox-checkbox" style={{ margin: 10 }} type="checkbox" onChange={() => (activeItem.presZoomText = !BoolCast(activeItem.presZoomText))} checked={BoolCast(activeItem.presZoomText)} />
+ </div>
+ <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()}>
+ {presEffect(PresEffect.None)}
+ {presEffect(PresEffect.Fade)}
+ {presEffect(PresEffect.Flip)}
+ {presEffect(PresEffect.Rotate)}
+ {presEffect(PresEffect.Bounce)}
+ {presEffect(PresEffect.Roll)}
</div>
</div>
- )}
+ <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
+ <div className="presBox-subheading">Effect direction</div>
+ <div className="ribbon-property">{StrCast(this.activeItem.presEffectDirection)}</div>
+ </div>
+ <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
+ {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+ {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+ {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+ {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+ {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+ </div>
+ </div>
<div className="ribbon-final-box">
<div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
Apply to all
@@ -1621,7 +1626,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get newDocumentToolbarDropdown() {
return (
<div
- className={'presBox-toolbar-dropdown'}
+ className="presBox-toolbar-dropdown"
style={{ display: this._newDocumentTools && this.layoutDoc.presStatus === 'edit' ? 'inline-flex' : 'none' }}
onClick={e => e.stopPropagation()}
onPointerUp={e => e.stopPropagation()}
@@ -1757,7 +1762,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (freeform && layout) doc = this.createTemplate(layout, 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 tabMap = CollectionDockingView.Instance?.tabMap;
+ const tab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc.type === DocumentType.COL)?.DashDoc;
+ const presCollection = DocumentManager.GetContextPath(this.activeItem).reverse().lastElement().presentationTargetDoc ?? tab;
const data = Cast(presCollection?.data, listSpec(Doc));
const presData = Cast(this.rootDoc.data, listSpec(Doc));
if (data && presData) {
@@ -1798,7 +1805,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
className="dropdown-play-button"
onClick={undoBatch(
action(() => {
- this.updateMinimize();
+ this.enterMinimize();
this.turnOffEdit(true);
this.gotoDocument(this.itemIndex, this.activeItem);
})
@@ -1821,7 +1828,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
scrollFocus = () => {
- this.startOrPause(false);
+ // this.gotoDocument(0);
+ // this.startOrPause(false);
return undefined;
};
@@ -1951,8 +1959,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get topPanel() {
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
+ const inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
return (
- <div className="presBox-buttons" style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
+ <div className={`presBox-buttons${inOverlay ? ' inOverlay' : ''}`} style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, 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={StopEvent} value={CollectionViewType.Stacking}>
@@ -1969,7 +1978,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</select>
)}
<div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
- <span className={`presBox-button ${this.layoutDoc.presStatus === 'edit' ? 'present' : ''}`}>
+ <span className={`presBox-button ${this.layoutDoc.presStatus === PresStatus.Edit ? 'present' : ''}`}>
<div
className="presBox-button-left"
onClick={undoBatch(() => {
@@ -2001,11 +2010,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@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 inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
// 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)}>
+ <div
+ className="presPanel-button"
+ style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }}
+ onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}>
<FontAwesomeIcon icon={'redo-alt'} />
</div>
</Tooltip>
@@ -2013,42 +2026,77 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div
className="presPanel-button"
style={{ opacity: presStart ? 0.4 : 1 }}
- onClick={e => {
- this.back();
- if (this._presTimer) {
- clearTimeout(this._presTimer);
- this.layoutDoc.presStatus = PresStatus.Manual;
- }
- e.stopPropagation();
- }}>
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.back();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ e.stopPropagation();
+ },
+ 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" onClick={e => this.startOrPause(true)}>
+ <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.startOrPause(true), false, false)}>
<FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} />
</div>
</Tooltip>
<div
className="presPanel-button"
style={{ opacity: presEnd ? 0.4 : 1 }}
- onClick={e => {
- this.next();
- if (this._presTimer) {
- clearTimeout(this._presTimer);
- this.layoutDoc.presStatus = PresStatus.Manual;
- }
- e.stopPropagation();
- }}>
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.next();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ e.stopPropagation();
+ },
+ 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' }} onClick={() => this.nextSlide(0)}>
+ <div
+ className="presPanel-button"
+ style={{ border: 'solid 1px white' }}
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.nextSlide(0);
+ },
+ false,
+ false
+ )
+ }>
<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}
+ <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: inOverlay || this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}>
+ {`${inOverlay ? '' : 'Slide'} ${this.itemIndex + 1} / ${this.childDocs.length}`}
</div>
<div className="presPanel-divider"></div>
{this.props.PanelWidth() > 250 ? (
@@ -2056,14 +2104,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
className="presPanel-button-text"
onClick={undoBatch(
action(() => {
- this.layoutDoc.presStatus = 'edit';
+ this.layoutDoc.presStatus = PresStatus.Edit;
clearTimeout(this._presTimer);
})
)}>
EXIT
</div>
) : (
- <div className="presPanel-button" onClick={undoBatch(action(() => (this.layoutDoc.presStatus = 'edit')))}>
+ <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.exitClicked, false, false)}>
<FontAwesomeIcon icon={'times'} />
</div>
)}
@@ -2073,13 +2121,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
startOrPause = (makeActive = true) => {
- if (this.itemIndex + 1 === this.childDocs.length) {
- this.gotoDocument(0);
- } else {
- makeActive && this.updateCurrentPresentation();
- if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
- else this.pauseAutoPres();
- }
+ makeActive && this.updateCurrentPresentation();
+ if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startPresentation(this.itemIndex);
+ else this.pauseAutoPres();
};
@action
@@ -2101,9 +2145,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@undoBatch
@action
- exitClicked = (e: PointerEvent) => {
- this.updateMinimize();
- this.layoutDoc.presStatus = PresStatus.Edit;
+ exitClicked = () => {
+ this.layoutDoc.presStatus = this._exitTrail?.() ?? this.exitMinimize();
clearTimeout(this._presTimer);
};
@@ -2138,8 +2181,9 @@ 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 presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
- const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ const presEnd = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
+ const presStart = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ const inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
return this.props.addDocTab === returnFalse ? ( // bcz: hack!! - addDocTab === returnFalse only when this is being rendered by the OverlayView which means the doc is a mini player
<div className="miniPres" onClick={e => e.stopPropagation()} onPointerEnter={action(e => (this._forceKeyEvents = true))}>
<div
@@ -2181,7 +2225,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
) : (
- <div className="presBox-cont" style={{ minWidth: DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }}>
+ <div className="presBox-cont" style={{ minWidth: inOverlay ? PresBox.minimizedWidth : undefined }}>
{this.topPanel}
{this.toolbar}
{this.newDocumentToolbarDropdown}
@@ -2226,12 +2270,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
}
static 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, OpenWhereMod.right);
finished?.();
};
- PresBox.NavigateToTarget(bestTarget, activeItem, openInTab, srcContext);
+ PresBox.NavigateToTarget(bestTarget, activeItem, openInTab);
}
}
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 5e1474b89..788900b46 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -50,9 +50,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get collapsedHeight() {
return 35;
} // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
- @computed get presStatus() {
- return this.presBox.presStatus;
- }
@computed get selectedArray() {
return this.presBoxView?.selectedArray;
}
@@ -364,19 +361,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@computed get recordingIsInOverlay() {
- let isInOverlay = false;
- DocListCast(Doc.MyOverlayDocs.data).forEach(doc => {
- if (doc.slides === this.rootDoc) {
- isInOverlay = true;
- // return
- }
- });
- return isInOverlay;
+ return DocListCast(Doc.MyOverlayDocs.data).some(doc => doc.slides === this.rootDoc);
}
// a previously recorded video will have timecode defined
- static videoIsRecorded = (activeItem: Doc) => {
- const casted = Cast(activeItem.recording, Doc, null);
+ static videoIsRecorded = (activeItem: Opt<Doc>) => {
+ const casted = Cast(activeItem?.recording, Doc, null);
return casted && 'currentTimecode' in casted;
};
@@ -391,10 +381,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
static removeEveryExistingRecordingInOverlay = () => {
// Remove every recording that already exists in overlay view
DocListCast(Doc.MyOverlayDocs.data).forEach(doc => {
- // if it's a recording video, don't remove from overlay (user can lose data)
- if (!PresElementBox.videoIsRecorded(DocCast(doc.slides))) return;
-
if (doc.slides !== null) {
+ // if it's a recording video, don't remove from overlay (user can lose data)
+ if (!PresElementBox.videoIsRecorded(DocCast(doc.slides))) return;
+
Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, doc);
}
});