public AccountSelectionFlipViewModel()
 {
     this.CompositeDisposable.Add(_accounts = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
         AccountsStore.Accounts,
         _ => new SelectableAccountViewModel(this, _.AuthenticateInfo, RaiseSelectedAccountsChanged),
         DispatcherHelper.UIDispatcher));
 }
Example #2
0
        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 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(
         ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
             InputModel.AccountSelector.Accounts,
             a => new TwitterAccountViewModel(a),
             DispatcherHelper.UIDispatcher));
     CompositeDisposable.Add(
         InputModel.AccountSelector.Accounts.ListenCollectionChanged()
                   .Subscribe(_ =>
                   {
                       RaisePropertyChanged(() => AuthInfoGridRowColumn);
                       this.RaisePropertyChanged(() => AuthInfoScreenNames);
                   }));
     CompositeDisposable.Add(this._accounts =
         ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
             InputModel.AccountSelector.Accounts,
             account => new TwitterAccountViewModel(account),
             DispatcherHelper.UIDispatcher));
     CompositeDisposable.Add(this._accounts
         .ListenCollectionChanged()
         .Subscribe(_ =>
         {
             this.RaisePropertyChanged(() => AuthInfoGridRowColumn);
             RaisePropertyChanged(() => IsBindingAuthInfoExisted);
         }));
     CompositeDisposable.Add(
         InputModel.AccountSelector.ListenPropertyChanged(
             () => InputModel.AccountSelector.IsSynchronizedWithTab)
                   .Subscribe(_ => RaisePropertyChanged(() => IsSynchronizedWithTab)));
 }
Example #4
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(
         ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
             InputModel.AccountSelector.Accounts,
             a => new TwitterAccountViewModel(a),
             DispatcherHelper.UIDispatcher));
     CompositeDisposable.Add(
         InputModel.AccountSelector.Accounts.ListenCollectionChanged()
         .Subscribe(_ =>
     {
         RaisePropertyChanged(() => AuthInfoGridRowColumn);
         this.RaisePropertyChanged(() => AuthInfoScreenNames);
     }));
     CompositeDisposable.Add(this._accounts =
                                 ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                                     InputModel.AccountSelector.Accounts,
                                     account => new TwitterAccountViewModel(account),
                                     DispatcherHelper.UIDispatcher));
     CompositeDisposable.Add(this._accounts
                             .ListenCollectionChanged()
                             .Subscribe(_ =>
     {
         this.RaisePropertyChanged(() => AuthInfoGridRowColumn);
         RaisePropertyChanged(() => IsBindingAuthInfoExisted);
     }));
     CompositeDisposable.Add(
         InputModel.AccountSelector.ListenPropertyChanged(
             () => InputModel.AccountSelector.IsSynchronizedWithTab)
         .Subscribe(_ => RaisePropertyChanged(() => IsSynchronizedWithTab)));
 }
Example #5
0
 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));
     RegisterEvents();
 }
 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();
 }
 /// <summary>
 ///     for design-time support.
 /// </summary>
 public BackstageViewModel()
 {
     if (DesignTimeUtil.IsInDesignMode)
     {
         return;
     }
     _twitterEvents = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
         BackstageModel.TwitterEvents,
         tev => new TwitterEventViewModel(tev),
         DispatcherHelper.UIDispatcher,
         DispatcherPriority.Background);
     CompositeDisposable.Add(_twitterEvents);
     _accounts = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
         BackstageModel.Accounts,
         a => new BackstageAccountViewModel(this, a),
         DispatcherHelper.UIDispatcher);
     CompositeDisposable.Add(_accounts);
     CompositeDisposable.Add(
         Observable.FromEvent(
             h => BackstageModel.CloseBackstage += h,
             h => BackstageModel.CloseBackstage -= h)
         .Subscribe(_ => this.Close()));
     CompositeDisposable.Add(
         Observable.FromEvent <BackstageEventBase>(
             h => BackstageModel.EventRegistered += h,
             h => BackstageModel.EventRegistered -= h)
         .Subscribe(ev =>
     {
         lock (_syncLock)
         {
             _waitingEvents.Enqueue(ev);
             Monitor.Pulse(_syncLock);
         }
     }));
     CompositeDisposable.Add(() =>
     {
         lock (_syncLock)
         {
             _isDisposed = true;
             Monitor.Pulse(_syncLock);
         }
     });
 }
Example #8
0
 public ColumnViewModel(MainAreaViewModel parent, ColumnModel model)
 {
     _parent = parent;
     _model = model;
     this.CompositeDisposable.Add(
         _tabs = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
             model.Tabs,
             _ => new TabViewModel(this, _),
             DispatcherHelper.UIDispatcher));
     this.CompositeDisposable.Add(
         Observable.FromEvent(
         h => _model.CurrentFocusTabChanged += h,
         h => _model.CurrentFocusTabChanged -= h)
         .Select(_ => _model.CurrentFocusTabIndex)
         .Subscribe(UpdateFocusFromModel));
     if (_tabs.Count > 0)
     {
         FocusedTab = _tabs[0];
     }
 }
Example #9
0
 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];
     }
 }
Example #10
0
 /// <summary>
 ///     for design-time support.
 /// </summary>
 public BackstageViewModel()
 {
     _twitterEvents = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
         BackstageModel.TwitterEvents,
         tev => new TwitterEventViewModel(tev),
         DispatcherHelper.UIDispatcher);
     CompositeDisposable.Add(_twitterEvents);
     _accounts = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
         BackstageModel.Accounts,
         a => new BackstageAccountViewModel(this, a),
         DispatcherHelper.UIDispatcher);
     CompositeDisposable.Add(_accounts);
     CompositeDisposable.Add(
         Observable.FromEvent(
             h => BackstageModel.CloseBackstage += h,
             h => BackstageModel.CloseBackstage -= h)
                   .Subscribe(_ => this.Close()));
     CompositeDisposable.Add(
         Observable.FromEvent<BackstageEventBase>(
             h => BackstageModel.EventRegistered += h,
             h => BackstageModel.EventRegistered -= h)
                   .Subscribe(ev =>
                   {
                       lock (_syncLock)
                       {
                           _waitingEvents.Enqueue(ev);
                           Monitor.Pulse(_syncLock);
                       }
                   }));
     CompositeDisposable.Add(() =>
     {
         lock (_syncLock)
         {
             _isDisposed = true;
             Monitor.Pulse(_syncLock);
         }
     });
 }
Example #11
0
        public StatusViewModel(TimelineViewModelBase parent, StatusModel status,
                               IEnumerable <long> initialBoundAccounts)
        {
            this._parent = parent;
            // get status model
            this.Model = status;
            this.RetweetedOriginalModel = status.RetweetedOriginal;

            // bind accounts
            this._bindingAccounts = initialBoundAccounts.Guard().ToArray();

            // initialize users information
            this._favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.FavoritedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._favoritedUsers);
            this.CompositeDisposable.Add(
                this._favoritedUsers.ListenCollectionChanged()
                .Subscribe(_ =>
            {
                this.RaisePropertyChanged(() => this.IsFavorited);
                this.RaisePropertyChanged(() => this.IsFavoritedUserExists);
                this.RaisePropertyChanged(() => this.FavoriteCount);
            }));
            this._retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.RetweetedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._retweetedUsers);
            this.CompositeDisposable.Add(
                this._retweetedUsers.ListenCollectionChanged()
                .Subscribe(_ =>
            {
                this.RaisePropertyChanged(() => this.IsRetweeted);
                this.RaisePropertyChanged(() => this.IsRetweetedUserExists);
                this.RaisePropertyChanged(() => this.RetweetCount);
            }));
            if (this.RetweetedOriginalModel != null)
            {
                this.CompositeDisposable.Add(
                    this.RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged()
                    .Subscribe(_ => this.RaisePropertyChanged(() => this.IsFavorited)));
                this.CompositeDisposable.Add(
                    this.RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged()
                    .Subscribe(_ => this.RaisePropertyChanged(() => this.IsRetweeted)));
            }

            // listen settings
            this.CompositeDisposable.Add(
                new EventListener <Action <bool> >(
                    h => Setting.AllowFavoriteMyself.ValueChanged += h,
                    h => Setting.AllowFavoriteMyself.ValueChanged -= h,
                    _ => this.RaisePropertyChanged(() => CanFavorite)));
            this.CompositeDisposable.Add(
                new EventListener <Action <bool> >(
                    h => Setting.ShowThumbnails.ValueChanged += h,
                    h => Setting.ShowThumbnails.ValueChanged -= h,
                    _ => this.RaisePropertyChanged(() => IsThumbnailAvailable)));
            this.CompositeDisposable.Add(
                new EventListener <Action <TweetDisplayMode> >(
                    h => Setting.TweetDisplayMode.ValueChanged += h,
                    h => Setting.TweetDisplayMode.ValueChanged -= h,
                    _ => this.RaisePropertyChanged(() => IsExpanded)));
            // when account is added/removed, all timelines are regenerated.
            // so, we don't have to listen any events which notify accounts addition/deletion.

            // resolve images
            var imgsubj = this.Model.ImagesSubject;

            if (imgsubj != null)
            {
                lock (imgsubj)
                {
                    var subscribe = imgsubj
                                    .Finally(() =>
                    {
                        this.RaisePropertyChanged(() => this.Images);
                        this.RaisePropertyChanged(() => this.ThumbnailImage);
                        this.RaisePropertyChanged(() => this.IsImageAvailable);
                        this.RaisePropertyChanged(() => this.IsThumbnailAvailable);
                    })
                                    .Subscribe();
                    this.CompositeDisposable.Add(subscribe);
                }
            }

            // look-up in-reply-to
            this._isInReplyToExists = this.Status.InReplyToStatusId.HasValue && this.Status.InReplyToStatusId != 0;
        }
Example #12
0
        public StatusViewModel(TimelineViewModelBase parent, StatusModel status,
                               IEnumerable<long> initialBoundAccounts)
        {
            this._parent = parent;
            // get status model
            this.Model = status;
            this.RetweetedOriginalModel = status.RetweetedOriginal;

            // bind accounts 
            this._bindingAccounts = initialBoundAccounts.Guard().ToArray();

            // initialize users information
            this._favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.FavoritedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._favoritedUsers);
            this.CompositeDisposable.Add(
                this._favoritedUsers.ListenCollectionChanged()
                               .Subscribe(_ =>
                               {
                                   this.RaisePropertyChanged(() => this.IsFavorited);
                                   this.RaisePropertyChanged(() => this.IsFavoritedUserExists);
                                   this.RaisePropertyChanged(() => this.FavoriteCount);
                               }));
            this._retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.RetweetedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._retweetedUsers);
            this.CompositeDisposable.Add(
                this._retweetedUsers.ListenCollectionChanged()
                               .Subscribe(_ =>
                               {
                                   this.RaisePropertyChanged(() => this.IsRetweeted);
                                   this.RaisePropertyChanged(() => this.IsRetweetedUserExists);
                                   this.RaisePropertyChanged(() => this.RetweetCount);
                               }));
            if (this.RetweetedOriginalModel != null)
            {
                this.CompositeDisposable.Add(
                            this.RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged()
                                                  .Subscribe(_ => this.RaisePropertyChanged(() => this.IsFavorited)));
                this.CompositeDisposable.Add(
                    this.RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged()
                                          .Subscribe(_ => this.RaisePropertyChanged(() => this.IsRetweeted)));
            }

            // listen settings
            this.CompositeDisposable.Add(
                new EventListener<Action<bool>>(
                    h => Setting.AllowFavoriteMyself.ValueChanged += h,
                    h => Setting.AllowFavoriteMyself.ValueChanged -= h,
                    _ => this.RaisePropertyChanged(() => CanFavorite)));
            // when account is added/removed, all timelines are regenerated.
            // so, we don't have to listen any events which notify accounts addition/deletion.

            // resolve images
            var imgsubj = this.Model.ImagesSubject;
            if (imgsubj != null)
            {
                lock (imgsubj)
                {
                    var subscribe = imgsubj
                        .Finally(() =>
                        {
                            this.RaisePropertyChanged(() => this.Images);
                            this.RaisePropertyChanged(() => this.FirstImage);
                            this.RaisePropertyChanged(() => this.IsImageAvailable);
                        })
                        .Subscribe();
                    this.CompositeDisposable.Add(subscribe);
                }
            }

            // look-up in-reply-to
            this._isInReplyToExists = this.Status.InReplyToStatusId.HasValue && this.Status.InReplyToStatusId != 0;
        }
Example #13
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();
        }
Example #14
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
            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;
        }
Example #15
0
        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);
        }
Example #16
0
        public StatusViewModel(TimelineViewModelBase parent, StatusModel status,
                               IEnumerable<long> initialBoundAccounts)
        {
            Interlocked.Increment(ref _instanceCount);
            this.CompositeDisposable.Add(() => Interlocked.Decrement(ref _instanceCount));
            this._parent = parent;
            // get status model
            this.Model = status;
            this.RetweetedOriginalModel = status.RetweetedOriginal;

            // bind accounts 
            this._bindingAccounts = initialBoundAccounts.Guard().ToArray();

            // initialize users information
            this._favoritedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.FavoritedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._favoritedUsers);
            this.CompositeDisposable.Add(
                this._favoritedUsers.ListenCollectionChanged()
                               .Subscribe(_ =>
                               {
                                   this.RaisePropertyChanged(() => this.IsFavorited);
                                   this.RaisePropertyChanged(() => this.IsFavoritedUserExists);
                                   this.RaisePropertyChanged(() => this.FavoriteCount);
                               }));
            this._retweetedUsers = ViewModelHelperRx.CreateReadOnlyDispatcherCollectionRx(
                this.Model.RetweetedUsers, user => new UserViewModel(user),
                DispatcherHelper.UIDispatcher, DispatcherPriority.Background);
            this.CompositeDisposable.Add(this._retweetedUsers);
            this.CompositeDisposable.Add(
                this._retweetedUsers.ListenCollectionChanged()
                               .Subscribe(_ =>
                               {
                                   this.RaisePropertyChanged(() => this.IsRetweeted);
                                   this.RaisePropertyChanged(() => this.IsRetweetedUserExists);
                                   this.RaisePropertyChanged(() => this.RetweetCount);
                               }));
            if (this.RetweetedOriginalModel != null)
            {
                this.CompositeDisposable.Add(
                            this.RetweetedOriginalModel.FavoritedUsers.ListenCollectionChanged()
                                                  .Subscribe(_ => this.RaisePropertyChanged(() => this.IsFavorited)));
                this.CompositeDisposable.Add(
                    this.RetweetedOriginalModel.RetweetedUsers.ListenCollectionChanged()
                                          .Subscribe(_ => this.RaisePropertyChanged(() => this.IsRetweeted)));
            }

            // resolve images
            var imgsubj = this.Model.ImagesSubject;
            if (imgsubj != null)
            {
                lock (imgsubj)
                {
                    var subscribe = imgsubj
                        .Finally(() =>
                        {
                            this.RaisePropertyChanged(() => this.Images);
                            this.RaisePropertyChanged(() => this.FirstImage);
                            this.RaisePropertyChanged(() => this.IsImageAvailable);
                        })
                        .Subscribe();
                    this.CompositeDisposable.Add(subscribe);
                }
            }

            // look-up in-reply-to
            this._isInReplyToExists = this.Status.InReplyToStatusId.HasValue && this.Status.InReplyToStatusId != 0;
        }
Example #17
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;
        }
Example #18
0
        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);
        }
Example #19
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);
        }