diff --git a/lib/data/models/settings_model.dart b/lib/data/models/settings_model.dart index bd291a151..9f89278fe 100644 --- a/lib/data/models/settings_model.dart +++ b/lib/data/models/settings_model.dart @@ -127,6 +127,7 @@ abstract class SettingsEntity static const EMAIL_SENDING_METHOD_MICROSOFT = 'office365'; static const EMAIL_SENDING_METHOD_POSTMARK = 'client_postmark'; static const EMAIL_SENDING_METHOD_MAILGUN = 'client_mailgun'; + static const EMAIL_SENDING_METHOD_SMTP = 'smtp'; static const LOCK_INVOICES_OFF = 'off'; static const LOCK_INVOICES_SENT = 'when_sent'; diff --git a/lib/ui/settings/email_settings.dart b/lib/ui/settings/email_settings.dart index feefc4098..65ee8d962 100644 --- a/lib/ui/settings/email_settings.dart +++ b/lib/ui/settings/email_settings.dart @@ -53,6 +53,10 @@ class _EmailSettingsState extends State { final _mailgunDomainController = TextEditingController(); final _customSendingEmailController = TextEditingController(); final _eInvoiceCertificatePassphraseController = TextEditingController(); + final _smtpHostController = TextEditingController(); + final _smtpUsernameController = TextEditingController(); + final _smtpPasswordController = TextEditingController(); + final _smtpLocalDomainController = TextEditingController(); List _controllers = []; @@ -87,6 +91,10 @@ class _EmailSettingsState extends State { _mailgunDomainController, _customSendingEmailController, _eInvoiceCertificatePassphraseController, + _smtpHostController, + _smtpUsernameController, + _smtpPasswordController, + _smtpLocalDomainController, ]; _controllers @@ -108,6 +116,10 @@ class _EmailSettingsState extends State { _mailgunDomainController.text = settings.mailgunDomain ?? ''; _eInvoiceCertificatePassphraseController.text = company.eInvoiceCertificatePassphrase; + _smtpHostController.text = company.smtpHost; + _smtpUsernameController.text = company.smtpUsername; + _smtpPasswordController.text = company.smtpPassword; + _smtpLocalDomainController.text = company.smtpLocalDomain; _controllers .forEach((dynamic controller) => controller.addListener(_onChanged)); @@ -157,7 +169,11 @@ class _EmailSettingsState extends State { ..eInvoiceCertificatePassphrase = isFiltered && eInvoiceCertificatePassphrase.isEmpty ? null - : eInvoiceCertificatePassphrase); + : eInvoiceCertificatePassphrase + ..smtpHost = _smtpHostController.text.trim() + ..smtpUsername = _smtpUsernameController.text.trim() + ..smtpPassword = _smtpPasswordController.text.trim() + ..smtpLocalDomain = _smtpLocalDomainController.text.trim()); if (company != viewModel.company) { viewModel.onCompanyChanged(company); } @@ -222,6 +238,9 @@ class _EmailSettingsState extends State { child: Text('Microsoft'), value: SettingsEntity.EMAIL_SENDING_METHOD_MICROSOFT), ], + DropdownMenuItem( + child: Text('SMTP'), + value: SettingsEntity.EMAIL_SENDING_METHOD_SMTP), DropdownMenuItem( child: Text('Postmark'), value: SettingsEntity.EMAIL_SENDING_METHOD_POSTMARK), @@ -349,6 +368,42 @@ class _EmailSettingsState extends State { value: endpoint, )) .toList()) + ] else if (settings.emailSendingMethod == + SettingsEntity.EMAIL_SENDING_METHOD_SMTP) ...[ + DecoratedFormField( + label: localization.host, + controller: _smtpHostController, + keyboardType: TextInputType.url, + onSavePressed: _onSavePressed, + validator: (value) => value.trim().isEmpty + ? localization.pleaseEnterAValue + : null, + ), + DecoratedFormField( + label: localization.username, + controller: _smtpUsernameController, + keyboardType: TextInputType.text, + onSavePressed: _onSavePressed, + validator: (value) => value.trim().isEmpty + ? localization.pleaseEnterAValue + : null, + ), + DecoratedFormField( + label: localization.password, + obscureText: true, + controller: _smtpPasswordController, + keyboardType: TextInputType.text, + onSavePressed: _onSavePressed, + validator: (value) => value.trim().isEmpty + ? localization.pleaseEnterAValue + : null, + ), + DecoratedFormField( + label: localization.localDomain, + controller: _smtpLocalDomainController, + keyboardType: TextInputType.url, + onSavePressed: _onSavePressed, + ), ], ], ), diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index abb11d0ae..4a4b757b1 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -18,6 +18,12 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'host': 'Host', + 'port': 'Port', + 'encryption': 'Encryption', + 'local_domain': 'Local Domain', + 'verify_peer': 'Verify Peer', + 'username': 'Username', 'nordigen_help': 'Note: connecting an account requires a GoCardless/Nordigen API key', 'participant_name': 'Participant Name', @@ -114232,6 +114238,30 @@ mixin LocalizationsProvider on LocaleCodeAware { _localizedValues[localeCode]!['nordigen_help'] ?? _localizedValues['en']!['nordigen_help']!; + String get host => + _localizedValues[localeCode]!['host'] ?? + _localizedValues['en']!['host']!; + + String get port => + _localizedValues[localeCode]!['port'] ?? + _localizedValues['en']!['port']!; + + String get encryption => + _localizedValues[localeCode]!['encryption'] ?? + _localizedValues['en']!['encryption']!; + + String get localDomain => + _localizedValues[localeCode]!['local_domain'] ?? + _localizedValues['en']!['local_domain']!; + + String get verifyPeer => + _localizedValues[localeCode]!['verify_peer'] ?? + _localizedValues['en']!['verify_peer']!; + + String get username => + _localizedValues[localeCode]!['username'] ?? + _localizedValues['en']!['username']!; + // STARTER: lang field - do not remove comment String lookup(String? key) {