整合表情下载导入逻辑

This commit is contained in:
gil zhang
2023-03-26 17:11:28 +08:00
parent 35ec2dfa90
commit 7ac03c5898
11 changed files with 285 additions and 42 deletions
@@ -132,6 +132,7 @@ public partial class App : Application
services.AddTransient<UploadEmojisDialogViewModel>();
services.AddTransient<UploadEmojisPage>();
services.AddTransient<MarketplacePage>();
services.AddTransient<MarketplaceViewModel>();
services.AddTransient<GestureClassificationPage>();
services.AddTransient<GestureClassificationViewModel>();
@@ -13,6 +13,7 @@
xmlns:local="using:Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:ElectronBot.BraincasePreview.Models"
xmlns:models1="using:Models"
Width="800"
Height="400"
MinWidth="800"
@@ -20,14 +21,14 @@
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Loaded">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.LoadedCommand}" />
<ic:EventTriggerBehavior EventName="Loading">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.LoadedCommand, Mode=OneWay}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Page.Resources>
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<DataTemplate x:Key="EmojisItemTemplate" x:DataType="models:EmoticonAction">
<DataTemplate x:Key="EmojisItemTemplate" x:DataType="models1:EmojisItemDto">
<Grid Margin="0,12,0,12" AutomationProperties.Name="{x:Bind Name}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="100" />
@@ -35,33 +36,30 @@
</Grid.ColumnDefinitions>
<Image
MaxHeight="100"
Source="{x:Bind Avatar}"
Source="{x:Bind PictureFileName}"
Stretch="Uniform" />
<StackPanel Grid.Column="1" Margin="12,0,0,0">
<TextBlock
Margin="0,4,0,6"
HorizontalAlignment="Left"
FontFamily="/Assets/Font/SmileySans-Oblique.ttf#得意黑"
FontSize="18"
LineHeight="20"
Style="{ThemeResource BaseTextBlockStyle}"
Text="{x:Bind Name}" />
<TextBlock
Margin="0,4,0,6"
FontFamily="/Assets/Font/SmileySans-Oblique.ttf#得意黑"
FontWeight="Normal"
MaxLines="2"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind Desc}"
TextTrimming="CharacterEllipsis" />
<StackPanel Orientation="Horizontal">
<!--<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,0,0"
HorizontalAlignment="Left"
FontFamily="/Assets/Font/SmileySans-Oblique.ttf#得意黑"
Style="{ThemeResource CaptionTextBlockStyle}"
Text="{x:Bind Name}" />
<TextBlock
@@ -85,18 +83,26 @@
Text=" Likes" />
</StackPanel>
</StackPanel>-->
</StackPanel>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid Width="800">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--<StackPanel Orientation="Horizontal">
<DropDownButton
<StackPanel Orientation="Horizontal">
<ProgressRing
x:Name="DownLoadRing"
Width="28"
Height="28"
Margin="12,4,12,4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsActive="{x:Bind ViewModel.IsActive, Mode=OneWay}" />
<!--<DropDownButton
Margin="8"
HorizontalAlignment="Left"
Content="种类">
@@ -117,30 +123,22 @@
<MenuFlyoutItem Text="复古" />
</MenuFlyout>
</DropDownButton.Flyout>
</DropDownButton>
</StackPanel>-->
</DropDownButton>-->
</StackPanel>
<ListView
x:Name="EmojisListView"
Grid.Row="1"
Width="auto"
Height="auto"
IsItemClickEnabled="True"
ItemTemplate="{StaticResource EmojisItemTemplate}"
ItemsSource="{x:Bind ViewModel.Actions, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.EmojisList, Mode=OneWay}"
SelectionMode="Single">
<ListView.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Name="ViewInfo" x:Uid="ViewEmojisInfo">
<MenuFlyoutItem x:Name="DownLoadEmojis" x:Uid="DownLoadEmojis">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Click">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.EmojisInfoCommand}" CommandParameter="{x:Bind EmojisListView.SelectedItem, Mode=TwoWay}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</MenuFlyoutItem>
<MenuFlyoutItem x:Name="AddPic" x:Uid="PlayEmojis">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Click">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.PlayEmojisCommand}" CommandParameter="{x:Bind EmojisListView.SelectedItem, Mode=TwoWay}" />
<ic:InvokeCommandAction Command="{x:Bind ViewModel.DownLoadEmojisCommand}" CommandParameter="{x:Bind EmojisListView.SelectedItem, Mode=TwoWay}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</MenuFlyoutItem>
@@ -27,14 +27,14 @@ namespace Controls;
/// </summary>
public sealed partial class MarketplacePage : Page
{
public EmojisEditViewModel ViewModel
public MarketplaceViewModel ViewModel
{
get;
}
public MarketplacePage()
{
ViewModel = App.GetService<EmojisEditViewModel>();
ViewModel = App.GetService<MarketplaceViewModel>();
this.InitializeComponent();
}
}
@@ -0,0 +1,23 @@
namespace Models
{
public class EmojisHttpData
{
public int PageIndex
{
get; set;
}
public int PageSize
{
get; set;
}
public int Count
{
get; set;
}
public List<EmojisItemDto> Items
{
get; set;
} = new();
}
}
@@ -11,6 +11,11 @@ public class EmojisItemDto
get; set;
} = string.Empty;
public string Desc
{
get; set;
} = string.Empty;
public decimal Price
{
get; set;
@@ -1,9 +1,13 @@
using System.Net.Http.Headers;
using System.Text.Json;
using Contracts.Services;
using ElectronBot.BraincasePreview;
using ElectronBot.BraincasePreview.Contracts.Services;
using ElectronBot.BraincasePreview.Helpers;
using ElectronBot.BraincasePreview.Models;
using Models;
using Windows.Media.Protection.PlayReady;
using Verdure.ElectronBot.Core.Helpers;
using Windows.Storage;
namespace Services;
public class EmojiseShopService : IEmojiseShopService
@@ -13,30 +17,165 @@ public class EmojiseShopService : IEmojiseShopService
private const string ProfileImageUploadUri = "http://api.douwp.club";
private readonly IEmojisFileService _emojisFileService;
public EmojiseShopService(IHttpClientFactory httpClientFactory, IEmojisFileService emojisFileService)
private readonly ILocalSettingsService _localSettingsService;
public EmojiseShopService(IHttpClientFactory httpClientFactory,
IEmojisFileService emojisFileService,
ILocalSettingsService localSettingsService)
{
_httpClientFactory = httpClientFactory;
_emojisFileService = emojisFileService;
_localSettingsService = localSettingsService;
}
public async Task<EmoticonAction> DownloadEmojisAsync(string id)
{
var httpClient = _httpClientFactory.CreateClient();
var response = await httpClient.GetAsync($"{ProfileImageUploadUri}/api/GridFS/Download/{id}");
using (var stream = await response.Content.ReadAsStreamAsync())
if (response.IsSuccessStatusCode)
{
using (var fileStream = new FileStream(@"C:\Users\gil\cursor-tutor\file.zip", FileMode.Create))
var contentDisposition = response?.Content?.Headers?.ContentDisposition.FileName;
var fileName = contentDisposition.Replace("\"", "");
using (var stream = await response.Content.ReadAsStreamAsync())
{
await stream.CopyToAsync(fileStream);
var folder = ApplicationData.Current.LocalFolder;
var storageFolder = await folder.CreateFolderAsync(Constants.EmojisTempFileFolder, CreationCollisionOption.OpenIfExists);
using (var fileStream = new FileStream($"{storageFolder.Path}/{fileName}", FileMode.Create))
{
await stream.CopyToAsync(fileStream);
}
ZipFileCreatorHelper.ExtractZipFile($"{storageFolder.Path}/{fileName}", storageFolder.Path);
var file = await storageFolder.GetFileAsync(fileName);
if (file != null)
{
await file.DeleteAsync();
}
var fileNames = await storageFolder.GetFilesAsync();
var list = (await _localSettingsService
.ReadSettingAsync<List<EmoticonAction>>(Constants.EmojisActionListKey)) ?? new List<EmoticonAction>();
var action = new EmoticonAction();
if (fileNames != null && fileNames.Count > 0)
{
foreach (var fileItem in fileNames)
{
if (fileItem.Name.Contains("manifest"))
{
var text = await FileIO.ReadTextAsync(fileItem);
var emojisFileInfo = JsonSerializer.Deserialize<EmojisFileManifest>(text) ?? throw new Exception("表情不存在");
action.Name = emojisFileInfo.Name;
action.NameId = emojisFileInfo.NameId;
action.Desc = emojisFileInfo.Description;
action.EmojisType = emojisFileInfo.EmojisType;
action.HasAction = emojisFileInfo.HasAction;
}
else
{
if (list.Where(e => e.NameId == fileItem.DisplayName).Any() || Constants.EMOJI_ACTION_LIST.Where(e => e.NameId == fileItem.DisplayName).Any())
{
ToastHelper.SendToast("EmojisNameIdAlreadyExists".GetLocalized(), TimeSpan.FromSeconds(3));
await storageFolder.DeleteAsync();
return null;
}
var actionFolder = await folder.CreateFolderAsync(Constants.EmojisFolder, CreationCollisionOption.OpenIfExists);
var storageFile = await actionFolder
.CreateFileAsync(fileItem.Name, CreationCollisionOption.OpenIfExists);
await FileIO.WriteBytesAsync(storageFile, await fileItem.ReadBytesAsync());
if (storageFile.FileType == ".mp4")
{
action.EmojisVideoPath = storageFile.Path;
}
else if (storageFile.FileType == ".png" ||
storageFile.FileType == ".jpg" ||
storageFile.FileType == ".jpeg")
{
action.Avatar = storageFile.Path;
}
else if (storageFile.FileType == ".json")
{
action.EmojisActionPath = storageFile.Path;
}
}
}
var actions = new List<EmoticonAction>()
{
action
};
list.AddRange(actions);
await _localSettingsService.SaveSettingAsync<List<EmoticonAction>>(Constants.EmojisActionListKey, list);
await storageFolder.DeleteAsync();
return new EmoticonAction();
}
}
}
return null;
}
public Task<EmojisItemDto> GetEmojisItemAsync(string id) => throw new NotImplementedException();
public Task<List<EmojisItemDto>> GetEmojisListAsync(EmojisItemQuery itemQuery) => throw new NotImplementedException();
public async Task<List<EmojisItemDto>> GetEmojisListAsync(EmojisItemQuery itemQuery)
{
var httpClient = _httpClientFactory.CreateClient();
var response = await httpClient.GetAsync($"{ProfileImageUploadUri}/api/v1/Catalog/items/by_page?typeId=-1&brandId=-1&pageSize={itemQuery.PageSize}&pageIndex={itemQuery.PageIndex}");
var list = new List<EmojisItemDto>();
if (response.IsSuccessStatusCode)
{
var resultData = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var emojisData = JsonSerializer.Deserialize<EmojisHttpData>(resultData, options);
if (emojisData is not null)
{
foreach (var emojisItem in emojisData.Items)
{
var item = new EmojisItemDto
{
Id = emojisItem.Id,
Name = emojisItem.Name,
Desc = emojisItem.Desc,
PictureFileId = emojisItem.PictureFileId,
PictureFileName = $"{ProfileImageUploadUri}/api/Pics/{emojisItem.PictureFileName}",
Price = emojisItem.Price,
VideoFileId = emojisItem.VideoFileId,
};
list.Add(item);
}
}
}
return list;
}
public async Task<bool> UploadEmojisAsync(EmoticonAction emoticon)
{
var pathName = await _emojisFileService.ExportEmojisFileToTempAsync(emoticon);
@@ -616,4 +616,13 @@
<data name="UploadEmojis.Text" xml:space="preserve">
<value>分享表情</value>
</data>
<data name="DownLoadEmojis.Text" xml:space="preserve">
<value>下载表情</value>
</data>
<data name="MarketplaceDialogClose" xml:space="preserve">
<value>关闭</value>
</data>
<data name="MarketplaceDialogTitle" xml:space="preserve">
<value>表情商城</value>
</data>
</root>
@@ -619,4 +619,13 @@
<data name="UploadEmojis.Text" xml:space="preserve">
<value>分享表情</value>
</data>
<data name="DownLoadEmojis.Text" xml:space="preserve">
<value>下载表情</value>
</data>
<data name="MarketplaceDialogClose" xml:space="preserve">
<value>关闭</value>
</data>
<data name="MarketplaceDialogTitle" xml:space="preserve">
<value>表情商城</value>
</data>
</root>
@@ -101,16 +101,15 @@ public partial class EmojisEditViewModel : ObservableRecipient
}
[RelayCommand]
public async void RandomContentEdit()
public async void Marketplace()
{
try
{
var randomContentEditDialog = new ContentDialog()
var marketplaceDialog = new ContentDialog()
{
Title = "AddRandomContentTitle".GetLocalized(),
PrimaryButtonText = "AddEmojisOkBtnContent".GetLocalized(),
CloseButtonText = "AddEmojisCancelBtnContent".GetLocalized(),
DefaultButton = ContentDialogButton.Primary,
Title = "MarketplaceDialogTitle".GetLocalized(),
CloseButtonText = "MarketplaceDialogClose".GetLocalized(),
DefaultButton = ContentDialogButton.Close,
XamlRoot = App.MainWindow.Content.XamlRoot,
Width = 800,
Height = 600,
@@ -118,7 +117,7 @@ public partial class EmojisEditViewModel : ObservableRecipient
Content = new MarketplacePage()
};
await randomContentEditDialog.ShowAsync();
await marketplaceDialog.ShowAsync();
}
catch (Exception)
{
@@ -0,0 +1,60 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Contracts.Services;
using ElectronBot.BraincasePreview.Helpers;
using Models;
namespace ElectronBot.BraincasePreview.ViewModels;
public partial class MarketplaceViewModel : ObservableRecipient
{
private ObservableCollection<EmojisItemDto> _emojisList = new();
private readonly IEmojiseShopService _emojiseShopService;
public MarketplaceViewModel(
IEmojiseShopService emojiseShopService)
{
_emojiseShopService = emojiseShopService;
}
[RelayCommand]
public async void Loaded()
{
var list = await _emojiseShopService.GetEmojisListAsync(new EmojisItemQuery { PageIndex = 0, PageSize = 100 });
EmojisList = new ObservableCollection<EmojisItemDto>(list);
}
[RelayCommand]
public async void DownLoadEmojis(object? obj)
{
if (obj is EmojisItemDto emojis)
{
IsActive = true;
var ret = await _emojiseShopService.DownloadEmojisAsync(emojis.VideoFileId);
if (ret is not null)
{
ToastHelper.SendToast("下载表情成功", TimeSpan.FromSeconds(3));
}
else
{
ToastHelper.SendToast("表情下载失败", TimeSpan.FromSeconds(3));
}
IsActive = false;
}
}
[ObservableProperty]
bool isActive = false;
public ObservableCollection<EmojisItemDto> EmojisList
{
get => _emojisList;
set => SetProperty(ref _emojisList, value);
}
}
@@ -64,7 +64,7 @@
x:Uid="MarketplaceBtn"
Margin="8"
HorizontalAlignment="Right"
Command="{x:Bind ViewModel.RandomContentEditCommand}"
Command="{x:Bind ViewModel.MarketplaceCommand}"
Foreground="{ThemeResource SystemAccentColor}">
<AppBarButton.Icon>
<FontIcon