Skip to content

Commit 0cdc7bb

Browse files
authored
fix: add sentinel value to track positions for insert-after-last insertion (#80)
1 parent c5992c7 commit 0cdc7bb

2 files changed

Lines changed: 13 additions & 7 deletions

File tree

src/components/timeline/interaction/interaction-calculations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export function buildTrackYPositions(tracks: readonly TrackState[]): number[] {
9393
positions.push(y);
9494
y += getTrackHeight(track.primaryAssetType);
9595
}
96+
positions.push(y); // sentinel: total height for "insert after last track"
9697
return positions;
9798
}
9899

tests/interaction-calculations.test.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,21 @@ describe("formatDragTime", () => {
118118

119119
describe("Track Y Position Calculations", () => {
120120
describe("buildTrackYPositions", () => {
121-
it("returns empty array for no tracks", () => {
122-
expect(buildTrackYPositions([])).toEqual([]);
121+
it("returns sentinel-only array for no tracks", () => {
122+
expect(buildTrackYPositions([])).toEqual([0]);
123123
});
124124

125125
it("calculates positions for image tracks (72px height)", () => {
126126
const tracks: TrackState[] = [createMockTrack([createMockClip(0, 1)], "image"), createMockTrack([createMockClip(0, 1, "image", 1)], "image")];
127-
expect(buildTrackYPositions(tracks)).toEqual([0, 72]);
127+
expect(buildTrackYPositions(tracks)).toEqual([0, 72, 144]);
128128
});
129129

130130
it("calculates positions for audio tracks (48px height)", () => {
131131
const tracks: TrackState[] = [
132132
createMockTrack([createMockClip(0, 1, "audio")], "audio"),
133133
createMockTrack([createMockClip(0, 1, "audio", 1)], "audio")
134134
];
135-
expect(buildTrackYPositions(tracks)).toEqual([0, 48]);
135+
expect(buildTrackYPositions(tracks)).toEqual([0, 48, 96]);
136136
});
137137

138138
it("handles mixed track types", () => {
@@ -141,20 +141,25 @@ describe("Track Y Position Calculations", () => {
141141
createMockTrack([createMockClip(0, 1, "audio", 1)], "audio") // 48px
142142
];
143143
const positions = buildTrackYPositions(tracks);
144-
expect(positions).toEqual([0, 72]); // Second track starts at 72
144+
expect(positions).toEqual([0, 72, 120]); // Sentinel at 72 + 48 = 120
145145
});
146146
});
147147

148148
describe("getTrackYPosition", () => {
149149
it("returns correct position from cache", () => {
150-
const cache = [0, 60, 120];
150+
const cache = [0, 60, 120, 180]; // includes sentinel
151151
expect(getTrackYPosition(0, cache)).toBe(0);
152152
expect(getTrackYPosition(1, cache)).toBe(60);
153153
expect(getTrackYPosition(2, cache)).toBe(120);
154154
});
155155

156+
it("returns sentinel position for insert-after-last index", () => {
157+
const cache = [0, 60, 120]; // 2 tracks + sentinel at 120
158+
expect(getTrackYPosition(2, cache)).toBe(120);
159+
});
160+
156161
it("returns 0 for out of bounds index", () => {
157-
const cache = [0, 60];
162+
const cache = [0, 60, 120]; // 2 tracks + sentinel
158163
expect(getTrackYPosition(5, cache)).toBe(0);
159164
});
160165
});

0 commit comments

Comments
 (0)