@@ -32,9 +32,23 @@ public partial class BackupViewModel : ViewModelBase, IDisposable
3232 ] ;
3333
3434 /* ── Local backup ── */
35- [ ObservableProperty ] private bool _isLocalBackupEnabled ;
35+ [ ObservableProperty , NotifyPropertyChangedFor ( nameof ( IsBackupRetentionAvailable ) ) ] private bool _isLocalBackupEnabled ;
36+ [ ObservableProperty , NotifyPropertyChangedFor ( nameof ( IsBackupRetentionAvailable ) ) ] private bool _isBackupTimestampingEnabled ;
37+ [ ObservableProperty ] private bool _isCustomBackupCountSelected ;
3638 [ ObservableProperty ] private string _backupDirectoryLabel = "" ;
3739
40+ public bool IsBackupRetentionAvailable => IsLocalBackupEnabled && IsBackupTimestampingEnabled ;
41+
42+ public IReadOnlyList < ( string Name , string Value ) > MaxBackupCountItems { get ; } =
43+ [
44+ ( CoreTools . Translate ( "Keep all backups" ) , "0" ) ,
45+ ( CoreTools . Translate ( "Keep the last {0} backups" , 5 ) , "5" ) ,
46+ ( CoreTools . Translate ( "Keep the last {0} backups" , 10 ) , "10" ) ,
47+ ( CoreTools . Translate ( "Keep the last {0} backups" , 25 ) , "25" ) ,
48+ ( CoreTools . Translate ( "Keep the last {0} backups" , 50 ) , "50" ) ,
49+ ( CoreTools . Translate ( "Custom..." ) , "custom" ) ,
50+ ] ;
51+
3852 /* ── Cloud backup ── */
3953 [ ObservableProperty ] private bool _isLoggedIn ;
4054 [ ObservableProperty ] private bool _isLoginButtonEnabled = true ;
@@ -55,6 +69,7 @@ public BackupViewModel()
5569 {
5670 _lifetimeToken = _lifetimeCancellation . Token ;
5771 _isLocalBackupEnabled = CoreSettings . Get ( CoreSettings . K . EnablePackageBackup_LOCAL ) ;
72+ _isBackupTimestampingEnabled = CoreSettings . Get ( CoreSettings . K . EnableBackupTimestamping ) ;
5873 RefreshDirectoryLabel ( ) ;
5974
6075 GitHubAuthService . AuthStatusChanged += OnAuthStatusChanged ;
@@ -87,6 +102,13 @@ private void EnableLocalBackupChanged()
87102 RestartRequired ? . Invoke ( this , EventArgs . Empty ) ;
88103 }
89104
105+ [ RelayCommand ]
106+ private void EnableBackupTimestampingChanged ( )
107+ {
108+ if ( IsDisposed ) return ;
109+ IsBackupTimestampingEnabled = CoreSettings . Get ( CoreSettings . K . EnableBackupTimestamping ) ;
110+ }
111+
90112 private void RefreshDirectoryLabel ( )
91113 {
92114 if ( IsDisposed ) return ;
@@ -120,28 +142,9 @@ public static async Task<bool> DoLocalBackupStatic()
120142 ?? [ ] ;
121143 string backupContents = await PackageBundlesPage . CreateBundle ( packages ) ;
122144
123- string dirName = CoreSettings . GetValue ( CoreSettings . K . ChangeBackupOutputDirectory ) ;
124- if ( string . IsNullOrEmpty ( dirName ) )
125- dirName = CoreData . UniGetUI_DefaultBackupDirectory ;
126-
127- if ( ! Directory . Exists ( dirName ) )
128- Directory . CreateDirectory ( dirName ) ;
129-
130- string fileName = CoreSettings . GetValue ( CoreSettings . K . ChangeBackupFileName ) ;
131- if ( string . IsNullOrEmpty ( fileName ) )
132- fileName = CoreTools . Translate (
133- "{pcName} installed packages" ,
134- new Dictionary < string , object ? > { { "pcName" , Environment . MachineName } }
135- ) ;
136-
137- if ( CoreSettings . Get ( CoreSettings . K . EnableBackupTimestamping ) )
138- fileName += " " + DateTime . Now . ToString ( "yyyy-MM-dd HH-mm-ss" ) ;
139-
140- fileName += ".ubundle" ;
141-
142- string filePath = Path . Combine ( dirName , fileName ) ;
143- await File . WriteAllTextAsync ( filePath , backupContents ) ;
145+ string filePath = await LocalBackupManager . SaveBackupAsync ( backupContents ) ;
144146 Logger . ImportantInfo ( "Local backup saved to " + filePath ) ;
147+ await Task . Run ( LocalBackupManager . ApplyRetentionLimit ) ;
145148 return true ;
146149 }
147150 catch ( Exception ex )
0 commit comments