diff --git a/ElectronBot.Braincase.sln b/ElectronBot.Braincase.sln index b7df522..1415a89 100644 --- a/ElectronBot.Braincase.sln +++ b/ElectronBot.Braincase.sln @@ -19,11 +19,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GestureClassification", "sr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Verdure.NotificationArea", "src\Verdure.NotificationArea\Verdure.NotificationArea.csproj", "{2DD1EED6-1778-41DF-9E0D-EC23C99416B4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectronBot.Copilot", "ElectronBot.Copilot\ElectronBot.Copilot.csproj", "{066FC203-FAD3-46D9-95A9-30FB6AE41583}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectronBot.Copilot", "src\ElectronBot.Copilot\ElectronBot.Copilot.csproj", "{066FC203-FAD3-46D9-95A9-30FB6AE41583}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWordKeyboard.DotNet", "HelloWordKeyboard.DotNet\HelloWordKeyboard.DotNet.csproj", "{D416CD59-E9AC-4726-9CDE-1D8A4F256A9B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWordKeyboard.DotNet", "src\HelloWordKeyboard.DotNet\HelloWordKeyboard.DotNet.csproj", "{D416CD59-E9AC-4726-9CDE-1D8A4F256A9B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWordKeyboard.ConsoleApp", "HelloWordKeyboard.ConsoleApp\HelloWordKeyboard.ConsoleApp.csproj", "{BF25733C-E01B-4611-B8AA-97A853F3E8FD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWordKeyboard.ConsoleApp", "src\HelloWordKeyboard.ConsoleApp\HelloWordKeyboard.ConsoleApp.csproj", "{BF25733C-E01B-4611-B8AA-97A853F3E8FD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/ElectronBot.Braincase/App.xaml.cs b/src/ElectronBot.Braincase/App.xaml.cs index 9fe9eb1..60113c2 100644 --- a/src/ElectronBot.Braincase/App.xaml.cs +++ b/src/ElectronBot.Braincase/App.xaml.cs @@ -223,7 +223,7 @@ public partial class App : Application services.AddSingleton(); services.AddTransient(); - services.AddSingleton(); + services.AddTransient(); services.AddSingleton(); @@ -232,6 +232,8 @@ public partial class App : Application services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); diff --git a/src/ElectronBot.Braincase/Assets/Images/Hw75CustomViewDefault.png b/src/ElectronBot.Braincase/Assets/Images/Hw75CustomViewDefault.png new file mode 100644 index 0000000..091c4ca Binary files /dev/null and b/src/ElectronBot.Braincase/Assets/Images/Hw75CustomViewDefault.png differ diff --git a/src/ElectronBot.Braincase/Constants.cs b/src/ElectronBot.Braincase/Constants.cs index 29dc29f..a260525 100644 --- a/src/ElectronBot.Braincase/Constants.cs +++ b/src/ElectronBot.Braincase/Constants.cs @@ -30,6 +30,8 @@ public class Constants public const string DefaultChatBotNameKey = "DefaultChatBotNameKey"; + public const string DefaultChatGPTNameKey = "DefaultChatGPTNameKey"; + public const string DefaultAudioNameKey = "DefaultAudioNameKey"; public const string CustomGestureAppConfigKey = "CustomGestureAppConfigKey"; diff --git a/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj b/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj index a275a2c..269021d 100644 --- a/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj +++ b/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj @@ -57,6 +57,7 @@ + @@ -254,7 +255,7 @@ - + @@ -268,9 +269,10 @@ - + + @@ -344,6 +346,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/ElectronBot.Braincase/Helpers/ElectronBotHelper.cs b/src/ElectronBot.Braincase/Helpers/ElectronBotHelper.cs index d9bda44..26d0669 100644 --- a/src/ElectronBot.Braincase/Helpers/ElectronBotHelper.cs +++ b/src/ElectronBot.Braincase/Helpers/ElectronBotHelper.cs @@ -578,6 +578,20 @@ public class ElectronBotHelper } } + public async Task CloseChatAsync() + { + try + { + var speechAndTTSService = App.GetService(); + await speechAndTTSService.ReleaseRecognizerAsync(); + //await speechAndTTSService.CancelAsync(); + } + catch (Exception) + { + + } + } + private async void MediaPlayer_MediaEnded(MediaPlayer sender, object args) { try diff --git a/src/ElectronBot.Braincase/Helpers/Hw75/Hw75Helper.cs b/src/ElectronBot.Braincase/Helpers/Hw75/Hw75Helper.cs index 4bc14ca..a6ee32d 100644 --- a/src/ElectronBot.Braincase/Helpers/Hw75/Hw75Helper.cs +++ b/src/ElectronBot.Braincase/Helpers/Hw75/Hw75Helper.cs @@ -21,6 +21,9 @@ public class Hw75Helper get; set; } + public string ViewName { get; set; } = "Hw75CustomView"; + + public event EventHandler? UpdateDataToDeviceHandler; private static Hw75Helper? _instance; @@ -68,13 +71,15 @@ public class Hw75Helper var pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); + var dpi = App.MainWindow.GetDpiForWindow(); + using var stream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, - 96, - 96, + dpi, + dpi, pixelBuffer.ToArray()); await encoder.FlushAsync(); @@ -87,7 +92,6 @@ public class Hw75Helper x.Resize(128, 296); //x.Grayscale(); }); - var byteArray = image.EnCodeImageToBytes(); diff --git a/src/ElectronBot.Braincase/Helpers/SettingsStorageExtensions.cs b/src/ElectronBot.Braincase/Helpers/SettingsStorageExtensions.cs index 4fdd1e7..b9e0593 100644 --- a/src/ElectronBot.Braincase/Helpers/SettingsStorageExtensions.cs +++ b/src/ElectronBot.Braincase/Helpers/SettingsStorageExtensions.cs @@ -1,5 +1,4 @@ using Verdure.ElectronBot.Core.Helpers; - using Windows.Storage; using Windows.Storage.Streams; @@ -19,7 +18,7 @@ public static class SettingsStorageExtensions public static async Task SaveAsync(this StorageFolder folder, string name, T content) { var file = await folder.CreateFileAsync(GetFileName(name), CreationCollisionOption.ReplaceExisting); - var fileContent = await Json.StringifyAsync(content); + var fileContent = await Verdure.ElectronBot.Core.Helpers.Json.StringifyAsync(content); await FileIO.WriteTextAsync(file, fileContent); } @@ -34,12 +33,12 @@ public static class SettingsStorageExtensions var file = await folder.GetFileAsync($"{name}.json"); var fileContent = await FileIO.ReadTextAsync(file); - return await Json.ToObjectAsync(fileContent); + return await Verdure.ElectronBot.Core.Helpers.Json.ToObjectAsync(fileContent); } public static async Task SaveAsync(this ApplicationDataContainer settings, string key, T value) { - settings.SaveString(key, await Json.StringifyAsync(value)); + settings.SaveString(key, await Verdure.ElectronBot.Core.Helpers.Json.StringifyAsync(value)); } public static void SaveString(this ApplicationDataContainer settings, string key, string value) @@ -53,7 +52,7 @@ public static class SettingsStorageExtensions if (settings.Values.TryGetValue(key, out obj)) { - return await Json.ToObjectAsync((string)obj); + return await Verdure.ElectronBot.Core.Helpers.Json.ToObjectAsync((string)obj); } return default; diff --git a/src/ElectronBot.Braincase/Hw75Views/Hw75CustomView.xaml b/src/ElectronBot.Braincase/Hw75Views/Hw75CustomView.xaml index cb79574..ef3d880 100644 --- a/src/ElectronBot.Braincase/Hw75Views/Hw75CustomView.xaml +++ b/src/ElectronBot.Braincase/Hw75Views/Hw75CustomView.xaml @@ -35,16 +35,16 @@ @@ -52,9 +52,9 @@ Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" + FontFamily="/Assets/Font/fusion-pixel-12px-monospaced-zh_hans.ttf#Fusion Pixel 12px Monospaced zh_hans" FontSize="36" Foreground="Black" - FontFamily="/Assets/Font/fusion-pixel-12px-monospaced-zh_hans.ttf#Fusion Pixel 12px Monospaced zh_hans" Text="{x:Bind ViewModel.TodayTime, Mode=OneWay}" /> @@ -65,9 +65,9 @@ Margin="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" + FontFamily="/Assets/Font/fusion-pixel-12px-monospaced-zh_hans.ttf#Fusion Pixel 12px Monospaced zh_hans" FontSize="{x:Bind ViewModel.ClockTitleConfig.Hw75CustomContentFontSize, Mode=OneWay}" Foreground="Black" - FontFamily="/Assets/Font/fusion-pixel-12px-monospaced-zh_hans.ttf#Fusion Pixel 12px Monospaced zh_hans" Text="{x:Bind ViewModel.ClockTitleConfig.Hw75CustomContent, Mode=OneWay}" TextAlignment="Center" TextWrapping="Wrap" diff --git a/src/ElectronBot.Braincase/Hw75Views/Hw75YellowCalendarView.xaml b/src/ElectronBot.Braincase/Hw75Views/Hw75YellowCalendarView.xaml index 50ab2a2..c931bb6 100644 --- a/src/ElectronBot.Braincase/Hw75Views/Hw75YellowCalendarView.xaml +++ b/src/ElectronBot.Braincase/Hw75Views/Hw75YellowCalendarView.xaml @@ -42,6 +42,17 @@ TextAlignment="Center" TextWrapping="Wrap" /> + + + + + - --> + + + /// 手势识别回复文本 /// @@ -59,7 +64,7 @@ public class CustomClockTitleConfig { get; set; - } = string.Empty; + } = "ms-appx:///Assets/Images/Hw75CustomViewDefault.png"; public float GaussianBlurValue { @@ -90,4 +95,14 @@ public class CustomClockTitleConfig get; set; } + + public string Hw75ViewName + { + get; set; + } = "Hw75CustomView"; + + public string ChatGPTVersion + { + get; set; + } = "gpt-3.5-turbo"; } diff --git a/src/ElectronBot.Braincase/Package.appxmanifest b/src/ElectronBot.Braincase/Package.appxmanifest index 55fcd69..199e05d 100644 --- a/src/ElectronBot.Braincase/Package.appxmanifest +++ b/src/ElectronBot.Braincase/Package.appxmanifest @@ -13,7 +13,7 @@ + Version="1.7.3.0" /> 电子脑壳 diff --git a/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotClient.cs b/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotClient.cs index 9d1827c..30e45e6 100644 --- a/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotClient.cs +++ b/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotClient.cs @@ -3,7 +3,10 @@ using ChatGPTSharp; using Contracts.Services; using ElectronBot.Braincase; using ElectronBot.Braincase.Contracts.Services; +using ElectronBot.Braincase.Helpers; using ElectronBot.Braincase.Models; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; namespace Services; public class ChatGPTChatbotClient : IChatbotClient @@ -12,6 +15,8 @@ public class ChatGPTChatbotClient : IChatbotClient private readonly ILocalSettingsService _localSettingsService; + private Kernel? _kernel; + private ChatGPTClient? _chatGptClient; public ChatGPTChatbotClient(ILocalSettingsService localSettingsService) { @@ -27,10 +32,50 @@ public class ChatGPTChatbotClient : IChatbotClient throw new Exception("配置为空"); } - _chatGptClient ??= new ChatGPTClient(result.ChatGPTSessionKey, "gpt-3.5-turbo"); - var msg = await _chatGptClient.SendMessage(message); + _kernel ??= Kernel.CreateBuilder() + .AddOpenAIChatCompletion(result.ChatGPTVersion, result.ChatGPTSessionKey) + .Build(); - return msg.Response ?? ""; + var chat = _kernel.GetRequiredService() + ?? throw new KernelException("not init chat"); + + var resMessage = string.Empty; + + try + { + await Task.Run(async () => + { + var history = new ChatHistory(); + history.AddMessage(AuthorRole.User, message); + var response = chat.GetStreamingChatMessageContentsAsync(history); + await foreach (var item in response) + { + resMessage += item; + //streamHandler?.Invoke(resMessage); + } + }); + + resMessage = resMessage.Trim(); + + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(resMessage, TimeSpan.FromSeconds(10)); + }); + + if (string.IsNullOrEmpty(resMessage)) + { + throw new KernelException("chat is empty"); + } + } + catch (Exception ex) + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(ex.Message, TimeSpan.FromSeconds(10)); + }); + } + + return resMessage; } } diff --git a/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotCustomClient.cs b/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotCustomClient.cs new file mode 100644 index 0000000..a4c7e16 --- /dev/null +++ b/src/ElectronBot.Braincase/Services/Chatbot/ChatGPTChatbotCustomClient.cs @@ -0,0 +1,91 @@ +using System.Net.Http.Headers; +using Contracts.Services; +using ElectronBot.Braincase; +using ElectronBot.Braincase.Contracts.Services; +using ElectronBot.Braincase.Helpers; +using ElectronBot.Braincase.Models; +using ElectronBot.Copilot; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; + +namespace Services; +public class ChatGPTChatbotCustomClient : IChatbotClient +{ + public string Name => "ChatGPT-Custom"; + + private readonly ILocalSettingsService _localSettingsService; + + private Kernel? _kernel; + public ChatGPTChatbotCustomClient(ILocalSettingsService localSettingsService) + { + _localSettingsService = localSettingsService; + } + public async Task AskQuestionResultAsync(string message) + { + var result = await _localSettingsService + .ReadSettingAsync(Constants.CustomClockTitleConfigKey); + + if (result == null) + { + throw new Exception("配置为空"); + } + + + var hasCustomEndpoint = !string.IsNullOrEmpty(result.OpenAIBaseUrl) && Uri.TryCreate(result.OpenAIBaseUrl, UriKind.Absolute, out var _); + var customHttpClient = hasCustomEndpoint + ? GetProxyClient(result.OpenAIBaseUrl) + : default; + + _kernel ??= Kernel.CreateBuilder() + .AddOpenAIChatCompletion(result.ChatGPTVersion, result.ChatGPTSessionKey, httpClient: customHttpClient) + .Build(); + + var chat = _kernel.GetRequiredService() + ?? throw new KernelException("not init chat"); + + var resMessage = string.Empty; + + try + { + await Task.Run(async () => + { + var history = new ChatHistory(); + history.AddMessage(AuthorRole.User, message); + var response = chat.GetStreamingChatMessageContentsAsync(history); + await foreach (var item in response) + { + resMessage += item; + //streamHandler?.Invoke(resMessage); + } + }); + + resMessage = resMessage.Trim(); + + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(resMessage, TimeSpan.FromSeconds(10)); + }); + + if (string.IsNullOrEmpty(resMessage)) + { + throw new KernelException("chat is empty"); + } + } + catch (Exception ex) + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(ex.Message, TimeSpan.FromSeconds(10)); + }); + } + + return resMessage; + } + + private static HttpClient GetProxyClient(string baseUrl) + { + var httpClient = new HttpClient(new ProxyOpenAIHttpClientHandler(baseUrl)); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream")); + return httpClient; + } +} diff --git a/src/ElectronBot.Braincase/Services/Chatbot/TuringChatbotClient.cs b/src/ElectronBot.Braincase/Services/Chatbot/TuringChatbotClient.cs index 66944c2..4d8de9c 100644 --- a/src/ElectronBot.Braincase/Services/Chatbot/TuringChatbotClient.cs +++ b/src/ElectronBot.Braincase/Services/Chatbot/TuringChatbotClient.cs @@ -3,6 +3,7 @@ using System.Text.Json; using Contracts.Services; using ElectronBot.Braincase; using ElectronBot.Braincase.Contracts.Services; +using ElectronBot.Braincase.Helpers; using ElectronBot.Braincase.Models; namespace Services; @@ -70,7 +71,11 @@ public class TuringChatbotClient : IChatbotClient if (retObj.Results != null && retObj.Results.Count > 0) { var retText = retObj.Results[0].Values.Text; - + + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(retText, TimeSpan.FromSeconds(5)); + }); return retText; } } diff --git a/src/ElectronBot.Braincase/Services/ComboxDataService.cs b/src/ElectronBot.Braincase/Services/ComboxDataService.cs index b5c5c05..e7e6e3d 100644 --- a/src/ElectronBot.Braincase/Services/ComboxDataService.cs +++ b/src/ElectronBot.Braincase/Services/ComboxDataService.cs @@ -36,7 +36,20 @@ public class ComboxDataService { new ComboxItemModel { DataKey = "Turing", DataValue = "TuringTitle".GetLocalized() }, - new ComboxItemModel { DataKey = "ChatGPT", DataValue ="ChatGPTTitle".GetLocalized() } + new ComboxItemModel { DataKey = "ChatGPT", DataValue ="ChatGPTTitle".GetLocalized() }, + new ComboxItemModel { DataKey = "ChatGPT-Custom", DataValue ="ChatGPTCustomTitle".GetLocalized() } + }; + } + + public ObservableCollection GetChatGPTVersionComboxList() + { + return new ObservableCollection + { + + new ComboxItemModel { DataKey = "gpt-3.5-turbo-0301", DataValue = "gpt-3.5-turbo-0301" }, + new ComboxItemModel { DataKey = "gpt-4", DataValue ="gpt-4" }, + new ComboxItemModel { DataKey = "gpt-4-0314", DataValue ="gpt-4-0314" }, + new ComboxItemModel { DataKey = "gpt-4-0613", DataValue ="gpt-4-0613" } }; } } diff --git a/src/ElectronBot.Braincase/Services/Hw75Services/GetWeathers/GpsGetWeather.cs b/src/ElectronBot.Braincase/Services/Hw75Services/GetWeathers/GpsGetWeather.cs index 49a4bbd..f91c5cb 100644 --- a/src/ElectronBot.Braincase/Services/Hw75Services/GetWeathers/GpsGetWeather.cs +++ b/src/ElectronBot.Braincase/Services/Hw75Services/GetWeathers/GpsGetWeather.cs @@ -1,4 +1,5 @@ -using ElectronBot.Braincase.Models; +using ElectronBot.Braincase.Helpers; +using ElectronBot.Braincase.Models; using ElectronBot.Braincase.Models.Gps; using ElectronBot.Braincase.Models.Name24; using Microsoft.Extensions.Options; @@ -20,36 +21,54 @@ namespace ElectronBot.Braincase.Services /// 纬度 /// 经度 /// 结果封装的类的实例 - public async static Task GetWeatherIdea() + public static async Task GetWeatherIdea() { - var accessStatus = await Geolocator.RequestAccessAsync(); - Geolocator geolocator = new Geolocator(); - if (accessStatus != GeolocationAccessStatus.Allowed) throw new Exception(); - Geoposition pos = await geolocator.GetGeopositionAsync(); - double lat = pos.Coordinate.Point.Position.Latitude; - double lon = pos.Coordinate.Point.Position.Longitude; - string querys = "from=5&lat=" + lat.ToString() + "&lng=" + lon.ToString() + "&need3HourForcast=0&needAlarm=0&needHourData=0&needIndex=1&needMoreDay=1"; - string url = host + path; - string urlLast = url + "?" + querys; - Uri uri = new Uri(urlLast); - string resultJson = string.Empty; - - var appCode = App.GetService>().Value.Hw75AppCode; - - using (var httpClient = new HttpClient()) - { - httpClient.DefaultRequestHeaders.Add("Authorization", "APPCODE " + appCode); - httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); - resultJson = await httpClient.GetStringAsync(uri); - } - var data = Newtonsoft.Json.JsonConvert.DeserializeObject(resultJson); var weatherDisplayed = new Weather_Displayed(); - var hour24 = await NameGet24Weather.NameGet24WeatherIdea(System.Web.HttpUtility.UrlEncode(data.showapi_res_body.cityInfo.c3, System.Text.Encoding.UTF8)); - //var hour24 = await NameGet24Weather.NameGet24WeatherIdea(TransCoding.UrlCode(data.showapi_res_body.cityInfo.c3, "utf-8")); - OrganizeWeatherData(weatherDisplayed, data, hour24); - return weatherDisplayed; + try + { + var accessStatus = await Geolocator.RequestAccessAsync(); + var geolocator = new Geolocator(); + if (accessStatus != GeolocationAccessStatus.Allowed) + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast($"请检查系统设置是否开启系统定位权限。", TimeSpan.FromSeconds(5)); + }); + return weatherDisplayed; + }; + var pos = await geolocator.GetGeopositionAsync(); + var lat = pos.Coordinate.Point.Position.Latitude; + var lon = pos.Coordinate.Point.Position.Longitude; + var querys = "from=5&lat=" + lat.ToString() + "&lng=" + lon.ToString() + "&need3HourForcast=0&needAlarm=0&needHourData=0&needIndex=1&needMoreDay=1"; + var url = host + path; + var urlLast = url + "?" + querys; + var uri = new Uri(urlLast); + var resultJson = string.Empty; + var appCode = App.GetService>().Value.Hw75AppCode; + + using (var httpClient = new HttpClient()) + { + httpClient.DefaultRequestHeaders.Add("Authorization", "APPCODE " + appCode); + httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + resultJson = await httpClient.GetStringAsync(uri); + } + var data = Newtonsoft.Json.JsonConvert.DeserializeObject(resultJson); + + var hour24 = await NameGet24Weather.NameGet24WeatherIdea(System.Web.HttpUtility.UrlEncode(data.showapi_res_body.cityInfo.c3, System.Text.Encoding.UTF8)); + //var hour24 = await NameGet24Weather.NameGet24WeatherIdea(TransCoding.UrlCode(data.showapi_res_body.cityInfo.c3, "utf-8")); + OrganizeWeatherData(weatherDisplayed, data, hour24); + } + catch(Exception ex) + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast($"天气获取错误。{ex.Message}", TimeSpan.FromSeconds(5)); + }); + } + + return weatherDisplayed; } #region 这是数据处理部分 diff --git a/src/ElectronBot.Braincase/Services/Hw75Services/YellowCalendar/GetYellowCalendarService.cs b/src/ElectronBot.Braincase/Services/Hw75Services/YellowCalendar/GetYellowCalendarService.cs index d77ffba..cad487f 100644 --- a/src/ElectronBot.Braincase/Services/Hw75Services/YellowCalendar/GetYellowCalendarService.cs +++ b/src/ElectronBot.Braincase/Services/Hw75Services/YellowCalendar/GetYellowCalendarService.cs @@ -1,5 +1,6 @@ using ElectronBot.Braincase; using ElectronBot.Braincase.Contracts.Services; +using ElectronBot.Braincase.Helpers; using ElectronBot.Braincase.Models; using Models.Hw75.YellowCalendar; @@ -21,7 +22,7 @@ public class GetYellowCalendarService var yellowCalendarStr = await _localSettingsService.ReadSettingAsync($"{Constants.YellowCalendarKey}-{DateTime.Now.ToShortDateString()}"); - if (noCache == true || string.IsNullOrWhiteSpace(yellowCalendarStr)) + if (noCache == true || string.IsNullOrWhiteSpace(yellowCalendarStr) || (!string.IsNullOrWhiteSpace(yellowCalendarStr) && !yellowCalendarStr.Contains("successed"))) { var httpClient = App.GetService(); @@ -36,9 +37,17 @@ public class GetYellowCalendarService { return data.Result; } + else + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast($"请检查聚合数据key的配置", TimeSpan.FromSeconds(5)); + }); + } } - catch + catch(Exception ex) { + } return new YellowCalendarResult(); diff --git a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicCustomViewProvider.cs b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicCustomViewProvider.cs index 05c0966..4bb7a37 100644 --- a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicCustomViewProvider.cs +++ b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicCustomViewProvider.cs @@ -11,6 +11,6 @@ public class Hw75DynamicCustomViewProvider : IHw75DynamicViewProvider public UIElement CreateHw75DynamickView(string viewName) { - return new Hw75CustomView(); + return App.GetService(); } } diff --git a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicTodoViewProvider.cs b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicTodoViewProvider.cs index 9b4e6b4..feb9eaf 100644 --- a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicTodoViewProvider.cs +++ b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicTodoViewProvider.cs @@ -11,6 +11,6 @@ public class Hw75DynamicTodoViewProvider : IHw75DynamicViewProvider public UIElement CreateHw75DynamickView(string viewName) { - return new TodoView(); + return App.GetService(); } } diff --git a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicWeatherViewProvider.cs b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicWeatherViewProvider.cs index 92e9c75..5c64201 100644 --- a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicWeatherViewProvider.cs +++ b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicWeatherViewProvider.cs @@ -11,6 +11,6 @@ public class Hw75DynamicWeatherViewProvider : IHw75DynamicViewProvider public UIElement CreateHw75DynamickView(string viewName) { - return new Hw75WeatherView(); + return App.GetService(); } } diff --git a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicYellowCalendarViewProvider.cs b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicYellowCalendarViewProvider.cs index c82c5a6..527cf4e 100644 --- a/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicYellowCalendarViewProvider.cs +++ b/src/ElectronBot.Braincase/Services/Hw75View/Hw75DynamicYellowCalendarViewProvider.cs @@ -10,6 +10,6 @@ public class Hw75DynamicYellowCalendarViewProvider : IHw75DynamicViewProvider public UIElement CreateHw75DynamickView(string viewName) { - return new Hw75YellowCalendarView(); + return App.GetService(); } } diff --git a/src/ElectronBot.Braincase/Services/LocalSettingsService.cs b/src/ElectronBot.Braincase/Services/LocalSettingsService.cs index f471316..fbb4c91 100644 --- a/src/ElectronBot.Braincase/Services/LocalSettingsService.cs +++ b/src/ElectronBot.Braincase/Services/LocalSettingsService.cs @@ -54,7 +54,7 @@ public class LocalSettingsService : ILocalSettingsService { if (ApplicationData.Current.LocalSettings.Values.TryGetValue(key, out var obj)) { - return await Json.ToObjectAsync((string)obj); + return await Verdure.ElectronBot.Core.Helpers.Json.ToObjectAsync((string)obj); } } else @@ -63,7 +63,7 @@ public class LocalSettingsService : ILocalSettingsService if (_settings != null && _settings.TryGetValue(key, out var obj)) { - return await Json.ToObjectAsync((string)obj); + return await Verdure.ElectronBot.Core.Helpers.Json.ToObjectAsync((string)obj); } } @@ -74,13 +74,13 @@ public class LocalSettingsService : ILocalSettingsService { if (RuntimeHelper.IsMSIX) { - ApplicationData.Current.LocalSettings.Values[key] = await Json.StringifyAsync(value); + ApplicationData.Current.LocalSettings.Values[key] = await Verdure.ElectronBot.Core.Helpers.Json.StringifyAsync(value); } else { await InitializeAsync(); - _settings[key] = await Json.StringifyAsync(value); + _settings[key] = await Verdure.ElectronBot.Core.Helpers.Json.StringifyAsync(value); await Task.Run(() => _fileService.Save(_applicationDataFolder, _localsettingsFile, _settings)); } diff --git a/src/ElectronBot.Braincase/Strings/en-us/Resources.resw b/src/ElectronBot.Braincase/Strings/en-us/Resources.resw index c140f6a..361d1fc 100644 --- a/src/ElectronBot.Braincase/Strings/en-us/Resources.resw +++ b/src/ElectronBot.Braincase/Strings/en-us/Resources.resw @@ -855,4 +855,10 @@ 点击关注我B站获取最新消息 + + ChatGPTCustom + + + ChatGPT-Model: + \ No newline at end of file diff --git a/src/ElectronBot.Braincase/Strings/ko-kr/Resources.resw b/src/ElectronBot.Braincase/Strings/ko-kr/Resources.resw index f3eba5c..055ddd7 100644 --- a/src/ElectronBot.Braincase/Strings/ko-kr/Resources.resw +++ b/src/ElectronBot.Braincase/Strings/ko-kr/Resources.resw @@ -831,4 +831,10 @@ 点击关注我B站获取最新消息 + + ChatGPTCustom + + + ChatGPT-Model: + \ No newline at end of file diff --git a/src/ElectronBot.Braincase/Strings/zh-cn/Resources.resw b/src/ElectronBot.Braincase/Strings/zh-cn/Resources.resw index 6d9642c..fa8c424 100644 --- a/src/ElectronBot.Braincase/Strings/zh-cn/Resources.resw +++ b/src/ElectronBot.Braincase/Strings/zh-cn/Resources.resw @@ -517,7 +517,13 @@ 删除 - 1.7.0 版本更新说明 + 1.7.2 版本更新说明 +1. 添加语音主动触发按钮,以及添加openai代理域名配置。 + +1.7.1 版本更新说明 +1. 优化提示信息和界面显示。 + +1.7.0 版本更新说明 1. 升级.Net版本为8.0. 2. 添加瀚文键盘模式。 @@ -861,4 +867,10 @@ 点击关注我B站获取最新消息 + + ChatGPTCustom + + + ChatGPT模型Id: + \ No newline at end of file diff --git a/src/ElectronBot.Braincase/Styles/Toast.xaml b/src/ElectronBot.Braincase/Styles/Toast.xaml index 97a2453..2198ff7 100644 --- a/src/ElectronBot.Braincase/Styles/Toast.xaml +++ b/src/ElectronBot.Braincase/Styles/Toast.xaml @@ -20,7 +20,8 @@ + Text="{TemplateBinding Content}" + TextWrapping="Wrap" /> diff --git a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75CustomViewModel.cs b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75CustomViewModel.cs index 34af075..89af939 100644 --- a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75CustomViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75CustomViewModel.cs @@ -22,7 +22,7 @@ public partial class Hw75CustomViewModel : ObservableRecipient private readonly ClockDiagnosticService _diagnosticService; - private bool isProcessing = false; + private const string ViewName = "Hw75CustomView"; [ObservableProperty] private Visibility _customContentVisibility = Visibility.Visible; @@ -30,6 +30,17 @@ public partial class Hw75CustomViewModel : ObservableRecipient + public Hw75CustomViewModel(ClockDiagnosticService clockDiagnosticService, + ILocalSettingsService localSettingsService) + { + _diagnosticService = clockDiagnosticService; + _localSettingsService = localSettingsService; + + _dispatcherTimer.Interval = new TimeSpan(0, 0, 60); + + _dispatcherTimer.Tick += DispatcherTimer_Tick; + } + public string TodayWeek { get => _todayWeek; @@ -105,22 +116,15 @@ public partial class Hw75CustomViewModel : ObservableRecipient private void DispatcherTimer_Tick(object? sender, object e) { - TodayTime = DateTimeOffset.Now.ToString("t"); - TodayWeek = DateTimeOffset.Now.ToString("ddd"); - Day = DateTimeOffset.Now.Day.ToString(); + if (Hw75Helper.Instance.ViewName == ViewName) + { + TodayTime = DateTimeOffset.Now.ToString("t"); + TodayWeek = DateTimeOffset.Now.ToString("ddd"); + Day = DateTimeOffset.Now.Day.ToString(); - Hw75Helper.Instance.InvokeHandler(); - } + Hw75Helper.Instance.InvokeHandler(); + } - public Hw75CustomViewModel(ClockDiagnosticService clockDiagnosticService, ILocalSettingsService localSettingsService - ) - { - _diagnosticService = clockDiagnosticService; - _localSettingsService = localSettingsService; - - _dispatcherTimer.Interval = new TimeSpan(0, 0, 60); - - _dispatcherTimer.Tick += DispatcherTimer_Tick; } } diff --git a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75DynamicViewModel.cs b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75DynamicViewModel.cs index f8c5559..d9c36f6 100644 --- a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75DynamicViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75DynamicViewModel.cs @@ -18,6 +18,8 @@ public partial class Hw75DynamicViewModel : ObservableRecipient private readonly DispatcherTimer _dispatcherTimer = new(); + private const string ViewName = "TodoView"; + [ObservableProperty] private ObservableCollection? _todoTaskLists; public Hw75DynamicViewModel(IMicrosoftGraphService microsoftGraphService, IdentityService identityService) diff --git a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75WeatherViewModel.cs b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75WeatherViewModel.cs index 32eac5c..fc4837b 100644 --- a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75WeatherViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75WeatherViewModel.cs @@ -32,6 +32,8 @@ public partial class Hw75WeatherViewModel : ObservableRecipient [ObservableProperty] private CustomClockTitleConfig? _clockTitleConfig; + private const string ViewName = "Hw75WeatherView"; + public Hw75WeatherViewModel(ILocalSettingsService localSettingsService) { _localSettingsService = localSettingsService; @@ -43,14 +45,16 @@ public partial class Hw75WeatherViewModel : ObservableRecipient private async void DispatcherTimer_Tick(object? sender, object e) { - var ret2 = await _localSettingsService.ReadSettingAsync(Constants.CustomClockTitleConfigKey); + if (Hw75Helper.Instance.ViewName == ViewName) + { + var ret2 = await _localSettingsService.ReadSettingAsync(Constants.CustomClockTitleConfigKey); - ClockTitleConfig = ret2 ?? new CustomClockTitleConfig(); + ClockTitleConfig = ret2 ?? new CustomClockTitleConfig(); - GpsResult = await GpsGetWeather.GetWeatherIdea(); - - Hw75Helper.Instance.InvokeHandler(); + GpsResult = await GpsGetWeather.GetWeatherIdea(); + Hw75Helper.Instance.InvokeHandler(); + } } [RelayCommand] diff --git a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75YellowCalendarViewModel.cs b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75YellowCalendarViewModel.cs index 9ac242e..bd76adc 100644 --- a/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75YellowCalendarViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/Hw75/Hw75YellowCalendarViewModel.cs @@ -17,6 +17,8 @@ public partial class Hw75YellowCalendarViewModel : ObservableRecipient private readonly DispatcherTimer _dispatcherTimer = new (); + private const string ViewName = "Hw75YellowCalendarView"; + public Hw75YellowCalendarViewModel() { _dispatcherTimer.Interval = new TimeSpan(1, 0, 0); @@ -26,9 +28,12 @@ public partial class Hw75YellowCalendarViewModel : ObservableRecipient private async void DispatcherTimer_Tick(object? sender, object e) { - YellowCalendarResult = await GetYellowCalendarService.GetYellowCalendarAsync(true); + if (Hw75Helper.Instance.ViewName == ViewName) + { + YellowCalendarResult = await GetYellowCalendarService.GetYellowCalendarAsync(true); - Hw75Helper.Instance.InvokeHandler(); + Hw75Helper.Instance.InvokeHandler(); + } } [RelayCommand] diff --git a/src/ElectronBot.Braincase/ViewModels/Hw75ViewModel.cs b/src/ElectronBot.Braincase/ViewModels/Hw75ViewModel.cs index 61f3b77..7edf379 100644 --- a/src/ElectronBot.Braincase/ViewModels/Hw75ViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/Hw75ViewModel.cs @@ -56,38 +56,39 @@ public partial class Hw75ViewModel : ObservableRecipient, INavigationAware [ObservableProperty] public ObservableCollection clockComboxModels; + [ObservableProperty] + private CustomClockTitleConfig _clockTitleConfig; + private readonly IHw75DynamicViewProviderFactory _viewProviderFactory; - private readonly DispatcherTimer _dispatcherTimer = new(); + private readonly ILocalSettingsService _localSettingsService; - public Hw75ViewModel(ComboxDataService comboxDataService, IHw75DynamicViewProviderFactory viewProviderFactory) + public Hw75ViewModel(ComboxDataService comboxDataService, IHw75DynamicViewProviderFactory viewProviderFactory, ILocalSettingsService localSettingsService) { ClockComboxModels = comboxDataService.GetHw75ViewComboxList(); _viewProviderFactory = viewProviderFactory; - _dispatcherTimer.Interval = new TimeSpan(0, 0, 50); - - _dispatcherTimer.Tick += DispatcherTimer_Tick; + _localSettingsService = localSettingsService; } - private async void DispatcherTimer_Tick(object? sender, object e) - { - //await Hw75Helper.Instance.SyncDataToDeviceAsync(Element); - } - - /// /// 表盘切换方法 /// [RelayCommand] - private void ClockChanged() + private async Task ClockChanged() { var clockName = ClockComBoxSelect?.DataKey; if (!string.IsNullOrWhiteSpace(clockName)) { + Hw75Helper.Instance.ViewName = clockName; + var viewProvider = _viewProviderFactory.CreateHw75DynamicViewProvider(clockName); Element = viewProvider.CreateHw75DynamickView(clockName); + + ClockTitleConfig.Hw75ViewName = clockName; + + await _localSettingsService.SaveSettingAsync(Constants.CustomClockTitleConfigKey, ClockTitleConfig); } } @@ -97,11 +98,16 @@ public partial class Hw75ViewModel : ObservableRecipient, INavigationAware } - public void OnNavigatedTo(object parameter) + public async void OnNavigatedTo(object parameter) { - var viewProvider = _viewProviderFactory.CreateHw75DynamicViewProvider("Hw75CustomView"); - Element = viewProvider.CreateHw75DynamickView("Hw75CustomView"); + var ret2 = await _localSettingsService.ReadSettingAsync(Constants.CustomClockTitleConfigKey); + + ClockTitleConfig = ret2 ?? new CustomClockTitleConfig(); + + var viewProvider = _viewProviderFactory.CreateHw75DynamicViewProvider(ClockTitleConfig.Hw75ViewName); + + Element = viewProvider.CreateHw75DynamickView(ClockTitleConfig.Hw75ViewName); Hw75Helper.Instance.UpdateDataToDeviceHandler += Instance_UpdateDataToDeviceHandler; @@ -133,8 +139,6 @@ public partial class Hw75ViewModel : ObservableRecipient, INavigationAware Hw75Helper.Instance.IsConnected = false; } - - _dispatcherTimer.Start(); } private async void Instance_UpdateDataToDeviceHandler(object? sender, EventArgs e) @@ -147,7 +151,7 @@ public partial class Hw75ViewModel : ObservableRecipient, INavigationAware { Hw75Helper.Instance.Hw75DynamicDevice?.Close(); Hw75Helper.Instance.IsConnected = false; + Hw75Helper.Instance.ViewName = "Hw75CustomView"; Hw75Helper.Instance.UpdateDataToDeviceHandler -= Instance_UpdateDataToDeviceHandler; - _dispatcherTimer.Stop(); } } diff --git a/src/ElectronBot.Braincase/ViewModels/MainViewModel.Properties.cs b/src/ElectronBot.Braincase/ViewModels/MainViewModel.Properties.cs index 9546fac..07da3bf 100644 --- a/src/ElectronBot.Braincase/ViewModels/MainViewModel.Properties.cs +++ b/src/ElectronBot.Braincase/ViewModels/MainViewModel.Properties.cs @@ -47,6 +47,8 @@ public partial class MainViewModel : ObservableRecipient string resultLabel; + [ObservableProperty] + string _sendText; /// /// 头部舵机 diff --git a/src/ElectronBot.Braincase/ViewModels/MainViewModel.cs b/src/ElectronBot.Braincase/ViewModels/MainViewModel.cs index 40f094f..c277091 100644 --- a/src/ElectronBot.Braincase/ViewModels/MainViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/MainViewModel.cs @@ -7,6 +7,8 @@ using System.Text.Json; using System.Windows.Input; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using Contracts.Services; +using Controls.CompactOverlay; using ElectronBot.Braincase.Contracts.Services; using ElectronBot.Braincase.Contracts.ViewModels; using ElectronBot.Braincase.Helpers; @@ -15,21 +17,17 @@ using ElectronBot.Braincase.Services; using Mediapipe.Net.Solutions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.UI.Xaml; +using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Media.Imaging; using Services; using Verdure.ElectronBot.Core.Models; using Windows.ApplicationModel; -using Windows.Graphics; using Windows.Graphics.Imaging; using Windows.Media.Core; using Windows.Media.Playback; using Windows.Media.SpeechRecognition; using Windows.Storage; -using Controls.CompactOverlay; -using Microsoft.UI.Windowing; namespace ElectronBot.Braincase.ViewModels; @@ -290,6 +288,228 @@ public partial class MainViewModel : ObservableRecipient, INavigationAware } } + [RelayCommand] + private async Task StartChat() + { + var config = (await _localSettingsService.ReadSettingAsync + (Constants.CustomClockTitleConfigKey)) ?? new CustomClockTitleConfig(); + + var textList = config.AnswerText.Split(",").ToList(); + + var r = new Random().Next(textList.Count); + + var text = textList[r]; + + ToastHelper.SendToast(text, TimeSpan.FromSeconds(4)); + + var localSettingsService = App.GetService(); + + var list = (await _localSettingsService + .ReadSettingAsync>(Constants.EmojisActionListKey)) ?? new List(); + + if (!list.Any(a => a.EmojisType == EmojisType.Default)) + { + var emoticonActions = Constants.EMOJI_ACTION_LIST; + await _localSettingsService.SaveSettingAsync(Constants.EmojisActionListKey, emoticonActions.ToList()); + list = emoticonActions.ToList(); + } + + if (list != null && list.Count > 0) + { + try + { + var emojis = list.First(l => l.NameId == "normal"); + + List actions = new(); + + if (emojis.HasAction) + { + if (!string.IsNullOrWhiteSpace(emojis.EmojisActionPath)) + { + try + { + var path = string.Empty; + + if (emojis.EmojisType == EmojisType.Default) + { + path = Package.Current.InstalledLocation.Path + $"\\Assets\\Emoji\\{emojis.EmojisActionPath}"; + } + else + { + path = emojis.EmojisActionPath; + } + + + var json = await File.ReadAllTextAsync(path); + + + var actionList = JsonSerializer.Deserialize>(json); + + if (actionList != null && actionList.Count > 0) + { + actions = actionList; + } + } + catch (Exception) + { + + } + } + } + + string? videoPath; + + if (emojis.EmojisType == EmojisType.Default) + { + videoPath = Package.Current.InstalledLocation.Path + $"\\Assets\\Emoji\\{emojis.NameId}.mp4"; + } + else + { + videoPath = emojis.EmojisVideoPath; + } + _ = ElectronBotHelper.Instance.MediaPlayerPlaySoundByTtsAsync(text, true); + await App.GetService().PlayActionExpressionAsync(emojis, actions); + } + catch (Exception) + { + } + } + } + + + [RelayCommand] + private async Task SendChat() + { + var config = (await _localSettingsService.ReadSettingAsync + (Constants.CustomClockTitleConfigKey)) ?? new CustomClockTitleConfig(); + + var textList = config.AnswerText.Split(",").ToList(); + + var r = new Random().Next(textList.Count); + + + var text = textList[r]; + + ToastHelper.SendToast("please wait for a moment", TimeSpan.FromSeconds(4)); + + var localSettingsService = App.GetService(); + + var list = (await _localSettingsService + .ReadSettingAsync>(Constants.EmojisActionListKey)) ?? new List(); + + if (!list.Any(a => a.EmojisType == EmojisType.Default)) + { + var emoticonActions = Constants.EMOJI_ACTION_LIST; + await _localSettingsService.SaveSettingAsync(Constants.EmojisActionListKey, emoticonActions.ToList()); + list = emoticonActions.ToList(); + } + + if (list != null && list.Count > 0) + { + try + { + var emojis = list.First(l => l.NameId == "normal"); + + List actions = new(); + + if (emojis.HasAction) + { + if (!string.IsNullOrWhiteSpace(emojis.EmojisActionPath)) + { + try + { + var path = string.Empty; + + if (emojis.EmojisType == EmojisType.Default) + { + path = Package.Current.InstalledLocation.Path + $"\\Assets\\Emoji\\{emojis.EmojisActionPath}"; + } + else + { + path = emojis.EmojisActionPath; + } + + + var json = await File.ReadAllTextAsync(path); + + + var actionList = JsonSerializer.Deserialize>(json); + + if (actionList != null && actionList.Count > 0) + { + actions = actionList; + } + } + catch (Exception) + { + + } + } + } + + string? videoPath; + + if (emojis.EmojisType == EmojisType.Default) + { + videoPath = Package.Current.InstalledLocation.Path + $"\\Assets\\Emoji\\{emojis.NameId}.mp4"; + } + else + { + videoPath = emojis.EmojisVideoPath; + } + _ = ElectronBotHelper.Instance.MediaPlayerPlaySoundByTtsAsync("please wait for a moment", false); + await App.GetService().PlayActionExpressionAsync(emojis, actions); + + try + { + //var chatGPTClient = App.GetService(); + + //var resultText = await chatGPTClient.AskQuestionResultAsync(args.Result.Text); + + //await ElectronBotHelper.Instance.MediaPlayerPlaySoundByTTSAsync(resultText); + + var chatBotClientFactory = App.GetService(); + + var chatBotClientName = (await App.GetService() + .ReadSettingAsync(Constants.DefaultChatBotNameKey))?.DataKey; + + if (string.IsNullOrEmpty(chatBotClientName)) + { + throw new Exception("no app key in the config"); + } + + var chatBotClient = chatBotClientFactory.CreateChatbotClient(chatBotClientName); + + var resultText = await chatBotClient.AskQuestionResultAsync(SendText); + + await ElectronBotHelper.Instance.MediaPlayerPlaySoundByTtsAsync(resultText, false); + } + catch (Exception ex) + { + App.MainWindow.DispatcherQueue.TryEnqueue(() => + { + ToastHelper.SendToast(ex.Message, TimeSpan.FromSeconds(3)); + }); + + } + } + catch (Exception) + { + } + } + } + + + [RelayCommand] + private async Task EndChat() + { + + ToastHelper.SendToast("end chat", TimeSpan.FromSeconds(4)); + + await ElectronBotHelper.Instance.CloseChatAsync(); + } + + [RelayCommand] private void ElectronEmulation() { @@ -633,7 +853,7 @@ public partial class MainViewModel : ObservableRecipient, INavigationAware var clockName = clockComBoxSelect?.DataKey; - if (clockName != "GooeyFooter"&&clockName!="CustomView") + if (clockName != "GooeyFooter" && clockName != "CustomView") { _dispatcherTimer.Interval = new TimeSpan(0, 0, 1); } diff --git a/src/ElectronBot.Braincase/ViewModels/SettingsViewModel.cs b/src/ElectronBot.Braincase/ViewModels/SettingsViewModel.cs index 0e5d42e..710148d 100644 --- a/src/ElectronBot.Braincase/ViewModels/SettingsViewModel.cs +++ b/src/ElectronBot.Braincase/ViewModels/SettingsViewModel.cs @@ -1,5 +1,4 @@ using System.Collections.ObjectModel; -using System.Text.RegularExpressions; using System.Windows.Input; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; @@ -9,6 +8,7 @@ using ElectronBot.Braincase.Helpers; using ElectronBot.Braincase.Models; using ElectronBot.Braincase.Services; using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Media.Imaging; using Verdure.ElectronBot.Core.Helpers; @@ -16,7 +16,6 @@ using Verdure.ElectronBot.Core.Models; using Windows.ApplicationModel; using Windows.Storage; using Windows.System; -using Microsoft.UI.Xaml.Controls; namespace ElectronBot.Braincase.ViewModels; @@ -62,6 +61,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware _identityService = identityService; _userDataService = userDataService; chatBotComboxModels = comboxDataService.GetChatBotClientComboxList(); + _chatGPTVersionomboxModels = comboxDataService.GetChatGPTVersionComboxList(); } @@ -115,7 +115,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware var isVisual = toggleSwitch.IsOn; ClockTitleConfig.CustomViewContentIsVisibility = isVisual; } - + await _localSettingsService .SaveSettingAsync(Constants.CustomClockTitleConfigKey, _clockTitleConfig); } @@ -158,7 +158,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware public async void RangeBase_OnValueChanged(object sender, RangeBaseValueChangedEventArgs e) { - + await _localSettingsService .SaveSettingAsync(Constants.CustomClockTitleConfigKey, _clockTitleConfig); } @@ -194,6 +194,18 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware [ObservableProperty] public ObservableCollection chatBotComboxModels; + /// + /// CHatGPTVersion选中数据 + /// + [ObservableProperty] + private ComboxItemModel? _chatGPTVersionSelect; + + /// + /// CHatGPTVersion列表 + /// + [ObservableProperty] + private ObservableCollection? _chatGPTVersionomboxModels; + /// /// 相机列表 @@ -291,7 +303,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware } [RelayCommand] - private async void RemoveEmojisAvatar() + private async Task RemoveEmojisAvatar() { ClockTitleConfig.CustomViewPicturePath = ""; await _localSettingsService @@ -310,6 +322,21 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware } } + [RelayCommand] + public async Task ChatGPTVersionChangedAsync() + { + var chatGPTName = ChatGPTVersionSelect?.DataKey; + + if (!string.IsNullOrWhiteSpace(chatGPTName)) + { + ClockTitleConfig.ChatGPTVersion = chatGPTName; + await _localSettingsService.SaveSettingAsync(Constants.DefaultChatGPTNameKey, chatGPTName); + + await _localSettingsService + .SaveSettingAsync(Constants.CustomClockTitleConfigKey, _clockTitleConfig); + } + } + [RelayCommand] public async Task FeedbackBtnAsync() { @@ -524,6 +551,18 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware ChatBotSelect = chatBotComboxModels.FirstOrDefault(c => c.DataValue == chatBotModel.DataValue); } + var chatGPTModel = await _localSettingsService + .ReadSettingAsync(Constants.DefaultChatGPTNameKey); + + if (!string.IsNullOrWhiteSpace(chatGPTModel)) + { + ChatGPTVersionSelect = ChatGPTVersionomboxModels?.FirstOrDefault(c => c.DataKey == chatGPTModel); + } + else + { + ChatGPTVersionSelect = ChatGPTVersionomboxModels?.FirstOrDefault(c => c.DataKey == ClockTitleConfig.ChatGPTVersion); + } + _identityService.LoggedIn += OnLoggedIn; _identityService.LoggedOut += OnLoggedOut; _userDataService.UserDataUpdated += OnUserDataUpdated; @@ -577,7 +616,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware var config = new ImageCropperConfig { ImageFile = file, - AspectRatio = 128d/296d + AspectRatio = 128d / 296d }; var croppedImage = await ImageHelper.CropImage(config); @@ -608,7 +647,7 @@ public partial class SettingsViewModel : ObservableRecipient, INavigationAware [RelayCommand] private async Task RemoveHw75Image() { - ClockTitleConfig.CustomHw75ImagePath = ""; + ClockTitleConfig.CustomHw75ImagePath = "ms-appx:///Assets/Images/Hw75CustomViewDefault.png"; await _localSettingsService .SaveSettingAsync(Constants.CustomClockTitleConfigKey, _clockTitleConfig); Hw75ImagePath = ""; diff --git a/src/ElectronBot.Braincase/Views/MainPage.xaml b/src/ElectronBot.Braincase/Views/MainPage.xaml index e4c343f..146ba87 100644 --- a/src/ElectronBot.Braincase/Views/MainPage.xaml +++ b/src/ElectronBot.Braincase/Views/MainPage.xaml @@ -2,8 +2,6 @@ x:Class="ElectronBot.Braincase.Views.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:clockControl="using:ElectronBot.Braincase.ClockViews" - xmlns:control="using:CommunityToolkit.WinUI.UI.Controls" xmlns:controlLocal="using:ElectronBot.Braincase.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="using:Microsoft.Xaml.Interactivity" @@ -132,7 +130,7 @@ @@ -298,6 +296,30 @@ + @@ -321,48 +343,75 @@ - - - + + - - - - + Child="{x:Bind ViewModel.Element, Mode=OneWay}" + CornerRadius="8" /> + + + + + + - - + + + + + + + + @@ -373,7 +422,7 @@ - + @@ -382,7 +431,7 @@ - + diff --git a/src/ElectronBot.Braincase/Views/SettingsPage.xaml b/src/ElectronBot.Braincase/Views/SettingsPage.xaml index 8b00e4f..5262a22 100644 --- a/src/ElectronBot.Braincase/Views/SettingsPage.xaml +++ b/src/ElectronBot.Braincase/Views/SettingsPage.xaml @@ -445,6 +445,36 @@ + + + + + + + + + + + + + + + + + + + @@ -520,6 +550,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/ElectronBot.Copilot/ElectronBot.Copilot.csproj b/src/ElectronBot.Copilot/ElectronBot.Copilot.csproj similarity index 87% rename from ElectronBot.Copilot/ElectronBot.Copilot.csproj rename to src/ElectronBot.Copilot/ElectronBot.Copilot.csproj index 18e321d..6de46e7 100644 --- a/ElectronBot.Copilot/ElectronBot.Copilot.csproj +++ b/src/ElectronBot.Copilot/ElectronBot.Copilot.csproj @@ -8,8 +8,8 @@ - - - + + + diff --git a/src/ElectronBot.Copilot/ProxyOpenAIHttpClientHandler.cs b/src/ElectronBot.Copilot/ProxyOpenAIHttpClientHandler.cs new file mode 100644 index 0000000..ff0bdf8 --- /dev/null +++ b/src/ElectronBot.Copilot/ProxyOpenAIHttpClientHandler.cs @@ -0,0 +1,25 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace ElectronBot.Copilot; + +public class ProxyOpenAIHttpClientHandler : HttpClientHandler +{ + private readonly string _proxyUrl; + + public ProxyOpenAIHttpClientHandler(string proxyUrl) + => _proxyUrl = proxyUrl.TrimEnd('/'); + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (request.RequestUri != null && request.RequestUri.Host.Equals("api.openai.com", StringComparison.OrdinalIgnoreCase)) + { + var path = request.RequestUri.PathAndQuery.TrimStart('/'); + request.RequestUri = new Uri($"{_proxyUrl}/{path}"); + } + + return base.SendAsync(request, cancellationToken); + } +} diff --git a/src/ElectronBot.Copilot/VerdureChatKernel.cs b/src/ElectronBot.Copilot/VerdureChatKernel.cs new file mode 100644 index 0000000..6a8abde --- /dev/null +++ b/src/ElectronBot.Copilot/VerdureChatKernel.cs @@ -0,0 +1,82 @@ +//using Microsoft.SemanticKernel; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Net.Http; +//using System.Net.Http.Headers; +//using System.Text; +//using System.Threading.Tasks; + +//namespace ElectronBot.Copilot +//{ +// public class VerdureChatKernel +// { +// private readonly ILocalSettingsService _localSettingsService; +// public VerdureChatKernel() +// { + +// } +// private Microsoft.SemanticKernel.Kernel _kernel; + +// /// +// /// 语义内核. +// /// +// public Kernel Kernel +// { +// get => _kernel; +// set +// { +// _kernel = value; +// } +// } + +// private static async Task LoadOpenAIConfiguration(VerdureChatKernel kernel, string modelName = default) +// { +// var accessKey = GlobalSettings.TryGet(SettingNames.OpenAIAccessKey); +// var org = GlobalSettings.TryGet(SettingNames.OpenAIOrganization); +// var customEndpoint = GlobalSettings.TryGet(SettingNames.OpenAICustomEndpoint); +// var model = string.IsNullOrEmpty(modelName) +// ? GlobalSettings.TryGet(SettingNames.DefaultOpenAIChatModelName) +// : modelName; + +// if (string.IsNullOrEmpty(accessKey) +// || string.IsNullOrEmpty(model)) +// { +// throw new Models.App.Args.KernelException(KernelExceptionType.InvalidConfiguration); +// } + +// var result = await App.Get<>_localSettingsService +// .ReadSettingAsync(Constants.CustomClockTitleConfigKey); + +// if (result == null) +// { +// throw new Exception("配置为空"); +// } + +// _chatGptClient ??= new ChatGPTClient(result.ChatGPTSessionKey, "gpt-3.5-turbo"); + +// _chatGptClient.Settings.OpenAIAPIBaseUri = result.OpenAIBaseUrl; + + + +// var hasCustomEndpoint = !string.IsNullOrEmpty(customEndpoint) && Uri.TryCreate(customEndpoint, UriKind.Absolute, out var _); +// var customHttpClient = hasCustomEndpoint +// ? GetProxyClient(customEndpoint) +// : default; + +// kernel.Kernel = Kernel +// .CreateBuilder() +// .AddOpenAIChatCompletion(model, accessKey, org, httpClient: customHttpClient) +// .Build(); +// } + + + +// private static HttpClient GetProxyClient(string baseUrl) +// { +// var httpClient = new HttpClient(new ProxyOpenAIHttpClientHandler(baseUrl)); +// httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream")); +// return httpClient; +// } +// } +//} diff --git a/src/GestureClassification/GestureClassification.csproj b/src/GestureClassification/GestureClassification.csproj index 377577d..879eca4 100644 --- a/src/GestureClassification/GestureClassification.csproj +++ b/src/GestureClassification/GestureClassification.csproj @@ -6,8 +6,8 @@ enable - - + + diff --git a/HelloWordKeyboard.ConsoleApp/HelloWordKeyboard.ConsoleApp.csproj b/src/HelloWordKeyboard.ConsoleApp/HelloWordKeyboard.ConsoleApp.csproj similarity index 100% rename from HelloWordKeyboard.ConsoleApp/HelloWordKeyboard.ConsoleApp.csproj rename to src/HelloWordKeyboard.ConsoleApp/HelloWordKeyboard.ConsoleApp.csproj diff --git a/HelloWordKeyboard.ConsoleApp/Program.cs b/src/HelloWordKeyboard.ConsoleApp/Program.cs similarity index 100% rename from HelloWordKeyboard.ConsoleApp/Program.cs rename to src/HelloWordKeyboard.ConsoleApp/Program.cs diff --git a/HelloWordKeyboard.ConsoleApp/SmileySans-Oblique.ttf b/src/HelloWordKeyboard.ConsoleApp/SmileySans-Oblique.ttf similarity index 100% rename from HelloWordKeyboard.ConsoleApp/SmileySans-Oblique.ttf rename to src/HelloWordKeyboard.ConsoleApp/SmileySans-Oblique.ttf diff --git a/HelloWordKeyboard.ConsoleApp/bzhan.png b/src/HelloWordKeyboard.ConsoleApp/bzhan.png similarity index 100% rename from HelloWordKeyboard.ConsoleApp/bzhan.png rename to src/HelloWordKeyboard.ConsoleApp/bzhan.png diff --git a/HelloWordKeyboard.ConsoleApp/default.jpg b/src/HelloWordKeyboard.ConsoleApp/default.jpg similarity index 100% rename from HelloWordKeyboard.ConsoleApp/default.jpg rename to src/HelloWordKeyboard.ConsoleApp/default.jpg diff --git a/HelloWordKeyboard.ConsoleApp/face.jpg b/src/HelloWordKeyboard.ConsoleApp/face.jpg similarity index 100% rename from HelloWordKeyboard.ConsoleApp/face.jpg rename to src/HelloWordKeyboard.ConsoleApp/face.jpg diff --git a/HelloWordKeyboard.DotNet/AssembleDataExtension.cs b/src/HelloWordKeyboard.DotNet/AssembleDataExtension.cs similarity index 100% rename from HelloWordKeyboard.DotNet/AssembleDataExtension.cs rename to src/HelloWordKeyboard.DotNet/AssembleDataExtension.cs diff --git a/HelloWordKeyboard.DotNet/HelloWordKeyboard.DotNet.csproj b/src/HelloWordKeyboard.DotNet/HelloWordKeyboard.DotNet.csproj similarity index 100% rename from HelloWordKeyboard.DotNet/HelloWordKeyboard.DotNet.csproj rename to src/HelloWordKeyboard.DotNet/HelloWordKeyboard.DotNet.csproj diff --git a/HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs b/src/HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs similarity index 91% rename from HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs rename to src/HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs index f349337..a73a9cb 100644 --- a/HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs +++ b/src/HelloWordKeyboard.DotNet/Hw75DynamicDevice.cs @@ -9,8 +9,6 @@ namespace HelloWordKeyboard.DotNet; public class Hw75DynamicDevice : IHw75DynamicDevice { - private const string Path = "\\\\?\\hid#vid_1d50&pid_615e&mi_01#8&a8a6dc9&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"; - private const int RePortCount = 63; private const int PayloadSize = RePortCount - 1; @@ -148,9 +146,14 @@ public class Hw75DynamicDevice : IHw75DynamicDevice { if (deviceInfo.UsagePage == ZmkxUasage) { - return new Device(deviceInfo.Path); + _device = new Device(deviceInfo.Path); + var version = GetVersion(); + if (version.Features.HasEink && version.Features.Eink == true) + { + return new Device(deviceInfo.Path); + } } } - throw new Exception("瀚文设备未连接"); + throw new Exception("瀚文拓展设备未连接"); } } \ No newline at end of file diff --git a/HelloWordKeyboard.DotNet/IHw75DynamicDevice.cs b/src/HelloWordKeyboard.DotNet/IHw75DynamicDevice.cs similarity index 100% rename from HelloWordKeyboard.DotNet/IHw75DynamicDevice.cs rename to src/HelloWordKeyboard.DotNet/IHw75DynamicDevice.cs diff --git a/HelloWordKeyboard.DotNet/Models/DeviceInfo.cs b/src/HelloWordKeyboard.DotNet/Models/DeviceInfo.cs similarity index 100% rename from HelloWordKeyboard.DotNet/Models/DeviceInfo.cs rename to src/HelloWordKeyboard.DotNet/Models/DeviceInfo.cs diff --git a/HelloWordKeyboard.DotNet/Protos/comm.proto b/src/HelloWordKeyboard.DotNet/Protos/comm.proto similarity index 100% rename from HelloWordKeyboard.DotNet/Protos/comm.proto rename to src/HelloWordKeyboard.DotNet/Protos/comm.proto diff --git a/HelloWordKeyboard.DotNet/hidapi.dll b/src/HelloWordKeyboard.DotNet/hidapi.dll similarity index 100% rename from HelloWordKeyboard.DotNet/hidapi.dll rename to src/HelloWordKeyboard.DotNet/hidapi.dll diff --git a/HelloWordKeyboard.DotNet/hidapi.lib b/src/HelloWordKeyboard.DotNet/hidapi.lib similarity index 100% rename from HelloWordKeyboard.DotNet/hidapi.lib rename to src/HelloWordKeyboard.DotNet/hidapi.lib diff --git a/src/Mediapipe.Net/Mediapipe.Net.csproj b/src/Mediapipe.Net/Mediapipe.Net.csproj index 94b116b..6b6da80 100644 --- a/src/Mediapipe.Net/Mediapipe.Net.csproj +++ b/src/Mediapipe.Net/Mediapipe.Net.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 true disable enable @@ -23,7 +23,7 @@ - +