Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 155 lines 3.6 kB view raw
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}