aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/LinkManager.ts3
-rw-r--r--src/client/views/nodes/AudioBox.tsx8
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx70
4 files changed, 43 insertions, 40 deletions
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index accf53676..bf927c5b8 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -54,7 +54,8 @@ export class LinkManager {
}, true);
relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] {
- return DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).reduce((list, anno) =>
+ const lfield = Doc.LayoutFieldKey(anchor);
+ return DocListCast(anchor[lfield + "-annotations"]).concat(DocListCast(anchor[lfield + "-annotations-timeline"])).reduce((list, anno) =>
[...list, ...LinkManager.Instance.relatedLinker(anno)],
LinkManager.Instance.directLinker(anchor).slice());
}, true);
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index e854d40be..8614200de 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -108,16 +108,16 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
return { la1, la2, linkTime };
}
+ getAnchor = () => {
+ return this.createMarker(this._ele?.currentTime || Cast(this.props.Document._currentTimecode, "number", null) || (this.audioState === "recording" ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined));
+ }
+
componentWillUnmount() {
Object.values(this._disposers).forEach(disposer => disposer?.());
const ind = DocUtils.ActiveRecordings.indexOf(this);
ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1));
}
- getAnchor = () => {
- return this.createMarker(this._ele?.currentTime || Cast(this.props.Document._currentTimecode, "number", null) || (this.audioState === "recording" ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined));
- }
-
@action
componentDidMount() {
this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e3da48749..6620614f8 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -541,7 +541,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch @action
drop = async (e: Event, de: DragManager.DropEvent) => {
- if (this.props.LayoutTemplateString) return;
+ if (this.props.dontRegisterView || this.props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return;
if (this.props.Document === CurrentUserUtils.ActiveDashboard) {
alert((e.target as any)?.closest?.("*.lm_content") ?
"You can't perform this move most likely because you don't have permission to modify the destination." :
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index c5e61eedd..6ca4a589a 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -28,7 +28,6 @@ import { LinkDocPreview } from "./LinkDocPreview";
import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment";
import { StyleProp } from "../StyleProvider";
import { computedFn } from "mobx-utils";
-import { DocumentManager } from "../../util/DocumentManager";
import { Dictionary } from "typescript-collections";
import { MarqueeAnnotator } from "../MarqueeAnnotator";
import { Id } from "../../../fields/FieldSymbols";
@@ -78,14 +77,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
@observable _playTimer?: NodeJS.Timeout = undefined;
@observable _fullScreen = false;
@observable _playing = false;
+ @computed get links() { return DocListCast(this.dataDoc.links); }
@computed get heightPercent() { return this.layoutDoc._showTimeline ? NumCast(this.layoutDoc._videoTimelineHeightPercent, VideoBox.heightPercent) : 100; }
@computed get videoDuration() { return NumCast(this.dataDoc[this.fieldKey + "-duration"]); }
@computed get markerDocs() { return DocListCast(this.dataDoc[this.annotationKey + "-timeline"]).concat(DocListCast(this.dataDoc[this.annotationKey])); }
+
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(VideoBox, fieldKey); }
- public get player(): HTMLVideoElement | null {
- return this._videoRef;
- }
+ public get player(): HTMLVideoElement | null { return this._videoRef; }
constructor(props: Readonly<FieldViewProps>) {
super(props);
@@ -98,6 +97,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
VideoBox.LabelPlayScript = VideoBox.LabelPlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(self, this.displayTimecode)`, { self: Doc.name, scriptContext: "any" })!;
}
+ getAnchor = () => {
+ return this.createMarker(Cast(this.layoutDoc._currentTimecode, "number", null));
+ }
+
+ choosePath(url: string) {
+ return url.indexOf(window.location.origin) === -1 ? Utils.CorsProxy(url) : url;
+ }
+
videoLoad = () => {
const aspect = this.player!.videoWidth / this.player!.videoHeight;
Doc.SetNativeWidth(this.dataDoc, this.player!.videoWidth);
@@ -154,13 +161,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
}
}
- choosePath(url: string) {
- if (url.indexOf(window.location.origin) === -1) {
- return Utils.CorsProxy(url);
- }
- return url;
- }
-
@action public Snapshot() {
const width = (this.layoutDoc._width || 0);
const height = (this.layoutDoc._height || 0);
@@ -230,6 +230,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
}
componentDidMount() {
+ this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
+
this._disposers.selection = reaction(() => this.props.isSelected(),
selected => {
if (!selected) {
@@ -239,29 +241,19 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
},
{ fireImmediately: true });
this._disposers.videoStart = reaction(
- () => this.Document._videoStart,
- (videoStart) => {
- if (videoStart !== undefined) {
- if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) {
- const delay = this.player ? 0 : 250; // wait for mainCont and try again to play
- setTimeout(() => this.player && this.Play(), delay);
- setTimeout(() => this.Document._videoStart = undefined, 10 + delay);
- }
- }
- },
+ () => !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc && this.props.renderDepth !== -1 ? Cast(this.Document._videoStart, "number", null) : undefined,
+ videoStart => videoStart !== undefined && setTimeout(() => {
+ this.player && this.Play();
+ setTimeout(() => this.Document._videoStart = undefined, 10);
+ }, this.player ? 0 : 250), // wait for mainCont and try again to play
{ fireImmediately: true }
);
this._disposers.videoStop = reaction(
- () => this.Document._videoStop,
- (videoStop) => {
- if (videoStop !== undefined) {
- if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) {
- const delay = this.player ? 0 : 250; // wait for mainCont and try again to play
- setTimeout(() => this.player && this.Pause(), delay);
- setTimeout(() => { this.Document._videoStop = undefined; }, 10 + delay);
- }
- }
- },
+ () => this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc ? Cast(this.Document._videoStop, "number", null) : undefined,
+ videoStop => videoStop !== undefined && setTimeout(() => {
+ this.player && this.Pause();
+ setTimeout(() => this.Document._videoStop = undefined, 10);
+ }, this.player ? 0 : 250), // wait for mainCont and try again to play
{ fireImmediately: true }
);
if (this.youtubeVideoId) {
@@ -334,7 +326,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
}
}
- // returns the video and timeline
@computed get content() {
const field = Cast(this.dataDoc[this.fieldKey], VideoField);
const interactive = Doc.GetSelectedTool() !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
@@ -569,6 +560,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
} else {
this.dataDoc[this.annotationKey + "-timeline"] = new List<Doc>([marker]);
}
+ return marker;
}
// play back the video from time
@@ -628,6 +620,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
return level;
}
+ playLink = (doc: Doc) => {
+ const startTime = NumCast(doc.displayTimecode);
+ const endTime = NumCast(doc.undisplayTimecode, null);
+ if (startTime !== undefined) {
+ this.layoutDoc.playOnSelect && (endTime ? this.playFrom(startTime, endTime) : this.playFrom(startTime));
+ }
+ }
// renders the markers as a document
renderInner = computedFn(function (this: VideoBox, mark: Doc, script: undefined | (() => ScriptField), doublescript: undefined | (() => ScriptField), x: number, y: number, width: number, height: number, annotationKey: string) {
const marker = observable({ view: undefined as any });
@@ -635,6 +634,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
marker, view: <DocumentView key="view" {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} ref={action((r: DocumentView | null) => marker.view = r)}
Document={mark}
DataDoc={undefined}
+ focus={() => this.playLink(mark)}
PanelWidth={() => width}
PanelHeight={() => height}
renderDepth={this.props.renderDepth + 1}
@@ -703,7 +703,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
</div>;
})}
{this.selectionContainer}
- <div className="audiobox-current" ref={this._audioRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc._currentTimecode) / this.videoDuration * 100}%`, pointerEvents: "none" }} />
+ <div className="audiobox-current" ref={this._audioRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }}
+ style={{ left: `${NumCast(this.layoutDoc._currentTimecode) / this.videoDuration * 100}%`, pointerEvents: "none" }}
+ />
</div>;
}
@@ -773,7 +775,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
scaling = () => this.props.scaling?.() || 1;
panelWidth = () => this.props.PanelWidth() * this.heightPercent / 100;
- panelHeight = () => this.props.PanelHeight() * this.heightPercent / 100;
+ panelHeight = () => this.layoutDoc._fitWidth ? this.panelWidth() / Doc.NativeAspect(this.rootDoc) : this.props.PanelHeight() * this.heightPercent / 100;
screenToLocalTransform = () => {
const offset = (this.props.PanelWidth() - this.panelWidth()) / 2 / this.scaling();
return this.props.ScreenToLocalTransform().translate(-offset, 0).scale(100 / this.heightPercent);