Emaıl templates.
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
|
namespace Wino.Core.Domain.Entities.Mail;
|
||||||
|
|
||||||
|
public class EmailTemplate
|
||||||
|
{
|
||||||
|
[PrimaryKey]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string HtmlContent { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -35,6 +35,8 @@ public enum WinoPage
|
|||||||
EventDetailsPage,
|
EventDetailsPage,
|
||||||
CalendarEventComposePage,
|
CalendarEventComposePage,
|
||||||
SignatureAndEncryptionPage,
|
SignatureAndEncryptionPage,
|
||||||
|
EmailTemplatesPage,
|
||||||
|
CreateEmailTemplatePage,
|
||||||
StoragePage,
|
StoragePage,
|
||||||
WelcomePageV2,
|
WelcomePageV2,
|
||||||
WelcomeHostPage,
|
WelcomeHostPage,
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
|
||||||
|
namespace Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
|
public interface IEmailTemplateService
|
||||||
|
{
|
||||||
|
Task<List<EmailTemplate>> GetEmailTemplatesAsync();
|
||||||
|
Task<EmailTemplate> GetEmailTemplateAsync(Guid templateId);
|
||||||
|
Task<EmailTemplate> CreateEmailTemplateAsync(EmailTemplate template);
|
||||||
|
Task<EmailTemplate> UpdateEmailTemplateAsync(EmailTemplate template);
|
||||||
|
Task<EmailTemplate> DeleteEmailTemplateAsync(EmailTemplate template);
|
||||||
|
}
|
||||||
@@ -254,6 +254,8 @@
|
|||||||
"DialogMessage_DeleteAccountConfirmationTitle": "All data associated with this account will be deleted from disk permanently.",
|
"DialogMessage_DeleteAccountConfirmationTitle": "All data associated with this account will be deleted from disk permanently.",
|
||||||
"DialogMessage_DeleteRecurringSeriesMessage": "This will delete all events in the series. Do you want to continue?",
|
"DialogMessage_DeleteRecurringSeriesMessage": "This will delete all events in the series. Do you want to continue?",
|
||||||
"DialogMessage_DeleteRecurringSeriesTitle": "Delete Recurring Series",
|
"DialogMessage_DeleteRecurringSeriesTitle": "Delete Recurring Series",
|
||||||
|
"DialogMessage_DeleteEmailTemplateConfirmationMessage": "Delete template \"{0}\"?",
|
||||||
|
"DialogMessage_DeleteEmailTemplateConfirmationTitle": "Delete Email Template",
|
||||||
"DialogMessage_DiscardDraftConfirmationMessage": "This draft will be discarded. Do you want to continue?",
|
"DialogMessage_DiscardDraftConfirmationMessage": "This draft will be discarded. Do you want to continue?",
|
||||||
"DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft",
|
"DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft",
|
||||||
"DialogMessage_EmptySubjectConfirmation": "Missing Subject",
|
"DialogMessage_EmptySubjectConfirmation": "Missing Subject",
|
||||||
@@ -849,6 +851,19 @@
|
|||||||
"SettingsShowSenderPictures_Title": "Show Sender Avatars",
|
"SettingsShowSenderPictures_Title": "Show Sender Avatars",
|
||||||
"SettingsEnableGravatarAvatars_Title": "Gravatar",
|
"SettingsEnableGravatarAvatars_Title": "Gravatar",
|
||||||
"SettingsEnableGravatarAvatars_Description": "Use gravatar (if available) as sender picture",
|
"SettingsEnableGravatarAvatars_Description": "Use gravatar (if available) as sender picture",
|
||||||
|
"SettingsEmailTemplates_Title": "Email Templates",
|
||||||
|
"SettingsEmailTemplates_Description": "Manage e-mail templates",
|
||||||
|
"SettingsEmailTemplates_CreatePageTitle": "New template",
|
||||||
|
"SettingsEmailTemplates_EditPageTitle": "Edit template",
|
||||||
|
"SettingsEmailTemplates_NewTemplateTitle": "New template",
|
||||||
|
"SettingsEmailTemplates_NewTemplateDescription": "Create a new e-mail template",
|
||||||
|
"SettingsEmailTemplates_NameTitle": "Name",
|
||||||
|
"SettingsEmailTemplates_NamePlaceholder": "Template name",
|
||||||
|
"SettingsEmailTemplates_DescriptionTitle": "Description",
|
||||||
|
"SettingsEmailTemplates_DescriptionPlaceholder": "Optional description",
|
||||||
|
"SettingsEmailTemplates_ContentTitle": "Template content",
|
||||||
|
"SettingsEmailTemplates_ContentDescription": "Edit the HTML content for this template.",
|
||||||
|
"SettingsEmailTemplates_NameRequired": "Template name is required.",
|
||||||
"SettingsEnableFavicons_Title": "Domain icons (Favicons)",
|
"SettingsEnableFavicons_Title": "Domain icons (Favicons)",
|
||||||
"SettingsEnableFavicons_Description": "Use domain favicons (if available) as sender picture",
|
"SettingsEnableFavicons_Description": "Use domain favicons (if available) as sender picture",
|
||||||
"SettingsMailList_ClearAvatarsCache_Button": "Clear cached avatars",
|
"SettingsMailList_ClearAvatarsCache_Button": "Clear cached avatars",
|
||||||
@@ -1006,6 +1021,7 @@
|
|||||||
"Composer_CertificateExpires": "Expires on: ",
|
"Composer_CertificateExpires": "Expires on: ",
|
||||||
"Composer_SmimeSignature": "S/MIME Signature",
|
"Composer_SmimeSignature": "S/MIME Signature",
|
||||||
"Composer_SmimeEncryption": "S/MIME Encryption",
|
"Composer_SmimeEncryption": "S/MIME Encryption",
|
||||||
|
"Composer_EmailTemplatesPlaceholder": "E-mail templates",
|
||||||
"SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval",
|
"SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval",
|
||||||
"SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail.",
|
"SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail.",
|
||||||
"ContactsPage_Title": "Contacts",
|
"ContactsPage_Title": "Contacts",
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel
|
|||||||
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
|
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
|
||||||
WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title,
|
WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title,
|
||||||
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
|
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
|
||||||
|
WinoPage.EmailTemplatesPage => Translator.SettingsEmailTemplates_Title,
|
||||||
WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title,
|
WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title,
|
||||||
WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title,
|
WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title,
|
||||||
WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title,
|
WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title,
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
|
|
||||||
public bool AreCertificatesAvailable => AvailableCertificates.Count > 0;
|
public bool AreCertificatesAvailable => AvailableCertificates.Count > 0;
|
||||||
|
|
||||||
|
public ObservableCollection<EmailTemplate> AvailableEmailTemplates { get; } = [];
|
||||||
public ObservableCollection<MailAttachmentViewModel> IncludedAttachments { get; set; } = [];
|
public ObservableCollection<MailAttachmentViewModel> IncludedAttachments { get; set; } = [];
|
||||||
public ObservableCollection<MailAccount> Accounts { get; set; } = [];
|
public ObservableCollection<MailAccount> Accounts { get; set; } = [];
|
||||||
public ObservableCollection<AccountContact> ToItems { get; set; } = [];
|
public ObservableCollection<AccountContact> ToItems { get; set; } = [];
|
||||||
@@ -148,6 +149,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
private readonly IFileService _fileService;
|
private readonly IFileService _fileService;
|
||||||
private readonly IFolderService _folderService;
|
private readonly IFolderService _folderService;
|
||||||
private readonly IAccountService _accountService;
|
private readonly IAccountService _accountService;
|
||||||
|
private readonly IEmailTemplateService _emailTemplateService;
|
||||||
private readonly IWinoRequestDelegator _worker;
|
private readonly IWinoRequestDelegator _worker;
|
||||||
public readonly IFontService FontService;
|
public readonly IFontService FontService;
|
||||||
public readonly IPreferencesService PreferencesService;
|
public readonly IPreferencesService PreferencesService;
|
||||||
@@ -161,6 +163,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
INativeAppService nativeAppService,
|
INativeAppService nativeAppService,
|
||||||
IFolderService folderService,
|
IFolderService folderService,
|
||||||
IAccountService accountService,
|
IAccountService accountService,
|
||||||
|
IEmailTemplateService emailTemplateService,
|
||||||
IWinoRequestDelegator worker,
|
IWinoRequestDelegator worker,
|
||||||
IContactService contactService,
|
IContactService contactService,
|
||||||
IFontService fontService,
|
IFontService fontService,
|
||||||
@@ -178,6 +181,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
_mimeFileService = mimeFileService;
|
_mimeFileService = mimeFileService;
|
||||||
_fileService = fileService;
|
_fileService = fileService;
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
|
_emailTemplateService = emailTemplateService;
|
||||||
_worker = worker;
|
_worker = worker;
|
||||||
_smimeCertificateService = smimeCertificateService;
|
_smimeCertificateService = smimeCertificateService;
|
||||||
|
|
||||||
@@ -520,6 +524,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
CurrentMailDraftItem = mailItem;
|
CurrentMailDraftItem = mailItem;
|
||||||
|
|
||||||
await UpdatePendingOperationStateAsync();
|
await UpdatePendingOperationStateAsync();
|
||||||
|
await LoadEmailTemplatesAsync();
|
||||||
await TryPrepareComposeAsync(true);
|
await TryPrepareComposeAsync(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,9 +544,25 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
|||||||
// Set the new draft item and prepare it.
|
// Set the new draft item and prepare it.
|
||||||
CurrentMailDraftItem = message.MailItemViewModel;
|
CurrentMailDraftItem = message.MailItemViewModel;
|
||||||
await UpdatePendingOperationStateAsync();
|
await UpdatePendingOperationStateAsync();
|
||||||
|
await LoadEmailTemplatesAsync();
|
||||||
await TryPrepareComposeAsync(true);
|
await TryPrepareComposeAsync(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task LoadEmailTemplatesAsync()
|
||||||
|
{
|
||||||
|
var templates = await _emailTemplateService.GetEmailTemplatesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
await ExecuteUIThread(() =>
|
||||||
|
{
|
||||||
|
AvailableEmailTemplates.Clear();
|
||||||
|
|
||||||
|
foreach (var template in templates)
|
||||||
|
{
|
||||||
|
AvailableEmailTemplates.Add(template);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async void Receive(SynchronizationActionsAdded message)
|
public async void Receive(SynchronizationActionsAdded message)
|
||||||
{
|
{
|
||||||
if (!ShouldTrackDraftSynchronizationState(message.AccountId))
|
if (!ShouldTrackDraftSynchronizationState(message.AccountId))
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
|
namespace Wino.Mail.ViewModels;
|
||||||
|
|
||||||
|
public partial class CreateEmailTemplatePageViewModel(
|
||||||
|
IEmailTemplateService emailTemplateService,
|
||||||
|
IMailDialogService dialogService,
|
||||||
|
INavigationService navigationService) : MailBaseViewModel
|
||||||
|
{
|
||||||
|
private readonly IEmailTemplateService _emailTemplateService = emailTemplateService;
|
||||||
|
private readonly IMailDialogService _dialogService = dialogService;
|
||||||
|
|
||||||
|
private EmailTemplate _editingTemplate;
|
||||||
|
|
||||||
|
public INavigationService NavigationService { get; } = navigationService;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string TemplateName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string TemplateDescription { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool IsExistingTemplate { get; set; }
|
||||||
|
|
||||||
|
public async Task<string> LoadAsync(object parameter)
|
||||||
|
{
|
||||||
|
EmailTemplate template = null;
|
||||||
|
|
||||||
|
var templateId = parameter switch
|
||||||
|
{
|
||||||
|
Guid guid when guid != Guid.Empty => guid,
|
||||||
|
string value when Guid.TryParse(value, out var parsedGuid) => parsedGuid,
|
||||||
|
EmailTemplate emailTemplate when emailTemplate.Id != Guid.Empty => emailTemplate.Id,
|
||||||
|
_ => Guid.Empty
|
||||||
|
};
|
||||||
|
|
||||||
|
if (templateId != Guid.Empty)
|
||||||
|
{
|
||||||
|
template = await _emailTemplateService.GetEmailTemplateAsync(templateId).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_editingTemplate = template;
|
||||||
|
|
||||||
|
await ExecuteUIThread(() =>
|
||||||
|
{
|
||||||
|
IsExistingTemplate = template != null;
|
||||||
|
TemplateName = template?.Name ?? string.Empty;
|
||||||
|
TemplateDescription = template?.Description ?? string.Empty;
|
||||||
|
});
|
||||||
|
|
||||||
|
return template?.HtmlContent ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveAsync(string htmlContent)
|
||||||
|
{
|
||||||
|
var trimmedName = TemplateName?.Trim() ?? string.Empty;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(trimmedName))
|
||||||
|
{
|
||||||
|
_dialogService.InfoBarMessage(
|
||||||
|
Translator.GeneralTitle_Error,
|
||||||
|
Translator.SettingsEmailTemplates_NameRequired,
|
||||||
|
InfoBarMessageType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var template = _editingTemplate ?? new EmailTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid()
|
||||||
|
};
|
||||||
|
|
||||||
|
template.Name = trimmedName;
|
||||||
|
template.Description = TemplateDescription?.Trim() ?? string.Empty;
|
||||||
|
template.HtmlContent = htmlContent ?? string.Empty;
|
||||||
|
|
||||||
|
if (_editingTemplate == null)
|
||||||
|
{
|
||||||
|
await _emailTemplateService.CreateEmailTemplateAsync(template).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _emailTemplateService.UpdateEmailTemplateAsync(template).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_editingTemplate = template;
|
||||||
|
NavigationService.GoBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync()
|
||||||
|
{
|
||||||
|
if (_editingTemplate == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var shouldDelete = await _dialogService.ShowConfirmationDialogAsync(
|
||||||
|
string.Format(Translator.DialogMessage_DeleteEmailTemplateConfirmationMessage, _editingTemplate.Name),
|
||||||
|
Translator.DialogMessage_DeleteEmailTemplateConfirmationTitle,
|
||||||
|
Translator.Buttons_Delete).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!shouldDelete)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await _emailTemplateService.DeleteEmailTemplateAsync(_editingTemplate).ConfigureAwait(false);
|
||||||
|
NavigationService.GoBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Messaging.Client.Navigation;
|
||||||
|
|
||||||
|
namespace Wino.Mail.ViewModels;
|
||||||
|
|
||||||
|
public partial class EmailTemplatesPageViewModel(IEmailTemplateService emailTemplateService) : MailBaseViewModel
|
||||||
|
{
|
||||||
|
private readonly IEmailTemplateService _emailTemplateService = emailTemplateService;
|
||||||
|
|
||||||
|
public ObservableCollection<EmailTemplate> EmailTemplates { get; } = [];
|
||||||
|
|
||||||
|
public async Task LoadAsync()
|
||||||
|
{
|
||||||
|
var templates = await _emailTemplateService.GetEmailTemplatesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
await ExecuteUIThread(() =>
|
||||||
|
{
|
||||||
|
EmailTemplates.Clear();
|
||||||
|
|
||||||
|
foreach (var template in templates)
|
||||||
|
{
|
||||||
|
EmailTemplates.Add(template);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateTemplate()
|
||||||
|
{
|
||||||
|
Messenger.Send(new BreadcrumbNavigationRequested(
|
||||||
|
Translator.SettingsEmailTemplates_CreatePageTitle,
|
||||||
|
WinoPage.CreateEmailTemplatePage));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenTemplate(EmailTemplate template)
|
||||||
|
{
|
||||||
|
if (template == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var title = string.IsNullOrWhiteSpace(template.Name)
|
||||||
|
? Translator.SettingsEmailTemplates_EditPageTitle
|
||||||
|
: template.Name;
|
||||||
|
|
||||||
|
Messenger.Send(new BreadcrumbNavigationRequested(
|
||||||
|
title,
|
||||||
|
WinoPage.CreateEmailTemplatePage,
|
||||||
|
template.Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,6 +167,8 @@ public partial class App : WinoApplication,
|
|||||||
services.AddTransient(typeof(AliasManagementPageViewModel));
|
services.AddTransient(typeof(AliasManagementPageViewModel));
|
||||||
services.AddTransient(typeof(ContactsPageViewModel));
|
services.AddTransient(typeof(ContactsPageViewModel));
|
||||||
services.AddTransient(typeof(SignatureAndEncryptionPageViewModel));
|
services.AddTransient(typeof(SignatureAndEncryptionPageViewModel));
|
||||||
|
services.AddTransient(typeof(EmailTemplatesPageViewModel));
|
||||||
|
services.AddTransient(typeof(CreateEmailTemplatePageViewModel));
|
||||||
services.AddTransient(typeof(CalendarPageViewModel));
|
services.AddTransient(typeof(CalendarPageViewModel));
|
||||||
services.AddTransient(typeof(CalendarSettingsPageViewModel));
|
services.AddTransient(typeof(CalendarSettingsPageViewModel));
|
||||||
services.AddTransient(typeof(CalendarAccountSettingsPageViewModel));
|
services.AddTransient(typeof(CalendarAccountSettingsPageViewModel));
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
|||||||
WinoPage.KeyboardShortcutsPage => typeof(KeyboardShortcutsPage),
|
WinoPage.KeyboardShortcutsPage => typeof(KeyboardShortcutsPage),
|
||||||
WinoPage.ContactsPage => typeof(ContactsPage),
|
WinoPage.ContactsPage => typeof(ContactsPage),
|
||||||
WinoPage.SignatureAndEncryptionPage => typeof(SignatureAndEncryptionPage),
|
WinoPage.SignatureAndEncryptionPage => typeof(SignatureAndEncryptionPage),
|
||||||
|
WinoPage.EmailTemplatesPage => typeof(EmailTemplatesPage),
|
||||||
|
WinoPage.CreateEmailTemplatePage => typeof(CreateEmailTemplatePage),
|
||||||
WinoPage.StoragePage => typeof(StoragePage),
|
WinoPage.StoragePage => typeof(StoragePage),
|
||||||
WinoPage.WelcomeHostPage => typeof(WelcomeHostPage),
|
WinoPage.WelcomeHostPage => typeof(WelcomeHostPage),
|
||||||
WinoPage.ProviderSelectionPage => typeof(ProviderSelectionPage),
|
WinoPage.ProviderSelectionPage => typeof(ProviderSelectionPage),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using Wino.Mail.ViewModels;
|
||||||
|
|
||||||
|
namespace Wino.Views.Abstract;
|
||||||
|
|
||||||
|
public abstract class CreateEmailTemplatePageAbstract : SettingsPageBase<CreateEmailTemplatePageViewModel>
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using Wino.Mail.ViewModels;
|
||||||
|
|
||||||
|
namespace Wino.Views.Abstract;
|
||||||
|
|
||||||
|
public abstract class EmailTemplatesPageAbstract : SettingsPageBase<EmailTemplatesPageViewModel>
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -138,6 +138,21 @@
|
|||||||
CommandAlignment="Right"
|
CommandAlignment="Right"
|
||||||
IsDynamicOverflowEnabled="True"
|
IsDynamicOverflowEnabled="True"
|
||||||
OverflowButtonAlignment="Left">
|
OverflowButtonAlignment="Left">
|
||||||
|
<AppBarElementContainer Visibility="{x:Bind helpers:XamlHelpers.CountToVisibilityConverter(ViewModel.AvailableEmailTemplates.Count), Mode=OneWay}">
|
||||||
|
<ComboBox
|
||||||
|
x:Name="EmailTemplatesComboBox"
|
||||||
|
MinWidth="220"
|
||||||
|
Margin="0,8,8,0"
|
||||||
|
ItemsSource="{x:Bind ViewModel.AvailableEmailTemplates, Mode=OneWay}"
|
||||||
|
PlaceholderText="{x:Bind domain:Translator.Composer_EmailTemplatesPlaceholder}"
|
||||||
|
SelectionChanged="EmailTemplateSelectionChanged">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="mail:EmailTemplate">
|
||||||
|
<TextBlock Text="{x:Bind Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</AppBarElementContainer>
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
MinWidth="40"
|
MinWidth="40"
|
||||||
HorizontalContentAlignment="Center"
|
HorizontalContentAlignment="Center"
|
||||||
@@ -145,9 +160,7 @@
|
|||||||
Visibility="{x:Bind ViewModel.IsDraftBusy, Mode=OneWay}">
|
Visibility="{x:Bind ViewModel.IsDraftBusy, Mode=OneWay}">
|
||||||
<ProgressRing IsActive="True" />
|
<ProgressRing IsActive="True" />
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarButton
|
<AppBarButton Click="ToggleEditorThemeClicked" ToolTipService.ToolTip="{x:Bind GetEditorThemeToolTip(WebViewEditor.IsEditorDarkMode), Mode=OneWay}">
|
||||||
Click="ToggleEditorThemeClicked"
|
|
||||||
ToolTipService.ToolTip="{x:Bind GetEditorThemeToolTip(WebViewEditor.IsEditorDarkMode), Mode=OneWay}">
|
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<coreControls:WinoFontIcon Icon="{x:Bind GetEditorThemeIcon(WebViewEditor.IsEditorDarkMode), Mode=OneWay}" />
|
<coreControls:WinoFontIcon Icon="{x:Bind GetEditorThemeIcon(WebViewEditor.IsEditorDarkMode), Mode=OneWay}" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Windows.Foundation;
|
|||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.UI.Core.Preview;
|
using Windows.UI.Core.Preview;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
using Wino.Core.Domain.Entities.Shared;
|
using Wino.Core.Domain.Entities.Shared;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
using Wino.Core.Domain.Models.Reader;
|
||||||
using Wino.Mail.ViewModels.Data;
|
using Wino.Mail.ViewModels.Data;
|
||||||
@@ -53,6 +54,15 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
|||||||
WebViewEditor.ToggleEditorTheme();
|
WebViewEditor.ToggleEditorTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void EmailTemplateSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not ComboBox comboBox || comboBox.SelectedItem is not EmailTemplate template)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await WebViewEditor.RenderHtmlAsync(template.HtmlContent);
|
||||||
|
comboBox.SelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
private async void GlobalFocusManagerGotFocus(object? sender, FocusManagerGotFocusEventArgs e)
|
private async void GlobalFocusManagerGotFocus(object? sender, FocusManagerGotFocusEventArgs e)
|
||||||
{
|
{
|
||||||
// In order to delegate cursor to the inner editor for WebView2.
|
// In order to delegate cursor to the inner editor for WebView2.
|
||||||
|
|||||||
@@ -14,11 +14,14 @@
|
|||||||
|
|
||||||
<ScrollViewer Padding="0,0,16,0" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer Padding="0,0,16,0" VerticalScrollBarVisibility="Auto">
|
||||||
<StackPanel Margin="0,8,0,24" Spacing="4">
|
<StackPanel Margin="0,8,0,24" Spacing="4">
|
||||||
<StackPanel.ChildrenTransitions>
|
<!--<StackPanel.ChildrenTransitions>
|
||||||
<TransitionCollection>
|
<TransitionCollection>
|
||||||
<EntranceThemeTransition FromVerticalOffset="50" IsStaggeringEnabled="True" />
|
<PopupThemeTransition />
|
||||||
|
-->
|
||||||
|
<!--<EntranceThemeTransition FromVerticalOffset="50" IsStaggeringEnabled="True" />-->
|
||||||
|
<!--
|
||||||
</TransitionCollection>
|
</TransitionCollection>
|
||||||
</StackPanel.ChildrenTransitions>
|
</StackPanel.ChildrenTransitions>-->
|
||||||
|
|
||||||
<!-- Hero Banner - Windows 11 style -->
|
<!-- Hero Banner - Windows 11 style -->
|
||||||
<Grid
|
<Grid
|
||||||
@@ -46,9 +49,7 @@
|
|||||||
Margin="20,0,0,0"
|
Margin="20,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Spacing="4">
|
Spacing="4">
|
||||||
<TextBlock
|
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Wino Mail" />
|
||||||
Style="{StaticResource TitleTextBlockStyle}"
|
|
||||||
Text="Wino Mail" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
Style="{StaticResource BodyTextBlockStyle}"
|
Style="{StaticResource BodyTextBlockStyle}"
|
||||||
@@ -62,12 +63,8 @@
|
|||||||
Margin="0,8,0,0"
|
Margin="0,8,0,0"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Spacing="8">
|
Spacing="8">
|
||||||
<HyperlinkButton
|
<HyperlinkButton Content="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" />
|
||||||
Content="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}"
|
<HyperlinkButton Content="{x:Bind domain:Translator.SettingsPaypal_Title}" NavigateUri="{x:Bind ViewModel.PaypalUrl, Mode=OneWay}" />
|
||||||
NavigateUri="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" />
|
|
||||||
<HyperlinkButton
|
|
||||||
Content="{x:Bind domain:Translator.SettingsPaypal_Title}"
|
|
||||||
NavigateUri="{x:Bind ViewModel.PaypalUrl, Mode=OneWay}" />
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -194,6 +191,17 @@
|
|||||||
</controls:SettingsCard.HeaderIcon>
|
</controls:SettingsCard.HeaderIcon>
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard
|
||||||
|
Click="SettingOptionClicked"
|
||||||
|
Description="{x:Bind domain:Translator.SettingsEmailTemplates_Description}"
|
||||||
|
Header="{x:Bind domain:Translator.SettingsEmailTemplates_Title}"
|
||||||
|
IsClickEnabled="True"
|
||||||
|
Tag="{x:Bind enums:WinoPage.EmailTemplatesPage}">
|
||||||
|
<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
<controls:SettingsCard
|
<controls:SettingsCard
|
||||||
Click="SettingOptionClicked"
|
Click="SettingOptionClicked"
|
||||||
Description="{x:Bind domain:Translator.SettingsStorage_Description}"
|
Description="{x:Bind domain:Translator.SettingsStorage_Description}"
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<abstract:CreateEmailTemplatePageAbstract
|
||||||
|
x:Class="Wino.Views.Settings.CreateEmailTemplatePage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:abstract="using:Wino.Views.Abstract"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:domain="using:Wino.Core.Domain"
|
||||||
|
xmlns:helpers="using:Wino.Helpers"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:mailControls="using:Wino.Mail.Controls"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid RowSpacing="12">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<controls:SettingsCard Grid.Row="0" Header="{x:Bind domain:Translator.SettingsEmailTemplates_NameTitle}" IsClickEnabled="False">
|
||||||
|
<TextBox
|
||||||
|
x:Name="TemplateNameTextBox"
|
||||||
|
PlaceholderText="{x:Bind domain:Translator.SettingsEmailTemplates_NamePlaceholder}"
|
||||||
|
Text="{x:Bind ViewModel.TemplateName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard Grid.Row="1" Header="{x:Bind domain:Translator.SettingsEmailTemplates_DescriptionTitle}" IsClickEnabled="False">
|
||||||
|
<TextBox
|
||||||
|
AcceptsReturn="True"
|
||||||
|
PlaceholderText="{x:Bind domain:Translator.SettingsEmailTemplates_DescriptionPlaceholder}"
|
||||||
|
Text="{x:Bind ViewModel.TemplateDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Spacing="8">
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{x:Bind domain:Translator.SettingsEmailTemplates_ContentTitle}" />
|
||||||
|
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind domain:Translator.SettingsEmailTemplates_ContentDescription}" />
|
||||||
|
<mailControls:EditorTabbedCommandBarControl CommandTarget="{x:Bind WebViewEditor}" />
|
||||||
|
<Border
|
||||||
|
MinHeight="420"
|
||||||
|
Background="{ThemeResource WinoContentZoneBackgroud}"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="7">
|
||||||
|
<mailControls:WebViewEditorControl x:Name="WebViewEditor" />
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="3"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="8">
|
||||||
|
<Button
|
||||||
|
Click="DeleteClicked"
|
||||||
|
Content="{x:Bind domain:Translator.Buttons_Delete}"
|
||||||
|
Style="{StaticResource AccentButtonStyle}"
|
||||||
|
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(ViewModel.IsExistingTemplate), Mode=OneWay}" />
|
||||||
|
<Button
|
||||||
|
Click="SaveClicked"
|
||||||
|
Content="{x:Bind domain:Translator.Buttons_Save}"
|
||||||
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</abstract:CreateEmailTemplatePageAbstract>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using Wino.Views.Abstract;
|
||||||
|
|
||||||
|
namespace Wino.Views.Settings;
|
||||||
|
|
||||||
|
public sealed partial class CreateEmailTemplatePage : CreateEmailTemplatePageAbstract
|
||||||
|
{
|
||||||
|
public CreateEmailTemplatePage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnNavigatedTo(e);
|
||||||
|
|
||||||
|
var htmlContent = await ViewModel.LoadAsync(e.Parameter);
|
||||||
|
await WebViewEditor.RenderHtmlAsync(htmlContent);
|
||||||
|
|
||||||
|
if (!ViewModel.IsExistingTemplate)
|
||||||
|
{
|
||||||
|
TemplateNameTextBox.Focus(FocusState.Programmatic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnNavigatingFrom(e);
|
||||||
|
WebViewEditor.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SaveClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
await ViewModel.SaveAsync(await WebViewEditor.GetHtmlBodyAsync() ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void DeleteClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
await ViewModel.DeleteAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<abstract:EmailTemplatesPageAbstract
|
||||||
|
x:Class="Wino.Views.Settings.EmailTemplatesPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:abstract="using:Wino.Views.Abstract"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:domain="using:Wino.Core.Domain"
|
||||||
|
xmlns:entities="using:Wino.Core.Domain.Entities.Mail"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<ScrollViewer>
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
<controls:SettingsCard
|
||||||
|
Click="NewTemplateClicked"
|
||||||
|
Description="{x:Bind domain:Translator.SettingsEmailTemplates_NewTemplateDescription}"
|
||||||
|
Header="{x:Bind domain:Translator.SettingsEmailTemplates_NewTemplateTitle}"
|
||||||
|
IsClickEnabled="True">
|
||||||
|
<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon Glyph="" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<ItemsControl ItemsSource="{x:Bind ViewModel.EmailTemplates, Mode=OneWay}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="entities:EmailTemplate">
|
||||||
|
<controls:SettingsCard
|
||||||
|
Click="TemplateClicked"
|
||||||
|
Description="{x:Bind Description}"
|
||||||
|
Header="{x:Bind Name}"
|
||||||
|
IsClickEnabled="True"
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Tag="{x:Bind}">
|
||||||
|
<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon Glyph="" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</abstract:EmailTemplatesPageAbstract>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Views.Abstract;
|
||||||
|
|
||||||
|
namespace Wino.Views.Settings;
|
||||||
|
|
||||||
|
public sealed partial class EmailTemplatesPage : EmailTemplatesPageAbstract
|
||||||
|
{
|
||||||
|
public EmailTemplatesPage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnNavigatedTo(e);
|
||||||
|
await ViewModel.LoadAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewTemplateClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ViewModel.CreateTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TemplateClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is FrameworkElement element && element.Tag is EmailTemplate template)
|
||||||
|
{
|
||||||
|
ViewModel.OpenTemplate(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,6 +50,9 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
|||||||
case WinoPage.StoragePage:
|
case WinoPage.StoragePage:
|
||||||
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
|
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
|
||||||
break;
|
break;
|
||||||
|
case WinoPage.EmailTemplatesPage:
|
||||||
|
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsEmailTemplates_Title, WinoPage.EmailTemplatesPage));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -375,6 +375,12 @@
|
|||||||
<Page Update="Views\Settings\AppPreferencesPage.xaml">
|
<Page Update="Views\Settings\AppPreferencesPage.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Update="Views\Settings\CreateEmailTemplatePage.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Views\Settings\EmailTemplatesPage.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Update="Views\Settings\EditAccountDetailsPage.xaml">
|
<Page Update="Views\Settings\EditAccountDetailsPage.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public class DatabaseService : IDatabaseService
|
|||||||
Connection.CreateTableAsync<ContactGroupMember>(),
|
Connection.CreateTableAsync<ContactGroupMember>(),
|
||||||
Connection.CreateTableAsync<CustomServerInformation>(),
|
Connection.CreateTableAsync<CustomServerInformation>(),
|
||||||
Connection.CreateTableAsync<AccountSignature>(),
|
Connection.CreateTableAsync<AccountSignature>(),
|
||||||
|
Connection.CreateTableAsync<EmailTemplate>(),
|
||||||
Connection.CreateTableAsync<MergedInbox>(),
|
Connection.CreateTableAsync<MergedInbox>(),
|
||||||
Connection.CreateTableAsync<MailAccountPreferences>(),
|
Connection.CreateTableAsync<MailAccountPreferences>(),
|
||||||
Connection.CreateTableAsync<MailAccountAlias>(),
|
Connection.CreateTableAsync<MailAccountAlias>(),
|
||||||
@@ -200,6 +201,7 @@ SET {nameof(KeyboardShortcut.Action)} =
|
|||||||
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccount_Order ON MailAccount([Order])").ConfigureAwait(false);
|
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccount_Order ON MailAccount([Order])").ConfigureAwait(false);
|
||||||
|
|
||||||
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_AccountSignature_MailAccountId ON AccountSignature(MailAccountId)").ConfigureAwait(false);
|
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_AccountSignature_MailAccountId ON AccountSignature(MailAccountId)").ConfigureAwait(false);
|
||||||
|
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_EmailTemplate_Name ON EmailTemplate(Name)").ConfigureAwait(false);
|
||||||
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccountAlias_AccountId ON MailAccountAlias(AccountId)").ConfigureAwait(false);
|
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccountAlias_AccountId ON MailAccountAlias(AccountId)").ConfigureAwait(false);
|
||||||
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccountAlias_AccountId_AliasAddress ON MailAccountAlias(AccountId, AliasAddress)").ConfigureAwait(false);
|
await Connection.ExecuteAsync("CREATE INDEX IF NOT EXISTS IX_MailAccountAlias_AccountId_AliasAddress ON MailAccountAlias(AccountId, AliasAddress)").ConfigureAwait(false);
|
||||||
await Connection.ExecuteAsync("CREATE UNIQUE INDEX IF NOT EXISTS IX_MailAccountPreferences_AccountId ON MailAccountPreferences(AccountId)").ConfigureAwait(false);
|
await Connection.ExecuteAsync("CREATE UNIQUE INDEX IF NOT EXISTS IX_MailAccountPreferences_AccountId ON MailAccountPreferences(AccountId)").ConfigureAwait(false);
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
|
namespace Wino.Services;
|
||||||
|
|
||||||
|
public class EmailTemplateService(IDatabaseService databaseService) : BaseDatabaseService(databaseService), IEmailTemplateService
|
||||||
|
{
|
||||||
|
public Task<List<EmailTemplate>> GetEmailTemplatesAsync()
|
||||||
|
{
|
||||||
|
return Connection.Table<EmailTemplate>()
|
||||||
|
.OrderBy(t => t.Name)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EmailTemplate> GetEmailTemplateAsync(Guid templateId)
|
||||||
|
{
|
||||||
|
return Connection.Table<EmailTemplate>()
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EmailTemplate> CreateEmailTemplateAsync(EmailTemplate template)
|
||||||
|
{
|
||||||
|
await Connection.InsertAsync(template, typeof(EmailTemplate)).ConfigureAwait(false);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EmailTemplate> UpdateEmailTemplateAsync(EmailTemplate template)
|
||||||
|
{
|
||||||
|
await Connection.UpdateAsync(template, typeof(EmailTemplate)).ConfigureAwait(false);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EmailTemplate> DeleteEmailTemplateAsync(EmailTemplate template)
|
||||||
|
{
|
||||||
|
await Connection.DeleteAsync<EmailTemplate>(template.Id).ConfigureAwait(false);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ public static class ServicesContainerSetup
|
|||||||
services.AddTransient<IAccountService, AccountService>();
|
services.AddTransient<IAccountService, AccountService>();
|
||||||
services.AddTransient<IContactService, ContactService>();
|
services.AddTransient<IContactService, ContactService>();
|
||||||
services.AddTransient<ISignatureService, SignatureService>();
|
services.AddTransient<ISignatureService, SignatureService>();
|
||||||
|
services.AddTransient<IEmailTemplateService, EmailTemplateService>();
|
||||||
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
||||||
services.AddTransient<ISpecialImapProviderConfigResolver, SpecialImapProviderConfigResolver>();
|
services.AddTransient<ISpecialImapProviderConfigResolver, SpecialImapProviderConfigResolver>();
|
||||||
services.AddTransient<IKeyboardShortcutService, KeyboardShortcutService>();
|
services.AddTransient<IKeyboardShortcutService, KeyboardShortcutService>();
|
||||||
|
|||||||
Reference in New Issue
Block a user