diff --git a/src/contentScript/index.ts b/src/contentScript/index.ts index 5026b30..df63ad6 100644 --- a/src/contentScript/index.ts +++ b/src/contentScript/index.ts @@ -8,6 +8,7 @@ import { doesUrlMatchPatterns } from '../shared/url' const BLOCK_DATA_STATUS = 'coderchartStatus' const BLOCK_DATA_SOURCE = 'coderchartSource' const PNG_PREPARING_LABEL = 'Preparing PNG…' +const PROMPT_RESET_DELAY_MS = 2000 let diagramCounter = 0 let blockIdentifierCounter = 0 let observer: MutationObserver | null = null @@ -737,9 +738,10 @@ function createErrorNotice(doc: Document, err: unknown, source: string): HTMLEle } setTimeout(() => { + if (!promptButton.isConnected) return promptButton.disabled = false promptButton.textContent = defaultLabel - }, 2000) + }, PROMPT_RESET_DELAY_MS) }) promptSection.append(promptButton, promptStatus, promptPreview) diff --git a/src/options/Options.tsx b/src/options/Options.tsx index 0fba4b7..dc5e8b8 100644 --- a/src/options/Options.tsx +++ b/src/options/Options.tsx @@ -1,4 +1,4 @@ -import { FormEvent, useEffect, useMemo, useState } from 'react' +import { FormEvent, useEffect, useMemo, useRef, useState } from 'react' import { DEFAULT_SETTINGS, ExtensionSettings, getSettings, saveSettings, normalizeSettings } from '../shared/settings' import './Options.css' @@ -6,12 +6,14 @@ import './Options.css' type SaveStatus = 'idle' | 'saving' | 'saved' | 'error' const defaultState = cloneSettings(DEFAULT_SETTINGS) +const SAVE_STATUS_RESET_DELAY_MS = 2400 export const Options = () => { const [settings, setSettings] = useState(defaultState) const [newPattern, setNewPattern] = useState('') const [status, setStatus] = useState('idle') const [errorMessage, setErrorMessage] = useState(null) + const resetStatusTimeout = useRef(null) useEffect(() => { let mounted = true @@ -31,6 +33,14 @@ export const Options = () => { } }, []) + useEffect(() => { + return () => { + if (resetStatusTimeout.current !== null) { + window.clearTimeout(resetStatusTimeout.current) + } + } + }, []) + const normalizedPatterns = useMemo(() => settings.hostPatterns.map((pattern) => pattern.trim()), [settings.hostPatterns]) const canAddPattern = useMemo(() => { @@ -74,6 +84,10 @@ export const Options = () => { const handleSubmit = async (event: FormEvent) => { event.preventDefault() + if (resetStatusTimeout.current !== null) { + window.clearTimeout(resetStatusTimeout.current) + resetStatusTimeout.current = null + } setStatus('saving') setErrorMessage(null) try { @@ -81,9 +95,10 @@ export const Options = () => { await saveSettings(normalized) setSettings(cloneSettings(normalized)) setStatus('saved') - setTimeout(() => { + resetStatusTimeout.current = window.setTimeout(() => { setStatus('idle') - }, 2400) + resetStatusTimeout.current = null + }, SAVE_STATUS_RESET_DELAY_MS) } catch (error) { console.error('Failed to save settings', error) setStatus('error')