mirror of
https://github.com/2dust/v2rayN.git
synced 2026-07-31 04:12:04 +03:00
746 lines
24 KiB
C#
746 lines
24 KiB
C#
using System.Reactive.Concurrency;
|
|
|
|
namespace ServiceLib.ViewModels;
|
|
|
|
public class MainWindowViewModel : MyReactiveObject
|
|
{
|
|
public Interaction<Unit, string?> ReadTextFromClipboardInteraction { get; } = new();
|
|
public Interaction<Unit, byte[]?> ScanScreenInteraction { get; } = new();
|
|
public Interaction<Unit, string?> BrowseImageFileInteraction { get; } = new();
|
|
public Interaction<bool?, Unit> ShowHideWindowInteraction { get; } = new();
|
|
|
|
public bool DesignMode { get; set; }
|
|
|
|
public ProfilesViewModel ProfilesViewModel { get; } = new();
|
|
public MsgViewModel MsgViewModel { get; } = new();
|
|
public ClashProxiesViewModel ClashProxiesViewModel { get; } = new();
|
|
public ClashConnectionsViewModel ClashConnectionsViewModel { get; } = new();
|
|
public CheckUpdateViewModel CheckUpdateViewModel { get; } = new();
|
|
public BackupAndRestoreViewModel BackupAndRestoreViewModel { get; } = new();
|
|
public StatusBarViewModel StatusBarViewModel { get; } = StatusBarViewModel.Instance;
|
|
|
|
#region Menu
|
|
|
|
//servers
|
|
public ReactiveCommand<Unit, Unit> AddVmessServerCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddHttpServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddNaiveServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddPolicyGroupServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddProxyChainServerCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> AddServerViaImageCmd { get; }
|
|
|
|
//Subscription
|
|
public ReactiveCommand<Unit, Unit> SubSettingCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> SubGroupUpdateCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> SubGroupUpdateViaProxyCmd { get; }
|
|
|
|
//Setting
|
|
public ReactiveCommand<Unit, Unit> OptionSettingCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> FullConfigTemplateCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }
|
|
public ReactiveCommand<Unit, Unit> OpenTheFileLocationCmd { get; }
|
|
|
|
//Presets
|
|
public ReactiveCommand<Unit, Unit> RegionalPresetDefaultCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> RegionalPresetRussiaCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> RegionalPresetIranCmd { get; }
|
|
|
|
public ReactiveCommand<Unit, Unit> ReloadCmd { get; }
|
|
|
|
[Reactive]
|
|
public bool BlReloadEnabled { get; set; }
|
|
|
|
[Reactive]
|
|
public bool ShowClashUI { get; set; }
|
|
|
|
[Reactive]
|
|
public int TabMainSelectedIndex { get; set; }
|
|
|
|
[Reactive] public bool BlIsWindows { get; set; }
|
|
|
|
[Reactive] public bool BlNewUpdate { get; set; }
|
|
|
|
[Reactive] public EGirdOrientation MainGirdOrientation { get; set; }
|
|
|
|
#endregion Menu
|
|
|
|
#region Init
|
|
|
|
public MainWindowViewModel()
|
|
{
|
|
_config = AppManager.Instance.Config;
|
|
BlIsWindows = Utils.IsWindows();
|
|
MainGirdOrientation = _config.UiItem.MainGirdOrientation;
|
|
|
|
#region WhenAnyValue && ReactiveCommand
|
|
|
|
//servers
|
|
AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.VMess);
|
|
});
|
|
AddVlessServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.VLESS);
|
|
});
|
|
AddShadowsocksServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Shadowsocks);
|
|
});
|
|
AddSocksServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.SOCKS);
|
|
});
|
|
AddHttpServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.HTTP);
|
|
});
|
|
AddTrojanServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Trojan);
|
|
});
|
|
AddHysteria2ServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Hysteria2);
|
|
});
|
|
AddTuicServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.TUIC);
|
|
});
|
|
AddWireguardServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.WireGuard);
|
|
});
|
|
AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Anytls);
|
|
});
|
|
AddNaiveServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Naive);
|
|
});
|
|
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.Custom);
|
|
});
|
|
AddPolicyGroupServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.PolicyGroup);
|
|
});
|
|
AddProxyChainServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerAsync(EConfigType.ProxyChain);
|
|
});
|
|
AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerViaClipboardAsync(null);
|
|
});
|
|
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerViaScanAsync();
|
|
});
|
|
AddServerViaImageCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AddServerViaImageAsync();
|
|
});
|
|
|
|
//Subscription
|
|
SubSettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await SubSettingAsync();
|
|
});
|
|
|
|
SubUpdateCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await UpdateSubscriptionProcess("", false);
|
|
});
|
|
SubUpdateViaProxyCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await UpdateSubscriptionProcess("", true);
|
|
});
|
|
SubGroupUpdateCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await UpdateSubscriptionProcess(_config.SubIndexId, false);
|
|
});
|
|
SubGroupUpdateViaProxyCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await UpdateSubscriptionProcess(_config.SubIndexId, true);
|
|
});
|
|
|
|
//Setting
|
|
OptionSettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await OptionSettingAsync();
|
|
});
|
|
RoutingSettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await RoutingSettingAsync();
|
|
});
|
|
DNSSettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await DNSSettingAsync();
|
|
});
|
|
FullConfigTemplateCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await FullConfigTemplateAsync();
|
|
});
|
|
GlobalHotkeySettingCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
var globalHotkeySettingViewModel = new GlobalHotkeySettingViewModel();
|
|
if (await AppManager.Instance.WindowDialog.ShowDialogAsync(globalHotkeySettingViewModel) == true)
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.OperationSuccess);
|
|
}
|
|
});
|
|
RebootAsAdminCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await AppManager.Instance.RebootAsAdmin();
|
|
});
|
|
ClearServerStatisticsCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await ClearServerStatistics();
|
|
});
|
|
OpenTheFileLocationCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await OpenTheFileLocation();
|
|
});
|
|
|
|
ReloadCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await Reload();
|
|
});
|
|
|
|
RegionalPresetDefaultCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await ApplyRegionalPreset(EPresetType.Default);
|
|
});
|
|
|
|
RegionalPresetRussiaCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await ApplyRegionalPreset(EPresetType.Russia);
|
|
});
|
|
|
|
RegionalPresetIranCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
await ApplyRegionalPreset(EPresetType.Iran);
|
|
});
|
|
|
|
#endregion WhenAnyValue && ReactiveCommand
|
|
|
|
#region AppEvents
|
|
|
|
AppEvents.AddServerViaClipboardRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async _ => await AddServerViaClipboardAsync(null));
|
|
|
|
AppEvents.HasUpdateNotified
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async bl => BlNewUpdate = bl);
|
|
|
|
#endregion AppEvents
|
|
|
|
ProfilesViewModel.RefreshServersRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async _ => await RefreshServers());
|
|
|
|
var vmReloadRequestedList = new List<IObservable<Unit>>
|
|
{
|
|
ProfilesViewModel.ReloadRequested.AsObservable(),
|
|
StatusBarViewModel.ReloadRequested.AsObservable(),
|
|
CheckUpdateViewModel.ReloadRequested.AsObservable(),
|
|
};
|
|
|
|
foreach (var reloadRequested in vmReloadRequestedList)
|
|
{
|
|
reloadRequested
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async _ => await Reload());
|
|
}
|
|
|
|
StatusBarViewModel.AddServerViaScanRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async _ => await AddServerViaScanAsync());
|
|
|
|
StatusBarViewModel.AddServerViaClipboardRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async _ => await AddServerViaClipboardAsync(null));
|
|
|
|
StatusBarViewModel.ShowHideWindowRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async blShow =>
|
|
{
|
|
await ShowHideWindowInteraction.Handle(blShow);
|
|
});
|
|
|
|
StatusBarViewModel.SetDefaultServerRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async indexId => await ProfilesViewModel.SetDefaultServer(indexId));
|
|
|
|
StatusBarViewModel.SubscriptionsUpdateRequested
|
|
.AsObservable()
|
|
.ObserveOn(RxSchedulers.MainThreadScheduler)
|
|
.Subscribe(async blProxy => await UpdateSubscriptionProcess("", blProxy));
|
|
|
|
_ = Init();
|
|
}
|
|
|
|
private async Task Init()
|
|
{
|
|
AppManager.Instance.ShowInTaskbar = true;
|
|
|
|
if (DesignMode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//await ConfigHandler.InitBuiltinRouting(_config);
|
|
await ConfigHandler.InitBuiltinDNS(_config);
|
|
await ConfigHandler.InitBuiltinFullConfigTemplate(_config);
|
|
await ProfileExManager.Instance.Init();
|
|
await CoreManager.Instance.Init(_config, UpdateHandler);
|
|
await CertPemManager.Instance.Init(_config);
|
|
TaskManager.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
|
|
|
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
|
|
{
|
|
await StatisticsManager.Instance.Init(_config, UpdateStatisticsHandler);
|
|
}
|
|
await RefreshServersDispatcherAsync();
|
|
|
|
await Reload();
|
|
}
|
|
|
|
#endregion Init
|
|
|
|
#region Actions
|
|
|
|
private async Task UpdateHandler(bool notify, string msg)
|
|
{
|
|
NoticeManager.Instance.SendMessage(msg);
|
|
if (notify)
|
|
{
|
|
NoticeManager.Instance.Enqueue(msg);
|
|
}
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
private async Task UpdateTaskHandler(bool success, string msg)
|
|
{
|
|
NoticeManager.Instance.SendMessageEx(msg);
|
|
if (success)
|
|
{
|
|
var indexIdOld = _config.IndexId;
|
|
await RefreshServersDispatcherAsync();
|
|
|
|
// If indexId changed or subIndexId is empty, directly reload.
|
|
if (indexIdOld != _config.IndexId || _config.SubIndexId.IsNullOrEmpty())
|
|
{
|
|
await Reload();
|
|
}
|
|
else
|
|
{
|
|
// The activity config belongs to the current group.
|
|
var profile = await AppManager.Instance.GetProfileItem(_config.IndexId);
|
|
if (profile != null && profile.Subid == _config.SubIndexId)
|
|
{
|
|
await Reload();
|
|
}
|
|
}
|
|
|
|
if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
|
|
{
|
|
await ProfilesViewModel.AdjustMainLvColWidth();
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task UpdateStatisticsHandler(ServerSpeedItem update)
|
|
{
|
|
if (!AppManager.Instance.ShowInTaskbar)
|
|
{
|
|
return;
|
|
}
|
|
AppEvents.DispatcherStatisticsRequested.Publish(update);
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
#endregion Actions
|
|
|
|
#region Servers && Groups
|
|
|
|
private async Task RefreshServers()
|
|
{
|
|
await ProfilesViewModel.RefreshServersBiz();
|
|
await StatusBarViewModel.RefreshServersBiz();
|
|
|
|
// await Task.Delay(200);
|
|
}
|
|
|
|
private async Task RefreshServersDispatcherAsync()
|
|
{
|
|
await Observable.Start(async () => await RefreshServers(), RxSchedulers.MainThreadScheduler);
|
|
}
|
|
|
|
private async Task RefreshSubscriptions()
|
|
{
|
|
await Observable.Start(async () => await ProfilesViewModel.RefreshSubscriptions(), RxSchedulers.MainThreadScheduler);
|
|
}
|
|
|
|
#endregion Servers && Groups
|
|
|
|
#region Add Servers
|
|
|
|
public async Task AddServerAsync(EConfigType eConfigType)
|
|
{
|
|
ProfileItem item = new()
|
|
{
|
|
Subid = _config.SubIndexId,
|
|
ConfigType = eConfigType,
|
|
IsSub = false,
|
|
};
|
|
|
|
bool? ret = false;
|
|
if (eConfigType == EConfigType.Custom)
|
|
{
|
|
var addServer2ViewModel = new AddServer2ViewModel(item);
|
|
ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(addServer2ViewModel);
|
|
}
|
|
else if (eConfigType.IsGroupType())
|
|
{
|
|
var addGroupServerViewModel = new AddGroupServerViewModel(item);
|
|
ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(addGroupServerViewModel);
|
|
}
|
|
else
|
|
{
|
|
var addServerViewModel = new AddServerViewModel(item);
|
|
ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(addServerViewModel);
|
|
}
|
|
if (ret == true)
|
|
{
|
|
await RefreshServersDispatcherAsync();
|
|
if (item.IndexId == _config.IndexId)
|
|
{
|
|
await Reload();
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task AddServerViaClipboardAsync(string? clipboardData)
|
|
{
|
|
var stringData = clipboardData;
|
|
if (clipboardData == null)
|
|
{
|
|
var result = await ReadTextFromClipboardInteraction.Handle(Unit.Default);
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
|
return;
|
|
}
|
|
stringData = result;
|
|
}
|
|
var ret = await ConfigHandler.AddBatchServers(_config, stringData, _config.SubIndexId, false);
|
|
if (ret > 0)
|
|
{
|
|
await RefreshSubscriptions();
|
|
await RefreshServersDispatcherAsync();
|
|
NoticeManager.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
|
|
}
|
|
else
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
|
}
|
|
}
|
|
|
|
public async Task AddServerViaScanAsync()
|
|
{
|
|
var result = await ScanScreenInteraction.Handle(Unit.Default);
|
|
await ScanScreenResult(result);
|
|
}
|
|
|
|
public async Task ScanScreenResult(byte[]? bytes)
|
|
{
|
|
var result = QRCodeUtils.ParseBarcode(bytes);
|
|
await AddScanResultAsync(result);
|
|
}
|
|
|
|
public async Task AddServerViaImageAsync()
|
|
{
|
|
var imageFileName = await BrowseImageFileInteraction.Handle(Unit.Default);
|
|
await AddScanResultAsync(imageFileName);
|
|
}
|
|
|
|
public async Task ScanImageResult(string fileName)
|
|
{
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = QRCodeUtils.ParseBarcode(fileName);
|
|
await AddScanResultAsync(result);
|
|
}
|
|
|
|
private async Task AddScanResultAsync(string? result)
|
|
{
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.NoValidQRcodeFound);
|
|
}
|
|
else
|
|
{
|
|
var ret = await ConfigHandler.AddBatchServers(_config, result, _config.SubIndexId, false);
|
|
if (ret > 0)
|
|
{
|
|
await RefreshSubscriptions();
|
|
await RefreshServersDispatcherAsync();
|
|
NoticeManager.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
|
|
}
|
|
else
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Add Servers
|
|
|
|
#region Subscription
|
|
|
|
private async Task SubSettingAsync()
|
|
{
|
|
var subSettingViewModel = new SubSettingViewModel();
|
|
if (await AppManager.Instance.WindowDialog.ShowDialogAsync(subSettingViewModel) == true)
|
|
{
|
|
await RefreshSubscriptions();
|
|
}
|
|
}
|
|
|
|
public async Task UpdateSubscriptionProcess(string subId, bool blProxy)
|
|
{
|
|
await Task.Run(async () => await SubscriptionHandler.UpdateProcess(_config, subId, blProxy, UpdateTaskHandler));
|
|
}
|
|
|
|
#endregion Subscription
|
|
|
|
#region Setting
|
|
|
|
private async Task OptionSettingAsync()
|
|
{
|
|
var settingViewModel = new OptionSettingViewModel();
|
|
var ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(settingViewModel);
|
|
if (ret == true)
|
|
{
|
|
MainGirdOrientation = _config.UiItem.MainGirdOrientation;
|
|
RxSchedulers.MainThreadScheduler.Schedule(async () =>
|
|
{
|
|
await StatusBarViewModel.InboundDisplayStatus();
|
|
});
|
|
await Reload();
|
|
}
|
|
}
|
|
|
|
private async Task RoutingSettingAsync()
|
|
{
|
|
var routingSettingViewModel = new RoutingSettingViewModel();
|
|
var ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(routingSettingViewModel);
|
|
if (ret == true)
|
|
{
|
|
await ConfigHandler.InitBuiltinRouting(_config);
|
|
RxSchedulers.MainThreadScheduler.Schedule(async () =>
|
|
{
|
|
await StatusBarViewModel.RefreshRoutingsMenu();
|
|
});
|
|
await Reload();
|
|
}
|
|
}
|
|
|
|
private async Task DNSSettingAsync()
|
|
{
|
|
var dnsSettingViewModel = new DNSSettingViewModel();
|
|
var ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(dnsSettingViewModel);
|
|
if (ret == true)
|
|
{
|
|
await Reload();
|
|
}
|
|
}
|
|
|
|
private async Task FullConfigTemplateAsync()
|
|
{
|
|
var fullConfigTemplateViewModel = new FullConfigTemplateViewModel();
|
|
var ret = await AppManager.Instance.WindowDialog.ShowDialogAsync(fullConfigTemplateViewModel);
|
|
if (ret == true)
|
|
{
|
|
await Reload();
|
|
}
|
|
}
|
|
|
|
private async Task ClearServerStatistics()
|
|
{
|
|
await StatisticsManager.Instance.ClearAllServerStatistics();
|
|
await RefreshServersDispatcherAsync();
|
|
}
|
|
|
|
private async Task OpenTheFileLocation()
|
|
{
|
|
var path = Utils.StartupPath();
|
|
if (Utils.IsWindows())
|
|
{
|
|
ProcUtils.ProcessStart(path);
|
|
}
|
|
else if (Utils.IsLinux())
|
|
{
|
|
ProcUtils.ProcessStart("xdg-open", path);
|
|
}
|
|
else if (Utils.IsMacOS())
|
|
{
|
|
ProcUtils.ProcessStart("open", path);
|
|
}
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
#endregion Setting
|
|
|
|
#region core job
|
|
|
|
private bool _hasNextReloadJob = false;
|
|
private readonly SemaphoreSlim _reloadSemaphore = new(1, 1);
|
|
|
|
public async Task Reload()
|
|
{
|
|
//If there are unfinished reload job, marked with next job.
|
|
if (!await _reloadSemaphore.WaitAsync(0))
|
|
{
|
|
_hasNextReloadJob = true;
|
|
return;
|
|
}
|
|
|
|
if (DesignMode)
|
|
{
|
|
_reloadSemaphore.Release();
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
SetReloadEnabled(false);
|
|
|
|
var profileItem = await ConfigHandler.GetDefaultServer(_config);
|
|
if (profileItem == null)
|
|
{
|
|
NoticeManager.Instance.Enqueue(ResUI.CheckServerSettings);
|
|
return;
|
|
}
|
|
var allResult = await CoreConfigContextBuilder.BuildAll(_config, profileItem);
|
|
if (NoticeManager.Instance.NotifyValidatorResult(allResult.CombinedValidatorResult) && !allResult.Success)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await Task.Run(async () =>
|
|
{
|
|
await LoadCore(allResult.MainResult.Context, allResult.PreSocksResult?.Context);
|
|
await SysProxyHandler.UpdateSysProxy(_config, false);
|
|
await Task.Delay(1000);
|
|
});
|
|
RxSchedulers.MainThreadScheduler.Schedule(async () =>
|
|
{
|
|
await StatusBarViewModel.TestServerAvailability();
|
|
});
|
|
|
|
var showClashUI = AppManager.Instance.IsRunningCore(ECoreType.sing_box);
|
|
if (showClashUI)
|
|
{
|
|
//await Observable.Start(async () =>
|
|
//{
|
|
// await ClashProxiesViewModel.ProxiesReload();
|
|
//}, RxSchedulers.MainThreadScheduler);
|
|
RxSchedulers.MainThreadScheduler.Schedule(async () =>
|
|
{
|
|
await ClashProxiesViewModel.ProxiesReload();
|
|
});
|
|
}
|
|
|
|
ReloadResult(showClashUI);
|
|
}
|
|
finally
|
|
{
|
|
SetReloadEnabled(true);
|
|
_reloadSemaphore.Release();
|
|
//If there is a next reload job, execute it.
|
|
if (_hasNextReloadJob)
|
|
{
|
|
_hasNextReloadJob = false;
|
|
await Reload();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ReloadResult(bool showClashUI)
|
|
{
|
|
RxSchedulers.MainThreadScheduler.Schedule(() =>
|
|
{
|
|
ShowClashUI = showClashUI;
|
|
TabMainSelectedIndex = showClashUI ? TabMainSelectedIndex : 0;
|
|
});
|
|
}
|
|
|
|
private void SetReloadEnabled(bool enabled)
|
|
{
|
|
RxSchedulers.MainThreadScheduler.Schedule(() => BlReloadEnabled = enabled);
|
|
}
|
|
|
|
private async Task LoadCore(CoreConfigContext? mainContext, CoreConfigContext? preContext)
|
|
{
|
|
await CoreManager.Instance.LoadCore(mainContext, preContext);
|
|
}
|
|
|
|
#endregion core job
|
|
|
|
#region Presets
|
|
|
|
public async Task ApplyRegionalPreset(EPresetType type)
|
|
{
|
|
await ConfigHandler.ApplyRegionalPreset(_config, type);
|
|
await ConfigHandler.InitRouting(_config);
|
|
RxSchedulers.MainThreadScheduler.Schedule(async () =>
|
|
{
|
|
await StatusBarViewModel.RefreshRoutingsMenu();
|
|
});
|
|
|
|
await ConfigHandler.SaveConfig(_config);
|
|
await new UpdateService(_config, UpdateTaskHandler).UpdateGeoFileAll();
|
|
await Reload();
|
|
}
|
|
|
|
#endregion Presets
|
|
}
|