WIP: Add timestamp to comments and fix frontend errors
This commit is contained in:
@@ -14,6 +14,7 @@ interface SongComment {
|
||||
author_id: string;
|
||||
author_name: string;
|
||||
created_at: string;
|
||||
timestamp: number; // Timestamp in seconds
|
||||
}
|
||||
|
||||
export function SongPage() {
|
||||
@@ -37,7 +38,7 @@ export function SongPage() {
|
||||
enabled: !!activeVersion,
|
||||
});
|
||||
|
||||
const { isPlaying, currentTime, play, pause, seekTo } = useWaveform(waveformRef, {
|
||||
const { isPlaying, currentTime, play, pause, seekTo, addMarker, clearMarkers } = useWaveform(waveformRef, {
|
||||
url: activeVersion ? `/api/v1/versions/${activeVersion}/stream` : null,
|
||||
peaksUrl: activeVersion ? `/api/v1/versions/${activeVersion}/waveform` : null,
|
||||
});
|
||||
@@ -59,12 +60,40 @@ export function SongPage() {
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [isPlaying, play, pause]);
|
||||
|
||||
const { data: comments } = useQuery({
|
||||
const { data: comments } = useQuery<SongComment[]>({
|
||||
queryKey: ["comments", songId],
|
||||
queryFn: () => api.get<SongComment[]>(`/songs/${songId}/comments`),
|
||||
enabled: !!songId,
|
||||
});
|
||||
|
||||
// Scroll to comment when a marker is clicked
|
||||
const scrollToComment = (commentId: string) => {
|
||||
const commentElement = document.getElementById(`comment-${commentId}`);
|
||||
if (commentElement) {
|
||||
commentElement.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
commentElement.style.backgroundColor = "var(--accent-bg)";
|
||||
setTimeout(() => {
|
||||
commentElement.style.backgroundColor = "var(--bg-subtle)";
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (comments) {
|
||||
clearMarkers();
|
||||
comments.forEach((comment) => {
|
||||
if (comment.timestamp !== undefined && comment.timestamp !== null) {
|
||||
addMarker({
|
||||
id: comment.id,
|
||||
time: comment.timestamp,
|
||||
onClick: () => scrollToComment(comment.id),
|
||||
icon: "https://via.placeholder.com/20", // Replace with actual user icon URL
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [comments, addMarker, clearMarkers]);
|
||||
|
||||
const addCommentMutation = useMutation({
|
||||
mutationFn: (body: string) => api.post(`/songs/${songId}/comments`, { body }),
|
||||
onSuccess: () => {
|
||||
@@ -131,6 +160,13 @@ export function SongPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Current Play Time Display */}
|
||||
<div style={{ marginBottom: 16, textAlign: "center" }}>
|
||||
<span style={{ color: "var(--text-muted)", fontSize: 14, fontFamily: "monospace" }}>
|
||||
Current Time: {formatTime(currentTime)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Annotations */}
|
||||
<div style={{ display: "grid", gap: 8, marginBottom: 32 }}>
|
||||
{annotations?.map((a) => (
|
||||
@@ -144,7 +180,7 @@ export function SongPage() {
|
||||
|
||||
<div style={{ display: "grid", gap: 8, marginBottom: 16 }}>
|
||||
{comments?.map((c) => (
|
||||
<div key={c.id} style={{ background: "var(--bg-subtle)", border: "1px solid var(--border)", borderRadius: 8, padding: "12px 16px" }}>
|
||||
<div id={`comment-${c.id}`} key={c.id} style={{ background: "var(--bg-subtle)", border: "1px solid var(--border)", borderRadius: 8, padding: "12px 16px" }}>
|
||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6 }}>
|
||||
<span style={{ fontWeight: 600, fontSize: 13, color: "var(--text)" }}>{c.author_name}</span>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
||||
@@ -157,6 +193,16 @@ export function SongPage() {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{c.timestamp !== undefined && c.timestamp !== null && (
|
||||
<div style={{ display: "flex", gap: 8, marginBottom: 6 }}>
|
||||
<button
|
||||
onClick={() => seekTo(c.timestamp)}
|
||||
style={{ background: "var(--accent-bg)", border: "1px solid var(--accent)", borderRadius: 4, color: "var(--accent)", cursor: "pointer", fontSize: 10, padding: "2px 8px", fontFamily: "monospace" }}
|
||||
>
|
||||
{formatTime(c.timestamp)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<p style={{ margin: 0, fontSize: 13, color: "var(--text)", lineHeight: 1.5 }}>{c.body}</p>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user