using DynamicData; using DynamicData.Binding; using Microsoft.VisualStudio.Threading; using NatTypeTester.Models; using ReactiveUI; using STUN; using System.Reactive.Linq; using Volo.Abp.DependencyInjection; namespace NatTypeTester.ViewModels; [ExposeServices( typeof(MainWindowViewModel), typeof(IScreen) )] public class MainWindowViewModel : ViewModelBase, IScreen { public RoutingState Router => LazyServiceProvider.LazyGetRequiredService(); public Config Config => LazyServiceProvider.LazyGetRequiredService(); private readonly IEnumerable _defaultServers = new HashSet { @"stun.hot-chilli.net", @"stunserver.stunprotocol.org", @"stun.syncthing.net", @"stun.qq.com", @"stun.miwifi.com" }; private SourceList List { get; } = new(); public readonly IObservableCollection StunServers = new ObservableCollectionExtended(); public MainWindowViewModel() { List.Connect() .DistinctValues(x => x) .ObserveOn(RxApp.MainThreadScheduler) .Bind(StunServers) .Subscribe(); } public void LoadStunServer() { foreach (string? server in _defaultServers) { List.Add(server); } Config.StunServer = _defaultServers.First(); Task.Run(() => { const string path = @"stun.txt"; if (!File.Exists(path)) { return; } foreach (string? line in File.ReadLines(path)) { if (!string.IsNullOrWhiteSpace(line) && StunServer.TryParse(line, out StunServer? stun)) { List.Add(stun.ToString()); } } }).Forget(); } }