public SetupVM( ISettingsService Settings, IConnectivityService Connectivity, [Dispatcher] IScheduler Dispatcher, IDiversityServiceClient Repository ) { this.Repository = Repository; this.Settings = Settings; // On First Page Visit (App Launch) // If There already is a configuration (Settings) // Go To Home Page this.FirstActivation() .SelectMany(_ => Settings.CurrentSettings()) .Select(x => (x != null) ? Page.Home : Page.SetupWelcome) .ToMessage(Messenger); _IsOnlineAvailable = this.ObservableToProperty(Connectivity.WifiAvailable(), x => x.IsOnlineAvailable, false, Dispatcher); // Show current login data in case of Reset Settings.SettingsObservable() .Subscribe(SetLogin); // Command To begin Setup this.ShowLogin = new ReactiveCommand(); ShowLogin.Select(_ => Page.SetupLogin) .ToMessage(Messenger); // Command Condition var userPassAndWifi = Observable.CombineLatest( Connectivity.WifiAvailable(), this.WhenAny(x => x.UserName, x => x.GetValue()).Select(string.IsNullOrWhiteSpace), this.WhenAny(x => x.Password, x => x.GetValue()).Select(string.IsNullOrWhiteSpace), (wifi, a, b) => wifi & !(a | b)); // Command and Errorhandling this.GetRepositories = new ReactiveAsyncCommand(userPassAndWifi); GetRepositories.ShowInFlightNotification(Notifications, DiversityResources.Setup_Info_ValidatingLogin); GetRepositories.ThrownExceptions .ShowServiceErrorNotifications(Notifications) .ShowErrorNotifications(Notifications) .Subscribe(); var loginAndRepo = GetRepositories.RegisterAsyncObservable(GetRepositoriesObservable).Publish().PermaRef(); // Page Navigation if Login Successful // i.e. Any repositories have been returned loginAndRepo .Snd() .Subscribe(NavigateOrNotifyInvalidCredentials); // Repo Selection this.Database = new ListSelectionHelper<string>(Dispatcher); loginAndRepo .Select(t => t.Item2) .Merge(EmptyProjectsOnLoginStart()) .Subscribe(Database.ItemsObserver); // Settings Propagation LatestLogin = loginAndRepo .Fst() .MostRecent(null) .GetEnumerator(); // Command Condition var repoSelected = Database.SelectedItemObservable .Select(repo => repo != NoRepo) .AndNoItemsInFlight(GetRepositories); // Command and Errorhandling this.GetProjects = new ReactiveAsyncCommand(repoSelected); GetProjects.ShowInFlightNotification(Notifications, DiversityResources.Setup_Info_GettingProjects); GetProjects.ThrownExceptions .ShowServiceErrorNotifications(Notifications) .ShowErrorNotifications(Notifications) .Subscribe(); var loginAndProjects = GetProjects.RegisterAsyncObservable(GetProjectsObservable).Publish().PermaRef(); // Page Navigation loginAndProjects .Select(_ => Page.SetupProject) .ToMessage(Messenger); // Project Selection Project = new ListSelectionHelper<Project>(Dispatcher); loginAndProjects .Snd() .Merge( EmptyReposOnRepoChange() ) .Subscribe(Project.ItemsObserver); // Settings Propagation LatestLoginWithRepo = loginAndProjects .Fst() .MostRecent(null) .GetEnumerator(); // Command Condition var projectSelected = Project.SelectedItemObservable .Select(p => p != NoProject) .AndNoItemsInFlight(GetProjects); // Command and Errorhandling this.GetProfile = new ReactiveAsyncCommand(projectSelected); GetProfile.ShowInFlightNotification(Notifications, DiversityResources.Setup_Info_GettingProfile); GetProfile.ThrownExceptions .ShowServiceErrorNotifications(Notifications) .ShowErrorNotifications(Notifications) .Subscribe(); var loginWithProfile = GetProfile.RegisterAsyncObservable(GetProfileObservable).Publish().PermaRef(); // Page Navigation loginWithProfile .Select(_ => Page.SetupGPS) .ToMessage(Messenger); // Settings Propagation LatestLoginWithProfile = loginWithProfile .MostRecent(null) .GetEnumerator(); // Command And Page Navigation this.Save = new ReactiveAsyncCommand(); Save.RegisterAsyncObservable(SaveSettings) .Select(_ => Page.SetupVocabulary) .ToMessage(Messenger); }
public TaxonManagementVM( IConnectivityService Connectivity, ITaxonService Taxa, IDiversityServiceClient Service, INotificationService Notification ) { this.Connectivity = Connectivity; this.Service = Service; this.Taxa = Taxa; this.Notification = Notification; _IsOnlineAvailable = this.ObservableToProperty(Connectivity.WifiAvailable(), x => x.IsOnlineAvailable); var localLists = this.FirstActivation() .SelectMany(_ => Taxa.getTaxonSelections() .ToObservable(ThreadPoolScheduler.Instance) .Select(list => new TaxonListVM(list))) .Publish(); LocalLists = localLists .ObserveOnDispatcher() .CreateCollection(); var onlineLists = localLists .IgnoreElements() //only download lists once the local ones are loaded .Concat(Observable.Return(null as TaxonListVM)) .CombineLatest(this.OnActivation(), (_, _2) => _2) .CheckConnectivity(Connectivity, Notification) .SelectMany(_ => { return Service.GetTaxonLists() .DisplayProgress(Notification, DiversityResources.TaxonManagement_State_DownloadingLists) .TakeUntil(this.OnDeactivation()); }) .ObserveOnDispatcher() .SelectMany(lists => lists.Where(list => !LocalLists.Any(loc => loc.Model == list)) // Filter lists already present locally .Select(list => new TaxonListVM(list)) ) .Publish(); PersonalLists = onlineLists.Where(vm => !vm.Model.IsPublicList) .CreateCollection(); PublicLists = onlineLists.Where(vm => vm.Model.IsPublicList) .CreateCollection(); onlineLists.Connect(); localLists.Connect(); Select = new ReactiveCommand<TaxonListVM>(vm => !vm.IsSelected && !vm.IsDownloading); Select.Subscribe(taxonlist => { foreach (var list in LocalLists) { if (list.Model.TaxonomicGroup == taxonlist.Model.TaxonomicGroup) list.Model.IsSelected = false; } Taxa.selectTaxonList(taxonlist.Model); }); Download = new ReactiveCommand<TaxonListVM>(vm => !vm.IsDownloading); Download .CheckConnectivity(Connectivity, Notification) .Subscribe(taxonlist => { if (Taxa.getTaxonTableFreeCount() > 0) { CurrentPivot = Pivot.Local; taxonlist.IsDownloading = true; makeListLocal(taxonlist); DownloadTaxonList(taxonlist) .DisplayProgress(Notification, DiversityResources.TaxonManagement_State_DownloadingList) .ObserveOnDispatcher() .ShowServiceErrorNotifications(Notification) .Subscribe(_ => { //Download Succeeded taxonlist.IsDownloading = false; if (Select.CanExecute(taxonlist)) Select.Execute(taxonlist); }, _ => //Download Failed { taxonlist.IsDownloading = false; removeLocalList(taxonlist); }, () => { }); } }); Delete = new ReactiveCommand<TaxonListVM>(vm => !vm.IsDownloading); Delete .Subscribe(taxonlist => { removeLocalList(taxonlist); }); Refresh = new ReactiveCommand<TaxonListVM>(vm => !vm.IsDownloading); Refresh .Subscribe(taxonlist => { if (Delete.CanExecute(taxonlist)) //Deletes synchronously Delete.Execute(taxonlist); if (Download.CanExecute(taxonlist)) Download.Execute(taxonlist); }); //Download all only on Personal pivot var canDownloadAll = this.WhenAny(x => x.CurrentPivot, x => x.GetValue()) .Select(p => p == Pivot.Personal) .CombineLatest(Connectivity.WifiAvailable(), (p, wi) => p && wi); DownloadAll = new ReactiveCommand(canDownloadAll, initialCondition: false); DownloadAll .SelectMany(_ => PersonalLists.ToArray()) .Where(vm => Download.CanExecute(vm)) .Subscribe(Download.Execute); }
public SettingsVM( ISettingsService Settings, ICleanupData Cleanup, IConnectivityService Connectivity ) { this.Cleanup = Cleanup; this.Settings = Settings; this.Connectivity = Connectivity; this.WhenAny(x => x.Model, x => x.Value) .Where(x => x != null) .Select(m => m.UseGPS) .Subscribe(x => UseGPS = x); Reset = new ReactiveAsyncCommand(Connectivity.WifiAvailable()); Reset.RegisterAsyncTask(OnReset); var setting_changed = this.WhenAny(x => x.UseGPS, x => x.Model, (gps, model) => (model.Value != null) ? model.Value.UseGPS != gps.Value : false); Save = new ReactiveCommand(setting_changed); Messenger.RegisterMessageSource( Save .Do(_ => saveModel()) .Select(_ => Page.Previous) ); RefreshVocabulary = new ReactiveCommand(Connectivity.WifiAvailable()); RefreshVocabulary .Subscribe(_ => { Messenger.SendMessage(Page.SetupVocabulary); }); ManageTaxa = new ReactiveCommand(); Messenger.RegisterMessageSource( ManageTaxa .Select(_ => Page.TaxonManagement) ); UploadData = new ReactiveCommand(); Messenger.RegisterMessageSource( UploadData .Select(_ => Page.Upload) ); DownloadData = new ReactiveCommand(); Messenger.RegisterMessageSource( DownloadData .Select(_ => Page.Download) ); Info = new ReactiveCommand(); Messenger.RegisterMessageSource( Info .Select(_ => Page.Info) ); ImportExport = new ReactiveCommand(); Messenger.RegisterMessageSource( ImportExport .Select(_ => Page.ImportExport) ); Settings .SettingsObservable() .Subscribe(x => Model = x); }
public MapManagementVM( IConnectivityService Network, IMapTransferService MapService, IMapStorageService MapStorage, INotificationService Notifications, [Dispatcher] IScheduler Dispatcher ) { Contract.Requires(Network != null); Contract.Requires(MapService != null); Contract.Requires(MapStorage != null); Contract.Requires(Notifications != null); this.Network = Network; this.MapService = MapService; this.MapStorage = MapStorage; this.FirstActivation() .Subscribe(_ => getMaps.Execute(null)); MapList = getMaps.RegisterAsyncFunction(_ => MapStorage.getAllMaps().Select(m => new MapVM(m))) .SelectMany(vms => vms.ToList()) .ObserveOn(Dispatcher) .CreateCollection(); MapList.ItemsAdded .Subscribe(item => _local_map_register.Add(item.ServerKey, Unit.Default)); MapList.ItemsRemoved .Subscribe(item => _local_map_register.Remove(item.ServerKey)); SelectMap = new ReactiveCommand<MapVM>(vm => !vm.IsDownloading); SelectMap .Select(vm => vm as IElementVM<Map>) .ToMessage(Messenger, MessageContracts.VIEW); SelectMap .Select(_ => Page.Previous) .ToMessage(Messenger); DeleteMap = new ReactiveCommand<MapVM>(vm => !vm.IsDownloading); DeleteMap .Do(vm => MapList.Remove(vm)) .Select(vm => vm.Model) .Where(map => map != null) .Subscribe(map => MapStorage.deleteMap(map)); _IsOnlineAvailable = this.ObservableToProperty( this.OnActivation() .SelectMany(Network.WifiAvailable().TakeUntil(this.OnDeactivation())) .Do(x => { }) , x => x.IsOnlineAvailable, false); SearchMaps = new ReactiveAsyncCommand(_IsOnlineAvailable); _SearchResults = this.ObservableToProperty<MapManagementVM, IReactiveCollection<MapVM>>( SearchMaps.RegisterAsyncFunction(s => searchMapsImpl(s as string)) .ObserveOn(Dispatcher) .Select(result => { try { return new ReactiveCollection<MapVM>(result.Select(x => new MapVM(null) { ServerKey = x })) as IReactiveCollection<MapVM>; } catch (Exception) { return null; } }), x => x.SearchResults); DownloadMap = new ReactiveCommand<MapVM>(vm => canBeDownloaded(vm as MapVM), Observable.Empty<Unit>()); DownloadMap .Where(downloadMap.CanExecute) .CheckConnectivity(Network, Notifications) .Do(vm => vm.IsDownloading = true) .Do(_ => CurrentPivot = Pivot.Local) .Do(vm => MapList.Add(vm)) .Subscribe(downloadMap.Execute); downloadMap.RegisterAsyncObservable(vm => { var vm_t = vm as MapVM; if (vm_t == null) return Observable.Empty<System.Tuple<MapVM, Map>>(); else return MapService.downloadMap(vm_t.ServerKey) .ShowServiceErrorNotifications(Notifications) .Catch((WebException ex) => { Notifications.showNotification(DiversityResources.MapManagement_Message_NoPermissions); return Observable.Empty<Map>(); }) .Select(map => System.Tuple.Create(vm_t, map)); }) .ObserveOn(Dispatcher) .Select(t => { if (t.Item1 != null) // VM { if (t.Item2 != null) // Map { t.Item1.SetModel(t.Item2); } else { MapList.Remove(t.Item1); } } return t.Item1; }).Subscribe(_ => SelectMap.RaiseCanExecuteChanged()); }