示例#1
0
        public MessageListViewModel(string folderId,
                                    FolderType folderType,
                                    MailBoxViewModel mailBox,
                                    IProfileDataQueryFactory queryFactory,
                                    IMailService mailService,
                                    ViewModelActivator activator)
        {
            var canExecute = this.WhenAnyObservable(x => x.Cache.SelectionChanged)
                             .Select(x => x.IndexCount() > 0)
                             .Publish();

            Activator = activator;

            Archive = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.MoveMessage(messageIds, FolderType.Archive);
            }, canExecute);

            Delete = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                if (folderType != FolderType.DeletedItems)
                {
                    await mailService.MoveMessage(messageIds, FolderType.DeletedItems);
                }
            }, canExecute);

            MarkAsRead = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.UpdateMessage(messageIds)
                .Set(m => m.IsRead, true)
                .ExecuteAsync();
            }, canExecute);

            MarkAsUnread = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.UpdateMessage(messageIds)
                .Set(m => m.IsRead, false)
                .ExecuteAsync();
            }, canExecute);

            SetFlag = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.UpdateMessage(messageIds)
                .Set(m => m.IsFlagged, true)
                .ExecuteAsync();
            }, canExecute);

            ClearFlag = ReactiveCommand.Create <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.UpdateMessage(messageIds)
                .Set(m => m.IsFlagged, false)
                .ExecuteAsync();
            }, canExecute);

            Move = ReactiveCommand.CreateFromTask <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);

                var selectionResult = await mailBox.PromptUserToSelectFolder(
                    messageIds.Count == 1 ? "Move a message" : $"Move {messageIds.Count} messages",
                    "Select another folder to move to:",
                    includeRoot: false,
                    destinationFolder => CanMoveTo(folderId, destinationFolder));

                if (!selectionResult.IsCancelled)
                {
                    await mailService.MoveMessage(messageIds, selectionResult.SelectedFolder.Id);
                }
            }, canExecute);

            MoveToJunk = ReactiveCommand.CreateFromTask <IReadOnlyList <string> >(async messageIds =>
            {
                PrepareMessageIds(ref messageIds);
                await mailService.MoveMessage(messageIds, FolderType.Junk);
            }, canExecute);

            this.WhenActivated(disposables =>
            {
                canExecute.Connect()
                .DisposeWith(disposables);

                Archive.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                Delete.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                SetFlag.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                ClearFlag.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                MarkAsRead.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                MarkAsUnread.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                Move.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                MoveToJunk.ThrownExceptions
                .Do(this.Log().Error)
                .Subscribe()
                .DisposeWith(disposables);

                Observable.CombineLatest(
                    this.WhenAnyValue(x => x.Order),
                    this.WhenAnyValue(x => x.Filter),
                    (order, filter) => (Order: order, Filter: filter))
                .DistinctUntilChanged()
                .Where(x => x.Order != MessageOrder.Sender)
                .Subscribe(x =>
                {
                    Cache?.Dispose();
                    Cache = new VirtualizingCache <MessageSummary, MessageSummaryViewModel, string>(
                        new PersistentVirtualizingSource <MessageSummary, string>(queryFactory,
                                                                                  GetItemSpecification(folderId, x.Order, x.Filter),
                                                                                  GetIndexSpecification(folderId, x.Order, x.Filter)),
                        mailService.MessageChanges
                        .Select(changes => FilterChanges(changes.ForFolder(folderId), x.Filter)),
                        state => new MessageSummaryViewModel(state, this, queryFactory));
                })
                .DisposeWith(disposables);

                this.WhenAnyObservable(x => x.Cache.SelectionChanged)
                .Select(ranges => ranges.Sum(r => r.Length))
                .Do(x => SelectionCount = x)
                .Subscribe()
                .DisposeWith(disposables);

                Disposable.Create(() =>
                {
                    Filter = MessageFilter.None;
                    Cache?.Dispose();
                    Cache          = null;
                    IsSelecting    = false;
                    SelectionCount = 0;
                })
                .DisposeWith(disposables);
            });
        }
示例#2
0
        public MailFolderViewModel(Node <MailFolder, string> node,
                                   MailBoxViewModel mailBox,
                                   IProfileDataQueryFactory queryFactory,
                                   IMailService mailService)
        {
            Id         = node.Item.Id;
            ParentId   = node.Item.ParentId;
            Name       = node.Item.Name;
            Type       = node.Item.Type;
            IsFavorite = node.Item.IsFavorite;
            Messages   = new MessageListViewModel(node.Item.Id, node.Item.Type,
                                                  mailBox, queryFactory, mailService, Activator);

            Synchronize = ReactiveCommand.CreateFromObservable(() => Observable
                                                               .StartAsync((token) => mailService.SynchronizeMessagesAsync(node.Item.Id, token))
                                                               .TakeUntil(CancelSynchronization));
            Synchronize.IsExecuting
            .ToPropertyEx(this, x => x.IsSynchronizing)
            .DisposeWith(_disposables);
            Synchronize.ThrownExceptions
            .Subscribe(ex => this.Log().Error(ex))
            .DisposeWith(_disposables);
            CancelSynchronization = ReactiveCommand.Create(() => { }, Synchronize.IsExecuting);

            Move = ReactiveCommand.CreateFromTask(async() =>
            {
                var result = await mailBox.PromptUserToSelectFolder(
                    "Move a folder",
                    "Select another folder to move to:",
                    includeRoot: true,
                    CanMoveTo);
                this.Log().Debug(result);
            });

            node.Children.Connect()
            .Transform(n => new MailFolderViewModel(n, mailBox, queryFactory, mailService))
            .Sort(SortExpressionComparer <MailFolderViewModel> .Ascending(f => f.Name))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _childFolders)
            .DisposeMany()
            .Subscribe()
            .DisposeWith(_disposables);

            mailService.MessageChanges
            .Where(changes => changes.AffectsFolder(node.Item.Id))
            .SelectMany(_ => CountMessages(queryFactory, node.Item.Id))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                UnreadCount = x.UnreadCount;
                TotalCount  = x.TotalCount;
            })
            .DisposeWith(_disposables);

            CountMessages(queryFactory, node.Item.Id)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                UnreadCount = x.UnreadCount;
                TotalCount  = x.TotalCount;
            })
            .DisposeWith(_disposables);
        }