WIP: Add timestamp to comments and fix frontend errors

This commit is contained in:
Mistral Vibe
2026-03-29 22:06:36 +02:00
parent f7a07ba05e
commit a8aba72b3a
6 changed files with 139 additions and 6 deletions

View File

@@ -8,6 +8,13 @@ export interface UseWaveformOptions {
onTimeUpdate?: (currentTime: number) => void;
}
export interface CommentMarker {
id: string;
time: number; // Time in seconds
onClick: () => void;
icon?: string; // URL for the account icon
}
export function useWaveform(
containerRef: React.RefObject<HTMLDivElement>,
options: UseWaveformOptions
@@ -17,6 +24,7 @@ export function useWaveform(
const [isReady, setIsReady] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const wasPlayingRef = useRef(false);
const markersRef = useRef<CommentMarker[]>([]);
useEffect(() => {
if (!containerRef.current || !options.url) return;
@@ -79,10 +87,63 @@ export function useWaveform(
wasPlayingRef.current = false;
};
const seekTo = (time: number) => {
if (wsRef.current && isReady) {
if (wsRef.current && isReady && isFinite(time)) {
wsRef.current.setTime(time);
}
};
return { isPlaying, isReady, currentTime, play, pause, seekTo };
const addMarker = (marker: CommentMarker) => {
if (wsRef.current && isReady) {
const wavesurfer = wsRef.current;
const markerElement = document.createElement("div");
markerElement.style.position = "absolute";
markerElement.style.width = "20px";
markerElement.style.height = "20px";
markerElement.style.borderRadius = "50% ";
markerElement.style.backgroundColor = "var(--accent)";
markerElement.style.cursor = "pointer";
markerElement.style.zIndex = "9999";
markerElement.style.left = `${(marker.time / wavesurfer.getDuration()) * 100}%`;
markerElement.style.transform = "translateX(-50%) translateY(-50%)";
markerElement.style.top = "50% ";
markerElement.title = `Comment at ${formatTime(marker.time)}`;
markerElement.onclick = marker.onClick;
if (marker.icon) {
const iconElement = document.createElement("img");
iconElement.src = marker.icon;
iconElement.style.width = "100% ";
iconElement.style.height = "100% ";
iconElement.style.borderRadius = "50% ";
markerElement.appendChild(iconElement);
}
const waveformContainer = containerRef.current;
if (waveformContainer) {
waveformContainer.style.position = "relative";
waveformContainer.appendChild(markerElement);
}
markersRef.current.push(marker);
}
};
const clearMarkers = () => {
const waveformContainer = containerRef.current;
if (waveformContainer) {
const markerElements = waveformContainer.querySelectorAll("div[title^='Comment at']");
markerElements.forEach((element) => {
waveformContainer.removeChild(element);
});
}
markersRef.current = [];
};
return { isPlaying, isReady, currentTime, play, pause, seekTo, addMarker, clearMarkers };
}
function formatTime(seconds: number): string {
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60);
return `${m}:${String(s).padStart(2, "0")}`;
}