import { useCallback, useEffect, useState } from 'react' import apiFetch from '@wordpress/api-fetch' export interface AutoUpdates { /** Whether WordPress updates the plugin automatically */ enabled: boolean /** False for users who cannot update plugins, and when the host decides */ canChange: boolean } const PATH = '/posten-bring-checkout/auto-updates' /** * Every component following the status on the page, so that turning * automatic updates on in one of them updates the others too, such as the * update notice next to the set-up step that turned them on. */ const followers = new Set<(autoUpdates: AutoUpdates) => void>() const tellFollowers = (autoUpdates: AutoUpdates) => followers.forEach(follow => follow(autoUpdates)) /** * Counts the start and the end of every change, so that a status asked for * before or while it was changed, and answered after, is known to be stale. */ let changes = 0 /** * Follows whether the plugin updates automatically and lets the merchant * turn it on or off. Pages that already know the status, like the order page * that has it prefetched, pass it in instead of asking for it again. */ const useAutoUpdates = (known?: AutoUpdates) => { const [autoUpdates, setAutoUpdates] = useState( known ) const [isSaving, setIsSaving] = useState(false) const [failed, setFailed] = useState(false) useEffect(() => { followers.add(setAutoUpdates) if (!known) { const changesWhenAsked = changes apiFetch({ path: PATH }) .then(status => { if (changes === changesWhenAsked) { tellFollowers(status) } }) .catch(() => undefined) } return () => { followers.delete(setAutoUpdates) } }, []) const turn = useCallback(async (enabled: boolean) => { setIsSaving(true) setFailed(false) changes += 1 try { tellFollowers( await apiFetch({ path: PATH, method: 'POST', data: { enabled }, }) ) } catch (e) { setFailed(true) } finally { changes += 1 setIsSaving(false) } }, []) return { autoUpdates, isSaving, failed, turn } } export default useAutoUpdates