AI action panel improvements.
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.82.1" />
|
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.82.1" />
|
||||||
<PackageVersion Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.14" />
|
<PackageVersion Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.14" />
|
||||||
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.1" />
|
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.1" />
|
||||||
<PackageVersion Include="Wino.Mail.Contracts" Version="1.0.14" />
|
<PackageVersion Include="Wino.Mail.Contracts" Version="1.0.15" />
|
||||||
<PackageVersion Include="MimeKit" Version="4.15.1" />
|
<PackageVersion Include="MimeKit" Version="4.15.1" />
|
||||||
<PackageVersion Include="morelinq" Version="4.4.0" />
|
<PackageVersion Include="morelinq" Version="4.4.0" />
|
||||||
<PackageVersion Include="Nito.AsyncEx" Version="5.1.2" />
|
<PackageVersion Include="Nito.AsyncEx" Version="5.1.2" />
|
||||||
|
|||||||
@@ -67,6 +67,21 @@ public interface IPreferencesService : INotifyPropertyChanged
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsWinoAccountButtonHidden { get; set; }
|
bool IsWinoAccountButtonHidden { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting: Default target language code used for AI translation actions.
|
||||||
|
/// </summary>
|
||||||
|
string AiDefaultTranslationLanguageCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting: Preferred target language code for AI summarize actions.
|
||||||
|
/// </summary>
|
||||||
|
string AiSummarizeLanguageCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting: Preferred folder path used when saving AI summaries.
|
||||||
|
/// </summary>
|
||||||
|
string AiSummarySavePath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes the current syncable preferences snapshot.
|
/// Serializes the current syncable preferences snapshot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public interface IWinoAccountApiClient
|
|||||||
Task<ApiEnvelope<JsonElement>> LogoutAsync(string refreshToken, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<JsonElement>> LogoutAsync(string refreshToken, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AuthUserDto>> GetCurrentUserAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AuthUserDto>> GetCurrentUserAsync(CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> RewriteAsync(string html, string mode, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> RewriteAsync(string html, string mode, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<WinoStoreCollectionsIdTicketInfo>> CreateCollectionsIdTicketAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<WinoStoreCollectionsIdTicketInfo>> CreateCollectionsIdTicketAsync(CancellationToken cancellationToken = default);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public interface IWinoAccountProfileService
|
|||||||
Task<bool> HasActiveAccountAsync();
|
Task<bool> HasActiveAccountAsync();
|
||||||
Task<ApiEnvelope<AuthUserDto>> GetCurrentUserAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AuthUserDto>> GetCurrentUserAsync(CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<AiTextResultDto>> RewriteAsync(string html, string mode, CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<AiTextResultDto>> RewriteAsync(string html, string mode, CancellationToken cancellationToken = default);
|
||||||
Task<ApiEnvelope<JsonElement>> SyncStoreEntitlementsAsync(CancellationToken cancellationToken = default);
|
Task<ApiEnvelope<JsonElement>> SyncStoreEntitlementsAsync(CancellationToken cancellationToken = default);
|
||||||
|
|||||||
@@ -724,6 +724,16 @@
|
|||||||
"SettingsAppPreferences_HideWinoAccountButton_Description": "Hide the title bar profile button that opens the Wino account flyout.",
|
"SettingsAppPreferences_HideWinoAccountButton_Description": "Hide the title bar profile button that opens the Wino account flyout.",
|
||||||
"SettingsAppPreferences_StoreUpdateNotifications_Title": "Store update notifications",
|
"SettingsAppPreferences_StoreUpdateNotifications_Title": "Store update notifications",
|
||||||
"SettingsAppPreferences_StoreUpdateNotifications_Description": "Show notifications and footer actions when a Microsoft Store update is available.",
|
"SettingsAppPreferences_StoreUpdateNotifications_Description": "Show notifications and footer actions when a Microsoft Store update is available.",
|
||||||
|
"SettingsAppPreferences_AiActions_Title": "AI actions",
|
||||||
|
"SettingsAppPreferences_AiActions_Description": "Choose default AI languages and where summaries should be saved.",
|
||||||
|
"SettingsAppPreferences_AiDefaultTranslationLanguage_Title": "Default translation language",
|
||||||
|
"SettingsAppPreferences_AiDefaultTranslationLanguage_Description": "Pick the default target language used by AI translate actions.",
|
||||||
|
"SettingsAppPreferences_AiSummarizeLanguage_Title": "Summarize language",
|
||||||
|
"SettingsAppPreferences_AiSummarizeLanguage_Description": "Choose the preferred summarize language for future AI summary output.",
|
||||||
|
"SettingsAppPreferences_AiSummarySavePath_Title": "Default summary save path",
|
||||||
|
"SettingsAppPreferences_AiSummarySavePath_Description": "Choose the folder Wino should use by default when saving AI summaries.",
|
||||||
|
"SettingsAppPreferences_AiSummarySavePath_Placeholder": "Use the system default save location",
|
||||||
|
"SettingsAppPreferences_AiSummarySavePath_InvalidHint": "This folder does not exist. The default save location will be used for summaries.",
|
||||||
"SettingsAutoSelectNextItem_Description": "Select the next item after you delete or move a mail.",
|
"SettingsAutoSelectNextItem_Description": "Select the next item after you delete or move a mail.",
|
||||||
"SettingsAutoSelectNextItem_Title": "Auto select next item",
|
"SettingsAutoSelectNextItem_Title": "Auto select next item",
|
||||||
"SettingsAvailableThemes_Description": "Select a theme from Wino's own collection for your taste or apply your own themes.",
|
"SettingsAvailableThemes_Description": "Select a theme from Wino's own collection for your taste or apply your own themes.",
|
||||||
@@ -1071,7 +1081,7 @@
|
|||||||
"AiActions_SignedOutDescription": "Translate, rewrite, and summarize emails with AI after signing in to your Wino Account and activating the AI Pack add-on.",
|
"AiActions_SignedOutDescription": "Translate, rewrite, and summarize emails with AI after signing in to your Wino Account and activating the AI Pack add-on.",
|
||||||
"AiActions_NoPackTitle": "AI Pack required",
|
"AiActions_NoPackTitle": "AI Pack required",
|
||||||
"AiActions_NoPackDescription": "You're signed in, but AI Pack is not active yet. Purchase it to use Wino's AI translation, rewrite, and summarize tools.",
|
"AiActions_NoPackDescription": "You're signed in, but AI Pack is not active yet. Purchase it to use Wino's AI translation, rewrite, and summarize tools.",
|
||||||
"AiActions_UsageSummary": "{0} of {1} requests used this month.",
|
"AiActions_UsageSummary": "{0} of {1} credits used this month.",
|
||||||
"Composer_AiRewritePolite": "Make it polite",
|
"Composer_AiRewritePolite": "Make it polite",
|
||||||
"Composer_AiRewritePoliteDescription": "Softens the wording while keeping the same intent.",
|
"Composer_AiRewritePoliteDescription": "Softens the wording while keeping the same intent.",
|
||||||
"Composer_AiRewriteAngry": "Make it angry",
|
"Composer_AiRewriteAngry": "Make it angry",
|
||||||
@@ -1243,7 +1253,7 @@
|
|||||||
"WinoAccount_Management_AiPackPromoTitle": "Unlock AI Pack",
|
"WinoAccount_Management_AiPackPromoTitle": "Unlock AI Pack",
|
||||||
"WinoAccount_Management_AiPackPromoDescription": "Supercharge your email workflow with AI-powered tools. Translate messages into 50+ languages, rewrite for clarity and tone, and get instant summaries of long threads.",
|
"WinoAccount_Management_AiPackPromoDescription": "Supercharge your email workflow with AI-powered tools. Translate messages into 50+ languages, rewrite for clarity and tone, and get instant summaries of long threads.",
|
||||||
"WinoAccount_Management_AiPackPromoPrice": "$4.99 / mo",
|
"WinoAccount_Management_AiPackPromoPrice": "$4.99 / mo",
|
||||||
"WinoAccount_Management_AiPackPromoRequests": "1,000 requests",
|
"WinoAccount_Management_AiPackPromoRequests": "1,000 credits",
|
||||||
"WinoAccount_Management_AiPackGetButton": "Get AI Pack",
|
"WinoAccount_Management_AiPackGetButton": "Get AI Pack",
|
||||||
"WinoAddOn_AI_PACK_Name": "Wino AI Pack",
|
"WinoAddOn_AI_PACK_Name": "Wino AI Pack",
|
||||||
"WinoAddOn_AI_PACK_Description": "AI-powered tools for translate, rewrite, and summarize actions in Wino Mail.",
|
"WinoAddOn_AI_PACK_Description": "AI-powered tools for translate, rewrite, and summarize actions in Wino Mail.",
|
||||||
@@ -1256,7 +1266,7 @@
|
|||||||
"WinoAccount_Management_StoreSyncFailed": "Your purchase finished, but Wino could not refresh your account benefits yet. Please try again in a moment.",
|
"WinoAccount_Management_StoreSyncFailed": "Your purchase finished, but Wino could not refresh your account benefits yet. Please try again in a moment.",
|
||||||
"WinoAccount_Management_AiPackSubscriptionActive": "Your subscription is active",
|
"WinoAccount_Management_AiPackSubscriptionActive": "Your subscription is active",
|
||||||
"WinoAccount_Management_AiPackRenews": "Renews {0:d}",
|
"WinoAccount_Management_AiPackRenews": "Renews {0:d}",
|
||||||
"WinoAccount_Management_AiPackRequestsUsed": "Requests used this month",
|
"WinoAccount_Management_AiPackRequestsUsed": "Credits used this month",
|
||||||
"WinoAccount_Management_AiPackResets": "Resets {0:d}",
|
"WinoAccount_Management_AiPackResets": "Resets {0:d}",
|
||||||
"WinoAccount_Management_AiPackUsageLoadFailed": "We had issues loading your AI usage balance.",
|
"WinoAccount_Management_AiPackUsageLoadFailed": "We had issues loading your AI usage balance.",
|
||||||
"WinoAccount_Management_AiPackFeatureTranslate": "Translate",
|
"WinoAccount_Management_AiPackFeatureTranslate": "Translate",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Ai;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.Domain.Models.Translations;
|
using Wino.Core.Domain.Models.Translations;
|
||||||
|
|
||||||
@@ -16,12 +18,14 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
IMailDialogService dialogService,
|
IMailDialogService dialogService,
|
||||||
IPreferencesService preferencesService,
|
IPreferencesService preferencesService,
|
||||||
IStartupBehaviorService startupBehaviorService,
|
IStartupBehaviorService startupBehaviorService,
|
||||||
ITranslationService translationService)
|
ITranslationService translationService,
|
||||||
|
IAiActionOptionsService aiActionOptionsService)
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
PreferencesService = preferencesService;
|
PreferencesService = preferencesService;
|
||||||
_startupBehaviorService = startupBehaviorService;
|
_startupBehaviorService = startupBehaviorService;
|
||||||
_translationService = translationService;
|
_translationService = translationService;
|
||||||
|
_aiActionOptionsService = aiActionOptionsService;
|
||||||
|
|
||||||
SearchModes =
|
SearchModes =
|
||||||
[
|
[
|
||||||
@@ -40,6 +44,7 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
SelectedDefaultSearchMode = SearchModes[(int)PreferencesService.DefaultSearchMode];
|
SelectedDefaultSearchMode = SearchModes[(int)PreferencesService.DefaultSearchMode];
|
||||||
SelectedDefaultApplicationMode = ApplicationModes[(int)PreferencesService.DefaultApplicationMode];
|
SelectedDefaultApplicationMode = ApplicationModes[(int)PreferencesService.DefaultApplicationMode];
|
||||||
EmailSyncIntervalMinutes = PreferencesService.EmailSyncIntervalMinutes;
|
EmailSyncIntervalMinutes = PreferencesService.EmailSyncIntervalMinutes;
|
||||||
|
SummarySavePath = PreferencesService.AiSummarySavePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPreferencesService PreferencesService { get; }
|
public IPreferencesService PreferencesService { get; }
|
||||||
@@ -56,6 +61,21 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public partial AppLanguageModel SelectedLanguage { get; set; }
|
public partial AppLanguageModel SelectedLanguage { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial List<AiTranslateLanguageOption> AvailableAiLanguages { get; set; } = [];
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial AiTranslateLanguageOption SelectedDefaultTranslationLanguage { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial AiTranslateLanguageOption SelectedSummarizeLanguage { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string SummarySavePath { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool HasInvalidSummarySavePath { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
[NotifyPropertyChangedFor(nameof(IsStartupBehaviorDisabled))]
|
[NotifyPropertyChangedFor(nameof(IsStartupBehaviorDisabled))]
|
||||||
[NotifyPropertyChangedFor(nameof(IsStartupBehaviorEnabled))]
|
[NotifyPropertyChangedFor(nameof(IsStartupBehaviorEnabled))]
|
||||||
@@ -64,7 +84,9 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
private readonly IMailDialogService _dialogService;
|
private readonly IMailDialogService _dialogService;
|
||||||
private readonly IStartupBehaviorService _startupBehaviorService;
|
private readonly IStartupBehaviorService _startupBehaviorService;
|
||||||
private readonly ITranslationService _translationService;
|
private readonly ITranslationService _translationService;
|
||||||
|
private readonly IAiActionOptionsService _aiActionOptionsService;
|
||||||
private bool _isLanguageInitialized;
|
private bool _isLanguageInitialized;
|
||||||
|
private bool _isAiPreferencesInitialized;
|
||||||
private int _emailSyncIntervalMinutes;
|
private int _emailSyncIntervalMinutes;
|
||||||
private string _selectedDefaultSearchMode;
|
private string _selectedDefaultSearchMode;
|
||||||
private string _selectedDefaultApplicationMode;
|
private string _selectedDefaultApplicationMode;
|
||||||
@@ -110,6 +132,31 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
_ = _translationService.InitializeLanguageAsync(value.Language);
|
_ = _translationService.InitializeLanguageAsync(value.Language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void OnSelectedDefaultTranslationLanguageChanged(AiTranslateLanguageOption value)
|
||||||
|
{
|
||||||
|
if (!_isAiPreferencesInitialized || value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PreferencesService.AiDefaultTranslationLanguageCode = value.Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnSelectedSummarizeLanguageChanged(AiTranslateLanguageOption value)
|
||||||
|
{
|
||||||
|
if (!_isAiPreferencesInitialized || value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PreferencesService.AiSummarizeLanguageCode = value.Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnSummarySavePathChanged(string value)
|
||||||
|
{
|
||||||
|
if (!_isAiPreferencesInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PreferencesService.AiSummarySavePath = value ?? string.Empty;
|
||||||
|
RefreshSummarySavePathState();
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task ToggleStartupBehaviorAsync()
|
private async Task ToggleStartupBehaviorAsync()
|
||||||
{
|
{
|
||||||
@@ -157,15 +204,56 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task BrowseSummarySavePathAsync()
|
||||||
|
{
|
||||||
|
var pickedPath = await _dialogService.PickWindowsFolderAsync();
|
||||||
|
if (string.IsNullOrWhiteSpace(pickedPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await ExecuteUIThread(() => SummarySavePath = pickedPath);
|
||||||
|
}
|
||||||
|
|
||||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(mode, parameters);
|
base.OnNavigatedTo(mode, parameters);
|
||||||
|
|
||||||
AvailableLanguages = _translationService.GetAvailableLanguages();
|
var availableLanguages = _translationService.GetAvailableLanguages();
|
||||||
|
var availableAiLanguages = new List<AiTranslateLanguageOption>(_aiActionOptionsService.GetTranslateLanguageOptions());
|
||||||
|
var startupBehaviorResult = await _startupBehaviorService.GetCurrentStartupBehaviorAsync();
|
||||||
|
|
||||||
|
await ExecuteUIThread(() =>
|
||||||
|
{
|
||||||
|
AvailableLanguages = availableLanguages;
|
||||||
SelectedLanguage = AvailableLanguages.Find(language => language.Language == PreferencesService.CurrentLanguage)
|
SelectedLanguage = AvailableLanguages.Find(language => language.Language == PreferencesService.CurrentLanguage)
|
||||||
?? (AvailableLanguages.Count > 0 ? AvailableLanguages[0] : null);
|
?? (AvailableLanguages.Count > 0 ? AvailableLanguages[0] : null);
|
||||||
_isLanguageInitialized = true;
|
_isLanguageInitialized = true;
|
||||||
|
|
||||||
StartupBehaviorResult = await _startupBehaviorService.GetCurrentStartupBehaviorAsync();
|
AvailableAiLanguages = availableAiLanguages;
|
||||||
|
SelectedDefaultTranslationLanguage = FindAiLanguageOption(PreferencesService.AiDefaultTranslationLanguageCode)
|
||||||
|
?? FindAiLanguageOption("en-US")
|
||||||
|
?? (AvailableAiLanguages.Count > 0 ? AvailableAiLanguages[0] : null);
|
||||||
|
SelectedSummarizeLanguage = FindAiLanguageOption(PreferencesService.AiSummarizeLanguageCode)
|
||||||
|
?? FindAiLanguageOption("en-US")
|
||||||
|
?? (AvailableAiLanguages.Count > 0 ? AvailableAiLanguages[0] : null);
|
||||||
|
SummarySavePath = PreferencesService.AiSummarySavePath;
|
||||||
|
RefreshSummarySavePathState();
|
||||||
|
_isAiPreferencesInitialized = true;
|
||||||
|
|
||||||
|
StartupBehaviorResult = startupBehaviorResult;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private AiTranslateLanguageOption FindAiLanguageOption(string languageCode)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(languageCode))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return AvailableAiLanguages.Find(option => option.Code == languageCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshSummarySavePathState()
|
||||||
|
{
|
||||||
|
HasInvalidSummarySavePath = !string.IsNullOrWhiteSpace(SummarySavePath) && !Directory.Exists(SummarySavePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,18 +143,16 @@
|
|||||||
Style="{StaticResource AccentButtonStyle}" />
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<Grid
|
||||||
x:Name="ReadyPanel"
|
x:Name="ReadyPanel"
|
||||||
Spacing="8"
|
ColumnSpacing="12"
|
||||||
Visibility="Collapsed">
|
Visibility="Collapsed">
|
||||||
<!-- Row 1: Action tabs + usage -->
|
|
||||||
<Grid ColumnSpacing="12">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
<!-- Column 1: Action tabs -->
|
||||||
<controls:Segmented
|
<controls:Segmented
|
||||||
x:Name="ActionSelector"
|
x:Name="ActionSelector"
|
||||||
Height="30"
|
Height="30"
|
||||||
@@ -187,27 +185,8 @@
|
|||||||
</controls:SegmentedItem>
|
</controls:SegmentedItem>
|
||||||
</controls:Segmented>
|
</controls:Segmented>
|
||||||
|
|
||||||
<StackPanel
|
<!-- Column 2: Action-specific options -->
|
||||||
Grid.Column="2"
|
<Grid Grid.Column="1" ColumnSpacing="8">
|
||||||
VerticalAlignment="Center"
|
|
||||||
Orientation="Horizontal"
|
|
||||||
Spacing="8">
|
|
||||||
<ProgressBar
|
|
||||||
x:Name="UsageProgressBar"
|
|
||||||
Width="100"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Maximum="1000"
|
|
||||||
Value="0" />
|
|
||||||
<TextBlock
|
|
||||||
x:Name="UsageSummaryTextBlock"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
|
||||||
Style="{StaticResource CaptionTextBlockStyle}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Row 2: Action-specific options -->
|
|
||||||
<Grid ColumnSpacing="8">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -284,11 +263,24 @@
|
|||||||
x:Name="SummarizeOptionsPanel"
|
x:Name="SummarizeOptionsPanel"
|
||||||
Spacing="8"
|
Spacing="8"
|
||||||
Visibility="Collapsed">
|
Visibility="Collapsed">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
Style="{StaticResource CaptionTextBlockStyle}"
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
Text="{x:Bind domain:Translator.Composer_AiSummarizeDescription, Mode=OneWay}" />
|
Text="{x:Bind domain:Translator.Composer_AiTranslateLanguage, Mode=OneWay}" />
|
||||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
<ComboBox
|
||||||
|
x:Name="SummarizeLanguageComboBox"
|
||||||
|
MinWidth="120"
|
||||||
|
SelectionChanged="SummarizeLanguageComboBox_SelectionChanged">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:AiTranslateLanguageOption">
|
||||||
|
<TextBlock Text="{x:Bind Label}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
x:Name="RunSummarizeButton"
|
x:Name="RunSummarizeButton"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -306,10 +298,30 @@
|
|||||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiSummarize, Mode=OneWay}"
|
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiSummarize, Mode=OneWay}"
|
||||||
Visibility="Collapsed" />
|
Visibility="Collapsed" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Column 3: Progress -->
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="8">
|
||||||
|
<ProgressBar
|
||||||
|
x:Name="UsageProgressBar"
|
||||||
|
Width="100"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Maximum="1000"
|
||||||
|
Value="0" />
|
||||||
|
<TextBlock
|
||||||
|
x:Name="UsageSummaryTextBlock"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
private readonly IStoreManagementService _storeManagementService = App.Current.Services.GetRequiredService<IStoreManagementService>();
|
private readonly IStoreManagementService _storeManagementService = App.Current.Services.GetRequiredService<IStoreManagementService>();
|
||||||
private readonly IMailDialogService _dialogService = App.Current.Services.GetRequiredService<IMailDialogService>();
|
private readonly IMailDialogService _dialogService = App.Current.Services.GetRequiredService<IMailDialogService>();
|
||||||
private readonly IAiActionOptionsService _optionsService = App.Current.Services.GetRequiredService<IAiActionOptionsService>();
|
private readonly IAiActionOptionsService _optionsService = App.Current.Services.GetRequiredService<IAiActionOptionsService>();
|
||||||
|
private readonly IPreferencesService _preferencesService = App.Current.Services.GetRequiredService<IPreferencesService>();
|
||||||
|
|
||||||
private bool _disposedValue;
|
private bool _disposedValue;
|
||||||
private bool _isRefreshing;
|
private bool _isRefreshing;
|
||||||
@@ -43,6 +44,8 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
|
|
||||||
public AiTranslateLanguageOption? SelectedTranslateLanguageOption { get; set; }
|
public AiTranslateLanguageOption? SelectedTranslateLanguageOption { get; set; }
|
||||||
|
|
||||||
|
public AiTranslateLanguageOption? SelectedSummarizeLanguageOption { get; set; }
|
||||||
|
|
||||||
public AiRewriteModeOption? SelectedRewriteModeOption { get; set; }
|
public AiRewriteModeOption? SelectedRewriteModeOption { get; set; }
|
||||||
|
|
||||||
public AiActionsPanel()
|
public AiActionsPanel()
|
||||||
@@ -90,19 +93,33 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
{
|
{
|
||||||
// Save current selections before replacing ItemsSource (which clears SelectedItem).
|
// Save current selections before replacing ItemsSource (which clears SelectedItem).
|
||||||
var previousTranslateCode = SelectedTranslateLanguageOption?.Code;
|
var previousTranslateCode = SelectedTranslateLanguageOption?.Code;
|
||||||
|
var previousSummarizeCode = SelectedSummarizeLanguageOption?.Code;
|
||||||
var previousRewriteMode = SelectedRewriteModeOption?.Mode;
|
var previousRewriteMode = SelectedRewriteModeOption?.Mode;
|
||||||
|
var preferredTranslateCode = string.IsNullOrWhiteSpace(previousTranslateCode)
|
||||||
|
? _preferencesService.AiDefaultTranslationLanguageCode
|
||||||
|
: previousTranslateCode;
|
||||||
|
var preferredSummarizeCode = string.IsNullOrWhiteSpace(previousSummarizeCode)
|
||||||
|
? _preferencesService.AiSummarizeLanguageCode
|
||||||
|
: previousSummarizeCode;
|
||||||
|
|
||||||
_translateOptions = _optionsService.GetTranslateLanguageOptions();
|
_translateOptions = _optionsService.GetTranslateLanguageOptions();
|
||||||
_rewriteOptions = _optionsService.GetRewriteModeOptions();
|
_rewriteOptions = _optionsService.GetRewriteModeOptions();
|
||||||
|
|
||||||
TranslateLanguageComboBox.ItemsSource = _translateOptions;
|
TranslateLanguageComboBox.ItemsSource = _translateOptions;
|
||||||
|
SummarizeLanguageComboBox.ItemsSource = _translateOptions;
|
||||||
RewriteModeComboBox.ItemsSource = _rewriteOptions;
|
RewriteModeComboBox.ItemsSource = _rewriteOptions;
|
||||||
|
|
||||||
// Restore selection by matching on value, falling back to first item.
|
// Restore selection by matching on value, falling back to first item.
|
||||||
SelectedTranslateLanguageOption = FindOption(_translateOptions, o => o.Code == previousTranslateCode) ?? (_translateOptions.Count > 0 ? _translateOptions[0] : null);
|
SelectedTranslateLanguageOption = FindOption(_translateOptions, o => o.Code == preferredTranslateCode)
|
||||||
|
?? FindOption(_translateOptions, o => o.Code == "en-US")
|
||||||
|
?? (_translateOptions.Count > 0 ? _translateOptions[0] : null);
|
||||||
|
SelectedSummarizeLanguageOption = FindOption(_translateOptions, o => o.Code == preferredSummarizeCode)
|
||||||
|
?? FindOption(_translateOptions, o => o.Code == "en-US")
|
||||||
|
?? (_translateOptions.Count > 0 ? _translateOptions[0] : null);
|
||||||
SelectedRewriteModeOption = FindOption(_rewriteOptions, o => o.Mode == previousRewriteMode) ?? (_rewriteOptions.Count > 0 ? _rewriteOptions[0] : null);
|
SelectedRewriteModeOption = FindOption(_rewriteOptions, o => o.Mode == previousRewriteMode) ?? (_rewriteOptions.Count > 0 ? _rewriteOptions[0] : null);
|
||||||
|
|
||||||
TranslateLanguageComboBox.SelectedItem = SelectedTranslateLanguageOption;
|
TranslateLanguageComboBox.SelectedItem = SelectedTranslateLanguageOption;
|
||||||
|
SummarizeLanguageComboBox.SelectedItem = SelectedSummarizeLanguageOption;
|
||||||
RewriteModeComboBox.SelectedItem = SelectedRewriteModeOption;
|
RewriteModeComboBox.SelectedItem = SelectedRewriteModeOption;
|
||||||
UpdateRewriteOptionState();
|
UpdateRewriteOptionState();
|
||||||
}
|
}
|
||||||
@@ -293,6 +310,7 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
BusyProgressBar.Visibility = isBusy ? Visibility.Visible : Visibility.Collapsed;
|
BusyProgressBar.Visibility = isBusy ? Visibility.Visible : Visibility.Collapsed;
|
||||||
ActionSelector.IsEnabled = !isBusy;
|
ActionSelector.IsEnabled = !isBusy;
|
||||||
TranslateLanguageComboBox.IsEnabled = !isBusy;
|
TranslateLanguageComboBox.IsEnabled = !isBusy;
|
||||||
|
SummarizeLanguageComboBox.IsEnabled = !isBusy;
|
||||||
RewriteModeComboBox.IsEnabled = !isBusy;
|
RewriteModeComboBox.IsEnabled = !isBusy;
|
||||||
CustomRewriteTextBox.IsEnabled = !isBusy;
|
CustomRewriteTextBox.IsEnabled = !isBusy;
|
||||||
RunTranslateButton.IsEnabled = !isBusy;
|
RunTranslateButton.IsEnabled = !isBusy;
|
||||||
@@ -426,6 +444,7 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
if (TranslateLanguageComboBox.SelectedItem is AiTranslateLanguageOption option)
|
if (TranslateLanguageComboBox.SelectedItem is AiTranslateLanguageOption option)
|
||||||
{
|
{
|
||||||
SelectedTranslateLanguageOption = option;
|
SelectedTranslateLanguageOption = option;
|
||||||
|
_preferencesService.AiDefaultTranslationLanguageCode = option.Code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,6 +457,15 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SummarizeLanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (SummarizeLanguageComboBox.SelectedItem is AiTranslateLanguageOption option)
|
||||||
|
{
|
||||||
|
SelectedSummarizeLanguageOption = option;
|
||||||
|
_preferencesService.AiSummarizeLanguageCode = option.Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateRewriteOptionState()
|
private void UpdateRewriteOptionState()
|
||||||
{
|
{
|
||||||
var isCustom = SelectedRewriteModeOption?.IsCustom ?? false;
|
var isCustom = SelectedRewriteModeOption?.IsCustom ?? false;
|
||||||
@@ -500,6 +528,12 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == AiActionType.Summarize && SelectedSummarizeLanguageOption == null)
|
||||||
|
{
|
||||||
|
_dialogService.InfoBarMessage(Translator.Composer_AiErrorTitle, Translator.WinoAccount_Error_ValidationFailed, InfoBarMessageType.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == AiActionType.Translate)
|
if (action == AiActionType.Translate)
|
||||||
{
|
{
|
||||||
var cachedTranslation = await HtmlHost.TryGetCachedTranslationHtmlAsync(SelectedTranslateLanguageOption?.Code ?? string.Empty, cancellationToken).ConfigureAwait(true);
|
var cachedTranslation = await HtmlHost.TryGetCachedTranslationHtmlAsync(SelectedTranslateLanguageOption?.Code ?? string.Empty, cancellationToken).ConfigureAwait(true);
|
||||||
@@ -539,7 +573,7 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
{
|
{
|
||||||
AiActionType.Translate => await _profileService.TranslateAsync(html, SelectedTranslateLanguageOption?.Code ?? string.Empty, cancellationToken).ConfigureAwait(true),
|
AiActionType.Translate => await _profileService.TranslateAsync(html, SelectedTranslateLanguageOption?.Code ?? string.Empty, cancellationToken).ConfigureAwait(true),
|
||||||
AiActionType.Rewrite => await _profileService.RewriteAsync(html, ResolveRewriteMode(), cancellationToken).ConfigureAwait(true),
|
AiActionType.Rewrite => await _profileService.RewriteAsync(html, ResolveRewriteMode(), cancellationToken).ConfigureAwait(true),
|
||||||
AiActionType.Summarize => await _profileService.SummarizeAsync(html, cancellationToken).ConfigureAwait(true),
|
AiActionType.Summarize => await _profileService.SummarizeAsync(html, SelectedSummarizeLanguageOption?.Code ?? string.Empty, cancellationToken).ConfigureAwait(true),
|
||||||
_ => ApiEnvelope<AiTextResultDto>.Failure(ApiErrorCodes.ValidationFailed)
|
_ => ApiEnvelope<AiTextResultDto>.Failure(ApiErrorCodes.ValidationFailed)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -684,7 +718,11 @@ public sealed partial class AiActionsPanel : UserControl, IDisposable
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var path = await _dialogService.PickFilePathAsync(HtmlHost.GetSuggestedSummaryFileName());
|
var configuredSummarySavePath = _preferencesService.AiSummarySavePath;
|
||||||
|
var path = !string.IsNullOrWhiteSpace(configuredSummarySavePath) && Directory.Exists(configuredSummarySavePath)
|
||||||
|
? Path.Combine(configuredSummarySavePath, HtmlHost.GetSuggestedSummaryFileName())
|
||||||
|
: await _dialogService.PickFilePathAsync(HtmlHost.GetSuggestedSummaryFileName());
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
{
|
{
|
||||||
args.Cancel = true;
|
args.Cancel = true;
|
||||||
|
|||||||
@@ -389,6 +389,24 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
|
|||||||
set => SetPropertyAndSave(nameof(IsWinoAccountButtonHidden), value);
|
set => SetPropertyAndSave(nameof(IsWinoAccountButtonHidden), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string AiDefaultTranslationLanguageCode
|
||||||
|
{
|
||||||
|
get => _configurationService.Get(nameof(AiDefaultTranslationLanguageCode), "en-US");
|
||||||
|
set => SetPropertyAndSave(nameof(AiDefaultTranslationLanguageCode), string.IsNullOrWhiteSpace(value) ? "en-US" : value.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AiSummarizeLanguageCode
|
||||||
|
{
|
||||||
|
get => _configurationService.Get(nameof(AiSummarizeLanguageCode), "en-US");
|
||||||
|
set => SetPropertyAndSave(nameof(AiSummarizeLanguageCode), string.IsNullOrWhiteSpace(value) ? "en-US" : value.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AiSummarySavePath
|
||||||
|
{
|
||||||
|
get => _configurationService.Get(nameof(AiSummarySavePath), string.Empty);
|
||||||
|
set => SetPropertyAndSave(nameof(AiSummarySavePath), value?.Trim() ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public WinoApplicationMode DefaultApplicationMode
|
public WinoApplicationMode DefaultApplicationMode
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:domain="using:Wino.Core.Domain"
|
xmlns:domain="using:Wino.Core.Domain"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:models="using:Wino.Core.Domain.Models.Ai"
|
||||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
xmlns:translations="using:Wino.Core.Domain.Models.Translations"
|
xmlns:translations="using:Wino.Core.Domain.Models.Translations"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
@@ -74,6 +75,67 @@
|
|||||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||||
</controls:SettingsCard.HeaderIcon>
|
</controls:SettingsCard.HeaderIcon>
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsExpander
|
||||||
|
Description="{x:Bind domain:Translator.SettingsAppPreferences_AiActions_Description}"
|
||||||
|
Header="{x:Bind domain:Translator.SettingsAppPreferences_AiActions_Title}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<controls:SettingsExpander.HeaderIcon>
|
||||||
|
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||||
|
</controls:SettingsExpander.HeaderIcon>
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_AiDefaultTranslationLanguage_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_AiDefaultTranslationLanguage_Title}">
|
||||||
|
<ComboBox ItemsSource="{x:Bind ViewModel.AvailableAiLanguages, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedDefaultTranslationLanguage, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:AiTranslateLanguageOption">
|
||||||
|
<TextBlock Text="{x:Bind Label}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarizeLanguage_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarizeLanguage_Title}">
|
||||||
|
<ComboBox ItemsSource="{x:Bind ViewModel.AvailableAiLanguages, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedSummarizeLanguage, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:AiTranslateLanguageOption">
|
||||||
|
<TextBlock Text="{x:Bind Label}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard
|
||||||
|
Description="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Description}"
|
||||||
|
Header="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Title}"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
VerticalContentAlignment="Stretch"
|
||||||
|
ContentAlignment="Vertical">
|
||||||
|
<StackPanel Spacing="8">
|
||||||
|
<Grid ColumnSpacing="12">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="0"
|
||||||
|
IsReadOnly="True"
|
||||||
|
PlaceholderText="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Placeholder}"
|
||||||
|
Text="{x:Bind ViewModel.SummarySavePath, Mode=OneWay}" />
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Command="{x:Bind ViewModel.BrowseSummarySavePathCommand}"
|
||||||
|
Content="{x:Bind domain:Translator.Buttons_Browse}" />
|
||||||
|
</Grid>
|
||||||
|
<TextBlock
|
||||||
|
Foreground="{ThemeResource SystemFillColorCautionBrush}"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_InvalidHint}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Visibility="{x:Bind ViewModel.HasInvalidSummarySavePath, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
|||||||
@@ -108,11 +108,11 @@ public sealed class WinoAccountApiClient : IWinoAccountApiClient, IDisposable
|
|||||||
public Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default)
|
public Task<ApiEnvelope<AiStatusResultDto>> GetAiStatusAsync(CancellationToken cancellationToken = default)
|
||||||
=> SendAuthorizedRequestAsync("api/v1/ai/status", WinoAccountApiJsonContext.Default.ApiEnvelopeAiStatusResultDto, cancellationToken);
|
=> SendAuthorizedRequestAsync("api/v1/ai/status", WinoAccountApiJsonContext.Default.ApiEnvelopeAiStatusResultDto, cancellationToken);
|
||||||
|
|
||||||
public Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, CancellationToken cancellationToken = default)
|
public Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, string targetLanguage, CancellationToken cancellationToken = default)
|
||||||
=> SendAuthorizedRequestAsync(
|
=> SendAuthorizedRequestAsync(
|
||||||
HttpMethod.Post,
|
HttpMethod.Post,
|
||||||
"api/v1/ai/summarize",
|
"api/v1/ai/summarize",
|
||||||
new SummarizeRequest(html),
|
new SummarizeRequest(html, targetLanguage),
|
||||||
WinoAccountApiJsonContext.Default.SummarizeRequest,
|
WinoAccountApiJsonContext.Default.SummarizeRequest,
|
||||||
WinoAccountApiJsonContext.Default.ApiEnvelopeAiTextResultDto,
|
WinoAccountApiJsonContext.Default.ApiEnvelopeAiTextResultDto,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|||||||
@@ -213,8 +213,8 @@ public sealed class WinoAccountProfileService : BaseDatabaseService, IWinoAccoun
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, CancellationToken cancellationToken = default)
|
public async Task<ApiEnvelope<AiTextResultDto>> SummarizeAsync(string html, string targetLanguage, CancellationToken cancellationToken = default)
|
||||||
=> await ExecuteAiOperationAsync(account => _apiClient.SummarizeAsync(html, cancellationToken), "summarize", cancellationToken).ConfigureAwait(false);
|
=> await ExecuteAiOperationAsync(account => _apiClient.SummarizeAsync(html, targetLanguage, cancellationToken), "summarize", cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
public async Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default)
|
public async Task<ApiEnvelope<AiTextResultDto>> TranslateAsync(string html, string targetLanguage, CancellationToken cancellationToken = default)
|
||||||
=> await ExecuteAiOperationAsync(account => _apiClient.TranslateAsync(html, targetLanguage, cancellationToken), "translate", cancellationToken).ConfigureAwait(false);
|
=> await ExecuteAiOperationAsync(account => _apiClient.TranslateAsync(html, targetLanguage, cancellationToken), "translate", cancellationToken).ConfigureAwait(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user