Ejemplo n.º 1
0
        public MainPageViewModel(INavigationService navigationService, IMessageService messageService)
            : base(navigationService)
        {
            _messageService = messageService;

            Title = "チャット";

            SendMessageCommand = Text.Select(s => !string.IsNullOrEmpty(s)).ToAsyncReactiveCommand();

            SendMessageCommand.Subscribe(async() =>
            {
                try
                {
                    await _messageService.SendMessage(Text.Value);

                    Text.Value = null;
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e);
                }
            });

            _messageService.Notified.Subscribe(message =>
            {
                Messages.Add(message);
            });
        }
Ejemplo n.º 2
0
        public TextChannelPageViewModel()
        {
            IsInvalidTextChannel = new ReactiveProperty <bool>(false);

            NowSendingMessage = new ReactiveProperty <bool>()
                                .AddTo(_CompositeDisposable);

            RawMessages = new ObservableCollection <IMessage>();

            var uiDispatcher = Windows.UI.Xaml.Window.Current.Dispatcher;

            Messages          = new ObservableCollection <MessageAggregatedByAuthorViewModel>();
            NowMessageLoading = new ReactiveProperty <bool>(false);


            RawMessages
            .CollectionChangedAsObservable()
            .Subscribe(async(x) =>
            {
                using (var releaser = await _MessageUpdateLock.LockAsync())
                {
                    if (x.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                    {
                        var items = x.NewItems;
                        // 前回受け取ったメッセージと同じ送信者の場合は
                        // 前回生成したMessageVMにIMessageをまとめる
                        foreach (var item in items.Cast <IMessage>())
                        {
                            var lastMessage = Messages.LastOrDefault();
                            if (lastMessage?.IsSameAuthor(item) ?? false)
                            {
                                await uiDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                                {
                                    lastMessage.AddMessage(item);
                                });
                            }
                            else
                            {
                                // 新規
                                await uiDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                                {
                                    Messages.Add(new MessageAggregatedByAuthorViewModel(item));
                                });
                            }
                        }
                    }
                    else if (x.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                    {
                        var items = x.OldItems;
                        // 前回受け取ったメッセージと同じ送信者の場合は
                        // 前回生成したMessageVMにIMessageをまとめる
                        foreach (var item in items.Cast <IMessage>())
                        {
                            await uiDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                            {
                                var message = Messages.FirstOrDefault(y => y.TryRemoveMessage(item));
                                if (message?.Messages.Count == 0)
                                {
                                    Messages.Remove(message);
                                }
                            });
                        }
                    }
                }
            })
            .AddTo(_CompositeDisposable);

            SendMessageText = new ReactiveProperty <string>("")
                              .AddTo(_CompositeDisposable);
            SendMessageCommand =
                Observable.CombineLatest(
                    NowSendingMessage.Select(x => !x),
                    SendMessageText.Select(x => !string.IsNullOrEmpty(x))
                    )
                .Select(x => x.All(y => y))
                .ToReactiveCommand()
                .AddTo(_CompositeDisposable);

            SendMessageCommand.Subscribe(async x => await SendMessage(SendMessageText.Value))
            .AddTo(_CompositeDisposable);
        }