public MapTransferService(IMapStorageService storage, ICredentialsService creds) { MapStorage = storage; CredentialsProvider = creds; using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { if (!isoStore.DirectoryExists("Maps")) { isoStore.CreateDirectory("Maps"); } } GetMapsListCompletedObservable = Observable.FromEventPattern<GetMapListFilterCompletedEventArgs>(d => MapService.GetMapListFilterCompleted += d, d => MapService.GetMapListFilterCompleted -= d); GetMapUrlCompletedObservable = Observable.FromEventPattern<GetMapUrlCompletedEventArgs>(d => MapService.GetMapUrlCompleted += d, d => MapService.GetMapUrlCompleted -= d); GetXmlUrlCompletedObservable = Observable.FromEventPattern<GetXmlUrlCompletedEventArgs>(d => MapService.GetXmlUrlCompleted += d, d => MapService.GetXmlUrlCompleted -= d); }
public ViewMapVM( IMapStorageService MapStorage, ILocationService Location, IFieldDataService Storage ) { Contract.Requires(MapStorage != null); Contract.Requires(Location != null); Contract.Requires(Storage != null); this.MapStorage = MapStorage; this.Location = Location; this.Storage = Storage; ImageScale = 1.0; ImageOffset = new Point(); SelectMap = new ReactiveCommand(); SelectMap .Select(_ => Page.MapManagement) .ToMessage(Messenger); this.FirstActivation() .Select(_ => Page.MapManagement) .ToMessage(Messenger); _CurrentMap = this.ObservableToProperty(Messenger.Listen<IElementVM<Map>>(MessageContracts.VIEW), x => x.CurrentMap); _CurrentMap .Where(vm => vm != null) .Select(vm => Observable.Start(() => MapStorage.loadMap(vm.Model))) .Switch() .ObserveOnDispatcher() .Select(stream => { var img = new BitmapImage(); img.SetSource(stream); stream.Close(); return img; }) .Subscribe(x => MapImage = x); var current_series = Messenger.Listen<ILocationOwner>(MessageContracts.VIEW); var current_localizable = Messenger.Listen<ILocalizable>(MessageContracts.VIEW); var current_series_if_not_localizable = current_series.Merge(current_localizable.Select(_ => null as ILocationOwner)); var current_localizable_if_not_series = current_localizable.Merge(current_series.Select(_ => null as ILocalizable)); var series_and_map = current_series_if_not_localizable .CombineLatest(_CurrentMap.Where(x => x != null), (es, map) => new { Map = map.Model, Series = es }) .Publish(); var add_locs = series_and_map .Select(pair => { if (pair.Series != null) { var stream = Storage.getGeoPointsForSeries(pair.Series.EntityID).ToObservable(ThreadPoolScheduler.Instance) //Fetch geopoints asynchronously on Threadpool thread .Merge(Messenger.Listen<GeoPointForSeries>(MessageContracts.SAVE).Where(gp => gp.SeriesID == pair.Series.EntityID)) //Listen to new Geopoints that are added to the current tour .Select(gp => pair.Map.PercentilePositionOnMap(gp)) .TakeUntil(series_and_map) .Replay(); stream.Connect(); return stream as IObservable<Point?>; } else return Observable.Empty<Point?>(); }).Replay(1); _AdditionalLocalizations = add_locs; add_locs.Connect(); series_and_map.Connect(); Observable.CombineLatest( current_localizable_if_not_series, _CurrentMap, (loc, map) => { if (map == null) return null; return map.Model.PercentilePositionOnMap(loc); }) .Subscribe(c => PrimaryLocalization = c); ToggleEditable = new ReactiveCommand(current_localizable_if_not_series.Select(l => l != null)); _IsEditable = this.ObservableToProperty( current_localizable_if_not_series.Select(_ => false) .Merge(ToggleEditable.Select(_ => true)), x => x.IsEditable); SetLocation = new ReactiveCommand(_IsEditable); SetLocation .Select(loc => loc as Point?) .Where(loc => loc != null) .Subscribe(loc => PrimaryLocalization = loc); var valid_localization = this.ObservableForProperty(x => x.PrimaryLocalization).Value() .Select(loc => loc.HasValue); Save = new ReactiveCommand(_IsEditable.BooleanAnd(valid_localization)); current_localizable_if_not_series .Where(loc => loc != null) .Select(loc => Save .Select(_ => loc) ) .Switch() .Do(c => c.SetCoordinates(CurrentMap.Model.GPSFromPercentilePosition(PrimaryLocalization.Value))) .Do(_ => Messenger.SendMessage(Page.Previous)) .ToMessage(Messenger, MessageContracts.SAVE); this.OnActivation() .Where(_ => CurrentMap != null) .SelectMany(_ => Location.Location().StartWith(null as Coordinate).TakeUntil(this.OnDeactivation())) .Select(c => CurrentMap.Model.PercentilePositionOnMap(c)) .Subscribe(c => CurrentLocation = c); }
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()); }