@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
33import Button from './Button' ;
44import { DownloadIcon , XIcon , CheckIcon , InfoIcon } from './Icons' ;
55import IconButton from './IconButton' ;
6+ import ToggleSwitch from './ToggleSwitch' ;
67import { useLogger } from '../hooks/useLogger' ;
78
89type UpdateNotificationStatus = 'downloading' | 'downloaded' | 'error' ;
@@ -16,6 +17,9 @@ interface UpdateNotificationProps {
1617 errorMessage ?: string | null ;
1718 errorDetails ?: string | null ;
1819 onInstall ?: ( ) => void ;
20+ autoInstallEnabled ?: boolean ;
21+ autoInstallSupported ?: boolean ;
22+ onAutoInstallChange ?: ( enabled : boolean ) => void ;
1923 onClose : ( ) => void ;
2024}
2125
@@ -46,6 +50,9 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({
4650 errorMessage,
4751 errorDetails,
4852 onInstall,
53+ autoInstallEnabled,
54+ autoInstallSupported = true ,
55+ onAutoInstallChange,
4956 onClose,
5057} ) => {
5158 const { addLog } = useLogger ( ) ;
@@ -95,6 +102,14 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({
95102 }
96103 } ;
97104
105+ const handleAutoInstallToggle = ( value : boolean ) => {
106+ if ( ! onAutoInstallChange ) {
107+ return ;
108+ }
109+ addLog ( 'INFO' , `User action: ${ value ? 'Enabled' : 'Disabled' } automatic update installation from toast.` ) ;
110+ onAutoInstallChange ( value ) ;
111+ } ;
112+
98113 const renderContent = ( ) => {
99114 if ( status === 'downloaded' ) {
100115 return (
@@ -103,6 +118,36 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({
103118 < p className = "text-sm text-text-secondary mt-1" >
104119 DocForge version < span className = "font-semibold text-text-main" > { versionLabel } </ span > has been downloaded and is ready to go.
105120 </ p >
121+ { typeof autoInstallEnabled === 'boolean' && (
122+ < div className = "mt-4 space-y-3 rounded-lg border border-border-color/70 bg-background/40 p-4" >
123+ < div className = "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between" >
124+ < div className = "space-y-1" >
125+ < p className = "text-sm font-semibold text-text-main" > Install updates automatically</ p >
126+ < p className = "text-xs text-text-secondary" >
127+ { autoInstallSupported
128+ ? 'DocForge will apply the update the next time you quit if this switch stays on.'
129+ : 'Automatic installation is only available in the desktop app.' }
130+ </ p >
131+ </ div >
132+ < ToggleSwitch
133+ id = "update-auto-install"
134+ checked = { autoInstallSupported ? autoInstallEnabled : false }
135+ disabled = { ! autoInstallSupported }
136+ onChange = { handleAutoInstallToggle }
137+ />
138+ </ div >
139+ { autoInstallSupported && ! autoInstallEnabled && (
140+ < p className = "text-xs text-warning" >
141+ Auto-install is off. You'll need to restart DocForge manually to finish this update.
142+ </ p >
143+ ) }
144+ { ! autoInstallSupported && (
145+ < p className = "text-xs text-text-secondary" >
146+ Switch to the desktop application to control automatic installation.
147+ </ p >
148+ ) }
149+ </ div >
150+ ) }
106151 < div className = "mt-4 flex gap-3" >
107152 { onInstall && (
108153 < Button onClick = { handleInstall } variant = "primary" className = "flex-1" >
0 commit comments