-
Notifications
You must be signed in to change notification settings - Fork 47
/
SettingViewModel.cs
229 lines (199 loc) · 5.3 KB
/
SettingViewModel.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
using BilibiliLiveRecordDownLoader.Interfaces;
using BilibiliLiveRecordDownLoader.Models;
using BilibiliLiveRecordDownLoader.Shared.Utils;
using BilibiliLiveRecordDownLoader.Utils;
using BilibiliLiveRecordDownLoader.Views.Dialogs;
using DynamicData;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.Threading;
using Microsoft.Win32;
using ModernWpf.Controls;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using RunAtStartup;
using System.Reactive;
using System.Reactive.Linq;
using UpdateChecker;
namespace BilibiliLiveRecordDownLoader.ViewModels;
public class SettingViewModel : ReactiveObject, IRoutableViewModel
{
public string UrlPathSegment => @"Settings";
public IScreen HostScreen { get; }
#region 属性
[Reactive]
public string? DiskUsageProgressBarText { get; set; }
[Reactive]
public double DiskUsageProgressBarValue { get; set; }
[Reactive]
public string? UpdateStatus { get; set; }
[Reactive]
public bool IsRunOnStartup { get; set; }
#endregion
#region Command
public ReactiveCommand<Unit, Unit> SelectMainDirCommand { get; }
public ReactiveCommand<Unit, Unit> OpenMainDirCommand { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateCommand { get; }
#endregion
private readonly ILogger _logger;
private readonly IConfigService _configService;
private readonly SourceList<RoomStatus> _roomList;
private readonly StartupService _startup;
public readonly Config Config;
private readonly string _startUpData = $"""
"{Environment.ProcessPath}" {Constants.ParameterSilent}
""";
public SettingViewModel(
IScreen hostScreen,
ILogger<SettingViewModel> logger,
IConfigService configService,
Config config,
SourceList<RoomStatus> roomList,
StartupService startup)
{
HostScreen = hostScreen;
_logger = logger;
_configService = configService;
Config = config;
_roomList = roomList;
_startup = startup;
SelectMainDirCommand = ReactiveCommand.Create(SelectDirectory);
OpenMainDirCommand = ReactiveCommand.CreateFromObservable(OpenDirectory);
CheckUpdateCommand = ReactiveCommand.CreateFromTask(CheckUpdateAsync);
InitAsync().Forget();
}
private async ValueTask InitAsync()
{
await _configService.LoadAsync(default);
await Task.Delay(TimeSpan.FromSeconds(1)); // Wait apiClient to load settings
_roomList.AddRange(Config.Rooms);
if (Config.IsCheckUpdateOnStart)
{
await CheckUpdateCommand.Execute();
}
}
private void SelectDirectory()
{
OpenFolderDialog dlg = new()
{
InitialDirectory = Config.MainDir
};
if (dlg.ShowDialog() is true)
{
Config.MainDir = dlg.FolderName;
}
}
private IObservable<Unit> OpenDirectory()
{
return Observable.Start(() =>
{
FileUtils.OpenDir(Config.MainDir);
return Unit.Default;
});
}
private async Task CheckUpdateAsync(CancellationToken token)
{
try
{
UpdateStatus = @"正在检查更新...";
string version = Utils.Utils.GetAppVersion()!;
GitHubReleasesUpdateChecker updateChecker = new(
@"HMBSbige",
@"BilibiliLiveRecordDownLoader",
Config.IsCheckPreRelease,
version
);
if (await updateChecker.CheckAsync(HttpClientUtils.BuildClient(Config.Cookie, Config.UserAgent, Config.HttpHandler), token))
{
if (updateChecker.LatestVersionUrl is null)
{
UpdateStatus = @"更新地址获取出错";
return;
}
UpdateStatus = $@"发现新版本:{updateChecker.LatestVersion}";
using DisposableContentDialog dialog = new();
dialog.Title = UpdateStatus;
dialog.Content = @"是否跳转到下载页?";
dialog.PrimaryButtonText = @"是";
dialog.SecondaryButtonText = @"否";
dialog.DefaultButton = ContentDialogButton.Primary;
if (await dialog.SafeShowAsync() == ContentDialogResult.Primary)
{
FileUtils.OpenUrl(updateChecker.LatestVersionUrl);
}
}
else
{
UpdateStatus = $@"没有找到新版本:{version} ≥ {updateChecker.LatestVersion}";
}
}
catch (Exception ex)
{
UpdateStatus = @"检查更新出错";
_logger.LogError(ex, UpdateStatus);
}
}
public IDisposable CreateDiskMonitor()
{
return Observable.Interval(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler).Subscribe(GetDiskUsage);
}
private void GetDiskUsage(long _)
{
(ulong availableFreeSpace, ulong totalSize, ulong totalFree) = FileUtils.GetDiskUsage(Config.MainDir);
if (totalSize != 0)
{
ulong usedSize = totalSize - totalFree;
DiskUsageProgressBarText = $@"已使用 {usedSize.ToHumanBytesString()}/{totalSize.ToHumanBytesString()} 剩余可用 {availableFreeSpace.ToHumanBytesString()}";
double percentage = usedSize / (double)totalSize;
DiskUsageProgressBarValue = percentage * 100;
}
else
{
DiskUsageProgressBarText = string.Empty;
DiskUsageProgressBarValue = 0;
}
}
public void CheckStartupStatus()
{
try
{
IsRunOnStartup = _startup.Check(_startUpData);
}
catch (Exception ex)
{
_logger.LogError(ex, @"检查自启动状态失败");
}
}
private void SetStartup()
{
try
{
_startup.Set(_startUpData);
}
catch (Exception ex)
{
_logger.LogError(ex, @"设置自启动失败");
}
}
private void RemoveStartup()
{
try
{
_startup.Delete();
}
catch (Exception ex)
{
_logger.LogError(ex, @"取消自启动失败");
}
}
public void SwitchStartup(bool enable)
{
if (enable)
{
SetStartup();
}
else
{
RemoveStartup();
}
}
}