diff --git a/src/SyncClipboard.Core/Clipboard/ClipboardFactoryBase.cs b/src/SyncClipboard.Core/Clipboard/ClipboardFactoryBase.cs index 296fda52..0c557ecd 100644 --- a/src/SyncClipboard.Core/Clipboard/ClipboardFactoryBase.cs +++ b/src/SyncClipboard.Core/Clipboard/ClipboardFactoryBase.cs @@ -101,6 +101,8 @@ private static Profile GetProfileBy(ClipboardProfileDTO profileDTO) } case ProfileType.Image: return new ImageProfile(profileDTO); + case ProfileType.Group: + return new GroupProfile(profileDTO); } return new UnknownProfile(); diff --git a/src/SyncClipboard.Core/Clipboard/Profile/GroupProfile.cs b/src/SyncClipboard.Core/Clipboard/Profile/GroupProfile.cs index 7bb21d52..2b5e1163 100644 --- a/src/SyncClipboard.Core/Clipboard/Profile/GroupProfile.cs +++ b/src/SyncClipboard.Core/Clipboard/Profile/GroupProfile.cs @@ -1,6 +1,8 @@ using Ionic.Zip; using Microsoft.Extensions.DependencyInjection; +using SyncClipboard.Abstract; using SyncClipboard.Core.Interfaces; +using SyncClipboard.Core.Models; using SyncClipboard.Core.Utilities; using System.Text; @@ -8,7 +10,21 @@ namespace SyncClipboard.Core.Clipboard; public class GroupProfile : FileProfile { - private readonly string[] _files; + private string[]? _files; + + public override ProfileType Type => ProfileType.Group; + public override string FileName + { + get + { + if (string.IsNullOrEmpty(base.FileName)) + { + FileName = $"{Path.GetRandomFileName()}.zip"; + } + return base.FileName; + } + set => base.FileName = value; + } protected override IClipboardSetter ClipboardSetter => ServiceProvider.GetRequiredService>(); @@ -18,6 +34,10 @@ public GroupProfile(string[] files) : base() _files = files; } + public GroupProfile(ClipboardProfileDTO profileDTO) : base(profileDTO) + { + } + public override async Task UploadProfile(IWebDav webdav, CancellationToken token) { await PrepareTransferFile(token); @@ -26,11 +46,13 @@ public override async Task UploadProfile(IWebDav webdav, CancellationToken token protected async Task PrepareTransferFile(CancellationToken token) { - var filePath = Path.Combine(LocalTemplateFolder, $"{Path.GetRandomFileName()}.zip"); + var filePath = Path.Combine(LocalTemplateFolder, FileName); using ZipFile zip = new ZipFile(); zip.AlternateEncoding = Encoding.UTF8; - zip.AlternateEncodingUsage = ZipOption.Always; + zip.AlternateEncodingUsage = ZipOption.AsNecessary; + + ArgumentNullException.ThrowIfNull(_files); _files.ForEach(path => { if (Directory.Exists(path)) @@ -46,4 +68,26 @@ protected async Task PrepareTransferFile(CancellationToken token) await Task.Run(() => zip.Save(filePath), token).WaitAsync(token); FullPath = filePath; } + + public override async Task BeforeSetLocal(CancellationToken token, IProgress? progress) + { + await base.BeforeSetLocal(token, progress); + + ArgumentNullException.ThrowIfNull(FullPath); + var extractPath = FullPath[..^4]; + if (!Directory.Exists(extractPath)) + Directory.CreateDirectory(extractPath); + + var fileList = new List(); + using ZipFile zip = ZipFile.Read(FullPath); + + await Task.Run(() => zip.ExtractAll(extractPath, ExtractExistingFileAction.DoNotOverwrite), token).WaitAsync(token); + _files = zip.EntryFileNames.Select(fileName => Path.Combine(extractPath, fileName.TrimEnd('\\', '/'))).ToArray(); + } + + protected override ClipboardMetaInfomation CreateMetaInformation() + { + ArgumentNullException.ThrowIfNull(_files); + return new ClipboardMetaInfomation() { Files = _files }; + } } diff --git a/src/SyncClipboard.WinUI3/AppServices.cs b/src/SyncClipboard.WinUI3/AppServices.cs index cfe07aca..663fb10d 100644 --- a/src/SyncClipboard.WinUI3/AppServices.cs +++ b/src/SyncClipboard.WinUI3/AppServices.cs @@ -37,6 +37,7 @@ public static ServiceCollection ConfigureServices() services.AddTransient, TextClipboardSetter>(); services.AddTransient, FileClipboardSetter>(); services.AddTransient, ImageClipboardSetter>(); + services.AddTransient, GroupClipboardSetter>(); return services; } diff --git a/src/SyncClipboard.WinUI3/ClipboardWinUI/GroupClipboardSetter.cs b/src/SyncClipboard.WinUI3/ClipboardWinUI/GroupClipboardSetter.cs new file mode 100644 index 00000000..2c4e044d --- /dev/null +++ b/src/SyncClipboard.WinUI3/ClipboardWinUI/GroupClipboardSetter.cs @@ -0,0 +1,35 @@ +using SyncClipboard.Core.Clipboard; +using SyncClipboard.Core.Models; +using System; +using System.IO; +using System.Linq; +using Windows.ApplicationModel.DataTransfer; +using Windows.Storage; + +namespace SyncClipboard.WinUI3.ClipboardWinUI; + +internal class GroupClipboardSetter : ClipboardSetterBase +{ + protected override DataPackage CreatePackage(ClipboardMetaInfomation metaInfomation) + { + if (metaInfomation.Files is null || metaInfomation.Files.Length == 0) + { + throw new ArgumentException("Not Contain File."); + } + + var items = metaInfomation.Files + .Where(file => Directory.Exists(file) || File.Exists(file)) + .Select(file => + { + if (Directory.Exists(file)) + { + return StorageFolder.GetFolderFromPathAsync(file).AsTask().Result; + } + return StorageFile.GetFileFromPathAsync(file).AsTask().Result; + }); + + var dataObject = new DataPackage(); + dataObject.SetStorageItems(items.ToArray()); + return dataObject; + } +}