aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionStackedTimeline.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionStackedTimeline.tsx')
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx56
1 files changed, 30 insertions, 26 deletions
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 22a575989..9d5cb257a 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -24,7 +24,7 @@ import { undoBatch, UndoManager } from '../../util/UndoManager';
import { AudioWaveform } from '../AudioWaveform';
import { CollectionSubView } from '../collections/CollectionSubView';
import { LightboxView } from '../LightboxView';
-import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps } from '../nodes/DocumentView';
+import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../nodes/DocumentView';
import { LabelBox } from '../nodes/LabelBox';
import { VideoBox } from '../nodes/VideoBox';
import './CollectionStackedTimeline.scss';
@@ -41,7 +41,9 @@ export type CollectionStackedTimelineProps = {
mediaPath: string;
dictationKey: string;
rawDuration: number;
+ dataFieldKey: string;
fieldKey: string;
+ thumbnails?: () => string[];
};
// trimming state: shows full clip, current trim bounds, or not trimming
@@ -80,6 +82,9 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
get minTrimLength() {
return Math.max(this._timeline?.getBoundingClientRect() ? 0.05 * this.clipDuration : 0, 0.5);
}
+ @computed get thumbnails() {
+ return this.props.thumbnails?.();
+ }
@computed get trimStart() {
return this.IsTrimming !== TrimScope.None ? this._trimStart : this.clipStart;
@@ -102,7 +107,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
}
@computed get currentTime() {
- return NumCast(this.layoutDoc._currentTimecode);
+ return NumCast(this.layoutDoc._layout_currentTimecode);
}
@computed get zoomFactor() {
@@ -114,7 +119,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
// onClick play scripts
CollectionStackedTimeline.RangeScript =
CollectionStackedTimeline.RangeScript ||
- ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, {
+ ScriptField.MakeFunction(`setTimeout(() => scriptContext.clickAnchor(this, clientX))`, {
+ // setTimeout is a hack to run script in its own properly named undo group (instead of being part of the generic onClick)
self: Doc.name,
scriptContext: 'any',
clientX: 'number',
@@ -219,12 +225,12 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
};
getLinkData(l: Doc) {
- let la1 = l.anchor1 as Doc;
- let la2 = l.anchor2 as Doc;
+ let la1 = l.link_anchor_1 as Doc;
+ let la2 = l.link_anchor_2 as Doc;
const linkTime = NumCast(la2[this.props.startTag], NumCast(la1[this.props.startTag]));
if (Doc.AreProtosEqual(la1, this.dataDoc)) {
- la1 = l.anchor2 as Doc;
- la2 = l.anchor1 as Doc;
+ la1 = l.link_anchor_2 as Doc;
+ la2 = l.link_anchor_1 as Doc;
}
return { la1, la2, linkTime };
}
@@ -292,10 +298,9 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
const clientX = e.clientX;
if (rect) {
this._hoverTime = this.toTimeline(clientX - rect.x, rect.width);
- if (this.dataDoc.thumbnails) {
+ if (this.thumbnails) {
const nearest = Math.floor((this._hoverTime / this.props.rawDuration) * VideoBox.numThumbnails);
- const thumbnails = StrListCast(this.dataDoc.thumbnails);
- const imgField = thumbnails?.length > 0 ? new ImageField(thumbnails[nearest]) : undefined;
+ const imgField = this.thumbnails.length > 0 ? new ImageField(this.thumbnails[nearest]) : undefined;
this._thumbnail = imgField?.url?.href ? imgField.url.href.replace('.png', '_m.png') : undefined;
}
}
@@ -399,17 +404,15 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
docAnchor ??
Docs.Create.LabelDocument({
title: ComputedField.MakeFunction(`self["${endTag}"] ? "#" + formatToTime(self["${startTag}"]) + "-" + formatToTime(self["${endTag}"]) : "#" + formatToTime(self["${startTag}"])`) as any,
- _minFontSize: 12,
- _maxFontSize: 24,
- _singleLine: true,
+ _label_minFontSize: 12,
+ _label_maxFontSize: 24,
_stayInCollection: true,
backgroundColor: 'rgba(128, 128, 128, 0.5)',
- useLinkSmallAnchor: true,
- hideLinkButton: true,
+ layout_hideLinkButton: true,
onClick: FollowLinkScript(),
annotationOn: rootDoc,
- _timelineLabel: true,
- borderRounding: anchorEndTime === undefined ? '100%' : undefined,
+ _isTimelineLabel: true,
+ layout_borderRounding: anchorEndTime === undefined ? '100%' : undefined,
});
Doc.GetProto(anchor)[startTag] = anchorStartTime;
Doc.GetProto(anchor)[endTag] = anchorEndTime;
@@ -434,7 +437,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
this.scrollToTime(seekTimeInSeconds);
}
} else {
- if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) && endTime > NumCast(this.layoutDoc._currentTimecode)) {
+ if (seekTimeInSeconds < NumCast(this.layoutDoc._layout_currentTimecode) && endTime > NumCast(this.layoutDoc._layout_currentTimecode)) {
if (!this.layoutDoc.autoPlayAnchors && this.props.playing()) {
this.props.Pause();
} else {
@@ -455,7 +458,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
}
const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.05;
const endTime = this.anchorEnd(anchorDoc);
- if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) + 1e-4 && endTime > NumCast(this.layoutDoc._currentTimecode) - 1e-4) {
+ if (seekTimeInSeconds < NumCast(this.layoutDoc._layout_currentTimecode) + 1e-4 && endTime > NumCast(this.layoutDoc._layout_currentTimecode) - 1e-4) {
if (this.props.playing()) this.props.Pause();
else if (this.layoutDoc.autoPlayAnchors) this.props.Play();
else if (!this.layoutDoc.autoPlayAnchors) {
@@ -596,6 +599,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
{!this.props.PanelHeight() ? null : (
<AudioWaveform
rawDuration={this.props.rawDuration}
+ fieldKey={this.props.dataFieldKey}
duration={this.clipDuration}
mediaPath={this.props.mediaPath}
layoutDoc={this.layoutDoc}
@@ -661,6 +665,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
interface StackedTimelineAnchorProps {
mark: Doc;
+ whenChildContentsActiveChanged: (isActive: boolean) => void;
+ addDocTab: (doc: Doc, where: OpenWhere) => boolean;
rangeClickScript: () => ScriptField;
rangePlayScript: () => ScriptField;
left: number;
@@ -709,7 +715,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
() => this.props.currentTimecode(),
time => {
const dictationDoc = Cast(this.props.layoutDoc['data-dictation'], Doc, null);
- const isDictation = dictationDoc && LinkManager.Links(this.props.mark).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc);
+ const isDictation = dictationDoc && LinkManager.Links(this.props.mark).some(link => Cast(link.link_anchor_1, Doc, null)?.annotationOn === dictationDoc);
if (
!LightboxView.LightboxDoc &&
// bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront.
@@ -746,7 +752,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
if (timelineOnly) {
if (!left && time !== undefined && time <= NumCast(anchor[this.props.startTag])) time = undefined;
Doc.SetInPlace(anchor, left ? this.props.startTag : this.props.endTag, time, true);
- if (!left) Doc.SetInPlace(anchor, 'borderRounding', time !== undefined ? undefined : '100%', true);
+ if (!left) Doc.SetInPlace(anchor, 'layout_borderRounding', time !== undefined ? undefined : '100%', true);
} else {
anchor[left ? '_timecodeToShow' : '_timecodeToHide'] = time;
}
@@ -808,16 +814,14 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
isDocumentActive={this.props.isDocumentActive}
PanelWidth={width}
PanelHeight={height}
- fitWidth={returnTrue}
+ layout_fitWidth={returnTrue}
ScreenToLocalTransform={screenXf}
- addDocTab={returnFalse}
pinToPres={emptyFunction}
- whenChildContentsActiveChanged={emptyFunction}
focus={focusFunc}
isContentActive={returnFalse}
searchFilterDocs={returnEmptyDoclist}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
+ childFilters={returnEmptyFilter}
+ childFiltersByRanges={returnEmptyFilter}
rootSelected={returnFalse}
onClick={script}
onDoubleClick={this.props.layoutDoc.autoPlayAnchors ? undefined : doublescript}