fix: add onCleanup for setTimeout in frontend pages

Prevents timers from firing after component unmount in Home (delete
confirmation timers), ArticleHistory (clear confirmation timer), and
SynthesisDetail (email success banner timer).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
master
oabrivard 3 months ago
parent 24d53a01d1
commit 5a66443a94

@ -2,6 +2,7 @@ import {
type Component,
createSignal,
onMount,
onCleanup,
Show,
For,
createEffect,
@ -56,6 +57,12 @@ const ArticleHistory: Component = () => {
const [filterSourceType, setFilterSourceType] = createSignal('');
const [page, setPage] = createSignal(0);
const [confirming, setConfirming] = createSignal(false);
const [confirmTimer, setConfirmTimer] = createSignal<ReturnType<typeof setTimeout> | undefined>();
onCleanup(() => {
const t = confirmTimer();
if (t) clearTimeout(t);
});
const totalPages = () => Math.max(1, Math.ceil(total() / PAGE_SIZE));
@ -92,7 +99,7 @@ const ArticleHistory: Component = () => {
const handleClear = async () => {
if (!confirming()) {
setConfirming(true);
setTimeout(() => setConfirming(false), 3000);
setConfirmTimer(setTimeout(() => setConfirming(false), 3000));
return;
}
try {

@ -2,6 +2,7 @@ import {
type Component,
createSignal,
onMount,
onCleanup,
Show,
For,
} from 'solid-js';
@ -32,6 +33,11 @@ const Home: Component = () => {
const [deletingId, setDeletingId] = createSignal<string | null>(null);
const [deleteTimers, setDeleteTimers] = createSignal<Record<string, ReturnType<typeof setTimeout>>>({});
onCleanup(() => {
const timers = deleteTimers();
Object.values(timers).forEach((timer) => clearTimeout(timer));
});
onMount(async () => {
try {
const data = await synthesesApi.list();

@ -2,6 +2,7 @@ import {
type Component,
createSignal,
onMount,
onCleanup,
Show,
For,
} from 'solid-js';
@ -83,6 +84,12 @@ const SynthesisDetail: Component = () => {
const [sendingEmail, setSendingEmail] = createSignal(false);
const [emailSuccess, setEmailSuccess] = createSignal(false);
const [emailError, setEmailError] = createSignal<string | null>(null);
const [emailTimer, setEmailTimer] = createSignal<ReturnType<typeof setTimeout> | undefined>();
onCleanup(() => {
const t = emailTimer();
if (t) clearTimeout(t);
});
// Export state
const [exportingMarkdown, setExportingMarkdown] = createSignal(false);
@ -147,7 +154,7 @@ const SynthesisDetail: Component = () => {
try {
await synthesesApi.sendEmail(synth.id, email());
setEmailSuccess(true);
setTimeout(() => setEmailSuccess(false), 5000);
setEmailTimer(setTimeout(() => setEmailSuccess(false), 5000));
} catch (err) {
if (isApiError(err)) {
setEmailError(err.message);

Loading…
Cancel
Save