mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-22 23:45:47 +00:00
fix: remove Save/Cancel from routing settings, save edits immediately (#9133)
This commit is contained in:
parent
35b98f945f
commit
b604a5b787
5 changed files with 33 additions and 101 deletions
|
|
@ -22,7 +22,6 @@ public class RoutingSettingViewModel : MyReactiveObject
|
||||||
public ReactiveCommand<Unit, Unit> RoutingAdvancedSetDefaultCmd { get; }
|
public ReactiveCommand<Unit, Unit> RoutingAdvancedSetDefaultCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> RoutingAdvancedImportRulesCmd { get; }
|
public ReactiveCommand<Unit, Unit> RoutingAdvancedImportRulesCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
|
||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
|
|
||||||
#endregion Reactive
|
#endregion Reactive
|
||||||
|
|
@ -53,12 +52,19 @@ public class RoutingSettingViewModel : MyReactiveObject
|
||||||
await RoutingAdvancedImportRules();
|
await RoutingAdvancedImportRules();
|
||||||
});
|
});
|
||||||
|
|
||||||
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
||||||
{
|
|
||||||
await SaveRoutingAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = Init();
|
_ = Init();
|
||||||
|
|
||||||
|
// Auto-save DomainStrategy when changed
|
||||||
|
this.WhenAnyValue(
|
||||||
|
x => x.DomainStrategy,
|
||||||
|
x => x.DomainStrategy4Singbox)
|
||||||
|
.Skip(1)
|
||||||
|
.DistinctUntilChanged()
|
||||||
|
.Subscribe(x =>
|
||||||
|
{
|
||||||
|
IsModified = true;
|
||||||
|
_ = SaveSettingsAsync();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
|
|
@ -96,20 +102,14 @@ public class RoutingSettingViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveRoutingAsync()
|
/// <summary>
|
||||||
|
/// Save DomainStrategy settings
|
||||||
|
/// </summary>
|
||||||
|
public async Task SaveSettingsAsync()
|
||||||
{
|
{
|
||||||
_config.RoutingBasicItem.DomainStrategy = DomainStrategy;
|
_config.RoutingBasicItem.DomainStrategy = DomainStrategy;
|
||||||
_config.RoutingBasicItem.DomainStrategy4Singbox = DomainStrategy4Singbox;
|
_config.RoutingBasicItem.DomainStrategy4Singbox = DomainStrategy4Singbox;
|
||||||
|
await ConfigHandler.SaveConfig(_config);
|
||||||
if (await ConfigHandler.SaveConfig(_config) == 0)
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.Enqueue(ResUI.OperationSuccess);
|
|
||||||
_updateView?.Invoke(EViewAction.CloseWindow, null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Refresh Save
|
#endregion Refresh Save
|
||||||
|
|
|
||||||
|
|
@ -20,24 +20,6 @@
|
||||||
<MenuItem x:Name="menuRoutingAdvancedImportRules2" Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" />
|
<MenuItem x:Name="menuRoutingAdvancedImportRules2" Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" />
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin4}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
DockPanel.Dock="Bottom"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<Button
|
|
||||||
x:Name="btnSave"
|
|
||||||
Width="100"
|
|
||||||
Content="{x:Static resx:ResUI.TbConfirm}"
|
|
||||||
IsDefault="True" />
|
|
||||||
<Button
|
|
||||||
x:Name="btnCancel"
|
|
||||||
Width="100"
|
|
||||||
Margin="{StaticResource MarginLr8}"
|
|
||||||
Content="{x:Static resx:ResUI.TbCancel}"
|
|
||||||
IsCancel="True" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<Grid
|
<Grid
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
ColumnDefinitions="Auto,Auto"
|
ColumnDefinitions="Auto,Auto"
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,12 @@ namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
{
|
{
|
||||||
private bool _manualClose = false;
|
|
||||||
|
|
||||||
public RoutingSettingWindow()
|
public RoutingSettingWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
Loaded += Window_Loaded;
|
Loaded += Window_Loaded;
|
||||||
Closing += RoutingSettingWindow_Closing;
|
Closing += RoutingSettingWindow_Closing;
|
||||||
btnCancel.Click += (s, e) => Close();
|
|
||||||
KeyDown += RoutingSettingWindow_KeyDown;
|
KeyDown += RoutingSettingWindow_KeyDown;
|
||||||
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
||||||
lstRoutings.DoubleTapped += LstRoutings_DoubleTapped;
|
lstRoutings.DoubleTapped += LstRoutings_DoubleTapped;
|
||||||
|
|
@ -38,8 +35,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,10 +42,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case EViewAction.CloseWindow:
|
|
||||||
Close(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.ShowYesNo:
|
case EViewAction.ShowYesNo:
|
||||||
if (await UI.ShowYesNo(this, ResUI.RemoveRules) != ButtonResult.Yes)
|
if (await UI.ShowYesNo(this, ResUI.RemoveRules) != ButtonResult.Yes)
|
||||||
{
|
{
|
||||||
|
|
@ -69,6 +60,21 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _closed = false;
|
||||||
|
|
||||||
|
private void RoutingSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if (_closed) return;
|
||||||
|
|
||||||
|
// DomainStrategy is auto-saved reactively; just ensure the caller knows changes were made
|
||||||
|
if (ViewModel?.IsModified == true)
|
||||||
|
{
|
||||||
|
e.Cancel = true;
|
||||||
|
_closed = true;
|
||||||
|
Close(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void RoutingSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
private void RoutingSettingWindow_KeyDown(object? sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
|
||||||
|
|
@ -125,25 +131,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
_manualClose = true;
|
|
||||||
Close(ViewModel?.IsModified);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RoutingSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
|
||||||
{
|
|
||||||
if (ViewModel?.IsModified == true)
|
|
||||||
{
|
|
||||||
if (!_manualClose)
|
|
||||||
{
|
|
||||||
btnCancel_Click(null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
private void Window_Loaded(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
btnCancel.Focus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,26 +52,6 @@
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
</ToolBarTray>
|
</ToolBarTray>
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
DockPanel.Dock="Bottom"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<Button
|
|
||||||
x:Name="btnSave"
|
|
||||||
Width="100"
|
|
||||||
Content="{x:Static resx:ResUI.TbConfirm}"
|
|
||||||
IsDefault="True"
|
|
||||||
Style="{StaticResource DefButton}" />
|
|
||||||
<Button
|
|
||||||
x:Name="btnCancel"
|
|
||||||
Width="100"
|
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
|
||||||
Content="{x:Static resx:ResUI.TbCancel}"
|
|
||||||
IsCancel="true"
|
|
||||||
Style="{StaticResource DefButton}" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
|
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ public partial class RoutingSettingWindow
|
||||||
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
||||||
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
|
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
|
||||||
menuRoutingAdvancedSelectAll.Click += menuRoutingAdvancedSelectAll_Click;
|
menuRoutingAdvancedSelectAll.Click += menuRoutingAdvancedSelectAll_Click;
|
||||||
btnCancel.Click += btnCancel_Click;
|
|
||||||
|
|
||||||
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
|
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
|
|
@ -33,8 +32,6 @@ public partial class RoutingSettingWindow
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
|
||||||
});
|
});
|
||||||
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
|
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
|
||||||
}
|
}
|
||||||
|
|
@ -43,10 +40,6 @@ public partial class RoutingSettingWindow
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case EViewAction.CloseWindow:
|
|
||||||
DialogResult = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.ShowYesNo:
|
case EViewAction.ShowYesNo:
|
||||||
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
|
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
|
||||||
{
|
{
|
||||||
|
|
@ -68,6 +61,7 @@ public partial class RoutingSettingWindow
|
||||||
|
|
||||||
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
|
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
|
// DomainStrategy is auto-saved reactively; just ensure the caller knows changes were made
|
||||||
if (ViewModel?.IsModified == true)
|
if (ViewModel?.IsModified == true)
|
||||||
{
|
{
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
|
|
@ -129,16 +123,4 @@ public partial class RoutingSettingWindow
|
||||||
{
|
{
|
||||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (ViewModel?.IsModified == true)
|
|
||||||
{
|
|
||||||
DialogResult = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue