Skip to content

Commit 6b7ede7

Browse files
committed
Replace window.alert() with in-app window
1 parent d09170a commit 6b7ede7

1 file changed

Lines changed: 37 additions & 7 deletions

File tree

pecan/src/components/TimelineBar.tsx

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ function TimelineBar({ plotLayouts = [] }: TimelineBarProps) {
154154
const replayFileInputRef = useRef<HTMLInputElement | null>(null);
155155
const configFileInputRef = useRef<HTMLInputElement | null>(null);
156156

157+
// In-app replacement for native alert() on import — shown as a dismissible
158+
// notice strip below. Success/info auto-dismisses; errors stay until dismissed.
159+
const [importNotice, setImportNotice] = useState<
160+
{ kind: "info" | "error"; message: string } | null
161+
>(null);
162+
useEffect(() => {
163+
if (importNotice?.kind !== "info") return;
164+
const timer = setTimeout(() => setImportNotice(null), 6000);
165+
return () => clearTimeout(timer);
166+
}, [importNotice]);
167+
157168
const handleImportConfigOnly = async (event: React.ChangeEvent<HTMLInputElement>) => {
158169
const file = event.target.files?.[0];
159170
if (!file) return;
@@ -188,13 +199,13 @@ function TimelineBar({ plotLayouts = [] }: TimelineBarProps) {
188199
applied.push("DBC");
189200
}
190201

191-
window.alert(
202+
setImportNotice(
192203
applied.length > 0
193-
? `Config imported: ${applied.join(", ")}`
194-
: "No plot/DBC config found in file."
204+
? { kind: "info", message: `Config imported: ${applied.join(", ")}` }
205+
: { kind: "info", message: "No plot/DBC config found in file." }
195206
);
196207
} catch (err) {
197-
window.alert(`Config import failed: ${err instanceof Error ? err.message : "unknown error"}`);
208+
setImportNotice({ kind: "error", message: `Config import failed: ${err instanceof Error ? err.message : "unknown error"}` });
198209
} finally {
199210
event.target.value = "";
200211
}
@@ -479,7 +490,7 @@ function TimelineBar({ plotLayouts = [] }: TimelineBarProps) {
479490
const parseResult = await parseReplayFile(file);
480491
if (parseResult.errors.length > 0 || parseResult.frames.length === 0) {
481492
const firstError = parseResult.errors[0]?.message ?? "No valid frames found in file.";
482-
window.alert(`Replay import failed: ${firstError}`);
493+
setImportNotice({ kind: "error", message: `Replay import failed: ${firstError}` });
483494
return;
484495
}
485496

@@ -502,11 +513,11 @@ function TimelineBar({ plotLayouts = [] }: TimelineBarProps) {
502513
}
503514

504515
if (parseResult.warnings.length > 0) {
505-
window.alert(`Replay imported with ${parseResult.warnings.length} warning(s).`);
516+
setImportNotice({ kind: "info", message: `Replay imported with ${parseResult.warnings.length} warning(s).` });
506517
}
507518
} catch (error) {
508519
const message = error instanceof Error ? error.message : "Unknown import error";
509-
window.alert(`Replay import failed: ${message}`);
520+
setImportNotice({ kind: "error", message: `Replay import failed: ${message}` });
510521
} finally {
511522
setIsImportingReplay(false);
512523
event.target.value = "";
@@ -595,6 +606,25 @@ function TimelineBar({ plotLayouts = [] }: TimelineBarProps) {
595606
}}
596607
/>
597608
)}
609+
{importNotice && (
610+
<div
611+
className={`flex items-center gap-2 mb-1.5 rounded px-2.5 py-1 text-[11px] border ${
612+
importNotice.kind === "error"
613+
? "bg-red-500/15 border-red-400/40 text-red-300"
614+
: "bg-sky-500/15 border-sky-400/40 text-sky-200"
615+
}`}
616+
>
617+
<span className="flex-1">{importNotice.kind === "error" ? "⚠ " : ""}{importNotice.message}</span>
618+
<button
619+
type="button"
620+
className="font-bold leading-none opacity-70 hover:opacity-100"
621+
onClick={() => setImportNotice(null)}
622+
title="Dismiss"
623+
>
624+
×
625+
</button>
626+
</div>
627+
)}
598628
{coldWarning && (
599629
<div className="flex items-center gap-2 mb-1.5 rounded bg-amber-500/15 border border-amber-400/40 px-2.5 py-1 text-[11px] text-amber-300">
600630
<span className="flex-1">{coldWarning}</span>

0 commit comments

Comments
 (0)