mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-16 04:25:45 +00:00
Add LiteMainWindowViewModel.cs file
This commit is contained in:
parent
90fec23835
commit
b7e737b3f8
1 changed files with 267 additions and 0 deletions
267
v2rayN/ViewModels/LiteMainWindowViewModel.cs
Normal file
267
v2rayN/ViewModels/LiteMainWindowViewModel.cs
Normal file
|
|
@ -0,0 +1,267 @@
|
||||||
|
using ReactiveUI.Fody.Helpers;
|
||||||
|
|
||||||
|
namespace v2rayN.ViewModels;
|
||||||
|
|
||||||
|
public class LiteMainWindowViewModel : ReactiveObject
|
||||||
|
{
|
||||||
|
[Reactive]
|
||||||
|
public string VlessLink { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string StatusText { get; set; } = "Не подключено";
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string StatusColor { get; set; } = "#0066cc";
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool IsConnected { get; set; } = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool IsConnecting { get; set; } = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool VlessInputEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool AutostartEnabled { get; set; } = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool AutoconnectEnabled { get; set; } = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool TrayMinimizeEnabled { get; set; } = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string ConnectButtonText { get; set; } = "ПОДКЛЮЧИТЬ";
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool ConnectingProgressVisible { get; set; } = false;
|
||||||
|
|
||||||
|
public ReactiveCommand<Unit, Unit> ConnectCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> DisconnectCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> ClearLinkCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> OpenLogsCommand { get; }
|
||||||
|
|
||||||
|
private readonly LiteConnectionBridge _connectionBridge;
|
||||||
|
private CancellationTokenSource? _cancellationTokenSource;
|
||||||
|
|
||||||
|
public LiteMainWindowViewModel()
|
||||||
|
{
|
||||||
|
_connectionBridge = new LiteConnectionBridge();
|
||||||
|
|
||||||
|
// Load saved settings
|
||||||
|
LoadSettings();
|
||||||
|
|
||||||
|
// Connect command
|
||||||
|
ConnectCommand = ReactiveCommand.CreateFromTask(
|
||||||
|
async _ => await ConnectVpn(),
|
||||||
|
this.WhenAnyValue(x => x.IsConnected, x => x.IsConnecting, x => x.VlessLink,
|
||||||
|
(connected, connecting, link) => !connected && !connecting && !string.IsNullOrWhiteSpace(link)));
|
||||||
|
|
||||||
|
// Disconnect command
|
||||||
|
DisconnectCommand = ReactiveCommand.CreateFromTask(
|
||||||
|
async _ => await DisconnectVpn(),
|
||||||
|
this.WhenAnyValue(x => x.IsConnected, x => x.IsConnecting,
|
||||||
|
(connected, connecting) => connected && !connecting));
|
||||||
|
|
||||||
|
// Clear link command
|
||||||
|
ClearLinkCommand = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
VlessLink = string.Empty;
|
||||||
|
SaveSettings();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Open logs command
|
||||||
|
OpenLogsCommand = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var logsPath = Path.Combine(Utils.GetAppDataPath(), "logs");
|
||||||
|
if (Directory.Exists(logsPath))
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "explorer.exe",
|
||||||
|
Arguments = logsPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(nameof(LiteMainWindowViewModel), ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update UI based on connection state
|
||||||
|
this.WhenAnyValue(x => x.IsConnected, x => x.IsConnecting)
|
||||||
|
.Subscribe(x =>
|
||||||
|
{
|
||||||
|
UpdateButtonState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateButtonState()
|
||||||
|
{
|
||||||
|
if (IsConnecting)
|
||||||
|
{
|
||||||
|
ConnectButtonText = "ПОДКЛЮЧЕНИЕ...";
|
||||||
|
ConnectingProgressVisible = true;
|
||||||
|
VlessInputEnabled = false;
|
||||||
|
StatusColor = "#ffaa00";
|
||||||
|
}
|
||||||
|
else if (IsConnected)
|
||||||
|
{
|
||||||
|
ConnectButtonText = "ОТКЛЮЧИТЬ";
|
||||||
|
ConnectingProgressVisible = false;
|
||||||
|
VlessInputEnabled = false;
|
||||||
|
StatusColor = "#00cc00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConnectButtonText = "ПОДКЛЮЧИТЬ";
|
||||||
|
ConnectingProgressVisible = false;
|
||||||
|
VlessInputEnabled = true;
|
||||||
|
StatusColor = "#0066cc";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ConnectVpn()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(VlessLink))
|
||||||
|
{
|
||||||
|
StatusText = "Ошибка: введите VLESS-ссылку";
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VlessLink.StartsWith("vless://", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
StatusText = "Ошибка: только VLESS + REALITY";
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
IsConnecting = true;
|
||||||
|
StatusText = "Подключение...";
|
||||||
|
StatusColor = "#ffaa00";
|
||||||
|
|
||||||
|
bool result = await _connectionBridge.ConnectAsync(VlessLink, _cancellationTokenSource.Token);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
IsConnected = true;
|
||||||
|
StatusText = "Подключено ✓";
|
||||||
|
StatusColor = "#00cc00";
|
||||||
|
SaveSettings();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusText = "Ошибка подключения";
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
StatusText = "Подключение отменено";
|
||||||
|
StatusColor = "#ffaa00";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(nameof(LiteMainWindowViewModel), ex);
|
||||||
|
StatusText = "Ошибка: " + ex.Message.Substring(0, Math.Min(30, ex.Message.Length));
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsConnecting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DisconnectVpn()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsConnecting = true;
|
||||||
|
StatusText = "Отключение...";
|
||||||
|
StatusColor = "#ffaa00";
|
||||||
|
|
||||||
|
bool result = await _connectionBridge.DisconnectAsync(_cancellationTokenSource?.Token ?? CancellationToken.None);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
IsConnected = false;
|
||||||
|
StatusText = "Не подключено";
|
||||||
|
StatusColor = "#0066cc";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusText = "Ошибка отключения";
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(nameof(LiteMainWindowViewModel), ex);
|
||||||
|
StatusText = "Ошибка отключения";
|
||||||
|
StatusColor = "#ff0000";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsConnecting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var config = AppManager.Instance?.GetAppConfig();
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
config.LiteLastVlessLink = VlessLink;
|
||||||
|
config.LiteAutostartEnabled = AutostartEnabled;
|
||||||
|
config.LiteAutoconnectEnabled = AutoconnectEnabled;
|
||||||
|
config.LiteTrayMinimizeEnabled = TrayMinimizeEnabled;
|
||||||
|
ConfigHandler.SaveConfig(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(nameof(LiteMainWindowViewModel), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var config = AppManager.Instance?.GetAppConfig();
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
VlessLink = config.LiteLastVlessLink ?? string.Empty;
|
||||||
|
AutostartEnabled = config.LiteAutostartEnabled;
|
||||||
|
AutoconnectEnabled = config.LiteAutoconnectEnabled;
|
||||||
|
TrayMinimizeEnabled = config.LiteTrayMinimizeEnabled;
|
||||||
|
|
||||||
|
// Auto-connect if enabled
|
||||||
|
if (AutoconnectEnabled && !string.IsNullOrWhiteSpace(VlessLink))
|
||||||
|
{
|
||||||
|
_ = Task.Delay(1000).ContinueWith(async _ => await ConnectVpn());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(nameof(LiteMainWindowViewModel), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cleanup()
|
||||||
|
{
|
||||||
|
_cancellationTokenSource?.Cancel();
|
||||||
|
_cancellationTokenSource?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue