@@ -63,6 +63,7 @@ export function SettingsModal({ onClose, knownIsPrivate }: SettingsModalProps) {
6363 const [ canChangeVisibility , setCanChangeVisibility ] = useState ( true )
6464 const [ isDeleting , setIsDeleting ] = useState ( false )
6565 const [ isSaving , setIsSaving ] = useState ( false )
66+ const prevVisibilityRef = useRef ( localVisibility )
6667
6768 useEffect ( ( ) => {
6869 setLocalName ( templateName )
@@ -116,7 +117,7 @@ export function SettingsModal({ onClose, knownIsPrivate }: SettingsModalProps) {
116117 // onClose is intentionally excluded; we use onCloseRef instead.
117118 } , [ provider , templateId , denyTemplateStorageAccess ] )
118119
119- const handleSave = async ( ) => {
120+ const saveTemplate = async ( opts ?: { closeAfter ?: boolean } ) => {
120121 if ( ! provider || ! localName . trim ( ) || templateStorageWriteBlocked ) return
121122
122123 setIsSaving ( true )
@@ -133,14 +134,18 @@ export function SettingsModal({ onClose, knownIsPrivate }: SettingsModalProps) {
133134 setTemplateId ( saved . id )
134135 setTemplateName ( localName . trim ( ) )
135136 setSyncStatus ( "saved" )
136- onClose ( )
137+ if ( opts ?. closeAfter !== false ) {
138+ onClose ( )
139+ }
137140 } catch ( err ) {
138141 if (
139142 applyTemplateStorageAccessFailure ( err , {
140143 denyTemplateStorageAccess,
141144 } )
142145 ) {
143- onClose ( )
146+ if ( opts ?. closeAfter !== false ) {
147+ onClose ( )
148+ }
144149 return
145150 }
146151 setSyncStatus (
@@ -152,6 +157,18 @@ export function SettingsModal({ onClose, knownIsPrivate }: SettingsModalProps) {
152157 }
153158 }
154159
160+ // Auto-save visibility changes (instant, like template name).
161+ useEffect ( ( ) => {
162+ if ( ! provider || ! templateId ) return
163+ if ( ! canChangeVisibility ) return
164+ if ( isSaving || isDeleting || templateStorageWriteBlocked ) return
165+ const prev = prevVisibilityRef . current
166+ if ( prev === localVisibility ) return
167+ prevVisibilityRef . current = localVisibility
168+ void saveTemplate ( { closeAfter : false } )
169+ // eslint-disable-next-line react-hooks/exhaustive-deps
170+ } , [ localVisibility ] )
171+
155172 const handleDelete = async ( ) => {
156173 if ( ! provider || ! templateId ) return
157174
@@ -355,7 +372,7 @@ export function SettingsModal({ onClose, knownIsPrivate }: SettingsModalProps) {
355372 < Button
356373 colorScheme = "blue"
357374 size = "md"
358- onClick = { handleSave }
375+ onClick = { ( ) => saveTemplate ( { closeAfter : true } ) }
359376 isLoading = { isSaving }
360377 isDisabled = {
361378 ! localName . trim ( ) || isDeleting || templateStorageWriteBlocked
0 commit comments