diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/LinkManager.ts | 3 | ||||
-rw-r--r-- | src/client/views/nodes/AudioBox.tsx | 8 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 70 |
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); |