@@ -42,12 +42,16 @@ export function ShareModal({
4242 const saved = share ?? initialShare ?? null
4343 const savedActive = saved ?. isActive ?? false
4444
45- const [ draftActive , setDraftActive ] = useState ( initialShare ?. isActive ?? false )
46- const isDirty = draftActive !== savedActive
45+ // `null` until the user toggles, so the switch always reflects the authoritative
46+ // saved state (which may resolve after mount via useFileShare) instead of a stale
47+ // initial snapshot — otherwise a Save could silently flip sharing the wrong way.
48+ const [ draftActive , setDraftActive ] = useState < boolean | null > ( null )
49+ const effectiveActive = draftActive ?? savedActive
50+ const isDirty = draftActive !== null && draftActive !== savedActive
4751
4852 const handleSave = ( ) => {
4953 upsertShare . mutate (
50- { workspaceId, fileId, isActive : draftActive } ,
54+ { workspaceId, fileId, isActive : effectiveActive } ,
5155 { onSuccess : ( ) => onOpenChange ( false ) }
5256 )
5357 }
@@ -62,15 +66,15 @@ export function ShareModal({
6266 type = 'custom'
6367 title = 'Access'
6468 hint = {
65- draftActive
69+ effectiveActive
6670 ? isDirty
6771 ? 'Save to make this file accessible to anyone with the link.'
6872 : 'Anyone with the link can view and download this file.'
6973 : 'Only workspace members can access this file.'
7074 }
7175 >
7276 < ChipSwitch
73- value = { draftActive ? 'public' : 'private' }
77+ value = { effectiveActive ? 'public' : 'private' }
7478 onChange = { ( value ) => setDraftActive ( value === 'public' ) }
7579 options = { VISIBILITY_OPTIONS }
7680 aria-label = 'File access'
0 commit comments