diff --git a/src/DownKyi/App.xaml.cs b/src/DownKyi/App.xaml.cs index 6a5d6a9..b3723d8 100644 --- a/src/DownKyi/App.xaml.cs +++ b/src/DownKyi/App.xaml.cs @@ -14,6 +14,7 @@ using DownKyi.Views.Settings; using DownKyi.Views.Toolbox; using DownKyi.Views.UserSpace; using Prism.Ioc; +using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -194,6 +195,7 @@ namespace DownKyi containerRegistry.RegisterForNavigation(ViewModels.UserSpace.ViewChannelViewModel.Tag); // dialogs + containerRegistry.RegisterDialog(ViewAlertDialogViewModel.Tag); containerRegistry.RegisterDialog(ViewDownloadSetterViewModel.Tag); containerRegistry.RegisterDialog(ViewParsingSelectorViewModel.Tag); diff --git a/src/DownKyi/DownKyi.csproj b/src/DownKyi/DownKyi.csproj index 1f6c474..33eefbb 100644 --- a/src/DownKyi/DownKyi.csproj +++ b/src/DownKyi/DownKyi.csproj @@ -115,10 +115,12 @@ + + @@ -186,6 +188,9 @@ + + ViewAlertDialog.xaml + ViewDownloadSetter.xaml @@ -344,6 +349,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/DownKyi/Images/SystemIcon.cs b/src/DownKyi/Images/SystemIcon.cs index b6bec27..b2b83cb 100644 --- a/src/DownKyi/Images/SystemIcon.cs +++ b/src/DownKyi/Images/SystemIcon.cs @@ -65,6 +65,34 @@ l1.8-2.2c0-0.1,0-0.5-0.1-0.8l-3.1-3.6C29.7,17.1,29.5,17,29.2,17z", Fill = "#FF000000" }; + + Info = new VectorImage + { + Height = 20, + Width = 20, + Data = @"M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 + 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z", + Fill = "#FF00bcf2" + }; + + Warning = new VectorImage + { + Height = 20, + Width = 20, + Data = @"M12 5.99L19.53 19H4.47L12 5.99M2.74 18c-.77 1.33.19 3 1.73 3h15.06c1.54 0 2.5-1.67 1.73-3L13.73 + 4.99c-.77-1.33-2.69-1.33-3.46 0L2.74 18zM11 11v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zm0 5h2v2h-2z", + Fill = "#FFffb900" + }; + + Error = new VectorImage + { + Height = 20, + Width = 20, + Data = @"M12 7c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1s-1-.45-1-1V8c0-.55.45-1 1-1zm-.01-5C6.47 2 2 6.48 2 12s4.47 + 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 + 8-3.58 8-8 8zm1-3h-2v-2h2v2z", + Fill = "#FFd83b01" + }; } public VectorImage Close { get; private set; } @@ -72,5 +100,9 @@ public VectorImage Minimize { get; private set; } public VectorImage Restore { get; private set; } public VectorImage Skin { get; private set; } + + public VectorImage Info { get; private set; } + public VectorImage Warning { get; private set; } + public VectorImage Error { get; private set; } } } diff --git a/src/DownKyi/Languages/Default.xaml b/src/DownKyi/Languages/Default.xaml index 91d20c1..0204679 100644 --- a/src/DownKyi/Languages/Default.xaml +++ b/src/DownKyi/Languages/Default.xaml @@ -293,7 +293,14 @@ 提取视频 + 信息 + 警告 + 错误 + + 确定 取消 + + 您确定要删除吗? 请选择文件夹 diff --git a/src/DownKyi/Services/AlertService.cs b/src/DownKyi/Services/AlertService.cs new file mode 100644 index 0000000..e30a9ff --- /dev/null +++ b/src/DownKyi/Services/AlertService.cs @@ -0,0 +1,75 @@ +using DownKyi.Images; +using DownKyi.Utils; +using DownKyi.ViewModels.Dialogs; +using Prism.Services.Dialogs; + +namespace DownKyi.Services +{ + public class AlertService + { + private readonly IDialogService dialogService; + + public AlertService(IDialogService dialogService) + { + this.dialogService = dialogService; + } + + /// + /// 显示一个信息弹窗 + /// + /// + /// + public ButtonResult ShowInfo(string message) + { + VectorImage image = SystemIcon.Instance().Info; + string title = DictionaryResource.GetString("Info"); + return ShowMessage(image, title, message); + } + + /// + /// 显示一个警告弹窗 + /// + /// + /// + public ButtonResult ShowWarning(string message) + { + VectorImage image = SystemIcon.Instance().Warning; + string title = DictionaryResource.GetString("Warning"); + return ShowMessage(image, title, message); + } + + /// + /// 显示一个错误弹窗 + /// + /// + /// + public ButtonResult ShowError(string message) + { + VectorImage image = SystemIcon.Instance().Error; + string title = DictionaryResource.GetString("Error"); + return ShowMessage(image, title, message); + } + + private ButtonResult ShowMessage(VectorImage image, string type, string message) + { + ButtonResult result = ButtonResult.None; + if (dialogService == null) + { + return result; + } + + DialogParameters param = new DialogParameters + { + { "image", image }, + { "title", type }, + { "message", message } + }; + dialogService.ShowDialog(ViewAlertDialogViewModel.Tag, param, buttonResult => + { + result = buttonResult.Result; + }); + return result; + } + + } +} diff --git a/src/DownKyi/ViewModels/BaseViewModel.cs b/src/DownKyi/ViewModels/BaseViewModel.cs index 54d623f..89d5852 100644 --- a/src/DownKyi/ViewModels/BaseViewModel.cs +++ b/src/DownKyi/ViewModels/BaseViewModel.cs @@ -1,6 +1,7 @@ using Prism.Events; using Prism.Mvvm; using Prism.Regions; +using Prism.Services.Dialogs; using System; using System.Windows; @@ -9,6 +10,7 @@ namespace DownKyi.ViewModels public class BaseViewModel : BindableBase, INavigationAware { protected readonly IEventAggregator eventAggregator; + protected readonly IDialogService dialogService; protected string ParentView = string.Empty; public BaseViewModel(IEventAggregator eventAggregator) @@ -16,6 +18,12 @@ namespace DownKyi.ViewModels this.eventAggregator = eventAggregator; } + public BaseViewModel(IEventAggregator eventAggregator, IDialogService dialogService) + { + this.eventAggregator = eventAggregator; + this.dialogService = dialogService; + } + public bool IsNavigationTarget(NavigationContext navigationContext) { return true; diff --git a/src/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs b/src/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs index 2da4b97..287d65b 100644 --- a/src/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs +++ b/src/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs @@ -115,16 +115,16 @@ namespace DownKyi.ViewModels.Dialogs public event Action RequestClose; - public bool CanCloseDialog() + public virtual bool CanCloseDialog() { return true; } - public void OnDialogClosed() + public virtual void OnDialogClosed() { } - public void OnDialogOpened(IDialogParameters parameters) + public virtual void OnDialogOpened(IDialogParameters parameters) { } diff --git a/src/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs b/src/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs new file mode 100644 index 0000000..4a61093 --- /dev/null +++ b/src/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs @@ -0,0 +1,65 @@ +using DownKyi.Images; +using Prism.Commands; +using Prism.Services.Dialogs; + +namespace DownKyi.ViewModels.Dialogs +{ + public class ViewAlertDialogViewModel : BaseDialogViewModel + { + public const string Tag = "DialogAlert"; + + #region 页面属性申明 + + private VectorImage image; + public VectorImage Image + { + get => image; + set => SetProperty(ref image, value); + } + + private string message; + public string Message + { + get { return message; } + set { SetProperty(ref message, value); } + } + + #endregion + + public ViewAlertDialogViewModel() + { + + } + + #region 命令申明 + + // 确认事件 + private DelegateCommand allowCommand; + public DelegateCommand AllowCommand => allowCommand ?? (allowCommand = new DelegateCommand(ExecuteAllowCommand)); + + /// + /// 确认事件 + /// + private void ExecuteAllowCommand() + { + ButtonResult result = ButtonResult.OK; + RaiseRequestClose(new DialogResult(result)); + } + + #endregion + + #region 接口实现 + + public override void OnDialogOpened(IDialogParameters parameters) + { + base.OnDialogOpened(parameters); + + Image = parameters.GetValue("image"); + Title = parameters.GetValue("title"); + Message = parameters.GetValue("message"); + } + + #endregion + + } +} diff --git a/src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs b/src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs index 4586b8a..d1f1b30 100644 --- a/src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs +++ b/src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs @@ -2,6 +2,7 @@ using DownKyi.Core.BiliApi.Zone; using DownKyi.Models; using Prism.Mvvm; +using Prism.Services.Dialogs; using System.Windows; using System.Windows.Media; @@ -9,6 +10,18 @@ namespace DownKyi.ViewModels.DownloadManager { public class DownloadBaseItem : BindableBase { + public IDialogService DialogService; + + public DownloadBaseItem() + { + DialogService = null; + } + + public DownloadBaseItem(IDialogService dialogService) + { + DialogService = dialogService; + } + // model数据 private DownloadBase downloadBase; public DownloadBase DownloadBase diff --git a/src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs b/src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs index 15fd55f..8bb6518 100644 --- a/src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs +++ b/src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs @@ -1,14 +1,20 @@ using DownKyi.Images; using DownKyi.Models; +using DownKyi.Services; using DownKyi.Utils; using Prism.Commands; +using Prism.Services.Dialogs; using System.IO; namespace DownKyi.ViewModels.DownloadManager { public class DownloadedItem : DownloadBaseItem { - public DownloadedItem() : base() + public DownloadedItem() : this(null) + { + } + + public DownloadedItem(IDialogService dialogService) : base(dialogService) { // 打开文件夹按钮 OpenFolder = ButtonIcon.Instance().Folder; @@ -131,6 +137,13 @@ namespace DownKyi.ViewModels.DownloadManager /// private void ExecuteRemoveVideoCommand() { + AlertService alertService = new AlertService(DialogService); + ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete")); + if (result != ButtonResult.OK) + { + return; + } + App.DownloadedList.Remove(this); } diff --git a/src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs b/src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs index dc51226..0f090eb 100644 --- a/src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs +++ b/src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs @@ -1,14 +1,20 @@ using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Images; using DownKyi.Models; +using DownKyi.Services; using DownKyi.Utils; using Prism.Commands; +using Prism.Services.Dialogs; namespace DownKyi.ViewModels.DownloadManager { public class DownloadingItem : DownloadBaseItem { - public DownloadingItem() : base() + public DownloadingItem() : this(null) + { + } + + public DownloadingItem(IDialogService dialogService) : base(dialogService) { // 暂停继续按钮 StartOrPause = ButtonIcon.Instance().Pause; @@ -211,6 +217,13 @@ namespace DownKyi.ViewModels.DownloadManager /// private void ExecuteDeleteCommand() { + AlertService alertService = new AlertService(DialogService); + ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete")); + if (result != ButtonResult.OK) + { + return; + } + App.DownloadingList.Remove(this); } diff --git a/src/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs b/src/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs index c4d94a1..9a081c3 100644 --- a/src/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs +++ b/src/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs @@ -1,9 +1,14 @@ using DownKyi.Core.Settings; +using DownKyi.Services; +using DownKyi.Utils; using Prism.Commands; using Prism.Events; +using Prism.Regions; +using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.Linq; using System.Threading.Tasks; @@ -31,10 +36,27 @@ namespace DownKyi.ViewModels.DownloadManager #endregion - public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService) { // 初始化DownloadedList DownloadedList = App.DownloadedList; + DownloadedList.CollectionChanged += new NotifyCollectionChangedEventHandler(async (object sender, NotifyCollectionChangedEventArgs e) => + { + await Task.Run(() => + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + foreach (var item in DownloadedList) + { + if (item != null && item.DialogService == null) + { + item.DialogService = dialogService; + } + } + } + }); + }); + SetDialogService(); DownloadFinishedSort finishedSort = SettingsManager.GetInstance().GetDownloadFinishedSort(); switch (finishedSort) @@ -95,6 +117,13 @@ namespace DownKyi.ViewModels.DownloadManager /// private async void ExecuteClearAllDownloadedCommand() { + AlertService alertService = new AlertService(dialogService); + ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete")); + if (result != ButtonResult.OK) + { + return; + } + // 使用Clear()不能触发NotifyCollectionChangedAction.Remove事件 // 因此遍历删除 // DownloadingList中元素被删除后不能继续遍历 @@ -113,5 +142,26 @@ namespace DownKyi.ViewModels.DownloadManager #endregion + private async void SetDialogService() + { + await Task.Run(() => + { + foreach (var item in DownloadedList) + { + if (item != null && item.DialogService == null) + { + item.DialogService = dialogService; + } + } + }); + } + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + base.OnNavigatedFrom(navigationContext); + + SetDialogService(); + } + } } diff --git a/src/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs b/src/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs index a30c30b..aade091 100644 --- a/src/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs +++ b/src/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs @@ -1,11 +1,15 @@ using DownKyi.Images; using DownKyi.Models; +using DownKyi.Services; using DownKyi.Utils; using Prism.Commands; using Prism.Events; +using Prism.Regions; +using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.Linq; using System.Threading.Tasks; @@ -26,10 +30,28 @@ namespace DownKyi.ViewModels.DownloadManager #endregion - public ViewDownloadingViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + public ViewDownloadingViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService) { // 初始化DownloadingList DownloadingList = App.DownloadingList; + DownloadingList.CollectionChanged += new NotifyCollectionChangedEventHandler(async (object sender, NotifyCollectionChangedEventArgs e) => + { + await Task.Run(() => + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + foreach (var item in DownloadingList) + { + if (item != null && item.DialogService == null) + { + item.DialogService = dialogService; + } + } + } + }); + }); + SetDialogService(); + } #region 命令申明 @@ -133,6 +155,13 @@ namespace DownKyi.ViewModels.DownloadManager /// private async void ExecuteDeleteAllDownloadingCommand() { + AlertService alertService = new AlertService(dialogService); + ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete")); + if (result != ButtonResult.OK) + { + return; + } + // 使用Clear()不能触发NotifyCollectionChangedAction.Remove事件 // 因此遍历删除 // DownloadingList中元素被删除后不能继续遍历 @@ -151,5 +180,26 @@ namespace DownKyi.ViewModels.DownloadManager #endregion + private async void SetDialogService() + { + await Task.Run(() => + { + foreach (var item in DownloadingList) + { + if (item != null && item.DialogService == null) + { + item.DialogService = dialogService; + } + } + }); + } + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + base.OnNavigatedFrom(navigationContext); + + SetDialogService(); + } + } } diff --git a/src/DownKyi/ViewModels/ViewIndexViewModel.cs b/src/DownKyi/ViewModels/ViewIndexViewModel.cs index 66a230d..ee1fbc8 100644 --- a/src/DownKyi/ViewModels/ViewIndexViewModel.cs +++ b/src/DownKyi/ViewModels/ViewIndexViewModel.cs @@ -9,6 +9,7 @@ using DownKyi.Utils; using Prism.Commands; using Prism.Events; using Prism.Regions; +using Prism.Services.Dialogs; using System; using System.IO; using System.Threading.Tasks; @@ -88,7 +89,7 @@ namespace DownKyi.ViewModels #endregion - public ViewIndexViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + public ViewIndexViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService) { #region 属性初始化 @@ -207,7 +208,10 @@ namespace DownKyi.ViewModels /// private void EnterBili() { - if (InputText == null || InputText == string.Empty) { return; } + if (InputText == null || InputText == string.Empty) + { + return; + } LogManager.Debug(Tag, $"InputText: {InputText}"); diff --git a/src/DownKyi/ViewModels/ViewVideoDetailViewModel.cs b/src/DownKyi/ViewModels/ViewVideoDetailViewModel.cs index edb6cf2..088a7ae 100644 --- a/src/DownKyi/ViewModels/ViewVideoDetailViewModel.cs +++ b/src/DownKyi/ViewModels/ViewVideoDetailViewModel.cs @@ -27,8 +27,6 @@ namespace DownKyi.ViewModels { public const string Tag = "PageVideoDetail"; - private readonly IDialogService dialogService; - // 保存输入字符串,避免被用户修改 private string input = null; @@ -106,10 +104,8 @@ namespace DownKyi.ViewModels #endregion - public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator) + public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService) { - this.dialogService = dialogService; - #region 属性初始化 // 初始化loading gif diff --git a/src/DownKyi/Views/Dialogs/ViewAlertDialog.xaml b/src/DownKyi/Views/Dialogs/ViewAlertDialog.xaml new file mode 100644 index 0000000..16de4ef --- /dev/null +++ b/src/DownKyi/Views/Dialogs/ViewAlertDialog.xaml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +