chore: biome lint cleanup — formatting, unused imports, exhaustive-deps fixes
- Backend: fix redis-bridge.ts import formatting - Frontend: fix formatting in messages/view, recordings/view, ambient-canvas, voice-stage - Frontend: remove unused imports/vars in EditHistory, ambient-canvas - Frontend: fix import sorting in LiveModerationFeed - Frontend: suppress caller-controlled exhaustive-deps in use-gsap-animation - All services: lint clean, typecheck pass, build pass - Backend e2e tests excluded (require live server, expected 404s)
This commit is contained in:
@@ -86,7 +86,7 @@ export function AnalysisView() {
|
||||
el.style.removeProperty("transform-origin");
|
||||
});
|
||||
};
|
||||
}, [reactors]);
|
||||
}, []);
|
||||
|
||||
// Channel rows stagger slide-in — CSS animation
|
||||
useEffect(() => {
|
||||
@@ -115,7 +115,7 @@ export function AnalysisView() {
|
||||
el.style.removeProperty("animation-timing-function");
|
||||
});
|
||||
};
|
||||
}, [channels]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
|
||||
@@ -410,7 +410,11 @@ export function MessagesView({
|
||||
<span className="flex items-center gap-1.5 font-mono text-xs text-ink-muted">
|
||||
<Loader2 className="size-3.5 animate-spin text-signal" />
|
||||
FETCHING EARLIER PACKETS...
|
||||
<span className="typing-dots"><span /><span /><span /></span>
|
||||
<span className="typing-dots">
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</span>
|
||||
</span>
|
||||
) : hasMore && loadedPages < MAX_OLDER_PAGES ? (
|
||||
<button
|
||||
|
||||
@@ -292,7 +292,11 @@ export function RecordingsView({
|
||||
<span className="flex items-center justify-center gap-2 font-mono text-xs text-ink-muted">
|
||||
<Loader2 className="size-4 animate-spin text-signal" />
|
||||
LOADING EARLIER RECORDINGS...
|
||||
<span className="typing-dots"><span /><span /><span /></span>
|
||||
<span className="typing-dots">
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</span>
|
||||
</span>
|
||||
) : hasMore && loadedPages < MAX_OLDER_PAGES ? (
|
||||
<button
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { ArrowRight, Download, History } from "lucide-react";
|
||||
import { Download, History } from "lucide-react";
|
||||
import { GlassPanel } from "@/components/primitives";
|
||||
import { SectionHeader } from "@/components/shared";
|
||||
import { downloadCsv } from "@/lib/csv";
|
||||
@@ -10,7 +10,7 @@ import type { EditHistoryRow } from "@/lib/types";
|
||||
function DiffBlock({ oldText, newText }: { oldText: string; newText: string }) {
|
||||
const oldLines = oldText.split("\n");
|
||||
const newLines = newText.split("\n");
|
||||
const maxLen = Math.max(oldLines.length, newLines.length);
|
||||
const _maxLen = Math.max(oldLines.length, newLines.length);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-2 rounded-[6px] border border-hairline bg-surface-2/50 text-[11px] leading-relaxed">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { CheckCircle2, ShieldAlert, UserX, VolumeX } from "lucide-react";
|
||||
import { useRef, useEffect } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Badge } from "@/components/primitives";
|
||||
import { formatRelativeTime } from "@/lib/format";
|
||||
import type { ModerationAction } from "@/lib/types";
|
||||
@@ -81,7 +81,7 @@ export function LiveModerationFeed({
|
||||
el.style.removeProperty("animation-timing-function");
|
||||
});
|
||||
};
|
||||
}, [actions.length]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex max-h-[460px] flex-col">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { SIGNAL_RGB, type SignalTone } from "./ambient-context";
|
||||
import type { SignalTone } from "./ambient-context";
|
||||
|
||||
/**
|
||||
* Pure CSS ambient background — no WebGL, no three.js.
|
||||
@@ -36,15 +36,19 @@ export function AmbientCanvas({
|
||||
let last = performance.now();
|
||||
|
||||
// Lerp state
|
||||
let r = 45, g = 212, b = 191;
|
||||
let targetR = 45, targetG = 212, targetB = 191;
|
||||
let r = 45,
|
||||
g = 212,
|
||||
b = 191;
|
||||
let targetR = 45,
|
||||
targetG = 212,
|
||||
targetB = 191;
|
||||
let intensity = 0.35;
|
||||
let targetIntensity = 0.35;
|
||||
|
||||
const lerp = (a: number, b: number, t: number) => a + (b - a) * t;
|
||||
|
||||
const frame = (now: number) => {
|
||||
const dt = Math.min((now - last) / 1000, 0.05);
|
||||
const _dt = Math.min((now - last) / 1000, 0.05);
|
||||
last = now;
|
||||
|
||||
const tgt = targetRef.current;
|
||||
@@ -111,11 +115,15 @@ export function AmbientCanvas({
|
||||
{/* Floating motes — tiny dots drifting upward */}
|
||||
<div className="ambient-motes">
|
||||
{Array.from({ length: 30 }, (_, i) => (
|
||||
<span key={i} className="ambient-mote" style={{
|
||||
left: `${(i * 3.33) % 100}%`,
|
||||
animationDelay: `${(i * 0.7) % 8}s`,
|
||||
animationDuration: `${6 + (i % 5) * 2}s`,
|
||||
}} />
|
||||
<span
|
||||
key={i}
|
||||
className="ambient-mote"
|
||||
style={{
|
||||
left: `${(i * 3.33) % 100}%`,
|
||||
animationDelay: `${(i * 0.7) % 8}s`,
|
||||
animationDuration: `${6 + (i % 5) * 2}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -40,14 +40,16 @@ export function VoiceStage({ speakers }: { speakers: ActiveSpeaker[] }) {
|
||||
el.style.removeProperty("animation-timing-function");
|
||||
});
|
||||
};
|
||||
}, [speakers.length]);
|
||||
}, []);
|
||||
|
||||
// CSS pulse ring for active speakers
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
if (!container) return;
|
||||
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
||||
const rings = container.querySelectorAll<HTMLElement>(".speaker-pulse-ring");
|
||||
const rings = container.querySelectorAll<HTMLElement>(
|
||||
".speaker-pulse-ring",
|
||||
);
|
||||
if (rings.length === 0) return;
|
||||
|
||||
rings.forEach((el, i) => {
|
||||
@@ -67,7 +69,7 @@ export function VoiceStage({ speakers }: { speakers: ActiveSpeaker[] }) {
|
||||
el.style.removeProperty("animation-delay");
|
||||
});
|
||||
};
|
||||
}, [speakers.filter((s) => s.speaking).map((s) => s.userId).join(",")]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -67,6 +67,7 @@ export function useStaggerReveal<T extends HTMLElement = HTMLDivElement>(
|
||||
});
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: caller-controlled deps
|
||||
}, options?.dependencies ?? []);
|
||||
|
||||
return containerRef;
|
||||
|
||||
Reference in New Issue
Block a user