diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Windows/UserProfile/NoticeWindow.axaml b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Windows/UserProfile/NoticeWindow.axaml index ae40448fe..31be1da40 100644 --- a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Windows/UserProfile/NoticeWindow.axaml +++ b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Windows/UserProfile/NoticeWindow.axaml @@ -3,7 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="500" - Width="600" Height="500" + Width="750" Height="500" x:Class="System.Application.UI.Views.Windows.NoticeWindow" xmlns:gif="using:AvaloniaGif" xmlns:service="using:System.Application.Services" @@ -19,103 +19,89 @@ x:CompileBindings="True"> - - - - - - - - - - - - - - - + + + + + - + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - + - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ST.Client/Services/Mvvm/NotificationService.cs b/src/ST.Client/Services/Mvvm/NotificationService.cs index dbefa13e1..6048dcf6c 100644 --- a/src/ST.Client/Services/Mvvm/NotificationService.cs +++ b/src/ST.Client/Services/Mvvm/NotificationService.cs @@ -1,6 +1,7 @@ using DynamicData; using DynamicData.Binding; using ReactiveUI; +using ReactiveUI.Fody.Helpers; using System.Application.Models; using System.Application.Properties; using System.Application.Settings; @@ -30,157 +31,82 @@ namespace System.Application.Services readonly IHttpService httpService = DI.Get(); - public SourceList NoticeTypesSource { get; } + public SourceCache NoticesSource { get; } - private ReadOnlyObservableCollection _NoticeTypes; + [Reactive] + public int UnreadNotificationsCount { get; set; } - public ReadOnlyObservableCollection NoticeTypes - { - get => _NoticeTypes; - set => this.RaiseAndSetIfChanged(ref _NoticeTypes, value); - } - - bool _IsLoading; - - public bool IsLoading - { - get => _IsLoading; - set => this.RaiseAndSetIfChanged(ref _IsLoading, value); - } - - bool _IsEmpty; - - public bool IsEmpty - { - get => _IsEmpty; - set => this.RaiseAndSetIfChanged(ref _IsEmpty, value); - } - - private NoticeTypeDTO? _SelectGroup; - - public NoticeTypeDTO? SelectGroup - { - get => _SelectGroup; - set => this.RaiseAndSetIfChanged(ref _SelectGroup, value); - } - - NoticeDTO _NoticeItem; - - public NoticeDTO NoticeItem - { - get => _NoticeItem; - set => this.RaiseAndSetIfChanged(ref _NoticeItem, value); - } + [Reactive] + public ObservableCollection NoticeTypes { get; set; } public NotificationService() { mCurrent = this; - NoticeTypesSource = new SourceList(); - this.WhenAnyValue(x => x.SelectGroup) - .Subscribe(async x => - { - if (x != null) - { - IsLoading = true; - await GetTable(x); - IsLoading = false; - } - }); - - NoticeTypesSource - .Connect() - .ObserveOn(RxApp.MainThreadScheduler) - .Sort(SortExpressionComparer.Ascending(x => x.Order).ThenBy(x => x.Name)) - .Bind(out _NoticeTypes) - .Subscribe(_ => - { - SelectGroup = NoticeTypesSource.Items.FirstOrDefault(); - }); - - } - - public async Task InitializeNotice() - { - IsLoading = true; - await GetTypes(); - IsLoading = false; + NoticesSource = new SourceCache(x => x.Id); + NoticeTypes = new ObservableCollection(); } public async Task GetNews(int trycount = 0) { - if (NoticeTypesSource.Count > 0) + var lastTime = await INotificationService.GetLastNotificationTime(); + var client = ICloudServiceClient.Instance.Notice; + var result = await client.NewMsg(null, null); + if (result.IsSuccess && result.Content != null) { - var lastTime = await INotificationService.GetLastNotificationTime(); - var basics = NoticeTypesSource.Items.FirstOrDefault(); - var client = ICloudServiceClient.Instance.Notice; - var result = await client.NewMsg(basics.Id, null); - if (result.IsSuccess && result.Content != null) + var noticeList = result.Content.Where(x => lastTime.HasValue ? x.EnableTime > lastTime : true); + if (noticeList.Count() > 1) { - var noticeList = result.Content.Where(x => lastTime.HasValue ? x.EnableTime > lastTime : true); - if (noticeList.Count() > 1) + await INotificationService.SetLastNotificationTime(noticeList.Max(x => x.EnableTime)); + INotificationService.Instance.Notify(new NotificationBuilder() { - await INotificationService.SetLastNotificationTime(noticeList.Max(x => x.EnableTime)); - INotificationService.Instance.Notify(new NotificationBuilder() + Title = AppResources.NotificationChannelType_Description_Announcement, + Content = AppResources.Notice_Tray.Format(result.Content.Length), + AutoCancel = NotificationBuilder.DefaultAutoCancel, + Type = NotificationType.Announcement, + Click = new NotificationBuilder.ClickAction(() => { - Title = AppResources.NotificationChannelType_Description_Announcement, - Content = AppResources.Notice_Tray.Format(result.Content.Length, basics.Name), - AutoCancel = NotificationBuilder.DefaultAutoCancel, - Type = NotificationType.Announcement, - Click = new NotificationBuilder.ClickAction(() => - { - IWindowManager.Instance.Show(CustomWindow.Notice); - }) - }); - } - else + IWindowManager.Instance.Show(CustomWindow.Notice); + }) + }); + } + else + { + var notice = noticeList.FirstOrDefault(); + if (notice != null && notice.EnableTime > lastTime) { - var notice = noticeList.FirstOrDefault(); - if (notice != null && notice.EnableTime > lastTime) - { - await INotificationService.SetLastNotificationTime(notice.EnableTime); - INotificationService.Instance.Notify(notice); - } - + await INotificationService.SetLastNotificationTime(notice.EnableTime); + INotificationService.Instance.Notify(notice); } } - } - else if (trycount <= 2) - { - await GetTypes(); - await GetNews(trycount++); + } } - public async Task GetTypes() + public async Task LoadNoticeTypes() { var client = ICloudServiceClient.Instance.Notice; var result = await client.Types(); if (result.IsSuccess) { - NoticeTypesSource.Clear(); - NoticeTypesSource.AddRange(result.Content!.OrderBy(x => x.Index)); + NoticeTypes.Clear(); + NoticeTypes.AddRange(result.Content!.OrderBy(x => x.Order)); } } - public async Task GetTable(NoticeTypeDTO selectGroup) + public async Task LoadNotification(NoticeTypeDTO? selectGroup) { - if (selectGroup != null) + var client = ICloudServiceClient.Instance.Notice; + var result = await client.Table(selectGroup?.Id, 0, 30); + if (result.IsSuccess) { - var client = ICloudServiceClient.Instance.Notice; - var result = await client.Table(selectGroup.Id, selectGroup.Index); - if (result.IsSuccess) + foreach (var item in result.Content!.DataSource) { - foreach (var item in result.Content!.DataSource) - { - if (!string.IsNullOrWhiteSpace(item.Picture)) - item.PictureStream = httpService.GetImageAsync(item.Picture, ImageChannelType.NoticePicture); - } - SelectGroup!.Items = result.Content!; - NoticeItem = SelectGroup!.Items.DataSource.FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(item.Picture)) + item.PictureStream = httpService.GetImageAsync(item.Picture, ImageChannelType.NoticePicture); } - IsEmpty = SelectGroup!.Items == null || SelectGroup.Items?.DataSource.Count == 0; - + NoticesSource.Clear(); + NoticesSource.AddOrUpdate(result.Content.DataSource); } } } diff --git a/src/ST.Client/UI/ViewModels/Pages/UserCenter/AccountPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/UserCenter/AccountPageViewModel.cs index 010fab2ad..e2ec7e390 100644 --- a/src/ST.Client/UI/ViewModels/Pages/UserCenter/AccountPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/UserCenter/AccountPageViewModel.cs @@ -76,15 +76,15 @@ namespace System.Application.UI.ViewModels UserService.Current.ShowWindow(CustomWindow.BindPhoneNumber); }); - public override async void Activation() - { - if (IsFirstActivation && !NotificationService.Current.NoticeTypes.Any_Nullable()) - await NotificationService.Current.InitializeNotice(); - var defaultNotice = NotificationService.Current?.NoticeTypesSource.Items.FirstOrDefault(); - if (defaultNotice != null && NotificationService.Current?.SelectGroup?.Id != defaultNotice.Id) - await NotificationService.Current!.GetTable(defaultNotice!); - base.Activation(); - } + //public override async void Activation() + //{ + // if (IsFirstActivation && !NotificationService.Current.NoticeTypes.Any_Nullable()) + // await NotificationService.Current.InitializeNotice(); + // var defaultNotice = NotificationService.Current?.NoticeTypesSource.Items.FirstOrDefault(); + // if (defaultNotice != null && NotificationService.Current?.SelectGroup?.Id != defaultNotice.Id) + // await NotificationService.Current!.GetTable(defaultNotice!); + // base.Activation(); + //} public bool IsSponsor => UserService.Current.User?.UserType.HasFlag(UserType.Sponsor) ?? false; diff --git a/src/ST.Client/UI/ViewModels/Windows/UserCenter/NoticeWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/UserCenter/NoticeWindowViewModel.cs index 8f82b4b72..f23c3e2c7 100644 --- a/src/ST.Client/UI/ViewModels/Windows/UserCenter/NoticeWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/UserCenter/NoticeWindowViewModel.cs @@ -1,6 +1,7 @@ using DynamicData; using DynamicData.Binding; using ReactiveUI; +using ReactiveUI.Fody.Helpers; using System.Application.Models; using System.Application.Services; using System.Application.UI.Resx; @@ -17,10 +18,44 @@ namespace System.Application.UI.ViewModels public ReactiveCommand? OpenNotice { get; } + private ReadOnlyObservableCollection _Notices; + + public ReadOnlyObservableCollection Notices => _Notices; + + [Reactive] + public bool IsLoading { get; set; } + + public bool IsEmpty => !Notices.Any_Nullable(); + + [Reactive] + public NoticeTypeDTO? SelectGroup { get; set; } + + [Reactive] + public NoticeDTO NoticeItem { get; set; } + public NoticeWindowViewModel() { Title = GetTitleByDisplayName(DisplayName); OpenNotice = ReactiveCommand.CreateFromTask(x => Browser2.OpenAsync(x)); + + NotificationService.Current.NoticesSource + .Connect() + .ObserveOn(RxApp.MainThreadScheduler) + .Sort(SortExpressionComparer.Ascending(x => x.EnableTime).ThenBy(x => x.Title)) + .Bind(out _Notices) + .Subscribe(_ => + { + NoticeItem = Notices.FirstOrDefault(); + this.RaisePropertyChanged(nameof(IsEmpty)); + }); + + this.WhenValueChanged(x => x.SelectGroup, false) + .Subscribe(async x => + { + IsLoading = true; + await NotificationService.Current.LoadNotification(x); + IsLoading = false; + }); } public void OpenNoticeWeb(NoticeDTO item) @@ -31,8 +66,9 @@ namespace System.Application.UI.ViewModels public override async void Activation() { - if (IsFirstActivation && NotificationService.Current.NoticeTypes.Count == 0) - await NotificationService.Current.InitializeNotice(); + //if (IsFirstActivation) + await NotificationService.Current.LoadNoticeTypes(); + await NotificationService.Current.LoadNotification(SelectGroup); base.Activation(); } diff --git a/src/ST.Services.CloudService.Models/Models/Notice/NoticeTypeDTO.cs b/src/ST.Services.CloudService.Models/Models/Notice/NoticeTypeDTO.cs index b04f352c1..81895eb23 100644 --- a/src/ST.Services.CloudService.Models/Models/Notice/NoticeTypeDTO.cs +++ b/src/ST.Services.CloudService.Models/Models/Notice/NoticeTypeDTO.cs @@ -38,36 +38,5 @@ namespace System.Application.Models [N_JsonProperty("2")] [S_JsonProperty("2")] public int Order { get; set; } - -#if MVVM_VM - /// - /// Table Index - /// - [MPIgnore] - [N_JsonIgnore] - [S_JsonIgnore] - public int Index - { - get => _Index; - set => this.RaiseAndSetIfChanged(ref _Index, value); - } - - int _Index = 1; - - /// - /// ้€š็Ÿฅๅˆ—่กจ - /// - [MPIgnore] - [N_JsonIgnore] - [S_JsonIgnore] - public PagedModel? Items - { - get => mItems; - set => this.RaiseAndSetIfChanged(ref mItems, value); - } - - PagedModel? mItems; - -#endif } } diff --git a/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/INoticeClient.cs b/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/INoticeClient.cs index 1863dd4cf..dfa97b24b 100644 --- a/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/INoticeClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/INoticeClient.cs @@ -8,8 +8,8 @@ namespace System.Application.Services.CloudService.Clients.Abstractions { Task> Types(); - Task>> Table(Guid typeId, int index, int? size = null); + Task>> Table(Guid? typeId, int index, int? size = null); - Task> NewMsg(Guid typeId, DateTimeOffset? time); + Task> NewMsg(Guid? typeId, DateTimeOffset? time); } } diff --git a/src/ST.Services.CloudService/Services/CloudService/Clients/NoticeClient.cs b/src/ST.Services.CloudService/Services/CloudService/Clients/NoticeClient.cs index abd2d6380..05d814189 100644 --- a/src/ST.Services.CloudService/Services/CloudService/Clients/NoticeClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/Clients/NoticeClient.cs @@ -21,22 +21,22 @@ namespace System.Application.Services.CloudService.Clients requestUri: "api/Notice/Types", cancellationToken: default); - public Task>> Table(Guid typeId, int index, int? size = null) + public Task>> Table(Guid? typeId, int index, int? size = null) => conn.SendAsync>( isPolly: true, isAnonymous: true, isSecurity: true, method: HttpMethod.Post, - requestUri: $"api/Notice/List/{typeId}/{(int)DeviceInfo2.Platform()}/{(int)DeviceInfo2.Idiom()}/?index={index}{(size.HasValue ? $"&size={size}" : "")}", + requestUri: $"api/Notice/List/{(int)DeviceInfo2.Platform()}/{(int)DeviceInfo2.Idiom()}/?index={index}{(typeId.HasValue ? $"&typeid={typeId}" : "")}{(size.HasValue ? $"&size={size}" : "")}", cancellationToken: default); - public Task> NewMsg(Guid typeId, DateTimeOffset? time) + public Task> NewMsg(Guid? typeId, DateTimeOffset? time) => conn.SendAsync( isPolly: true, isAnonymous: true, isSecurity: true, method: HttpMethod.Get, - requestUri: $"api/Notice/NewMsg/{typeId}/{(int)DeviceInfo2.Platform()}/{(int)DeviceInfo2.Idiom()}{(time.HasValue ? $"?time={time}" : "")}", + requestUri: $"api/Notice/NewMsg/{(int)DeviceInfo2.Platform()}/{(int)DeviceInfo2.Idiom()}?v=1{(typeId.HasValue ? $"&typeid={typeId}" : "")}{(time.HasValue ? $"?time={time}" : "")}", cancellationToken: default); } diff --git a/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs b/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs index 1ccbbda14..bcee8090f 100644 --- a/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs @@ -268,13 +268,13 @@ namespace System.Application.Services.CloudService return ApiResponse.Ok(new NoticeTypeDTO[] { }); } - public async Task> NewMsg(Guid typeId, DateTimeOffset? time) + public async Task> NewMsg(Guid? typeId, DateTimeOffset? time) { await Task.Delay(1500); return ApiResponse.Ok(new NoticeDTO[] { }); } - public async Task>> Table(Guid typeId, int index, int? size = null) + public async Task>> Table(Guid? typeId, int index, int? size = null) { await Task.Delay(1500); return ApiResponse.Ok(new PagedModel { });