public InputCoreViewModel(InputViewModel parent) { this._parent = parent; this._provider = new InputAreaSuggestItemProvider(); CompositeDisposable.Add( this._bindingHashtags = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.BindingHashtags, tag => new BindHashtagViewModel(tag, () => UnbindHashtag(tag)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_bindingHashtags .ListenCollectionChanged() .Subscribe(_ => { InputData.BoundTags = _bindingHashtags.Select(h => h.Hashtag).ToArray(); RaisePropertyChanged(() => IsBindingHashtagExisted); })); _bindableHashtagCandidates = new DispatcherCollection<BindHashtagViewModel>(DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_bindableHashtagCandidates .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindableHashtagExisted))); CompositeDisposable.Add(_draftedInputs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.Drafts, _ => new InputDataViewModel(this, _, vm => InputModel.InputCore.Drafts.Remove(vm)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_draftedInputs .ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => DraftCount); RaisePropertyChanged(() => IsDraftsExisted); })); // listen setting changed CompositeDisposable.Add( Setting.SuppressTagBindingInReply.ListenValueChanged( _ => RaisePropertyChanged(() => IsBindHashtagEnabled))); // listen text control CompositeDisposable.Add(new EventListener<Action<CursorPosition>>( h => InputModel.SetCursorRequest += h, h => InputModel.SetCursorRequest -= h, SetCursor)); var plistener = new PropertyChangedEventListener(InputModel.InputCore); plistener.Add(() => InputModel.InputCore.CurrentInputData, (_, e) => InputDataChanged()); CompositeDisposable.Add(plistener); // initialize clipboard watcher. ClipboardWatcher watcher; CompositeDisposable.Add(watcher = new ClipboardWatcher()); watcher.ClipboardChanged += (o, e) => RaisePropertyChanged(() => IsClipboardContentImage); watcher.StartWatching(); Setting.DisableGeoLocationService.ValueChanged += this.UpdateGeoLocationService; this.UpdateGeoLocationService(Setting.DisableGeoLocationService.Value); }
public MainAreaViewModel() { CompositeDisposable.Add( _columns = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( TabManager.Columns, cm => new ColumnViewModel(this, cm), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add( Observable.FromEvent( h => TabManager.CurrentFocusColumnChanged += h, h => TabManager.CurrentFocusColumnChanged -= h) .Select(_ => TabManager.CurrentFocusColumnIndex) .Subscribe(UpdateFocusFromModel)); CompositeDisposable.Add( _columns.ListenCollectionChanged(_ => _columns.ForEach(c => c.UpdateFocus()))); RegisterEvents(); }
public ColumnViewModel(MainAreaViewModel parent, ColumnModel model) { this._parent = parent; this._model = model; this.CompositeDisposable.Add( this._tabs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( model.Tabs, _ => new TabViewModel(this, _), DispatcherHelper.UIDispatcher)); this.CompositeDisposable.Add( Observable.FromEvent( h => this._model.CurrentFocusTabChanged += h, h => this._model.CurrentFocusTabChanged -= h) .Select(_ => this._model.CurrentFocusTabIndex) .Subscribe(this.UpdateFocusFromModel)); this.CompositeDisposable.Add(_tabs.ListenCollectionChanged(_ => this._tabs.ForEach(item => item.UpdateFocus()))); if (this._tabs.Count > 0) { this.FocusedTab = this._tabs[0]; } }
public AccountSelectorViewModel(InputViewModel parent) { _parent = parent; this._accountSelectionFlip = new AccountSelectionFlipViewModel(); this.AccountSelectionFlip.Closed += () => { // After selection accounts, return focus to text box // if input area is opened. if (_parent.IsOpening) { _parent.FocusToTextBox(); } }; this.AccountSelectionFlip.SelectedAccountsChanged += () => { InputModel.AccountSelector.Accounts.Clear(); Setting.Accounts.Collection .Where(a => AccountSelectionFlip.SelectedAccounts.Contains(a)) .ForEach(InputModel.AccountSelector.Accounts.Add); }; CompositeDisposable.Add(this.AccountSelectionFlip); CompositeDisposable.Add(_accounts = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.AccountSelector.Accounts, a => new TwitterAccountViewModel(a), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_accounts.ListenCollectionChanged(_ => { RaisePropertyChanged(() => AuthInfoGridRowColumn); RaisePropertyChanged(() => AuthInfoScreenNames); RaisePropertyChanged(() => IsBoundAccountExists); })); CompositeDisposable.Add( InputModel.AccountSelector.ListenPropertyChanged( () => InputModel.AccountSelector.IsSynchronizedWithTab, _ => RaisePropertyChanged(() => IsSynchronizedWithTab))); }
public InputCoreViewModel(InputViewModel parent) { this._parent = parent; this._provider = new InputAreaSuggestItemProvider(); CompositeDisposable.Add( this._bindingHashtags = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.BindingHashtags, tag => new BindHashtagViewModel(tag, () => UnbindHashtag(tag)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_bindingHashtags .ListenCollectionChanged() .Subscribe(_ => { InputData.BoundTags = _bindingHashtags.Select(h => h.Hashtag).ToArray(); RaisePropertyChanged(() => IsBindingHashtagExisted); })); _bindableHashtagCandidates = new DispatcherCollection <BindHashtagViewModel>(DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_bindableHashtagCandidates .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindableHashtagExisted))); CompositeDisposable.Add(_draftedInputs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.Drafts, _ => new InputDataViewModel(this, _, vm => InputModel.InputCore.Drafts.Remove(vm)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_draftedInputs .ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => DraftCount); RaisePropertyChanged(() => IsDraftsExisted); })); // listen setting changed CompositeDisposable.Add( Setting.SuppressTagBindingInReply.ListenValueChanged( _ => RaisePropertyChanged(() => IsBindHashtagEnabled))); // listen text control CompositeDisposable.Add(new EventListener <Action <CursorPosition> >( h => InputModel.SetCursorRequest += h, h => InputModel.SetCursorRequest -= h, SetCursor)); var plistener = new PropertyChangedEventListener(InputModel.InputCore); plistener.Add(() => InputModel.InputCore.CurrentInputData, (_, e) => InputDataChanged()); CompositeDisposable.Add(plistener); // create temporary directory and reserve deletion before exit app. do { _tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); } while (Directory.Exists(_tempDir)); Directory.CreateDirectory(_tempDir); App.ApplicationExit += () => { try { Directory.Delete(this._tempDir, true); } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) { // I think that is sign from God that I must not delete that folder if failed. } }; // initialize clipboard watcher. ClipboardWatcher watcher; CompositeDisposable.Add(watcher = new ClipboardWatcher()); watcher.ClipboardChanged += (o, e) => RaisePropertyChanged(() => IsClipboardContentImage); watcher.StartWatching(); Setting.DisableGeoLocationService.ValueChanged += this.UpdateGeoLocationService; this.UpdateGeoLocationService(Setting.DisableGeoLocationService.Value); }
public InputCoreViewModel(InputViewModel parent) { this._parent = parent; this._provider = new InputAreaSuggestItemProvider(); CompositeDisposable.Add( this._bindingHashtags = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.BindingHashtags, tag => new BindHashtagViewModel(tag, () => UnbindHashtag(tag)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_bindingHashtags .ListenCollectionChanged() .Subscribe(_ => { InputData.BoundTags = _bindingHashtags.Select(h => h.Hashtag).ToArray(); RaisePropertyChanged(() => IsBindingHashtagExisted); })); _bindableHashtagCandidates = new DispatcherCollection<BindHashtagViewModel>(DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_bindableHashtagCandidates .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindableHashtagExisted))); CompositeDisposable.Add(_draftedInputs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputModel.InputCore.Drafts, _ => new InputDataViewModel(this, _, vm => InputModel.InputCore.Drafts.Remove(vm)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_draftedInputs .ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => DraftCount); RaisePropertyChanged(() => IsDraftsExisted); })); // listen setting changed CompositeDisposable.Add( Setting.SuppressTagBindingInReply.ListenValueChanged( _ => RaisePropertyChanged(() => IsBindHashtagEnabled))); // listen text control CompositeDisposable.Add(new EventListener<Action<CursorPosition>>( h => InputModel.SetCursorRequest += h, h => InputModel.SetCursorRequest -= h, SetCursor)); var plistener = new PropertyChangedEventListener(InputModel.InputCore); plistener.Add(() => InputModel.InputCore.CurrentInputData, (_, e) => InputDataChanged()); CompositeDisposable.Add(plistener); // create temporary directory and reserve deletion before exit app. do { _tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); } while (Directory.Exists(_tempDir)); Directory.CreateDirectory(_tempDir); App.ApplicationExit += () => { try { Directory.Delete(this._tempDir, true); } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) { // I think that is sign from God that I must not delete that folder if failed. } }; // initialize clipboard watcher. ClipboardWatcher watcher; CompositeDisposable.Add(watcher = new ClipboardWatcher()); watcher.ClipboardChanged += (o, e) => RaisePropertyChanged(() => IsClipboardContentImage); watcher.StartWatching(); Setting.DisableGeoLocationService.ValueChanged += this.UpdateGeoLocationService; this.UpdateGeoLocationService(Setting.DisableGeoLocationService.Value); }
public ColumnViewModel(MainAreaViewModel parent, ColumnModel model) { this._parent = parent; this._model = model; this.CompositeDisposable.Add( this._tabs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( model.Tabs, _ => new TabViewModel(this, _), DispatcherHelper.UIDispatcher)); this.CompositeDisposable.Add( Observable.FromEvent( h => this._model.CurrentFocusTabChanged += h, h => this._model.CurrentFocusTabChanged -= h) .Select(_ => this._model.CurrentFocusTabIndex) .Subscribe(this.UpdateFocusFromModel)); this.CompositeDisposable.Add( _tabs.ListenCollectionChanged().Subscribe(_ => this._tabs.ForEach(item => item.UpdateFocus()))); if (this._tabs.Count > 0) { this.FocusedTab = this._tabs[0]; } }
public StatusViewModel(TimelineViewModelBase parent, StatusModel status, IEnumerable <long> initialBoundAccounts) { _parent = parent; // get status model Model = status; RetweetedStatusModel = status.RetweetedStatus; // bind accounts _bindingAccounts = initialBoundAccounts.Guard().ToArray(); // initialize users information CompositeDisposable.Add( _favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.FavoritedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background)); CompositeDisposable.Add( _favoritedUsers.ListenCollectionChanged(_ => { RaisePropertyChanged(() => IsFavorited); RaisePropertyChanged(() => IsFavoritedUserExists); RaisePropertyChanged(() => FavoriteCount); })); CompositeDisposable.Add( _retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.RetweetedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background)); CompositeDisposable.Add( _retweetedUsers.ListenCollectionChanged(_ => { RaisePropertyChanged(() => IsRetweeted); RaisePropertyChanged(() => IsRetweetedUserExists); RaisePropertyChanged(() => RetweetCount); })); if (RetweetedStatusModel != null) { CompositeDisposable.Add( RetweetedStatusModel.FavoritedUsers.ListenCollectionChanged( _ => RaisePropertyChanged(() => IsFavorited))); CompositeDisposable.Add( RetweetedStatusModel.RetweetedUsers.ListenCollectionChanged( _ => RaisePropertyChanged(() => IsRetweeted))); } // listen settings CompositeDisposable.Add( new EventListener <Action <bool> >( h => Setting.AllowFavoriteMyself.ValueChanged += h, h => Setting.AllowFavoriteMyself.ValueChanged -= h, _ => RaisePropertyChanged(() => CanFavorite))); CompositeDisposable.Add( new EventListener <Action <ThumbnailMode> >( h => Setting.ThumbnailMode.ValueChanged += h, h => Setting.ThumbnailMode.ValueChanged -= h, _ => { RaisePropertyChanged(() => IsThumbnailAvailable); RaisePropertyChanged(() => IsThumbnailsAvailable); })); CompositeDisposable.Add( new EventListener <Action <TweetDisplayMode> >( h => Setting.TweetDisplayMode.ValueChanged += h, h => Setting.TweetDisplayMode.ValueChanged -= h, _ => { RaisePropertyChanged(() => IsExpanded); RaisePropertyChanged(() => IsSingleLine); })); // when account is added/removed, all timelines are regenerated. // so, we don't have to listen any events which notify accounts addition/deletion. CompositeDisposable.Add(_images = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.Images, m => new ThumbnailImageViewModel(m), DispatcherHelper.UIDispatcher)); // resolve images CompositeDisposable.Add(_images.ListenCollectionChanged(_ => { RaisePropertyChanged(() => ThumbnailImage); RaisePropertyChanged(() => IsImageAvailable); RaisePropertyChanged(() => IsThumbnailAvailable); RaisePropertyChanged(() => IsThumbnailsAvailable); })); // look-up in-reply-to _isInReplyToExists = Status.InReplyToStatusId.HasValue && Status.InReplyToStatusId != 0; }
/// <summary> /// Constructor /// </summary> public InputAreaViewModel() { _provider = new InputAreaSuggestItemProvider(); #region Account control _accountSelectionFlip = new AccountSelectionFlipViewModel(); _accountSelectionFlip.Closed += () => { // After selection accounts, return focus to text box // if input area is opened. if (IsOpening) { FocusToTextBox(); } }; var accountSelectReflecting = false; _accountSelectionFlip.SelectedAccountsChanged += () => { if (!_isSuppressAccountChangeRelay) { // write-back accountSelectReflecting = true; InputAreaModel.BindingAccounts.Clear(); _accountSelectionFlip.SelectedAccounts .ForEach(InputAreaModel.BindingAccounts.Add); accountSelectReflecting = false; _baseSelectedAccounts = InputAreaModel.BindingAccounts.Select(_ => _.Id).ToArray(); } InputInfo.Accounts = AccountSelectionFlip.SelectedAccounts; RaisePropertyChanged(() => AuthInfoGridRowColumn); UpdateTextCount(); RaisePropertyChanged(() => IsPostLimitPredictionEnabled); }; CompositeDisposable.Add(_accountSelectionFlip); CompositeDisposable.Add( new CollectionChangedEventListener( InputAreaModel.BindingAccounts, (_, __) => { RaisePropertyChanged(() => IsPostLimitPredictionEnabled); if (accountSelectReflecting) return; _baseSelectedAccounts = InputAreaModel.BindingAccounts .Select(a => a.Id) .ToArray(); ApplyBaseSelectedAccounts(); UpdateTextCount(); })); #endregion CompositeDisposable.Add(_bindingHashtags = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputAreaModel.BindingHashtags, _ => new BindHashtagViewModel(_, () => UnbindHashtag(_)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_bindingHashtags .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindingHashtagExisted))); _bindableHashtagCandidates = new DispatcherCollection<BindHashtagViewModel>(DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_bindableHashtagCandidates .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindableHashtagExisted))); CompositeDisposable.Add(_draftedInputs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputAreaModel.Drafts, _ => new TweetInputInfoViewModel(this, _, vm => InputAreaModel.Drafts.Remove(vm)), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_draftedInputs .ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => DraftCount); RaisePropertyChanged(() => IsDraftsExisted); })); CompositeDisposable.Add(_bindingAuthInfos = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( InputAreaModel.BindingAccounts, account => new TwitterAccountViewModel(account), DispatcherHelper.UIDispatcher)); CompositeDisposable.Add(_bindingAuthInfos .ListenCollectionChanged() .Subscribe(_ => RaisePropertyChanged(() => IsBindingAuthInfoExisted))); CompositeDisposable.Add( new EventListener<Action<IEnumerable<TwitterAccount>, string, CursorPosition, TwitterStatus>>( h => InputAreaModel.SetTextRequested += h, h => InputAreaModel.SetTextRequested -= h, (infos, body, cursor, inReplyTo) => { OpenInput(false); if (!CheckClearInput(body)) return; if (infos != null) { OverrideSelectedAccounts(infos); } if (inReplyTo != null) { Task.Run(async () => InReplyTo = new StatusViewModel(await StatusModel.Get(inReplyTo))); } switch (cursor) { case CursorPosition.Begin: Messenger.Raise(new TextBoxSetCaretMessage(0)); break; case CursorPosition.End: Messenger.Raise(new TextBoxSetCaretMessage(InputText.Length)); break; } })); CompositeDisposable.Add( new EventListener<Action<IEnumerable<TwitterAccount>, TwitterUser>>( _ => InputAreaModel.SendDirectMessageRequested += _, _ => InputAreaModel.SendDirectMessageRequested -= _, (infos, user) => { OpenInput(false); CheckClearInput(); OverrideSelectedAccounts(infos); DirectMessageTo = new UserViewModel(user); })); CompositeDisposable.Add(InitPostLimitPrediction()); _geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default); _geoWatcher.StatusChanged += (_, e) => { if (e.Status != GeoPositionStatus.Ready) { IsLocationEnabled = true; } else { IsLocationEnabled = false; AttachedLocation = null; } }; CompositeDisposable.Add(_geoWatcher); _geoWatcher.Start(); }
public StatusViewModel(TimelineViewModelBase parent, StatusModel status, IEnumerable<long> initialBoundAccounts) { _parent = parent; // get status model Model = status; RetweetedOriginalModel = status.RetweetedOriginal; // bind accounts _bindingAccounts = initialBoundAccounts.Guard().ToArray(); // initialize users information CompositeDisposable.Add( _favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.FavoritedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background)); CompositeDisposable.Add( _favoritedUsers.ListenCollectionChanged(_ => { RaisePropertyChanged(() => IsFavorited); RaisePropertyChanged(() => IsFavoritedUserExists); RaisePropertyChanged(() => FavoriteCount); })); CompositeDisposable.Add( _retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.RetweetedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background)); CompositeDisposable.Add( _retweetedUsers.ListenCollectionChanged(_ => { RaisePropertyChanged(() => IsRetweeted); RaisePropertyChanged(() => IsRetweetedUserExists); RaisePropertyChanged(() => RetweetCount); })); if (RetweetedOriginalModel != null) { CompositeDisposable.Add( RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged( _ => RaisePropertyChanged(() => IsFavorited))); CompositeDisposable.Add( RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged( _ => RaisePropertyChanged(() => IsRetweeted))); } // listen settings CompositeDisposable.Add( new EventListener<Action<bool>>( h => Setting.AllowFavoriteMyself.ValueChanged += h, h => Setting.AllowFavoriteMyself.ValueChanged -= h, _ => RaisePropertyChanged(() => CanFavorite))); CompositeDisposable.Add( new EventListener<Action<ThumbnailMode>>( h => Setting.ThumbnailMode.ValueChanged += h, h => Setting.ThumbnailMode.ValueChanged -= h, _ => { RaisePropertyChanged(() => IsThumbnailAvailable); RaisePropertyChanged(() => IsThumbnailsAvailable); })); CompositeDisposable.Add( new EventListener<Action<TweetDisplayMode>>( h => Setting.TweetDisplayMode.ValueChanged += h, h => Setting.TweetDisplayMode.ValueChanged -= h, _ => { RaisePropertyChanged(() => IsExpanded); RaisePropertyChanged(() => IsSingleLine); })); // when account is added/removed, all timelines are regenerated. // so, we don't have to listen any events which notify accounts addition/deletion. CompositeDisposable.Add(_images = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.Images, m => new ThumbnailImageViewModel(m), DispatcherHelper.UIDispatcher)); // resolve images CompositeDisposable.Add(_images.ListenCollectionChanged(_ => { RaisePropertyChanged(() => ThumbnailImage); RaisePropertyChanged(() => IsImageAvailable); RaisePropertyChanged(() => IsThumbnailAvailable); RaisePropertyChanged(() => IsThumbnailsAvailable); })); // look-up in-reply-to _isInReplyToExists = Status.InReplyToStatusId.HasValue && Status.InReplyToStatusId != 0; }
public StatusViewModel(TimelineViewModelBase parent, StatusModel status, IEnumerable<long> initialBoundAccounts) { _parent = parent; // get status model Model = status; RetweetedOriginalModel = status.RetweetedOriginal; // bind accounts _bindingAccounts = initialBoundAccounts.Guard().ToArray(); // initialize users information _favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.FavoritedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_favoritedUsers); CompositeDisposable.Add( _favoritedUsers.ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => IsFavorited); RaisePropertyChanged(() => IsFavoritedUserExists); RaisePropertyChanged(() => FavoriteCount); })); _retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.RetweetedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher); CompositeDisposable.Add(_retweetedUsers); CompositeDisposable.Add( _retweetedUsers.ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => IsRetweeted); RaisePropertyChanged(() => IsRetweetedUserExists); RaisePropertyChanged(() => RetweetCount); })); if (RetweetedOriginalModel != null) { CompositeDisposable.Add( RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged() .Subscribe(_ => this.RaisePropertyChanged(() => IsFavorited))); CompositeDisposable.Add( RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged() .Subscribe(_ => this.RaisePropertyChanged(() => IsRetweeted))); } // resolve images var imgsubj = Model.ImagesSubject; if (imgsubj != null) { lock (imgsubj) { var subscribe = imgsubj .Finally(() => { RaisePropertyChanged(() => Images); RaisePropertyChanged(() => FirstImage); RaisePropertyChanged(() => IsImageAvailable); }) .Subscribe(); CompositeDisposable.Add(subscribe); } } // look-up in-reply-to if (!status.Status.InReplyToStatusId.HasValue) return; var inReplyTo = StoreHelper.GetTweet(status.Status.InReplyToStatusId.Value) .Subscribe(replyTo => { this._inReplyTo = replyTo; this.RaisePropertyChanged(() => this.IsInReplyToExists); this.RaisePropertyChanged(() => this.InReplyToUserImage); this.RaisePropertyChanged(() => this.InReplyToUserName); this.RaisePropertyChanged(() => this.InReplyToUserScreenName); this.RaisePropertyChanged(() => this.InReplyToBody); }); this.CompositeDisposable.Add(inReplyTo); }
public StatusViewModel(TimelineViewModelBase parent, StatusModel status, IEnumerable<long> initialBoundAccounts) { Interlocked.Increment(ref _instanceCount); CompositeDisposable.Add(() => Interlocked.Decrement(ref _instanceCount)); _parent = parent; // get status model Model = status; RetweetedOriginalModel = status.RetweetedOriginal; // bind accounts _bindingAccounts = initialBoundAccounts.Guard().ToArray(); // initialize users information _favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.FavoritedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background); CompositeDisposable.Add(_favoritedUsers); CompositeDisposable.Add( _favoritedUsers.ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => IsFavorited); RaisePropertyChanged(() => IsFavoritedUserExists); RaisePropertyChanged(() => FavoriteCount); })); _retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx( Model.RetweetedUsers, user => new UserViewModel(user), DispatcherHelper.UIDispatcher, DispatcherPriority.Background); CompositeDisposable.Add(_retweetedUsers); CompositeDisposable.Add( _retweetedUsers.ListenCollectionChanged() .Subscribe(_ => { RaisePropertyChanged(() => IsRetweeted); RaisePropertyChanged(() => IsRetweetedUserExists); RaisePropertyChanged(() => RetweetCount); })); if (RetweetedOriginalModel != null) { CompositeDisposable.Add( RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged() .Subscribe(_ => this.RaisePropertyChanged(() => IsFavorited))); CompositeDisposable.Add( RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged() .Subscribe(_ => this.RaisePropertyChanged(() => IsRetweeted))); } // resolve images var imgsubj = Model.ImagesSubject; if (imgsubj != null) { lock (imgsubj) { var subscribe = imgsubj .Finally(() => { RaisePropertyChanged(() => Images); RaisePropertyChanged(() => FirstImage); RaisePropertyChanged(() => IsImageAvailable); }) .Subscribe(); CompositeDisposable.Add(subscribe); } } // look-up in-reply-to _isInReplyToExists = status.Status.InReplyToStatusId.HasValue; }