mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {useMemo} from 'react' 2 3import {useNux, useSaveNux} from '#/state/queries/nuxs' 4import {ACTIVE_UPDATE_ID} from '#/components/PolicyUpdateOverlay/config' 5import {logger} from '#/components/PolicyUpdateOverlay/logger' 6import {IS_DEV} from '#/env' 7import {device, useStorage} from '#/storage' 8 9export type PolicyUpdateState = { 10 completed: boolean 11 complete: () => void 12} 13 14export function usePolicyUpdateState({ 15 enabled, 16}: { 17 /** 18 * Used to skip the policy update overlay until we're actually ready to 19 * show it. 20 */ 21 enabled: boolean 22}) { 23 const nux = useNux(ACTIVE_UPDATE_ID) 24 const {mutate: save, variables} = useSaveNux() 25 const deviceStorage = useStorage(device, [ACTIVE_UPDATE_ID]) 26 const debugOverride = 27 !!useStorage(device, ['policyUpdateDebugOverride'])[0] && IS_DEV 28 29 return useMemo(() => { 30 /** 31 * If not enabled, then just return a completed state so the app functions 32 * as normal. 33 */ 34 if (!enabled) { 35 return { 36 completed: true, 37 complete() {}, 38 } 39 } 40 41 const nuxIsReady = nux.status === 'ready' 42 const nuxIsCompleted = nux.nux?.completed === true 43 const nuxIsOptimisticallyCompleted = !!variables?.completed 44 const [completedForDevice, setCompletedForDevice] = deviceStorage 45 46 const completed = computeCompletedState({ 47 nuxIsReady, 48 nuxIsCompleted, 49 nuxIsOptimisticallyCompleted, 50 completedForDevice, 51 }) 52 53 logger.debug(`state`, { 54 completed, 55 nux, 56 completedForDevice, 57 }) 58 59 if (!debugOverride) { 60 syncCompletedState({ 61 nuxIsReady, 62 nuxIsCompleted, 63 nuxIsOptimisticallyCompleted, 64 completedForDevice, 65 save, 66 setCompletedForDevice, 67 }) 68 } 69 70 return { 71 completed, 72 complete() { 73 logger.debug(`user completed`) 74 save({ 75 id: ACTIVE_UPDATE_ID, 76 completed: true, 77 data: undefined, 78 }) 79 setCompletedForDevice(true) 80 }, 81 } 82 }, [enabled, nux, save, variables, deviceStorage, debugOverride]) 83} 84 85export function computeCompletedState({ 86 nuxIsReady, 87 nuxIsCompleted, 88 nuxIsOptimisticallyCompleted, 89 completedForDevice, 90}: { 91 nuxIsReady: boolean 92 nuxIsCompleted: boolean 93 nuxIsOptimisticallyCompleted: boolean 94 completedForDevice: boolean | undefined 95}): boolean { 96 /** 97 * Assume completed to prevent flash 98 */ 99 let completed = true 100 101 /** 102 * Prefer server state, if available 103 */ 104 if (nuxIsReady) { 105 completed = nuxIsCompleted 106 } 107 108 /** 109 * Override with optimistic state or device state 110 */ 111 if (nuxIsOptimisticallyCompleted || !!completedForDevice) { 112 completed = true 113 } 114 115 return completed 116} 117 118export function syncCompletedState({ 119 nuxIsReady, 120 nuxIsCompleted, 121 nuxIsOptimisticallyCompleted, 122 completedForDevice, 123 save, 124 setCompletedForDevice, 125}: { 126 nuxIsReady: boolean 127 nuxIsCompleted: boolean 128 nuxIsOptimisticallyCompleted: boolean 129 completedForDevice: boolean | undefined 130 save: ReturnType<typeof useSaveNux>['mutate'] 131 setCompletedForDevice: (value: boolean) => void 132}) { 133 /* 134 * Sync device state to server state for this account 135 */ 136 if ( 137 nuxIsReady && 138 !nuxIsCompleted && 139 !nuxIsOptimisticallyCompleted && 140 !!completedForDevice 141 ) { 142 logger.debug(`syncing device state to server state`) 143 save({ 144 id: ACTIVE_UPDATE_ID, 145 completed: true, 146 data: undefined, 147 }) 148 } else if (nuxIsReady && nuxIsCompleted && !completedForDevice) { 149 logger.debug(`syncing server state to device state`) 150 /* 151 * Sync server state to device state 152 */ 153 setCompletedForDevice(true) 154 } 155}