public NiconicoFollowToggleButtonService( IScheduler scheduler, FollowManager followManager, DialogService dialogService ) { FollowManager = followManager; DialogService = dialogService; _followTarget = new ReactiveProperty <IFollowable>(scheduler, null).AddTo(disposables); _nowProcessFollow = new ReactiveProperty <bool>(scheduler, false).AddTo(disposables); _isFollowTarget = new ReactiveProperty <bool>(scheduler, false).AddTo(disposables); CanToggleFollow = new [] { _followTarget.ToUnit(), _isFollowTarget.ToUnit() } .CombineLatest() .Select(_ => { var isFollow = _isFollowTarget.Value; if (_followTarget.Value == null) { return(false); } return(isFollow ? true : FollowManager.CanMoreAddFollow(_followTarget.Value) ); }) .ToReadOnlyReactiveProperty(eventScheduler: scheduler) .AddTo(disposables); ToggleFollowCommand = new[] { _nowProcessFollow.Select(x => !x), CanToggleFollow } .CombineLatestValuesAreAllTrue() .ToAsyncReactiveCommand() .AddTo(disposables); ToggleFollowCommand.Subscribe(async() => { _nowProcessFollow.Value = true; try { var followTarget = _followTarget.Value; if (FollowManager.IsFollowItem(followTarget)) { if (await ConfirmRemovingFollow()) { var result = await FollowManager.RemoveFollow(followTarget); } } else if (FollowManager.CanMoreAddFollow(followTarget)) { await FollowManager.AddFollow(followTarget); } _isFollowTarget.Value = FollowManager.IsFollowItem(FollowTarget.Value); } finally { _nowProcessFollow.Value = false; } // トグルボタンの押したらとりあえず切り替わる仕様に対応するためのコード // 現在のフォロー状態に応じたトグル状態を確実化する await Task.Delay(500); RaisePropertyChanged(nameof(IsFollowTarget)); }) .AddTo(disposables); }