public TimelineViewModelBase(TimelineModelBase model) { this._model = model; this._timeline = new ObservableCollection <StatusViewModel>(); DispatcherHolder.Enqueue(this.InitializeCollection, DispatcherPriority.Background); this.CompositeDisposable.Add( new EventListener <Action <bool> >( h => model.InvalidationStateChanged += h, h => model.InvalidationStateChanged -= h, s => this.IsLoading = s)); this.CompositeDisposable.Add(() => { if (_listener != null) { _listener.Dispose(); } }); this.CompositeDisposable.Add( this.ListenPropertyChanged(() => this.CurrentAccounts) .ObserveOnDispatcher() .Select(_ => this.CurrentAccounts.ToArray()) .Subscribe(a => _timeline.ForEach(s => s.BindingAccounts = a))); this.IsLoading = true; this._model.InvalidateTimeline(); }
public StatusesViewModel(TimelineModelBase model, IReactiveProperty <Status> inReplyTo, TabsModel tabs, bool streamingOnStartup = false) { this.model = model; this.inReplyTo = inReplyTo; this.tabs = tabs; IsStreaming = this.model.StreamingStarted.ToReadOnlyReactiveProperty(); IsStreamingAvailable = this.model.IsStreamingAvailable; Statuses = this.model.ToReadOnlyReactiveCollection(s => new StatusViewModel(s)); ReloadCommand = new AsyncReactiveCommand() .WithSubscribe(() => this.model.FetchPreviousAsync()); ReloadOlderCommand = new AsyncReactiveCommand() .WithSubscribe(() => this.model.FetchNextAsync()); ToggleStreamingCommand = Observable.Repeat(IsStreamingAvailable, 1).ToReactiveCommand() .WithSubscribe(() => this.model.StreamingStarting.Value = !IsStreaming.Value); var IsStatusSelected = SelectedStatus.Select(x => x != null); OpenCommand = IsStatusSelected.ToReactiveCommand() .WithSubscribe(() => Process.Start(SelectedStatus.Value.Status.Url ?? SelectedStatus.Value.Status.Reblog.Url)); FavouriteCommand = IsStatusSelected.ToAsyncReactiveCommand() .WithSubscribe(() => this.model.FavouriteAsync(SelectedStatus.Value.Status.Id)); ReblogCommand = IsStatusSelected.ToAsyncReactiveCommand() .WithSubscribe(() => this.model.ReblogAsync(SelectedStatus.Value.Status.Id)); ReplyCommand = IsStatusSelected.ToReactiveCommand() .WithSubscribe(() => this.inReplyTo.Value = SelectedStatus.Value.Status); DeleteCommand = IsStatusSelected.ToAsyncReactiveCommand() .WithSubscribe(() => this.model.DeleteAsync(SelectedStatus.Value.Status.Id)); OpenAccountTabCommand = IsStatusSelected.ToReactiveCommand() .WithSubscribe(() => { Account account = SelectedStatus.Value.OriginalStatus.Account; this.tabs.SwitchToOrOpen(new AccountTabParameters() { Name = $"user: {account.AccountName}", Id = account.Id }); }); this.model.StreamingStarting.Value = streamingOnStartup; ReloadCommand.Execute(); }
public TimelineViewModelBase(TimelineModelBase model) { this._model = model; this._timeline = new ObservableCollection <StatusViewModel>(); DispatcherHelper.UIDispatcher.InvokeAsync(this.InitializeCollection, DispatcherPriority.Background); this.CompositeDisposable.Add( new EventListener <Action <bool> >( h => model.IsLoadingChanged += h, h => model.IsLoadingChanged -= h, isLoading => { if (isLoading) { // send immediate // ! MUST BE DispatcherPriority.Send ! // for update binding value before beginning rendering. DispatcherHelper.UIDispatcher.InvokeAsync(() => { this.IsLoading = true; }, DispatcherPriority.Send); } else { // wait for dispatcher DispatcherHelper.UIDispatcher.InvokeAsync(() => { // this clause is invoked later, so re-check currrent value if (model.IsLoading == false) { this.IsLoading = false; } }, DispatcherPriority.ContextIdle); } })); this.CompositeDisposable.Add(() => { if (_listener != null) { _listener.Dispose(); } }); this.CompositeDisposable.Add( this.ListenPropertyChanged(() => this.CurrentAccounts, e => DispatcherHelper.UIDispatcher.InvokeAsync(() => { var a = this.CurrentAccounts.ToArray(); this._timeline.ForEach(s => s.BindingAccounts = a); }))); this.CompositeDisposable.Add( Setting.ScrollLockStrategy.ListenValueChanged( v => { RaisePropertyChanged(() => this.IsScrollLockEnabled); RaisePropertyChanged(() => this.IsScrollLockOnlyScrolled); })); this.CompositeDisposable.Add( Setting.IsAnimateScrollToNewTweet.ListenValueChanged( v => RaisePropertyChanged(() => IsAnimationEnabled))); this.CompositeDisposable.Add( Setting.IsScrollByPixel.ListenValueChanged( v => { RaisePropertyChanged(() => ScrollUnit); RaisePropertyChanged(() => IsAnimationEnabled); })); this._model.InvalidateTimeline(); }