Files
v2rayN/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs
DHR60 9664ee380e ViewModel-First (#9621)
* Interaction

* Remove view action

* ViewModel-first

* MainGirdOrientation Hot Reload

* Fix avalonia preview

* Remove CloseWindowInteraction

* Fix

* Avoid threading issues

* Fix

* ProfilesSelect

* Try fix previewer

* Remove AppEvents.ProfilesRefreshRequested

* Remove AppEvents.SubscriptionsRefreshRequested

* Remove AppEvents.ProxiesReloadRequested

* Remove AppEvents.AdjustMainLvColWidthRequested

* Remove AppEvents.SetDefaultServerRequested

* Remove AppEvents.RoutingsMenuRefreshRequested

* Remove AppEvents.TestServerRequested

* Remove AppEvents.InboundDisplayRequested

* Remove AppEvents.SubscriptionsUpdateRequested

* Remove AppEvents.ShowHideWindowRequested

* Remove AppEvents.ReloadRequested

* Remove AppEvents.AddServerRequested

* Fix
2026-07-14 09:05:05 +08:00

94 lines
3.0 KiB
C#

namespace ServiceLib.ViewModels;
public class SubEditViewModel : MyReactiveObject, ICloseable
{
public event EventHandler? RequestClose;
[Reactive]
public SubItem SelectedSource { get; set; }
public ReactiveCommand<Unit, Unit> SelectPrevProfileCmd { get; }
public ReactiveCommand<Unit, Unit> SelectNextProfileCmd { get; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public SubEditViewModel(SubItem subItem)
{
_config = AppManager.Instance.Config;
SelectPrevProfileCmd = ReactiveCommand.CreateFromTask(async () =>
{
var profileItem = await SelectProfileAsync();
if (profileItem != null)
{
SelectedSource?.PrevProfile = profileItem.Remarks;
SelectedSource = JsonUtils.DeepCopy(SelectedSource);
}
});
SelectNextProfileCmd = ReactiveCommand.CreateFromTask(async () =>
{
var profileItem = await SelectProfileAsync();
if (profileItem != null)
{
SelectedSource?.NextProfile = profileItem.Remarks;
SelectedSource = JsonUtils.DeepCopy(SelectedSource);
}
});
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveSubAsync();
});
SelectedSource = subItem.Id.IsNullOrEmpty() ? subItem : JsonUtils.DeepCopy(subItem);
}
private async Task SaveSubAsync()
{
var remarks = SelectedSource.Remarks;
if (remarks.IsNullOrEmpty())
{
NoticeManager.Instance.Enqueue(ResUI.PleaseFillRemarks);
return;
}
var url = SelectedSource.Url;
if (url.IsNotEmpty())
{
var uri = Utils.TryUri(url);
if (uri == null)
{
NoticeManager.Instance.Enqueue(ResUI.InvalidUrlTip);
return;
}
//Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{
NoticeManager.Instance.Enqueue(ResUI.InsecureUrlProtocol);
//return;
}
}
if (await ConfigHandler.AddSubItem(_config, SelectedSource) == 0)
{
NoticeManager.Instance.Enqueue(ResUI.OperationSuccess);
RequestClose?.Invoke(this, EventArgs.Empty);
}
else
{
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
}
}
private async Task<ProfileItem?> SelectProfileAsync()
{
var profileSelectViewModel = new ProfilesSelectViewModel();
profileSelectViewModel.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
var result = await AppManager.Instance.WindowDialog.ShowDialogAsync(profileSelectViewModel);
if (result != true)
{
return null;
}
var profileItem = await profileSelectViewModel.GetProfileItem();
return profileItem;
}
}