You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

OnlineConfigViewModel.cs 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using ReactiveUI;
  2. using ReactiveUI.Fody.Helpers;
  3. using ReactiveUI.Validation.Extensions;
  4. using ReactiveUI.Validation.Helpers;
  5. using Shadowsocks.Controller;
  6. using Shadowsocks.Localization;
  7. using Shadowsocks.Model;
  8. using Shadowsocks.View;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Linq;
  13. using System.Reactive;
  14. using System.Reactive.Linq;
  15. using System.Text;
  16. using System.Windows;
  17. namespace Shadowsocks.WPF.ViewModels
  18. {
  19. public class OnlineConfigViewModel : ReactiveValidationObject
  20. {
  21. public OnlineConfigViewModel()
  22. {
  23. _config = Program.MainController.GetCurrentConfiguration();
  24. _controller = Program.MainController;
  25. _menuViewController = Program.MenuController;
  26. Sources = new ObservableCollection<string>(_config.onlineConfigSource);
  27. SelectedSource = "";
  28. Address = "";
  29. // TODO in v5: if http:// show warning as materialDesign:HintAssist.HelperText
  30. AddressRule = this.ValidationRule(
  31. viewModel => viewModel.Address,
  32. address => address.StartsWith("http://"),
  33. "Warning: getting online configuration from plain HTTP sources is NOT secure!");
  34. var canUpdateCopyRemove = this.WhenAnyValue(
  35. x => x.SelectedSource,
  36. selectedSource => !string.IsNullOrWhiteSpace(selectedSource));
  37. var canUpdateAll = this.WhenAnyValue(
  38. x => x.Sources.Count,
  39. count => count > 0);
  40. var canAdd = this.WhenAnyValue(
  41. x => x.Address,
  42. address => Uri.IsWellFormedUriString(address, UriKind.Absolute) &&
  43. (address.StartsWith("https://") || address.StartsWith("http://")));
  44. Update = ReactiveCommand.CreateFromTask(() => _controller.UpdateOnlineConfig(SelectedSource), canUpdateCopyRemove);
  45. UpdateAll = ReactiveCommand.CreateFromTask(_controller.UpdateAllOnlineConfig, canUpdateAll);
  46. CopyLink = ReactiveCommand.Create(() => Clipboard.SetText(SelectedSource), canUpdateCopyRemove);
  47. Remove = ReactiveCommand.Create(() =>
  48. {
  49. bool result;
  50. var urlToRemove = SelectedSource; // save it here because SelectedSource is lost once we remove the selection
  51. do
  52. {
  53. result = Sources.Remove(urlToRemove);
  54. } while (result);
  55. _controller.RemoveOnlineConfig(urlToRemove);
  56. }, canUpdateCopyRemove);
  57. Add = ReactiveCommand.Create(() =>
  58. {
  59. Sources.Add(Address);
  60. SelectedSource = Address;
  61. _controller.SaveOnlineConfigSource(Sources.ToList());
  62. Address = "";
  63. }, canAdd);
  64. // TODO in v5: use MaterialDesignThemes snackbar messages
  65. this.WhenAnyObservable(x => x.Update)
  66. .Subscribe(x =>
  67. {
  68. if (x)
  69. MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateSuccess"));
  70. else
  71. MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateFailure"));
  72. });
  73. this.WhenAnyObservable(x => x.UpdateAll)
  74. .Subscribe(x =>
  75. {
  76. if (x.Count == 0)
  77. MessageBox.Show(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateAllSuccess"));
  78. else
  79. {
  80. var stringBuilder = new StringBuilder(LocalizationProvider.GetLocalizedValue<string>("sip008UpdateAllFailure"));
  81. foreach (var url in x)
  82. stringBuilder.AppendLine(url);
  83. MessageBox.Show(stringBuilder.ToString());
  84. }
  85. });
  86. }
  87. private readonly Configuration _config;
  88. private readonly ShadowsocksController _controller;
  89. private readonly MenuViewController _menuViewController;
  90. public ValidationHelper AddressRule { get; }
  91. public ReactiveCommand<Unit, bool> Update { get; }
  92. public ReactiveCommand<Unit, List<string>> UpdateAll { get; }
  93. public ReactiveCommand<Unit, Unit> CopyLink { get; }
  94. public ReactiveCommand<Unit, Unit> Remove { get; }
  95. public ReactiveCommand<Unit, Unit> Add { get; }
  96. [Reactive]
  97. public ObservableCollection<string> Sources { get; private set; }
  98. [Reactive]
  99. public string SelectedSource { get; set; }
  100. [Reactive]
  101. public string Address { get; set; }
  102. }
  103. }