Skip to content

Commit

Permalink
* Fixed a couple errors that can happen when creating a new timeline.…
Browse files Browse the repository at this point in the history
… (and a couple other small issues)

* MS there is a button at the end of the timeline-steps, for adding a new timeline-step. (needed in case there are no existing steps on which to click the "..." button)
  • Loading branch information
Venryx committed Jan 20, 2024
1 parent 4ed0781 commit 8bc6cf8
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 36 deletions.
21 changes: 13 additions & 8 deletions Packages/client/Source/UI/@Shared/Maps/MapGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {useMemo} from "react";
import {Graph, KeyframeInfo} from "tree-grapher";
import {GetMapState, GetPlayingTimeline, GetPlayingTimelineAppliedStepIndex, GetPlayingTimelineRevealNodes_All} from "Store/main/maps/mapStates/$mapState";
import {GetOpenMapID} from "Store/main";
import {GetPercentFromXToY} from "js-vextensions";
import {AssertWarn, GetPercentFromXToY} from "js-vextensions";
import {CatchBail, CreateAccessor} from "web-vcore/.yalc/mobx-graphlink";
import {comparer} from "web-vcore/nm/mobx";
import {ARG_MAX_WIDTH_FOR_IT_AND_ARG_BAR_TO_FIT_BEFORE_PREMISE_TOOLBAR, ARG_MAX_WIDTH_FOR_IT_TO_FIT_BEFORE_PREMISE_TOOLBAR, TOOLBAR_HEIGHT_BASE} from "./Node/NodeLayoutConstants";
Expand All @@ -21,8 +21,10 @@ export class NodeDataForTreeGrapher {
}

const animation_transitionPeriod = .5;
export const GetPercentThroughTransition = (lastKeyframe_time: number, nextKeyframe_time: number, currentTime: number|n)=>{
if (currentTime == null) return 0;
export const GetPercentThroughTransition = (lastKeyframe_time: number|n, nextKeyframe_time: number|n, currentTime: number|n)=>{
//AssertWarn(lastKeyframe_time != null, "lastKeyframe_time must be non-null.");
//AssertWarn(nextKeyframe_time != null, "nextKeyframe_time must be non-null.");
if (lastKeyframe_time == null || nextKeyframe_time == null || currentTime == null) return null;
return GetPercentFromXToY(lastKeyframe_time.KeepAtLeast(nextKeyframe_time - animation_transitionPeriod), nextKeyframe_time, currentTime);
};

Expand All @@ -46,14 +48,17 @@ export const GetTimelineApplyEssentials = CreateAccessor({cache_comparer: compar

const stepTimes = GetTimelineStepTimesFromStart(steps);
const stepsReached = GetTimelineStepsReachedByTimeX(timeline.id, currentTime);
const currentStep_time: number|n = stepTimes[stepsReached.length - 1];
const nextStep_time: number|n = stepTimes[stepsReached.length];
const stepsReachedAtNext = stepsReached.concat(steps[stepsReached.length]);
const currentStep_time: number|null = stepTimes[stepsReached.length - 1];
const nextStep_time: number|null = stepTimes[stepsReached.length];
const stepsReachedAtNext = stepsReached.length < steps.length ? stepsReached.concat(steps[stepsReached.length]) : stepsReached;

return {
mapID, map, mapState, timeline, steps,
//currentTime, // exclude current-time field; this is because we don't know how precisely the caller needs to know this, so we don't want the cache being unnecessarily invalidated all the time
stepTimes, currentStep_time, nextStep_time, stepsReached, stepsReachedAtNext,
stepTimes,
currentStep_time: nextStep_time as number|n, // needs to be redeclared as nullable fsr
nextStep_time: nextStep_time as number|n, // needs to be redeclared as nullable fsr
stepsReached, stepsReachedAtNext,
};
});

Expand All @@ -69,7 +74,7 @@ export function useGraph(forLayoutHelper: boolean, layoutHelperGraph: Graph|null
//const finalKeyframe_time = stepTimes.Last();
const nodePathsVisibleAtNextKeyframe = [map.rootNode].concat(GetVisiblePathsAfterSteps(stepsReachedAtNext));
const layout = layoutHelperGraph!.GetLayout(undefined, group=>RevealPathsIncludesNode(nodePathsVisibleAtNextKeyframe, group.leftColumn_userData?.["nodePath"] as string))!;
const percentThroughTransition = GetPercentThroughTransition(currentStep_time, nextStep_time, currentTime);
const percentThroughTransition = GetPercentThroughTransition(currentStep_time, nextStep_time, currentTime) ?? 0;
return {layout, percentThroughTransition};
};
const mainGraph_getNextKeyframeInfo = ()=>CatchBail(null, mainGraph_getNextKeyframeInfo_base);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const TimelineEffectApplier_Smooth = observer_mgl((props: {map: Map, mapS
const lastFocusNodeRectsMerged = MergeNodeRects(lastFocusNodePaths, lastKeyframe_groupRects);
const nextFocusNodeRectsMerged = MergeNodeRects(nextFocusNodePaths, nextKeyframe_groupRects);
if (lastFocusNodeRectsMerged == null || nextFocusNodeRectsMerged == null) return null;
const percentFromLastToNext = GetPercentThroughTransition(currentStep_time, nextStep_time, mapState.playingTimeline_time);
const percentFromLastToNext = GetPercentThroughTransition(currentStep_time, nextStep_time, mapState.playingTimeline_time) ?? 0;
const focusNodeRects_interpolated = InterpolateRect(lastFocusNodeRectsMerged, nextFocusNodeRectsMerged, percentFromLastToNext);
//console.log("percentFromLastToNext:", percentFromLastToNext);

Expand Down
5 changes: 3 additions & 2 deletions Packages/client/Source/UI/@Shared/Maps/Node/NodeBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import {BaseComponent, BaseComponentPlus, GetDOM, UseCallback, UseEffect} from "
import {useRef_nodeLeftColumn} from "tree-grapher";
import {Row} from "web-vcore/nm/react-vcomponents.js";
import {UseForcedExpandForPath} from "Store/main/maps.js";
import {GetClassForFrameRenderAtTime} from "UI/@Shared/Timelines/TimelinePanel/StepList/RecordDropdown.js";
import {autorun} from "mobx";
import {AutoRun_HandleBail} from "Utils/AutoRuns/@Helpers.js";
import {GetClassForFrameRenderAtTime} from "UI/@Shared/Timelines/TimelinePanel/StepList/RecordDropdown.js";
import {NodeUI_BottomPanel} from "./DetailBoxes/NodeUI_BottomPanel.js";
import {NodeUI_LeftBox} from "./DetailBoxes/NodeUI_LeftBox.js";
import {DefinitionsPanel} from "./DetailBoxes/Panels/DefinitionsPanel.js";
Expand Down Expand Up @@ -151,7 +152,7 @@ export class NodeBox extends BaseComponentPlus(
//const playingTimeline = map ? GetPlayingTimeline(map.id) : null;
UseEffect(()=>{
//if (playingTimeline == null) return;
const dispose = autorun(()=>{
const dispose = AutoRun_HandleBail(()=>{
const nodeRevealHighlightTime = GetNodeRevealHighlightTime();
const timeSinceRevealedByTimeline_simplified = map ? GetTimeSinceNodeRevealedByPlayingTimeline(map.id, path, true, true) : null;
const timeSinceRevealedByTimeline_precise = ()=>(map ? GetTimeSinceNodeRevealedByPlayingTimeline(map.id, path, true, false) : null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class TimelineDetailsUI extends BaseComponentPlus({enabled: true} as {bas
} else {
newData.videoID = null;
}
Change();
}}/>
{newData.videoID != null &&
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {ShowMessageBox} from "react-vmessagebox";
import {autorun} from "web-vcore/nm/mobx";
import {AudioMeta} from "Utils/OPFS/Map/AudioMeta";
import {zIndexes} from "Utils/UI/ZIndexes";
import {AutoRun_HandleBail} from "Utils/AutoRuns/@Helpers";
import {ModifyAudioFileMeta, SetStepClipTimeInAudio} from "./StepList/Editing/StepEditorUI";

class ParseData {
Expand Down Expand Up @@ -83,7 +84,7 @@ export class AudioPanel extends BaseComponent<{map: Map, timeline: Timeline}, {}
ParseWavesurferData();
}
useEffect(()=>{
const dispose = autorun(()=>{
const dispose = AutoRun_HandleBail(()=>{
if (uiState.act_startPlayAtTimeX != -1) {
const targetTime = uiState.act_startPlayAtTimeX;
// avoid recursive loop, by performing action out of call-stack (and thus mobx autorun's observation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {Droppable, DroppableProvided, DroppableStateSnapshot} from "web-vcore/nm
import {AudioFilePlayer} from "./StepList/AudioFilePlayer.js";
import {StepUI} from "./StepList/StepUI.js";
import {RecordDropdown} from "./StepList/RecordDropdown.js";
import {AddTimelineStep_Simple} from "./StepList/Editing/StepEditorUI.js";

// for use by react-beautiful-dnd (using text-replacement/node-modules-patching)
G({LockMapEdgeScrolling});
Expand Down Expand Up @@ -421,6 +422,13 @@ export class StepList extends BaseComponent<{map: Map, timeline: Timeline}, {},
return (
<Column ref={c=>provided.innerRef(GetDOM(c) as any)} {...provided.droppableProps}>
{reactList()}
{steps.length == 0 && !mapState.timelineEditMode && <Row>Switch to edit-mode to add steps.</Row>}
{mapState.timelineEditMode &&
<Row style={{justifyContent: "center"}}>
<Button text="Add timeline step" mt={5} mb={5} enabled={creatorOrMod} onClick={()=>{
AddTimelineStep_Simple(timeline.id, steps, steps.length);
}}/>
</Row>}
</Column>
);
}}
Expand All @@ -442,7 +450,7 @@ export class StepList extends BaseComponent<{map: Map, timeline: Timeline}, {},
const {map, timeline, steps, creatorOrMod} = this.PropsStash;
if (steps == null) return <div key={key}/>;
const step = steps[index];
const nextStep = steps[index + 1];
//const nextStep = steps[index + 1];

//return <StepEditorUI key={step.id} index={index} map={map} timeline={timeline!} step={step} nextStep={nextStep} draggable={creatorOrMod}/>;
return <StepUI key={step.id} index={index} last={index == steps.length - 1} map={map} timeline={timeline} steps={steps} step={step} player={this.player}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ export async function SetStepClipVolume(opfsForMap: OPFS_Map, audioMeta: AudioMe

export type StepEditorUIProps = {index: number, map: Map, timeline: Timeline, step: TimelineStep, nextStep: TimelineStep|n, draggable?: boolean} & {dragInfo?: DragInfo};

export async function AddTimelineStep_Simple(timelineID: string, steps: TimelineStep[], insertIndex: number) {
if (MeID() == null) return ShowSignInPopup();
if (steps == null) return; // steps must still be loading; just ignore the click

// calculate the insert-index to be just after the middle entry of the visible-step-range
/*const visibleStepRange = this.stepList?.getVisibleRange() ?? [steps.length - 1, steps.length - 1];
const insertIndex = Math.floor(visibleStepRange.Average() + 1);*/

const prevStepForInsert = steps[insertIndex - 1];
const nextStepForInsert = steps[insertIndex];

const newStep = new TimelineStep({
timelineID,
orderKey: OrderKey.between(prevStepForInsert?.orderKey, nextStepForInsert?.orderKey).toString(),
groupID: "full",
message: "",
nodeReveals: [],
});
await RunCommand_AddTimelineStep(newStep);
}

@MakeDraggable(({index, step, draggable}: StepEditorUIProps)=>{
if (draggable == false) return undefined as any; // completely disable draggable behavior (see web-vcore/.../DNDHelpers.tsx for more info)
// upgrade note: make sure dnd isn't broken from having to comment the next line out
Expand Down Expand Up @@ -127,26 +148,6 @@ export class StepEditorUI extends BaseComponentPlus({} as StepEditorUIProps, {pl
}

const steps = GetTimelineSteps(timeline.id);
const addStep = (insertIndex: number)=>{
if (MeID() == null) return ShowSignInPopup();
if (steps == null) return; // steps must still be loading; just ignore the click

// calculate the insert-index to be just after the middle entry of the visible-step-range
/*const visibleStepRange = this.stepList?.getVisibleRange() ?? [steps.length - 1, steps.length - 1];
const insertIndex = Math.floor(visibleStepRange.Average() + 1);*/

const prevStepForInsert = steps[insertIndex - 1];
const nextStepForInsert = steps[insertIndex];

const newStep = new TimelineStep({
timelineID: timeline.id,
orderKey: OrderKey.between(prevStepForInsert?.orderKey, nextStepForInsert?.orderKey).toString(),
groupID: "full",
message: "",
nodeReveals: [],
});
RunCommand_AddTimelineStep(newStep);
};

const asDragPreview = dragInfo && dragInfo.snapshot.isDragging;
const result = (
Expand Down Expand Up @@ -223,10 +224,10 @@ export class StepEditorUI extends BaseComponentPlus({} as StepEditorUIProps, {pl
{pos: new Vector2(buttonRect.left, buttonRect.top + buttonRect.height)},
<>
<VMenuItem text="Add step (above)" enabled={creatorOrMod} style={liveSkin.Style_VMenuItem()} onClick={()=>{
addStep(index);
AddTimelineStep_Simple(timeline.id, steps, index);
}}/>
<VMenuItem text="Add step (below)" enabled={creatorOrMod} style={liveSkin.Style_VMenuItem()} onClick={()=>{
addStep(index + 1);
AddTimelineStep_Simple(timeline.id, steps, index + 1);
}}/>
<VMenuItem text="Clone" enabled={creatorOrMod} style={liveSkin.Style_VMenuItem()}
onClick={e=>{
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"tree-grapher": "0.0.8",
"ui-debug-kit": "0.0.7",
"wavesurfer.js": "7.6.0",
"web-vcore": "0.0.94"
"web-vcore": "0.0.95"
},
"packageManager": "yarn@4.0.2"
}

0 comments on commit 8bc6cf8

Please sign in to comment.