mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 16:25:35 +00:00
fix(editor): allow scrolling all audio tracks
Allow timeline content to grow with additional audio rows so the existing scroll container can reach lower tracks.
This commit is contained in:
@@ -60,6 +60,10 @@ import Item from "./Item";
|
||||
import KeyframeMarkers from "./KeyframeMarkers";
|
||||
import Row from "./Row";
|
||||
import TimelineWrapper from "./TimelineWrapper";
|
||||
import {
|
||||
getTimelineContentMinHeightPx,
|
||||
getTimelineRowsMinHeightPx,
|
||||
} from "./timelineLayout";
|
||||
import { type AudioPeaksData, useAudioPeaks } from "./useAudioPeaks";
|
||||
import { buildInteractionZoomSuggestions } from "./zoomSuggestionUtils";
|
||||
|
||||
@@ -702,12 +706,18 @@ function Timeline({
|
||||
).sort((left, right) => getAnnotationTrackIndex(left) - getAnnotationTrackIndex(right)),
|
||||
[annotationItems],
|
||||
);
|
||||
const timelineRowCount = 2 + annotationRowIds.length + audioRowIds.length;
|
||||
const timelineRowsMinHeightPx = getTimelineRowsMinHeightPx(timelineRowCount);
|
||||
const timelineContentMinHeightPx = getTimelineContentMinHeightPx(timelineRowCount);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={setRefs}
|
||||
style={style}
|
||||
className="select-none bg-editor-bg h-full min-h-0 relative cursor-pointer group flex flex-col"
|
||||
style={{
|
||||
...style,
|
||||
minHeight: `max(100%, ${timelineContentMinHeightPx}px)`,
|
||||
}}
|
||||
className="select-none bg-editor-bg relative cursor-pointer group flex flex-col"
|
||||
onClick={handleTimelineClick}
|
||||
>
|
||||
<div className="absolute inset-0 bg-[linear-gradient(to_right,hsl(var(--foreground)/0.03)_1px,transparent_1px)] bg-[length:20px_100%] pointer-events-none" />
|
||||
@@ -720,7 +730,10 @@ function Timeline({
|
||||
keyframes={keyframes}
|
||||
/>
|
||||
|
||||
<div className="relative z-10 flex flex-1 min-h-0 flex-col">
|
||||
<div
|
||||
className="relative z-10 flex flex-1 min-h-0 flex-col"
|
||||
style={{ minHeight: timelineRowsMinHeightPx }}
|
||||
>
|
||||
<Row id={CLIP_ROW_ID} isEmpty={clipItems.length === 0} hint="Press C to split clip">
|
||||
{audioPeaks && <AudioWaveform peaks={audioPeaks} />}
|
||||
<ClipMarkerOverlay videoDurationMs={videoDurationMs} />
|
||||
|
||||
@@ -375,7 +375,7 @@ export default function TimelineWrapper({
|
||||
autoScroll={{ enabled: false }}
|
||||
resizeHandleWidth={28}
|
||||
>
|
||||
<div className="relative h-full min-h-0">
|
||||
<div className="relative min-h-full">
|
||||
{children}
|
||||
{/* Floating tooltip shown during drag/resize */}
|
||||
<div
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
getTimelineContentMinHeightPx,
|
||||
getTimelineRowsMinHeightPx,
|
||||
TIMELINE_AXIS_HEIGHT_PX,
|
||||
TIMELINE_ROW_MIN_HEIGHT_PX,
|
||||
} from "./timelineLayout";
|
||||
|
||||
describe("timelineLayout", () => {
|
||||
it("reserves vertical space for every rendered timeline row", () => {
|
||||
expect(getTimelineRowsMinHeightPx(5)).toBe(5 * TIMELINE_ROW_MIN_HEIGHT_PX);
|
||||
expect(getTimelineContentMinHeightPx(5)).toBe(
|
||||
TIMELINE_AXIS_HEIGHT_PX + 5 * TIMELINE_ROW_MIN_HEIGHT_PX,
|
||||
);
|
||||
});
|
||||
|
||||
it("ignores invalid row counts", () => {
|
||||
expect(getTimelineRowsMinHeightPx(-1)).toBe(0);
|
||||
expect(getTimelineRowsMinHeightPx(Number.NaN)).toBe(0);
|
||||
expect(getTimelineContentMinHeightPx(Number.POSITIVE_INFINITY)).toBe(
|
||||
TIMELINE_AXIS_HEIGHT_PX,
|
||||
);
|
||||
});
|
||||
|
||||
it("floors fractional row counts", () => {
|
||||
expect(getTimelineRowsMinHeightPx(2.9)).toBe(2 * TIMELINE_ROW_MIN_HEIGHT_PX);
|
||||
expect(getTimelineContentMinHeightPx(2.9)).toBe(
|
||||
TIMELINE_AXIS_HEIGHT_PX + 2 * TIMELINE_ROW_MIN_HEIGHT_PX,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
export const TIMELINE_AXIS_HEIGHT_PX = 32;
|
||||
export const TIMELINE_ROW_MIN_HEIGHT_PX = 28;
|
||||
|
||||
function normalizeRowCount(rowCount: number) {
|
||||
if (!Number.isFinite(rowCount)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.max(0, Math.floor(rowCount));
|
||||
}
|
||||
|
||||
export function getTimelineRowsMinHeightPx(rowCount: number) {
|
||||
return normalizeRowCount(rowCount) * TIMELINE_ROW_MIN_HEIGHT_PX;
|
||||
}
|
||||
|
||||
export function getTimelineContentMinHeightPx(rowCount: number) {
|
||||
return TIMELINE_AXIS_HEIGHT_PX + getTimelineRowsMinHeightPx(rowCount);
|
||||
}
|
||||
Reference in New Issue
Block a user