/// <inheritdoc /> public override IObservable <DeviceState> GetAndObserveState() => _state .DistinctUntilChanged() .Select(isOn => new DeviceState( PinNumber.ToString(), ImmutableDictionary <string, string> .Empty.SetItem("state", isOn ? "on" : "off"), isPersistedState: true));
/// <summary> /// Initializes a new instance of the <see cref="FeatureActivator"/> class. /// </summary> /// <param name="activate">A function to be called when the first observer subscribes and all dependencies (if any) are available.</param> /// <param name="deactivate">A function to be called when any dependency becomes unavailable.</param> /// <param name="dependsOn">A set of dependencies, all of which must produce a true result in order for activation to be triggered.</param> public FeatureActivator(Func <T> activate, Func <T> deactivate, params IObservable <bool>[] dependsOn) { if (activate == null) { throw new ArgumentNullException("activate"); } this.activate = activate; this.deactivate = deactivate ?? (() => default(T)); IObservable <bool> dependenciesAvailable = new BehaviorSubject <bool>(true); foreach (var dependency in dependsOn) { dependenciesAvailable = dependenciesAvailable.CombineLatest(dependency, (x, y) => x && y); } available = dependenciesAvailable .DistinctUntilChanged() .Select(availableNow => { if (!availableNow) { if (hasBeenActivated) { return(Deactivate()); } return(default(T)); } return(Activate()); }) .Replay(1); }
public ObservableProperty(TValue defaultValue, INotifyPropertyChangedEx notifier, string propertyName) { _current = defaultValue; _values = new BehaviorSubject <TValue>(defaultValue); _notifySubscription = _values.DistinctUntilChanged().Do(value => _current = value).Subscribe(value => notifier.NotifyOfPropertyChange(propertyName)); }
public void Initialize() { Observable.FromEventPattern <ConnectionStateChangedEventArgs>(ev => Client.ConnectionStateChanged += ev, ev => Client.ConnectionStateChanged -= ev) .Select(pattern => pattern.EventArgs.NewState) .Subscribe(connectionStateSubject.OnNext) .AddDisposableTo(disposables); connectionStateSubject .DistinctUntilChanged() .Where(state => state == TwinCAT.ConnectionState.Connected) .Do(UpdateSymbols) .Subscribe() .AddDisposableTo(disposables); IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); var localhost = host .AddressList .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork); AmsNetIds = DeviceFinder.BroadcastSearchAsync(localhost).Result.Select(x => new NetId { Name = x.Name, Address = x.AmsNetId.ToString() }).ToList(); }
public static IObservable <IImmutableList <TItem> > PoolPerElement <TOwner, TItem>( this IObservable <IEnumerable <TOwner> > owners, Func <int, IObservable <TOwner>, TItem> createNewItem) { return(Observable.Defer(() => { var pool = ImmutableList <Tuple <BehaviorSubject <TOwner>, TItem> > .Empty; return owners.Select(o => { var ownersArray = o.ToArray(); var split = Math.Min(ownersArray.Length, pool.Count); for (int i = 0; i < split; i++) { pool[i].Item1.OnNext(ownersArray[i]); } for (int i = split; i < ownersArray.Length; i++) { var owner = new BehaviorSubject <TOwner>(ownersArray[i]); var item = createNewItem(i, owner.DistinctUntilChanged()); pool = pool.Add(Tuple.Create(owner, item)); } return pool .Select(p => p.Item2) .Take(ownersArray.Length) .ToImmutableList(); }); }) .DistinctUntilChanged(list => list.Count)); }
public LogsViewService(ILogFilterResultsService logFilterResultsService, IDialogService dialogService) { _logEvents = new BehaviorSubject <IList <LogEvent> >(Array.Empty <LogEvent>()); _selectedLogEventProperty = new BehaviorSubject <LogEvent>(null); LogEvents = _logEvents.AsObservable(); // Subscribe to log filter result logFilterResultsService .Result .AsItemsBehaviorObservable() .ObserveOn(Dispatcher) .Subscribe(_logEvents); LogEvents.Subscribe(CoerceSelectedLogEvent); SelectedLogEventProperty = _selectedLogEventProperty .DistinctUntilChanged() .AsObservable(); OpenLogEventCommand = Command.Create( SelectedLogEventProperty.Select <LogEvent, Func <object, bool> >(logEvent => param => logEvent != null), async(param) => { await dialogService.ShowDialog(new LogEventDialog()); } ); SelectNextCommand = Command.Create((object o) => Move(1)); SelectPreviousCommand = Command.Create((object o) => Move(-1)); SelectNextPageCommand = Command.Create((object o) => NextPage()); SelectPreviousPageCommand = Command.Create((object o) => PreviousPage()); SelectFirstCommand = Command.Create((object o) => SelectFirst()); SelectLastCommand = Command.Create((object o) => SelectLast()); }
public void Initialize() { Observable.FromEventPattern <ConnectionStateChangedEventArgs>(ev => Client.ConnectionStateChanged += ev, ev => Client.ConnectionStateChanged -= ev) .Select(pattern => pattern.EventArgs.NewState) .Subscribe(connectionStateSubject.OnNext) .AddDisposableTo(disposables); connectionStateSubject .DistinctUntilChanged() .Where(state => state == TwinCAT.ConnectionState.Connected) .Do(UpdateSymbols) .Subscribe() .AddDisposableTo(disposables); Observable.Interval(TimeSpan.FromSeconds(1)) .Do(_ => CheckConnectionHealth()) .Subscribe() .AddDisposableTo(disposables); IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); var localhost = host .AddressList .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork); Observable.Return(Unit.Default) .SelectMany(_ => DeviceFinder.BroadcastSearchAsync(localhost)) .Select(x => x.Select(d => new NetId { Name = d.Name, Address = d.AmsNetId.ToString() })) .Subscribe(foundNetIdSubject.OnNext) .AddDisposableTo(disposables) ; }
public override async Task <bool> Initialize() { try { logger.LogInformation($"Connecting with Beckhoff at '{settingsProvider.Settings.BeckhoffSettings.AmsNetId}:{settingsProvider.Settings.BeckhoffSettings.Port}'..."); InitializeBeckhoff(settingsProvider.Settings.BeckhoffSettings); } catch (Exception e) { logger.LogError(e, "Error while initializing beckhoff"); } Observable.Interval(TimeSpan.FromSeconds(1)) .Do(_ => CheckConnectionHealth()) .Subscribe() .AddDisposableTo(Disposables); connectionStateSubject .DistinctUntilChanged() .Do(state => logger.LogDebug($"Connection state changed to '{state}'")) .Subscribe() .AddDisposableTo(Disposables); adsStateSubject .DistinctUntilChanged() .Do(state => logger.LogDebug($"Ads state changed to '{state}'")) .Do(UpdateSymbols) .Subscribe() .AddDisposableTo(Disposables); return(await base.Initialize()); }
public TokenResetViewModel( IUserAccessManager userAccessManager, ITogglDataSource dataSource, IDialogService dialogService, IMvxNavigationService navigationService, IUserPreferences userPreferences, IAnalyticsService analyticsService, ISchedulerProvider schedulerProvider, IRxActionFactory rxActionFactory, IInteractorFactory interactorFactory ) { Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); Ensure.Argument.IsNotNull(userAccessManager, nameof(userAccessManager)); Ensure.Argument.IsNotNull(dialogService, nameof(dialogService)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(userPreferences, nameof(userPreferences)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory)); Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory)); this.dataSource = dataSource; this.userAccessManager = userAccessManager; this.dialogService = dialogService; this.navigationService = navigationService; this.userPreferences = userPreferences; this.analyticsService = analyticsService; this.schedulerProvider = schedulerProvider; this.rxActionFactory = rxActionFactory; this.interactorFactory = interactorFactory; Email = emailSubject .DistinctUntilChanged() .AsDriver(schedulerProvider); IsPasswordMasked = isPasswordMaskedSubject .DistinctUntilChanged() .AsDriver(schedulerProvider); TogglePasswordVisibility = rxActionFactory.FromAction(togglePasswordVisibility); Done = rxActionFactory.FromObservable(done); SignOut = rxActionFactory.FromAsync(signout); Error = Done.Errors .Select(transformException); HasError = Error .Select(error => !string.IsNullOrEmpty(error)) .DistinctUntilChanged() .AsDriver(schedulerProvider); NextIsEnabled = Password .Select(Multivac.Password.From) .CombineLatest(Done.Executing, (password, isExecuting) => password.IsValid && !isExecuting) .DistinctUntilChanged() .AsDriver(schedulerProvider); }
public Observable(T initalValue) { this.values = new BehaviorSubject <T>(initalValue); values.DistinctUntilChanged().Subscribe(x => { FirePropertyChanged(x) }); }
public ValveSubject() { var valveOperations = valveSubject.DistinctUntilChanged(); input.Buffer( bufferOpenings: valveOperations.Where(v => v == Valve.Closed), bufferClosingSelector: _ => valveOperations.Where(v => v == Valve.Open)) .SelectMany(t => t).Subscribe(input); input.Where(t => valveSubject.Value == Valve.Open).Subscribe(output); }
public Property(TValue defaultValue, string propertyName, Action <PropertyChangedEventArgs> notifyPropertyChanged) { _current = defaultValue; _values = new BehaviorSubject <TValue>(defaultValue); _notifySubscription = _values .DistinctUntilChanged() .Do(value => _current = value) .Subscribe(value => notifyPropertyChanged(new PropertyChangedEventArgs(propertyName))); }
public ActiveDownload(IConnectableObservable <DownloadProgress> downloadProgress, Action completed, string name) { Name = name; LogTo.Verbose("[{download}] Created ActiveDownload", Name); disposable.Add(downloadProgress.Subscribe(progress)); disposable.Add(downloadProgress.Connect()); disposable.Add(progress.DistinctUntilChanged(dp => dp.State).Subscribe(dp => LogTo.Verbose("[{download}] State changed to {state}", Name, dp.State))); disposable.Add(progress.Subscribe(_ => { }, completed)); }
public IObservable <bool> GetActivationForView(ReactiveUI.IActivatable view) { BehaviorSubject <bool> activation; if (ActivationMap.TryGetValue(view, out activation)) { return(activation); } activation = new BehaviorSubject <bool>(false); ActivationMap.Add(view, activation); return(activation.DistinctUntilChanged()); }
public bool Initialize() { try { Logger?.Information($"Connecting with Beckhoff at '{settings.AmsNetId}:{settings.Port}'..."); InitializeBeckhoff(); } catch (Exception e) { Logger?.Error(e, "Error while initializing beckhoff"); } Observable.Interval(TimeSpan.FromSeconds(1)) .Do(_ => CheckConnectionHealth()) .Subscribe() .AddDisposableTo(Disposables); connectionStateSubject .DistinctUntilChanged() .Do(state => Logger?.Debug($"Connection state changed to '{state}'")) .Subscribe() .AddDisposableTo(Disposables); adsStateSubject .DistinctUntilChanged() .Do(state => Logger?.Debug($"Ads state changed to '{state}'")) .Do(UpdateSymbols) .Subscribe() .AddDisposableTo(Disposables); connectionStateSubject.AddDisposableTo(Disposables); adsStateSubject.AddDisposableTo(Disposables); symbolsSubject.AddDisposableTo(Disposables); return(true); }
/// <summary> /// Constructor. /// </summary> /// <param name="dataStorage">Storage instance.</param> public ReactiveData(DataStorage dataStorage) { RefreshingStateObservable = _refreshingState.DistinctUntilChanged(); var rootObservable = Observable.Return(Unit.Default) .Concat(_refreshSucceeded); FeedListObservable = rootObservable .Select(t => dataStorage.GetAllFeeds()) .Concat() .Replay(1) .RefCount(); }
public Property(T?initialValue, Func <T?, T?, T?>?coerceValue = null, IEqualityComparer <T>?comparer = null) { this.Value = initialValue; this.coerceValue = coerceValue; stream = new BehaviorSubject <T>(CoerceValue(initialValue) !); ValueChanged = stream .DistinctUntilChanged(comparer.OrDefault()) .Select(_ => Unit.Default); disposables.Add(stream.Subscribe(value => Value = value)); disposables.Add(new Disposable(() => stream.OnCompleted())); }
public UpdateService(bool isUpdateCheckDisabled, string updatesPath) { IsUpdateCheckEnabled = !isUpdateCheckDisabled; _updateManager = new UpdateManager( new LocalPackageResolver(updatesPath, "TogglDesktopInstaller*.exe"), new NsisPackageExtractor()); Toggl.OnUpdateDownloadStatus .Where(x => x.DownloadStatus != Toggl.DownloadStatus.Done) .Subscribe(_updateStatusSubject); Toggl.OnUpdateDownloadStatus .Where(x => x.DownloadStatus == Toggl.DownloadStatus.Done) .Subscribe(PrepareUpdate); UpdateStatus = _updateStatusSubject.AsObservable(); UpdateChannel = new BehaviorSubject <string>("stable"); UpdateChannel.DistinctUntilChanged().Skip(1).Subscribe(channel => Toggl.SetUpdateChannel(channel)); }
public MainWindowViewModel() { _disposables = new CompositeDisposable(); _connectionDisposables = new CompositeDisposable(); VideoPlayer = new VideoPlayerModel().AddTo(_disposables); ConnectedDevice = new DeviceModel(); SelectDeviceCommand = new ReactiveCommand().AddTo(_disposables); SelectDeviceCommand.Delay(new TimeSpan(100)).ObserveOnUIDispatcher().SelectMany(_ => DialogHost.Show(new DeviceSelectDialog(), OnSelectDeviceDialogClosing).ToObservable()) .Subscribe(async(result) => await ConnenctDevice(result as DiscoverResult)).AddTo(_disposables); _viewMode = new BehaviorSubject <ViewMode>(ViewMode.None).AddTo(_disposables); IsModeRec = new ReactiveProperty <bool>().AddTo(_disposables); IsModeLive = new ReactiveProperty <bool>().AddTo(_disposables); IsModeInput = new ReactiveProperty <bool>().AddTo(_disposables); IsModeOutput = new ReactiveProperty <bool>().AddTo(_disposables); _viewMode.DistinctUntilChanged().Subscribe(m => { IsModeRec.Value = (m == ViewMode.Rec); IsModeLive.Value = (m == ViewMode.Live); IsModeInput.Value = (m == ViewMode.Input); IsModeOutput.Value = (m == ViewMode.Output); }).AddTo(_disposables); IsModeRec.Where(b => b).Subscribe(async(_) => await ToRecMode()).AddTo(_disposables); IsModeLive.Where(b => b).Subscribe(async(_) => await ToLiveMode()).AddTo(_disposables); IsModeInput.Where(b => b).Subscribe(async(_) => await ToInputMode()).AddTo(_disposables); IsModeOutput.Where(b => b).Subscribe(async(_) => await ToOutputMode()).AddTo(_disposables); _viewMode.OnNext(ViewMode.Output); SliderValue = new[] { new ReactiveProperty <double>(1.0).AddTo(_disposables), new ReactiveProperty <double>(0.0).AddTo(_disposables), new ReactiveProperty <double>(0.0).AddTo(_disposables), new ReactiveProperty <double>(0.0).AddTo(_disposables) }; SliderMaximum = new ReactiveProperty <double>(1.0).AddTo(_disposables); IsSliderActive = new[] { new ReactiveProperty <bool>(true).AddTo(_disposables), new ReactiveProperty <bool>(false).AddTo(_disposables), new ReactiveProperty <bool>(false).AddTo(_disposables), new ReactiveProperty <bool>(false).AddTo(_disposables) }; SliderValue[0].Subscribe(async(value) => await OnSliderValueChanged(0, value)).AddTo(_disposables); SliderValue[1].Subscribe(async(value) => await OnSliderValueChanged(1, value)).AddTo(_disposables); SliderValue[2].Subscribe(async(value) => await OnSliderValueChanged(2, value)).AddTo(_disposables); SliderValue[3].Subscribe(async(value) => await OnSliderValueChanged(3, value)).AddTo(_disposables); }
private IObservable <int> TransferFileAsync(SongTransferMessage message) { const int bufferSize = 32 * 1024; int written = 0; Stream stream = this.currentFileTransferClient.GetStream(); var progress = new BehaviorSubject <int>(0); Task.Run(async() => { this.Log().Info("Starting a file transfer with ID: {0} and a size of {1} bytes", message.TransferId, message.Data.Length); var traits = new Dictionary <string, string> { { "Size", message.Data.Length.ToString() } }; using (Insights.TrackTime("Song Transfer", traits)) { byte[] data = await NetworkHelpers.PackFileTransferMessageAsync(message); using (var dataStream = new MemoryStream(data)) { var buffer = new byte[bufferSize]; int count; while ((count = dataStream.Read(buffer, 0, bufferSize)) > 0) { stream.Write(buffer, 0, count); written += count; progress.OnNext((int)(100 * ((double)written / data.Length))); } } } progress.OnCompleted(); }); return(progress.DistinctUntilChanged()); }
/// <summary> /// Initializes a new instance of the <see cref="StateHolder{THeldState, THeldStateBuilder}"/> class. /// </summary> protected StateHolder() { _transactionBuffer = new ActionBlock <Tracked <TransactionFunc> >( transaction => { // This block will run serially because MaxDegreeOfParallelism is 1 // That means we can read from and modify the current state (held in the subject) atomically transaction.Value(_currentStateSubject); transaction.Complete(); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, TaskScheduler = TaskScheduler.Default }); _transactionBufferEx = new TransformBlock <KeyValuePair <Guid, TransactionFunc>, Guid>( transaction => { transaction.Value(_currentStateSubject); return(transaction.Key); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, TaskScheduler = TaskScheduler.Default }); CurrentState = _currentStateSubject.DistinctUntilChanged(); }
public SocketManager(IObservable <string> endpointObservable) { /* This determines when we want the socket to be open */ needOpenSubject = new BehaviorSubject <bool>(false); /* Setup the frame management */ this.GetPropertyValues(x => x.Socket) .Subscribe(x => { if (x == null) { if (frameDisposable != null) { frameDisposable.Dispose(); frameDisposable = null; } } else { frameDisposable = Observable.FromEventPattern <MessageReceivedEventArgs>(x, "MessageReceived") .Select(y => JObject.Parse(y.EventArgs.Message)) .Subscribe(y => framesSubject.OnNext(y)) .DisposeWith(compositeDisposable); } }).DisposeWith(compositeDisposable); this.GetPropertyValues(x => x.Socket) .DistinctUntilChanged() .Where(x => x == null) .Zip(endpointObservable, (x, y) => y) .Subscribe(x => { connectingSubject = new BehaviorSubject <SocketState>(SocketState.None); Socket = new WebSocket(x).DisposeWith(compositeDisposable); }).DisposeWith(compositeDisposable); this.GetPropertyValues(x => x.Socket) .DistinctUntilChanged() .Where(x => x != null) .Subscribe(x => { var whenOpen = GetConnectionStateObservable(x); /* Heartbeat */ whenOpen.CombineLatest(needOpenSubject.AsObservable().DistinctUntilChanged(), Observable.Interval(TimeSpan.FromMilliseconds(HEARTBEAT_INTERVAL)), (currentState, needOpen, _time) => currentState == SocketState.Open && needOpen) .Catch <bool, Exception>(ex => Observable.Return(false)) .Where(y => y) .Subscribe(_ => SendHeartbeat()); /* Control whether to open or close the socket */ whenOpen.DistinctUntilChanged() .Scan(new StateChange(), (prev, next) => new StateChange(prev.Current, next)) .Select(s => s.Current) .CombineLatest(needOpenSubject.DistinctUntilChanged(), (isOpen, needOpen) => new Tuple <SocketState, bool>(isOpen, needOpen)) .Delay(TimeSpan.FromMilliseconds(250)) .Catch <Tuple <SocketState, bool>, Exception>(ex => { x.Close(); connectingSubject.Dispose(); connectingSubject = null; this.Socket = null; publicState.OnNext(SocketState.Errored); return(Observable.Return(new Tuple <SocketState, bool>(SocketState.None, false))); }) .Subscribe(t => { var isOpen = t.Item1; var needOpen = t.Item2; if (!(isOpen == SocketState.Open || isOpen == SocketState.Opening) && needOpen) { if (x.State != WebSocketState.Connecting) { connectingSubject.OnNext(SocketState.Opening); x.Open(); } } else if (isOpen == SocketState.Open && !needOpen) { x.Close(); connectingSubject.OnNext(SocketState.Closing); } publicState.OnNext(isOpen); }).DisposeWith(compositeDisposable); /* Setup logic for sending messages. We queue them up until we're connected, then send. */ var published = sendSubject.Delay(TimeSpan.FromMilliseconds(20)).Publish(); published.Subscribe(p => x.Send(p)).DisposeWith(compositeDisposable); whenOpen.Catch <SocketState, Exception>(ex => Observable.Return(SocketState.None)) .Subscribe(s => { if (s == SocketState.Open) { sendConnection = new CompositeDisposable(published.Connect(), Disposable.Create(() => sendSubject.Clear())); } else if (sendConnection != null) { sendConnection.Dispose(); } }).DisposeWith(compositeDisposable); }); }
public MutableProperty(T initialValue) { _subject = new BehaviorSubject <T>(initialValue); _distinctValue = _subject.DistinctUntilChanged(); }
public LoginViewModel( ILoginManager loginManager, IAnalyticsService analyticsService, IOnboardingStorage onboardingStorage, IForkingNavigationService navigationService, IPasswordManagerService passwordManagerService, IErrorHandlingService errorHandlingService, ILastTimeUsageStorage lastTimeUsageStorage, ITimeService timeService, ISchedulerProvider schedulerProvider) { Ensure.Argument.IsNotNull(loginManager, nameof(loginManager)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(passwordManagerService, nameof(passwordManagerService)); Ensure.Argument.IsNotNull(errorHandlingService, nameof(errorHandlingService)); Ensure.Argument.IsNotNull(lastTimeUsageStorage, nameof(lastTimeUsageStorage)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); this.timeService = timeService; this.loginManager = loginManager; this.analyticsService = analyticsService; this.onboardingStorage = onboardingStorage; this.navigationService = navigationService; this.errorHandlingService = errorHandlingService; this.lastTimeUsageStorage = lastTimeUsageStorage; this.passwordManagerService = passwordManagerService; this.schedulerProvider = schedulerProvider; var emailObservable = emailSubject.Select(email => email.TrimmedEnd()); Shake = shakeSubject.AsDriver(this.schedulerProvider); Email = emailObservable .Select(email => email.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); Password = passwordSubject .Select(password => password.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsLoading = isLoadingSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); ErrorMessage = errorMessageSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsPasswordMasked = isPasswordMaskedSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsShowPasswordButtonVisible = Password .Select(password => password.Length > 1) .CombineLatest(isShowPasswordButtonVisibleSubject.AsObservable(), CommonFunctions.And) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); HasError = ErrorMessage .Select(string.IsNullOrEmpty) .Select(CommonFunctions.Invert) .AsDriver(this.schedulerProvider); LoginEnabled = emailObservable .CombineLatest( passwordSubject.AsObservable(), IsLoading, (email, password, isLoading) => email.IsValid && password.IsValid && !isLoading) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsPasswordManagerAvailable = passwordManagerService.IsAvailable; }
public SignupViewModel( IApiFactory apiFactory, IUserAccessManager userAccessManager, IAnalyticsService analyticsService, IOnboardingStorage onboardingStorage, IForkingNavigationService navigationService, IErrorHandlingService errorHandlingService, ILastTimeUsageStorage lastTimeUsageStorage, ITimeService timeService, ISchedulerProvider schedulerProvider, IRxActionFactory rxActionFactory, IPlatformInfo platformInfo) { Ensure.Argument.IsNotNull(apiFactory, nameof(apiFactory)); Ensure.Argument.IsNotNull(userAccessManager, nameof(userAccessManager)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(errorHandlingService, nameof(errorHandlingService)); Ensure.Argument.IsNotNull(lastTimeUsageStorage, nameof(lastTimeUsageStorage)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory)); Ensure.Argument.IsNotNull(platformInfo, nameof(platformInfo)); this.apiFactory = apiFactory; this.userAccessManager = userAccessManager; this.analyticsService = analyticsService; this.onboardingStorage = onboardingStorage; this.navigationService = navigationService; this.errorHandlingService = errorHandlingService; this.lastTimeUsageStorage = lastTimeUsageStorage; this.timeService = timeService; this.schedulerProvider = schedulerProvider; this.rxActionFactory = rxActionFactory; this.platformInfo = platformInfo; Login = rxActionFactory.FromAsync(login); Signup = rxActionFactory.FromAsync(signup); GoogleSignup = rxActionFactory.FromAsync(googleSignup); PickCountry = rxActionFactory.FromAsync(pickCountry); var emailObservable = emailSubject.Select(email => email.TrimmedEnd()); Shake = shakeSubject.AsDriver(this.schedulerProvider); Email = emailObservable .Select(email => email.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); Password = passwordSubject .Select(password => password.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsLoading = isLoadingSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsCountryErrorVisible = isCountryErrorVisibleSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); ErrorMessage = errorMessageSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); CountryButtonTitle = countryNameSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsPasswordMasked = isPasswordMaskedSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsShowPasswordButtonVisible = Password .Select(password => password.Length > 1) .CombineLatest(isShowPasswordButtonVisibleSubject.AsObservable(), CommonFunctions.And) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); HasError = ErrorMessage .Select(string.IsNullOrEmpty) .Select(CommonFunctions.Invert) .AsDriver(this.schedulerProvider); SignupEnabled = emailObservable .CombineLatest( passwordSubject.AsObservable(), IsLoading, countryNameSubject.AsObservable(), (email, password, isLoading, countryName) => email.IsValid && password.IsValid && !isLoading && (countryName != Resources.SelectCountry)) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); SuccessfulSignup = successfulSignupSubject .AsDriver(this.schedulerProvider); }
public LoginViewModel( IUserAccessManager userAccessManager, IAnalyticsService analyticsService, IOnboardingStorage onboardingStorage, INavigationService navigationService, IErrorHandlingService errorHandlingService, ILastTimeUsageStorage lastTimeUsageStorage, ITimeService timeService, ISchedulerProvider schedulerProvider, IRxActionFactory rxActionFactory, IInteractorFactory interactorFactory) : base(navigationService) { Ensure.Argument.IsNotNull(userAccessManager, nameof(userAccessManager)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(errorHandlingService, nameof(errorHandlingService)); Ensure.Argument.IsNotNull(lastTimeUsageStorage, nameof(lastTimeUsageStorage)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory)); Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory)); this.timeService = timeService; this.userAccessManager = userAccessManager; this.analyticsService = analyticsService; this.onboardingStorage = onboardingStorage; this.errorHandlingService = errorHandlingService; this.lastTimeUsageStorage = lastTimeUsageStorage; this.schedulerProvider = schedulerProvider; this.interactorFactory = interactorFactory; var emailObservable = emailSubject.Select(email => email.TrimmedEnd()); Signup = rxActionFactory.FromAsync(signup); ForgotPassword = rxActionFactory.FromAsync(forgotPassword); Shake = shakeSubject.AsDriver(this.schedulerProvider); Email = emailObservable .Select(email => email.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); Password = passwordSubject .Select(password => password.ToString()) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsLoading = isLoadingSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); ErrorMessage = errorMessageSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsPasswordMasked = isPasswordMaskedSubject .DistinctUntilChanged() .AsDriver(this.schedulerProvider); IsShowPasswordButtonVisible = Password .Select(password => password.Length > 1) .CombineLatest(isShowPasswordButtonVisibleSubject.AsObservable(), CommonFunctions.And) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); HasError = ErrorMessage .Select(string.IsNullOrEmpty) .Select(CommonFunctions.Invert) .AsDriver(this.schedulerProvider); LoginEnabled = emailObservable .CombineLatest( passwordSubject.AsObservable(), IsLoading, (email, password, isLoading) => email.IsValid && password.IsValid && !isLoading) .DistinctUntilChanged() .AsDriver(this.schedulerProvider); }
public IObservable <IChangeSet <IModListingGetter> > Get(out IObservable <ErrorResponse> state, IScheduler?scheduler = null) { var stateSubj = new BehaviorSubject <Exception?>(null); state = stateSubj .DistinctUntilChanged() .Select(x => x == null ? ErrorResponse.Success : ErrorResponse.Fail(x)); return(Observable.Create <IChangeSet <IModListingGetter> >((observer) => { CompositeDisposable disp = new(); SourceList <IModListingGetter> list = new(); var ret = PluginLive.Changed .Merge(CccLive.Changed) .StartWith(Unit.Default); if (Timings.Throttle.Ticks > 0) { ret = ret.ThrottleWithOptionalScheduler(Timings.Throttle, scheduler); } disp.Add( ret.Select(_ => { return Observable.Return(Unit.Default) .Do(_ => { try { // Short circuit if not subscribed anymore if (disp.IsDisposed) { return; } var refreshedListings = ListingsProvider.Get().ToArray(); // ToDo // Upgrade to SetTo mechanics. // SourceLists' EditDiff seems weird list.Clear(); list.AddRange(refreshedListings); stateSubj.OnNext(null); } catch (Exception ex) { // Short circuit if not subscribed anymore if (disp.IsDisposed) { return; } stateSubj.OnNext(ex); throw; } }) .RetryWithRampingBackoff <Unit, Exception>( Timings.RetryInterval, Timings.RetryIntervalMax, scheduler); }) .Switch() .Subscribe()); list.Connect() .Subscribe(observer); return disp; }) .ObserveOnIfApplicable(scheduler)); }
public IObservable <TState> Select() { return(_observableState.DistinctUntilChanged()); }
public EditTimeEntryViewModel( ITimeService timeService, ITogglDataSource dataSource, ISyncManager syncManager, IInteractorFactory interactorFactory, IMvxNavigationService navigationService, IOnboardingStorage onboardingStorage, IDialogService dialogService, IAnalyticsService analyticsService, IStopwatchProvider stopwatchProvider, IRxActionFactory actionFactory, ISchedulerProvider schedulerProvider) { Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); Ensure.Argument.IsNotNull(syncManager, nameof(syncManager)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(dialogService, nameof(dialogService)); Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(stopwatchProvider, nameof(stopwatchProvider)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(actionFactory, nameof(actionFactory)); this.dataSource = dataSource; this.syncManager = syncManager; this.timeService = timeService; this.dialogService = dialogService; this.interactorFactory = interactorFactory; this.navigationService = navigationService; this.analyticsService = analyticsService; this.stopwatchProvider = stopwatchProvider; this.schedulerProvider = schedulerProvider; this.actionFactory = actionFactory; OnboardingStorage = onboardingStorage; workspaceIdSubject .Where(id => id.HasValue) .Subscribe(id => workspaceId = id.Value) .DisposedBy(disposeBag); isEditingDescriptionSubject = new BehaviorSubject <bool>(false); Description = new BehaviorRelay <string>(string.Empty, CommonFunctions.Trim); projectClientTaskSubject = new BehaviorSubject <ProjectClientTaskInfo>(ProjectClientTaskInfo.Empty); ProjectClientTask = projectClientTaskSubject .AsDriver(ProjectClientTaskInfo.Empty, schedulerProvider); IsBillableAvailable = workspaceIdSubject .Where(id => id.HasValue) .SelectMany(workspaceId => interactorFactory.IsBillableAvailableForWorkspace(workspaceId.Value).Execute()) .DistinctUntilChanged() .AsDriver(false, schedulerProvider); isBillableSubject = new BehaviorSubject <bool>(false); IsBillable = isBillableSubject .DistinctUntilChanged() .AsDriver(false, schedulerProvider); startTimeSubject = new BehaviorSubject <DateTimeOffset>(DateTimeOffset.UtcNow); var startTimeObservable = startTimeSubject.DistinctUntilChanged(); StartTime = startTimeObservable .AsDriver(default(DateTimeOffset), schedulerProvider); var now = timeService.CurrentDateTimeObservable.StartWith(timeService.CurrentDateTime); durationSubject = new ReplaySubject <TimeSpan?>(bufferSize: 1); Duration = durationSubject .Select(duration => duration.HasValue ? Observable.Return(duration.Value) : now.CombineLatest( startTimeObservable, (currentTime, startTime) => currentTime - startTime)) .Switch() .DistinctUntilChanged() .AsDriver(TimeSpan.Zero, schedulerProvider); var stopTimeObservable = Observable.CombineLatest(startTimeObservable, durationSubject, calculateStopTime) .DistinctUntilChanged(); StopTime = stopTimeObservable .AsDriver(null, schedulerProvider); var isTimeEntryRunningObservable = stopTimeObservable .Select(stopTime => !stopTime.HasValue) .Do(value => isRunning = value) .DistinctUntilChanged(); IsTimeEntryRunning = isTimeEntryRunningObservable .AsDriver(false, schedulerProvider); tagsSubject = new BehaviorSubject <IEnumerable <IThreadSafeTag> >(Enumerable.Empty <IThreadSafeTag>()); Tags = tagsSubject .Select(tags => tags.Select(ellipsize).ToImmutableList()) .AsDriver(ImmutableList <string> .Empty, schedulerProvider); isInaccessibleSubject = new BehaviorSubject <bool>(false); IsInaccessible = isInaccessibleSubject .DistinctUntilChanged() .AsDriver(false, schedulerProvider); syncErrorMessageSubject = new BehaviorSubject <string>(string.Empty); SyncErrorMessage = syncErrorMessageSubject .Select(error => error ?? string.Empty) .DistinctUntilChanged() .AsDriver(string.Empty, schedulerProvider); IsSyncErrorMessageVisible = syncErrorMessageSubject .Select(error => !string.IsNullOrEmpty(error)) .DistinctUntilChanged() .AsDriver(false, schedulerProvider); Preferences = interactorFactory.GetPreferences().Execute() .AsDriver(null, schedulerProvider); // Actions Close = actionFactory.FromAsync(closeWithConfirmation); SelectProject = actionFactory.FromAsync(selectProject); SelectTags = actionFactory.FromAsync(selectTags); ToggleBillable = actionFactory.FromAction(toggleBillable); EditTimes = actionFactory.FromAsync <EditViewTapSource>(editTimes); SelectStartDate = actionFactory.FromAsync(selectStartDate); StopTimeEntry = actionFactory.FromAction(stopTimeEntry, isTimeEntryRunningObservable); DismissSyncErrorMessage = actionFactory.FromAction(dismissSyncErrorMessage); Save = actionFactory.FromAsync(save); Delete = actionFactory.FromAsync(delete); }
public void Should_pause_and_resume() { //Arrange var scheduler = new TestScheduler(); var isRunningTrigger = new BehaviorSubject <bool>(true); Action pause = () => isRunningTrigger.OnNext(false); Action resume = () => isRunningTrigger.OnNext(true); var source = scheduler.CreateHotObservable( ReactiveTest.OnNext(0.1.Seconds(), 1), ReactiveTest.OnNext(2.0.Seconds(), 2), ReactiveTest.OnNext(4.0.Seconds(), 3), ReactiveTest.OnNext(6.0.Seconds(), 4), ReactiveTest.OnNext(8.0.Seconds(), 5)); scheduler.Schedule(TimeSpan.FromSeconds(0.5), () => { pause(); }); scheduler.Schedule(TimeSpan.FromSeconds(5.0), () => { resume(); }); //Act var sut = Observable.Create <IObservable <int> >(o => { var current = source.Replay(); var connection = new SerialDisposable(); connection.Disposable = current.Connect(); return(isRunningTrigger .DistinctUntilChanged() .Select(isRunning => { if (isRunning) { //Return the current replayed values. return current; } else { //Disconnect and replace current. current = source.Replay(); connection.Disposable = current.Connect(); //yield silence until the next time we resume. return Observable.Never <int>(); } }) .Subscribe(o)); }).Switch(); var observer = scheduler.CreateObserver <int>(); using (sut.Subscribe(observer)) { scheduler.Start(); } //Assert var expected = new[] { ReactiveTest.OnNext(0.1.Seconds(), 1), ReactiveTest.OnNext(5.0.Seconds(), 2), ReactiveTest.OnNext(5.0.Seconds(), 3), ReactiveTest.OnNext(6.0.Seconds(), 4), ReactiveTest.OnNext(8.0.Seconds(), 5) }; CollectionAssert.AreEqual(expected, observer.Messages); }