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); }
private void UpdateHashtagCandidates() { var hashtags = TwitterRegexPatterns.ValidHashtag.Matches(InputData.Text) .OfType <Match>() .Select(_ => _.Groups[1].Value) .Where(s => !String.IsNullOrEmpty(s)) .Distinct() .Except(BindingHashtags.Select(_ => _.Hashtag)) .ToArray(); BindableHashtagCandidates .Where(_ => !hashtags.Contains(_.Hashtag)) .ToList() .ForEach(_ => BindableHashtagCandidates.Remove(_)); hashtags .Where(_ => !BindableHashtagCandidates.Select(t => t.Hashtag).Contains(_)) .Select(_ => new BindHashtagViewModel(_, () => BindHashtag(_))) .ForEach(BindableHashtagCandidates.Add); }
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); }
/// <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 (!this._suppressAccountChangeRelay) { // 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(_ => { InputInfo.Hashtags = _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( 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(_ => this.RaisePropertyChanged(() => AuthInfoGridRowColumn))); 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))); } var offset = cursor.Index; if (offset < 0) { offset = InputText.Length - offset + 1; } Messenger.Raise(new TextBoxSetCaretMessage(offset, cursor.SelectionLength)); })); 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( new EventListener<Action>( h => InputAreaModel.OnPreviousPostUpdated += h, h => InputAreaModel.OnPreviousPostUpdated -= h, () => this.RaisePropertyChanged(() => CanAmend))); CompositeDisposable.Add(InitPostLimitPrediction()); if (!Setting.DisableGeoLocationService.Value) { _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(); } this.RegisterEvents(); }