test
1 week ago
useCompleteOnboarding.js
1 week ago
useDateRangePicker.js
1 month ago
useEmail.ts
1 month ago
useEngagementChartData.js
1 month ago
useLicenseSettings.js
1 month ago
useLink.js
1 month ago
useMediaDetail.js
1 month ago
useMediaLibrary.js
1 month ago
useMediaList.ts
1 month ago
usePerformanceSettings.js
1 month ago
useRegisterActivePage.js
1 month ago
useSettingOption.js
1 month ago
useSimpleSettingsPage.js
1 month ago
useTopPerforming.js
1 month ago
useTopVideosPaginated.js
1 month ago
useUpgradeCTA.js
1 month ago
useUserDetail.js
1 month ago
useSettingOption.js
56 lines
| 1 | import { useCallback, useMemo } from 'react'; |
| 2 | import isEqual from 'lodash/isEqual'; |
| 3 | import { useSettingsData } from '../pages/settings/shared/SettingsDataProvider'; |
| 4 | |
| 5 | const useSettingOption = ( optionKey, defaultValue ) => { |
| 6 | const { |
| 7 | settings, |
| 8 | lastSaved, |
| 9 | isLoading, |
| 10 | savingKeys, |
| 11 | updateLocal, |
| 12 | resetKey, |
| 13 | saveSlice, |
| 14 | } = useSettingsData(); |
| 15 | |
| 16 | // WP core's /wp/v2/settings returns `null` for any stored value that fails |
| 17 | // its registered schema (e.g. an empty string stored for a `boolean` option). |
| 18 | // Treat null the same as undefined so the UI falls back to the default and |
| 19 | // saves don't echo that null back — which WP rejects with |
| 20 | // `rest_invalid_stored_value`. |
| 21 | const rawData = settings?.[ optionKey ]; |
| 22 | const data = |
| 23 | rawData === undefined || rawData === null ? defaultValue : rawData; |
| 24 | |
| 25 | const savedValue = lastSaved?.[ optionKey ]; |
| 26 | const effectiveSaved = |
| 27 | savedValue === undefined || savedValue === null |
| 28 | ? defaultValue |
| 29 | : savedValue; |
| 30 | |
| 31 | const setData = useCallback( |
| 32 | ( next ) => updateLocal( optionKey, next ), |
| 33 | [ optionKey, updateLocal ] |
| 34 | ); |
| 35 | |
| 36 | const save = useCallback( () => saveSlice( [ optionKey ] ), [ saveSlice, optionKey ] ); |
| 37 | const reset = useCallback( () => resetKey( optionKey ), [ resetKey, optionKey ] ); |
| 38 | |
| 39 | // Derived (not a flag): typing + reverting is cleanly not-dirty, and pasting |
| 40 | // identical content doesn't falsely mark the page dirty. Deep equality is |
| 41 | // required because most option values are objects (e.g. branding, bunny_stream). |
| 42 | const isDirty = useMemo( |
| 43 | () => ! isEqual( data, effectiveSaved ), |
| 44 | [ data, effectiveSaved ] |
| 45 | ); |
| 46 | |
| 47 | const isSaving = savingKeys.has( optionKey ); |
| 48 | |
| 49 | return useMemo( |
| 50 | () => ( { data, setData, save, reset, isDirty, isSaving, isLoading } ), |
| 51 | [ data, setData, save, reset, isDirty, isSaving, isLoading ] |
| 52 | ); |
| 53 | }; |
| 54 | |
| 55 | export default useSettingOption; |
| 56 |