feat: 添加重复下载提醒的设置

This commit is contained in:
姚彪
2023-12-24 01:06:29 +08:00
parent c3ed7cc4ff
commit 7a4b411e03
9 changed files with 467 additions and 186 deletions

View File

@@ -0,0 +1,8 @@
namespace DownKyi.Core.Settings;
public enum RepeatDownloadStrategy
{
Ask,
ReDownload,
JumpOver
};

View File

@@ -37,6 +37,9 @@ public partial class App : PrismApplication
{
public static ObservableCollection<DownloadingItem> DownloadingList { get; set; }
public static ObservableCollection<DownloadedItem> DownloadedList { get; set; }
public new static App Current => (App)Application.Current!;
public new MainWindow MainWindow => Container.Resolve<MainWindow>();
private IClassicDesktopStyleApplicationLifetime _appLife;
// 下载服务
private IDownloadService? _downloadService;
@@ -51,8 +54,15 @@ public partial class App : PrismApplication
AvaloniaXamlLoader.Load(this);
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// desktop.Startup += OnStartup;
desktop.Exit += OnExit!;
_appLife = desktop;
}
else
{
if (!Design.IsDesignMode)
{
throw new NotImplementedException("Not support this system.");
}
}
base.Initialize();
@@ -106,12 +116,14 @@ public partial class App : PrismApplication
// UserSpace
containerRegistry.RegisterForNavigation<ViewArchive>(ViewArchiveViewModel.Tag);
// containerRegistry.RegisterForNavigation<Views.UserSpace.ViewChannel>(ViewModels.UserSpace.ViewChannelViewModel.Tag);
containerRegistry.RegisterForNavigation<Views.UserSpace.ViewSeasonsSeries>(ViewModels.UserSpace.ViewSeasonsSeriesViewModel.Tag);
containerRegistry.RegisterForNavigation<Views.UserSpace.ViewSeasonsSeries>(ViewModels.UserSpace
.ViewSeasonsSeriesViewModel.Tag);
// dialogs
containerRegistry.RegisterDialog<ViewAlertDialog>(ViewAlertDialogViewModel.Tag);
containerRegistry.RegisterDialog<ViewDownloadSetter>(ViewDownloadSetterViewModel.Tag);
containerRegistry.RegisterDialog<ViewParsingSelector>(ViewParsingSelectorViewModel.Tag);
containerRegistry.RegisterDialog<ViewAlreadyDownloadedDialog>(ViewAlreadyDownloadedDialogViewModel.Tag);
}

View File

@@ -0,0 +1,9 @@
using DownKyi.Core.Settings;
namespace DownKyi.Models;
public class RepeatDownloadStrategyDisplay
{
public string Name { get; set; }
public RepeatDownloadStrategy RepeatDownloadStrategy { get; set; }
}

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.BiliApi.Zone;
@@ -30,16 +31,16 @@ namespace DownKyi.Services.Download;
public class AddToDownloadService
{
private readonly string Tag = "AddToDownloadService";
private IInfoService videoInfoService;
private VideoInfoView videoInfoView;
private List<VideoSection> videoSections;
private IInfoService _videoInfoService;
private VideoInfoView _videoInfoView;
private List<VideoSection>? _videoSections;
// 下载内容
private bool downloadAudio = true;
private bool downloadVideo = true;
private bool downloadDanmaku = true;
private bool downloadSubtitle = true;
private bool downloadCover = true;
private bool _downloadAudio = true;
private bool _downloadVideo = true;
private bool _downloadDanmaku = true;
private bool _downloadSubtitle = true;
private bool _downloadCover = true;
/// <summary>
/// 添加下载
@@ -50,13 +51,13 @@ public class AddToDownloadService
switch (streamType)
{
case PlayStreamType.VIDEO:
videoInfoService = new VideoInfoService(null);
_videoInfoService = new VideoInfoService(null);
break;
case PlayStreamType.BANGUMI:
videoInfoService = new BangumiInfoService(null);
_videoInfoService = new BangumiInfoService(null);
break;
case PlayStreamType.CHEESE:
videoInfoService = new CheeseInfoService(null);
_videoInfoService = new CheeseInfoService(null);
break;
default:
break;
@@ -73,13 +74,13 @@ public class AddToDownloadService
switch (streamType)
{
case PlayStreamType.VIDEO:
videoInfoService = new VideoInfoService(id);
_videoInfoService = new VideoInfoService(id);
break;
case PlayStreamType.BANGUMI:
videoInfoService = new BangumiInfoService(id);
_videoInfoService = new BangumiInfoService(id);
break;
case PlayStreamType.CHEESE:
videoInfoService = new CheeseInfoService(id);
_videoInfoService = new CheeseInfoService(id);
break;
default:
break;
@@ -88,14 +89,14 @@ public class AddToDownloadService
public void SetVideoInfoService(IInfoService videoInfoService)
{
this.videoInfoService = videoInfoService;
_videoInfoService = videoInfoService;
}
public void GetVideo(VideoInfoView videoInfoView, List<VideoSection> videoSections, List<int> selectedVideo)
{
this.videoInfoView = videoInfoView;
this.videoSections = videoSections;
foreach (VideoSection section in videoSections.Where(videoSection => videoSection.IsSelected))
_videoInfoView = videoInfoView;
_videoSections = videoSections;
foreach (var section in videoSections.Where(videoSection => videoSection.IsSelected))
{
foreach (var item in section.VideoPages)
{
@@ -109,32 +110,32 @@ public class AddToDownloadService
public void GetVideo()
{
videoInfoView = videoInfoService.GetVideoView();
if (videoInfoView == null)
_videoInfoView = _videoInfoService.GetVideoView();
if (_videoInfoView == null)
{
LogManager.Debug(Tag, "VideoInfoView is null.");
return;
}
videoSections = videoInfoService.GetVideoSections(true);
if (videoSections == null)
_videoSections = _videoInfoService.GetVideoSections(true);
if (_videoSections == null)
{
LogManager.Debug(Tag, "videoSections is not exist.");
videoSections = new List<VideoSection>
_videoSections = new List<VideoSection>
{
new VideoSection
new()
{
Id = 0,
Title = "default",
IsSelected = true,
VideoPages = videoInfoService.GetVideoPages()
VideoPages = _videoInfoService.GetVideoPages()
}
};
}
// 将所有视频设置为选中
foreach (VideoSection section in videoSections)
foreach (var section in _videoSections)
{
foreach (var item in section.VideoPages)
{
@@ -149,14 +150,14 @@ public class AddToDownloadService
/// <param name="videoInfoService"></param>
public void ParseVideo(IInfoService videoInfoService)
{
if (videoSections == null)
if (_videoSections == null)
{
return;
}
foreach (VideoSection section in videoSections)
foreach (var section in _videoSections)
{
foreach (VideoPage page in section.VideoPages)
foreach (var page in section.VideoPages)
{
// 执行解析任务
videoInfoService.GetVideoStream(page);
@@ -168,56 +169,43 @@ public class AddToDownloadService
/// 选择文件夹和下载项
/// </summary>
/// <param name="dialogService"></param>
public async Task<string> SetDirectory(IDialogService dialogService)
public async Task<string?> SetDirectory(IDialogService dialogService)
{
// 选择的下载文件夹
string directory = string.Empty;
var directory = string.Empty;
// 是否使用默认下载目录
if (SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES)
{
// 下载内容
VideoContentSettings videoContent = SettingsManager.GetInstance().GetVideoContent();
downloadAudio = videoContent.DownloadAudio;
downloadVideo = videoContent.DownloadVideo;
downloadDanmaku = videoContent.DownloadDanmaku;
downloadSubtitle = videoContent.DownloadSubtitle;
downloadCover = videoContent.DownloadCover;
var videoContent = SettingsManager.GetInstance().GetVideoContent();
_downloadAudio = videoContent.DownloadAudio;
_downloadVideo = videoContent.DownloadVideo;
_downloadDanmaku = videoContent.DownloadDanmaku;
_downloadSubtitle = videoContent.DownloadSubtitle;
_downloadCover = videoContent.DownloadCover;
directory = SettingsManager.GetInstance().GetSaveVideoRootPath();
}
else
{
bool run = true;
// 打开文件夹选择器
await dialogService.ShowDialogAsync(ViewDownloadSetterViewModel.Tag, null, result =>
{
if (result.Result == ButtonResult.OK)
{
// 选择的下载文件夹
directory = result.Parameters.GetValue<string>("directory");
if (result.Result != ButtonResult.OK) return;
// 选择的下载文件夹
directory = result.Parameters.GetValue<string>("directory");
// 下载内容
downloadAudio = result.Parameters.GetValue<bool>("downloadAudio");
downloadVideo = result.Parameters.GetValue<bool>("downloadVideo");
downloadDanmaku = result.Parameters.GetValue<bool>("downloadDanmaku");
downloadSubtitle = result.Parameters.GetValue<bool>("downloadSubtitle");
downloadCover = result.Parameters.GetValue<bool>("downloadCover");
}
run = false;
// 下载内容
_downloadAudio = result.Parameters.GetValue<bool>("downloadAudio");
_downloadVideo = result.Parameters.GetValue<bool>("downloadVideo");
_downloadDanmaku = result.Parameters.GetValue<bool>("downloadDanmaku");
_downloadSubtitle = result.Parameters.GetValue<bool>("downloadSubtitle");
_downloadCover = result.Parameters.GetValue<bool>("downloadCover");
});
// await Task.Run(() =>
// {
// while (true)
// {
// if (!run) break;
// Thread.Sleep(100);
// }
// });
}
if (directory == String.Empty)
if (directory == string.Empty)
{
return null;
}
@@ -234,7 +222,7 @@ public class AddToDownloadService
// 下载设置dialog中如果点击取消或者关闭窗口
// 会返回空字符串,
// 这时直接退出
if (directory == null || directory == string.Empty)
if (string.IsNullOrEmpty(directory))
{
return null;
}
@@ -252,33 +240,33 @@ public class AddToDownloadService
/// 添加到下载列表
/// </summary>
/// <param name="eventAggregator">传递事件的对象</param>
/// <param name="dialogService">dialog</param>
/// <param name="directory">下载路径</param>
/// <param name="isAll">是否下载所有,包括未选中项</param>
/// <returns>添加的数量</returns>
public int AddToDownload(IEventAggregator eventAggregator, string directory, bool isAll = false)
public async Task<int> AddToDownload(IEventAggregator eventAggregator, IDialogService dialogService, string? directory, bool isAll = false)
{
if (directory == null || directory == string.Empty)
if (string.IsNullOrEmpty(directory))
{
return -1;
}
if (videoSections == null)
if (_videoSections == null)
{
return -1;
}
// 视频计数
int i = 0;
var i = 0;
// 添加到下载
foreach (VideoSection section in videoSections)
foreach (var section in _videoSections)
{
if (section.VideoPages == null)
{
continue;
}
foreach (VideoPage page in section.VideoPages)
foreach (var page in section.VideoPages)
{
// 只下载选中项,跳过未选中项
if (!isAll && !page.IsSelected)
@@ -293,11 +281,11 @@ public class AddToDownloadService
}
// 判断VideoQuality
int retry = 0;
var retry = 0;
while (page.VideoQuality == null && retry < 5)
{
// 执行解析任务
videoInfoService.GetVideoStream(page);
_videoInfoService.GetVideoStream(page);
retry++;
}
@@ -309,20 +297,18 @@ public class AddToDownloadService
// 判断是否同一个视频需要cid、画质、音质、视频编码都相同
// 如果存在正在下载列表,则跳过,并提示
bool isDownloading = false;
foreach (DownloadingItem item in App.DownloadingList)
var isDownloading = false;
foreach (var item in App.DownloadingList)
{
if (item.DownloadBase == null)
{
continue;
}
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality &&
item.AudioCodec.Name == page.AudioQualityFormat &&
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat &&
item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent<MessageEvent>()
.Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloading")}");
eventAggregator.GetEvent<MessageEvent>().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloading")}");
isDownloading = true;
break;
}
@@ -334,21 +320,59 @@ public class AddToDownloadService
}
// TODO 如果存在下载完成列表,弹出选择框是否再次下载
bool isDownloaded = false;
foreach (DownloadedItem item in App.DownloadedList)
var isDownloaded = false;
foreach (var item in App.DownloadedList)
{
if (item.DownloadBase == null)
{
continue;
}
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality &&
item.AudioCodec.Name == page.AudioQualityFormat &&
if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat &&
item.VideoCodecName == page.VideoQuality.SelectedVideoCodec)
{
eventAggregator.GetEvent<MessageEvent>()
.Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloaded")}");
isDownloaded = true;
// eventAggregator.GetEvent<MessageEvent>().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloaded")}");
// isDownloaded = true;
var repeatDownloadStrategy = SettingsManager.GetInstance().GetRepeatDownloadStrategy();
switch (repeatDownloadStrategy)
{
case RepeatDownloadStrategy.Ask:
{
var result = ButtonResult.Cancel;
await Dispatcher.UIThread.Invoke(async () =>
{
var param = new DialogParameters
{
{ "message", $"{item.Name}已下载,是否重新下载" },
};
await dialogService.ShowDialogAsync(ViewAlreadyDownloadedDialogViewModel.Tag, param,
buttonResult => { result = buttonResult.Result; });
});
if (result == ButtonResult.OK)
{
App.PropertyChangeAsync(() => { App.DownloadedList.Remove(item); });
isDownloaded = false;
}
else
{
isDownloaded = true;
}
break;
}
case RepeatDownloadStrategy.ReDownload:
isDownloaded = false;
break;
case RepeatDownloadStrategy.JumpOver:
isDownloaded = true;
break;
default:
isDownloaded = true;
break;
}
break;
}
}
@@ -359,9 +383,9 @@ public class AddToDownloadService
}
// 视频分区
int zoneId = -1;
List<ZoneAttr> zoneList = VideoZone.Instance().GetZones();
ZoneAttr zone = zoneList.Find(it => it.Id == videoInfoView.TypeId);
var zoneId = -1;
var zoneList = VideoZone.Instance().GetZones();
var zone = zoneList.Find(it => it.Id == _videoInfoView.TypeId);
if (zone != null)
{
if (zone.ParentId == 0)
@@ -370,7 +394,7 @@ public class AddToDownloadService
}
else
{
ZoneAttr zoneParent = zoneList.Find(it => it.Id == zone.ParentId);
var zoneParent = zoneList.Find(it => it.Id == zone.ParentId);
if (zoneParent != null)
{
zoneId = zoneParent.Id;
@@ -379,19 +403,19 @@ public class AddToDownloadService
}
// 如果只有一个视频章节,则不在命名中出现
string sectionName = string.Empty;
if (videoSections.Count > 1)
var sectionName = string.Empty;
if (_videoSections.Count > 1)
{
sectionName = section.Title;
}
// 文件路径
List<FileNamePart> fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
FileName fileName = FileName.Builder(fileNameParts)
var fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
var fileName = FileName.Builder(fileNameParts)
.SetSection(Format.FormatFileName(sectionName))
.SetMainTitle(Format.FormatFileName(videoInfoView.Title))
.SetMainTitle(Format.FormatFileName(_videoInfoView.Title))
.SetPageTitle(Format.FormatFileName(page.Name))
.SetVideoZone(videoInfoView.VideoZone.Split('>')[0])
.SetVideoZone(_videoInfoView.VideoZone.Split('>')[0])
.SetAudioQuality(page.AudioQualityFormat)
.SetVideoQuality(page.VideoQuality == null ? "" : page.VideoQuality.QualityFormat)
.SetVideoCodec(page.VideoQuality == null ? "" :
@@ -407,7 +431,7 @@ public class AddToDownloadService
.SetUpName(Format.FormatFileName(page.Owner.Name));
// 序号设置
OrderFormat orderFormat = SettingsManager.GetInstance().GetOrderFormat();
var orderFormat = SettingsManager.GetInstance().GetOrderFormat();
switch (orderFormat)
{
case OrderFormat.NATURAL:
@@ -419,11 +443,11 @@ public class AddToDownloadService
}
// 合成绝对路径
string filePath = Path.Combine(directory, fileName.RelativePath());
var filePath = Path.Combine(directory, fileName.RelativePath());
// 视频类别
PlayStreamType playStreamType;
switch (videoInfoView.TypeId)
switch (_videoInfoView.TypeId)
{
case -10:
playStreamType = PlayStreamType.CHEESE;
@@ -457,46 +481,42 @@ public class AddToDownloadService
}
// 添加到下载列表
App.PropertyChangeAsync(new Action(() =>
App.PropertyChangeAsync(() =>
{
// 如果不存在,直接添加到下载列表
DownloadBase downloadBase = new DownloadBase
var downloadBase = new DownloadBase
{
Bvid = page.Bvid,
Avid = page.Avid,
Cid = page.Cid,
EpisodeId = page.EpisodeId,
CoverUrl = videoInfoView.CoverUrl,
CoverUrl = _videoInfoView.CoverUrl,
PageCoverUrl = page.FirstFrame,
ZoneId = zoneId,
FilePath = filePath,
Order = page.Order,
MainTitle = videoInfoView.Title,
MainTitle = _videoInfoView.Title,
Name = page.Name,
Duration = page.Duration,
VideoCodecName = page.VideoQuality.SelectedVideoCodec,
Resolution = new Quality
{ Name = page.VideoQuality.QualityFormat, Id = page.VideoQuality.Quality },
AudioCodec = Constant.GetAudioQualities().FirstOrDefault(t =>
{
return t.Name == page.AudioQualityFormat;
}),
Resolution = new Quality { Name = page.VideoQuality.QualityFormat, Id = page.VideoQuality.Quality },
AudioCodec = Constant.GetAudioQualities().FirstOrDefault(t => { return t.Name == page.AudioQualityFormat; })
};
Downloading downloading = new Downloading
var downloading = new Downloading
{
PlayStreamType = playStreamType,
DownloadStatus = DownloadStatus.NOT_STARTED,
};
// 需要下载的内容
downloadBase.NeedDownloadContent["downloadAudio"] = downloadAudio;
downloadBase.NeedDownloadContent["downloadVideo"] = downloadVideo;
downloadBase.NeedDownloadContent["downloadDanmaku"] = downloadDanmaku;
downloadBase.NeedDownloadContent["downloadSubtitle"] = downloadSubtitle;
downloadBase.NeedDownloadContent["downloadCover"] = downloadCover;
downloadBase.NeedDownloadContent["downloadAudio"] = _downloadAudio;
downloadBase.NeedDownloadContent["downloadVideo"] = _downloadVideo;
downloadBase.NeedDownloadContent["downloadDanmaku"] = _downloadDanmaku;
downloadBase.NeedDownloadContent["downloadSubtitle"] = _downloadSubtitle;
downloadBase.NeedDownloadContent["downloadCover"] = _downloadCover;
DownloadingItem downloadingItem = new DownloadingItem
var downloadingItem = new DownloadingItem
{
DownloadBase = downloadBase,
Downloading = downloading,
@@ -505,7 +525,7 @@ public class AddToDownloadService
App.DownloadingList.Add(downloadingItem);
Thread.Sleep(10);
}));
});
i++;
}
}

View File

@@ -0,0 +1,66 @@
using DownKyi.Images;
using Prism.Commands;
using Prism.Services.Dialogs;
namespace DownKyi.ViewModels.Dialogs;
public class ViewAlreadyDownloadedDialogViewModel : BaseDialogViewModel
{
public const string Tag = "AlreadyDownloadedAlert";
#region
private VectorImage? _image;
public VectorImage? Image
{
get => _image;
set => SetProperty(ref _image, value);
}
private string? _message;
public string? Message
{
get => _message;
set => SetProperty(ref _message, value);
}
#endregion
public ViewAlreadyDownloadedDialogViewModel()
{
Title = "提示";
Image = SystemIcon.Instance().Warning;
}
#region
private DelegateCommand? _yesCommand;
public DelegateCommand YesCommand => _yesCommand ??= new DelegateCommand(ExecuteYesCommand);
private void ExecuteYesCommand()
{
RaiseRequestClose(new DialogResult(ButtonResult.OK));
}
// 关闭窗口事件
private DelegateCommand? _closeCommand;
public new DelegateCommand CloseCommand => _closeCommand ??= new DelegateCommand(ExecuteCloseCommand);
/// <summary>
/// 关闭窗口事件
/// </summary>
private void ExecuteCloseCommand()
{
RaiseRequestClose(new DialogResult(ButtonResult.Cancel));
}
#endregion
public override void OnDialogOpened(IDialogParameters parameters)
{
Message = parameters.GetValue<string>("message");
}
}

View File

@@ -14,72 +14,88 @@ public class ViewBasicViewModel : ViewModelBase
{
public const string Tag = "PageSettingsBasic";
private bool isOnNavigatedTo;
private bool _isOnNavigatedTo;
#region
private bool none;
private bool _none;
public bool None
{
get { return none; }
set { SetProperty(ref none, value); }
get => _none;
set => SetProperty(ref _none, value);
}
private bool closeApp;
private bool _closeApp;
public bool CloseApp
{
get { return closeApp; }
set { SetProperty(ref closeApp, value); }
get => _closeApp;
set => SetProperty(ref _closeApp, value);
}
private bool closeSystem;
private bool _closeSystem;
public bool CloseSystem
{
get { return closeSystem; }
set { SetProperty(ref closeSystem, value); }
get => _closeSystem;
set => SetProperty(ref _closeSystem, value);
}
private bool listenClipboard;
private bool _listenClipboard;
public bool ListenClipboard
{
get { return listenClipboard; }
set { SetProperty(ref listenClipboard, value); }
get => _listenClipboard;
set => SetProperty(ref _listenClipboard, value);
}
private bool autoParseVideo;
private bool _autoParseVideo;
public bool AutoParseVideo
{
get { return autoParseVideo; }
set { SetProperty(ref autoParseVideo, value); }
get => _autoParseVideo;
set => SetProperty(ref _autoParseVideo, value);
}
private List<ParseScopeDisplay> parseScopes;
private List<ParseScopeDisplay> _parseScopes;
public List<ParseScopeDisplay> ParseScopes
{
get { return parseScopes; }
set { SetProperty(ref parseScopes, value); }
get => _parseScopes;
set => SetProperty(ref _parseScopes, value);
}
private ParseScopeDisplay selectedParseScope;
private ParseScopeDisplay _selectedParseScope;
public ParseScopeDisplay SelectedParseScope
{
get { return selectedParseScope; }
set { SetProperty(ref selectedParseScope, value); }
get => _selectedParseScope;
set => SetProperty(ref _selectedParseScope, value);
}
private bool autoDownloadAll;
private bool _autoDownloadAll;
public bool AutoDownloadAll
{
get => autoDownloadAll;
set => SetProperty(ref autoDownloadAll, value);
get => _autoDownloadAll;
set => SetProperty(ref _autoDownloadAll, value);
}
private List<RepeatDownloadStrategyDisplay> _repeatDownloadStrategy;
public List<RepeatDownloadStrategyDisplay> RepeatDownloadStrategy
{
get => _repeatDownloadStrategy;
set => SetProperty(ref _repeatDownloadStrategy, value);
}
private RepeatDownloadStrategyDisplay _selectedRepeatDownloadStrategy;
public RepeatDownloadStrategyDisplay SelectedRepeatDownloadStrategy
{
get => _selectedRepeatDownloadStrategy;
set => SetProperty(ref _selectedRepeatDownloadStrategy, value);
}
#endregion
@@ -89,14 +105,19 @@ public class ViewBasicViewModel : ViewModelBase
#region
// 解析范围
ParseScopes = new List<ParseScopeDisplay>()
ParseScopes = new List<ParseScopeDisplay>
{
new ParseScopeDisplay { Name = DictionaryResource.GetString("ParseNone"), ParseScope = ParseScope.NONE },
new ParseScopeDisplay
{ Name = DictionaryResource.GetString("ParseSelectedItem"), ParseScope = ParseScope.SELECTED_ITEM },
new ParseScopeDisplay
{ Name = DictionaryResource.GetString("ParseCurrentSection"), ParseScope = ParseScope.CURRENT_SECTION },
new ParseScopeDisplay { Name = DictionaryResource.GetString("ParseAll"), ParseScope = ParseScope.ALL }
new() { Name = DictionaryResource.GetString("ParseNone"), ParseScope = ParseScope.NONE },
new() { Name = DictionaryResource.GetString("ParseSelectedItem"), ParseScope = ParseScope.SELECTED_ITEM },
new() { Name = DictionaryResource.GetString("ParseCurrentSection"), ParseScope = ParseScope.CURRENT_SECTION },
new() { Name = DictionaryResource.GetString("ParseAll"), ParseScope = ParseScope.ALL }
};
RepeatDownloadStrategy = new List<RepeatDownloadStrategyDisplay>
{
new() { Name = DictionaryResource.GetString("RepeatDownloadAsk"), RepeatDownloadStrategy = Core.Settings.RepeatDownloadStrategy.Ask },
new() { Name = DictionaryResource.GetString("RepeatDownloadReDownload"), RepeatDownloadStrategy = Core.Settings.RepeatDownloadStrategy.ReDownload },
new() { Name = DictionaryResource.GetString("RepeatDownloadReJumpOver"), RepeatDownloadStrategy = Core.Settings.RepeatDownloadStrategy.JumpOver }
};
#endregion
@@ -110,40 +131,41 @@ public class ViewBasicViewModel : ViewModelBase
{
base.OnNavigatedTo(navigationContext);
isOnNavigatedTo = true;
_isOnNavigatedTo = true;
// 下载完成后的操作
AfterDownloadOperation afterDownload = SettingsManager.GetInstance().GetAfterDownloadOperation();
var afterDownload = SettingsManager.GetInstance().GetAfterDownloadOperation();
SetAfterDownloadOperation(afterDownload);
// 是否监听剪贴板
AllowStatus isListenClipboard = SettingsManager.GetInstance().IsListenClipboard();
var isListenClipboard = SettingsManager.GetInstance().IsListenClipboard();
ListenClipboard = isListenClipboard == AllowStatus.YES;
// 是否自动解析视频
AllowStatus isAutoParseVideo = SettingsManager.GetInstance().IsAutoParseVideo();
var isAutoParseVideo = SettingsManager.GetInstance().IsAutoParseVideo();
AutoParseVideo = isAutoParseVideo == AllowStatus.YES;
// 解析范围
ParseScope parseScope = SettingsManager.GetInstance().GetParseScope();
var parseScope = SettingsManager.GetInstance().GetParseScope();
SelectedParseScope = ParseScopes.FirstOrDefault(t => { return t.ParseScope == parseScope; });
// 解析后是否自动下载解析视频
AllowStatus isAutoDownloadAll = SettingsManager.GetInstance().IsAutoDownloadAll();
var isAutoDownloadAll = SettingsManager.GetInstance().IsAutoDownloadAll();
AutoDownloadAll = isAutoDownloadAll == AllowStatus.YES;
isOnNavigatedTo = false;
// 重复下载策略
var repeatDownloadStrategy = SettingsManager.GetInstance().GetRepeatDownloadStrategy();
SelectedRepeatDownloadStrategy = RepeatDownloadStrategy.FirstOrDefault(t => { return t.RepeatDownloadStrategy == repeatDownloadStrategy; });
_isOnNavigatedTo = false;
}
#region
// 下载完成后的操作事件
private DelegateCommand<string> afterDownloadOperationCommand;
private DelegateCommand<string>? _afterDownloadOperationCommand;
public DelegateCommand<string> AfterDownloadOperationCommand => afterDownloadOperationCommand ??
(afterDownloadOperationCommand =
new DelegateCommand<string>(
ExecuteAfterDownloadOperationCommand));
public DelegateCommand<string> AfterDownloadOperationCommand => _afterDownloadOperationCommand ??= new DelegateCommand<string>(ExecuteAfterDownloadOperationCommand);
/// <summary>
/// 下载完成后的操作事件
@@ -167,51 +189,45 @@ public class ViewBasicViewModel : ViewModelBase
break;
}
bool isSucceed = SettingsManager.GetInstance().SetAfterDownloadOperation(afterDownload);
var isSucceed = SettingsManager.GetInstance().SetAfterDownloadOperation(afterDownload);
PublishTip(isSucceed);
}
// 是否监听剪贴板事件
private DelegateCommand listenClipboardCommand;
private DelegateCommand? _listenClipboardCommand;
public DelegateCommand ListenClipboardCommand => listenClipboardCommand ??
(listenClipboardCommand =
new DelegateCommand(ExecuteListenClipboardCommand));
public DelegateCommand ListenClipboardCommand => _listenClipboardCommand ??= new DelegateCommand(ExecuteListenClipboardCommand);
/// <summary>
/// 是否监听剪贴板事件
/// </summary>
private void ExecuteListenClipboardCommand()
{
AllowStatus isListenClipboard = ListenClipboard ? AllowStatus.YES : AllowStatus.NO;
var isListenClipboard = ListenClipboard ? AllowStatus.YES : AllowStatus.NO;
bool isSucceed = SettingsManager.GetInstance().IsListenClipboard(isListenClipboard);
var isSucceed = SettingsManager.GetInstance().IsListenClipboard(isListenClipboard);
PublishTip(isSucceed);
}
private DelegateCommand autoParseVideoCommand;
private DelegateCommand? _autoParseVideoCommand;
public DelegateCommand AutoParseVideoCommand => autoParseVideoCommand ??
(autoParseVideoCommand =
new DelegateCommand(ExecuteAutoParseVideoCommand));
public DelegateCommand AutoParseVideoCommand => _autoParseVideoCommand ??= new DelegateCommand(ExecuteAutoParseVideoCommand);
/// <summary>
/// 是否自动解析视频
/// </summary>
private void ExecuteAutoParseVideoCommand()
{
AllowStatus isAutoParseVideo = AutoParseVideo ? AllowStatus.YES : AllowStatus.NO;
var isAutoParseVideo = AutoParseVideo ? AllowStatus.YES : AllowStatus.NO;
bool isSucceed = SettingsManager.GetInstance().IsAutoParseVideo(isAutoParseVideo);
var isSucceed = SettingsManager.GetInstance().IsAutoParseVideo(isAutoParseVideo);
PublishTip(isSucceed);
}
// 解析范围事件
private DelegateCommand<object> parseScopesCommand;
private DelegateCommand<object>? _parseScopesCommand;
public DelegateCommand<object> ParseScopesCommand => parseScopesCommand ??
(parseScopesCommand =
new DelegateCommand<object>(ExecuteParseScopesCommand));
public DelegateCommand<object> ParseScopesCommand => _parseScopesCommand ??= new DelegateCommand<object>(ExecuteParseScopesCommand);
/// <summary>
/// 解析范围事件
@@ -219,30 +235,48 @@ public class ViewBasicViewModel : ViewModelBase
/// <param name="parameter"></param>
private void ExecuteParseScopesCommand(object parameter)
{
if (!(parameter is ParseScopeDisplay parseScope))
if (parameter is not ParseScopeDisplay parseScope)
{
return;
}
bool isSucceed = SettingsManager.GetInstance().SetParseScope(parseScope.ParseScope);
var isSucceed = SettingsManager.GetInstance().SetParseScope(parseScope.ParseScope);
PublishTip(isSucceed);
}
// 解析后是否自动下载解析视频
private DelegateCommand autoDownloadAllCommand;
private DelegateCommand? _autoDownloadAllCommand;
public DelegateCommand AutoDownloadAllCommand => autoDownloadAllCommand ??
(autoDownloadAllCommand =
new DelegateCommand(ExecuteAutoDownloadAllCommand));
public DelegateCommand AutoDownloadAllCommand => _autoDownloadAllCommand ??= new DelegateCommand(ExecuteAutoDownloadAllCommand);
/// <summary>
/// 解析后是否自动下载解析视频
/// </summary>
private void ExecuteAutoDownloadAllCommand()
{
AllowStatus isAutoDownloadAll = AutoDownloadAll ? AllowStatus.YES : AllowStatus.NO;
var isAutoDownloadAll = AutoDownloadAll ? AllowStatus.YES : AllowStatus.NO;
bool isSucceed = SettingsManager.GetInstance().IsAutoDownloadAll(isAutoDownloadAll);
var isSucceed = SettingsManager.GetInstance().IsAutoDownloadAll(isAutoDownloadAll);
PublishTip(isSucceed);
}
// 解析范围事件
private DelegateCommand<object>? _repeatDownloadStrategyCommand;
public DelegateCommand<object> RepeatDownloadStrategyCommand => _repeatDownloadStrategyCommand ??= new DelegateCommand<object>(ExecuteRepeatDownloadStrategyCommand);
/// <summary>
/// 解析范围事件
/// </summary>
/// <param name="parameter"></param>
private void ExecuteRepeatDownloadStrategyCommand(object parameter)
{
if (parameter is not RepeatDownloadStrategyDisplay repeatDownloadStrategy)
{
return;
}
var isSucceed = SettingsManager.GetInstance().SetRepeatDownloadStrategy(repeatDownloadStrategy.RepeatDownloadStrategy);
PublishTip(isSucceed);
}
@@ -276,7 +310,7 @@ public class ViewBasicViewModel : ViewModelBase
/// <param name="isSucceed"></param>
private void PublishTip(bool isSucceed)
{
if (isOnNavigatedTo)
if (_isOnNavigatedTo)
{
return;
}

View File

@@ -0,0 +1,98 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
x:Class="DownKyi.Views.Dialogs.ViewAlreadyDownloadedDialog"
xmlns:vmd="clr-namespace:DownKyi.ViewModels.Dialogs"
xmlns:prismExtension="clr-namespace:DownKyi.PrismExtension.Dialog"
x:DataType="vmd:ViewAlreadyDownloadedDialogViewModel">
<prismExtension:Dialog.Theme>
<ControlTheme TargetType="Window">
<Setter Property="CanResize" Value="False" />
<Setter Property="ShowInTaskbar" Value="False" />
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="SystemDecorations" Value="None" />
</ControlTheme>
</prismExtension:Dialog.Theme>
<Border BorderBrush="{DynamicResource BrushWindowBorder}" BorderThickness="1,1,0.6,0.6">
<Grid Background="{DynamicResource BrushBackground}" RowDefinitions="40,*">
<Grid
Grid.Row="0"
Background="{DynamicResource BrushBackgroundGreyTranslucent3}"
KeyboardNavigation.TabNavigation="None" ColumnDefinitions="*,50,*,50">
<StackPanel
Grid.Column="0"
Margin="10,0"
VerticalAlignment="Center"
Orientation="Horizontal">
<ContentControl
Margin="0,0,10,0"
IsVisible="{Binding Image,Converter={x:Static ObjectConverters.IsNotNull}}">
<Path
Width="{Binding Image.Width}"
Height="{Binding Image.Height}"
Data="{Binding Image.Data}"
Fill="{Binding Image.Fill}"
Stretch="Uniform" />
</ContentControl>
<TextBlock
VerticalAlignment="Center"
FontSize="14"
Foreground="{DynamicResource BrushCaptionForeground}"
Text="{Binding Title}" />
</StackPanel>
<Button
Grid.Column="3"
Command="{Binding CloseCommand}"
ToolTip.Tip="{DynamicResource Close}"
Theme="{StaticResource CloseBtnStyle}">
<Path
Width="{Binding CloseIcon.Width}"
Height="{Binding CloseIcon.Height}"
Data="{Binding CloseIcon.Data}"
Fill="{DynamicResource ColorSystemBtnTintDark}"
Stretch="UniformToFill" />
</Button>
</Grid>
<Grid Grid.Row="1" Margin="0,10,0,20" RowDefinitions="*,*">
<TextBlock
Grid.Row="0"
Margin="0,10,0,30"
Padding="15,0"
MaxWidth="600"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="14"
Foreground="{DynamicResource BrushTextDark}"
Text="{Binding Message}"
TextWrapping="Wrap" />
<Grid Row="1" ColumnDefinitions="*,*">
<Button
Grid.Column="0"
Width="75"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Command="{Binding YesCommand}"
Content="{DynamicResource Yes}"
FontSize="12"
Foreground="{DynamicResource BrushText}"
Theme="{StaticResource BtnStyle}" />
<Button
Grid.Column="1"
Width="75"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Command="{Binding CloseCommand}"
Content="{DynamicResource No}"
FontSize="12"
Foreground="{DynamicResource BrushText}"
Theme="{StaticResource BtnStyle}" />
</Grid>
</Grid>
</Grid>
</Border>
</UserControl>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace DownKyi.Views.Dialogs;
public partial class ViewAlreadyDownloadedDialog : UserControl
{
public ViewAlreadyDownloadedDialog()
{
InitializeComponent();
}
}

View File

@@ -107,7 +107,28 @@
Foreground="{DynamicResource BrushTextDark}"
IsChecked="{Binding AutoDownloadAll, Mode=TwoWay}"
Theme="{StaticResource CheckBoxStyle}" />
<StackPanel Margin="0,20,0,0" Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
FontSize="12"
Foreground="{DynamicResource BrushTextDark}"
Text="{DynamicResource RepeatDownloadStrategy}" />
<ComboBox
Name="NameRepeatDownloadStrategy"
Width="120"
VerticalContentAlignment="Center"
DisplayMemberBinding="{Binding Name}"
ItemsSource="{Binding RepeatDownloadStrategy}"
SelectedItem="{Binding SelectedRepeatDownloadStrategy}">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="SelectionChanged">
<ia:InvokeCommandAction Command="{Binding RepeatDownloadStrategyCommand}"
CommandParameter="{Binding ElementName=NameRepeatDownloadStrategy, Path=SelectedItem}" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</ComboBox>
</StackPanel>
<StackPanel Margin="10" />
</StackPanel>
</ScrollViewer>