Browse Source

Merge pull request #985 from nextcloud/refactor/neon/l10n

refactor l10n handling
pull/990/head
Nikolas Rimikis 2 years ago committed by GitHub
parent
commit
c2cabdfb42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .husky/pre-commit
  2. 6
      packages/app/l10n.yaml
  3. 1
      packages/neon/neon/l10n.yaml
  4. 38
      packages/neon/neon/lib/l10n/localizations.dart
  5. 4
      packages/neon/neon/lib/l10n/localizations_en.dart
  6. 4
      packages/neon/neon/lib/src/app.dart
  7. 6
      packages/neon/neon/lib/src/models/app_implementation.dart
  8. 14
      packages/neon/neon/lib/src/pages/account_settings.dart
  9. 8
      packages/neon/neon/lib/src/pages/home.dart
  10. 8
      packages/neon/neon/lib/src/pages/login.dart
  11. 10
      packages/neon/neon/lib/src/pages/login_check_account.dart
  12. 20
      packages/neon/neon/lib/src/pages/login_check_server_status.dart
  13. 4
      packages/neon/neon/lib/src/pages/login_flow.dart
  14. 2
      packages/neon/neon/lib/src/pages/login_qr_code.dart
  15. 6
      packages/neon/neon/lib/src/pages/nextcloud_app_settings.dart
  16. 2
      packages/neon/neon/lib/src/pages/route_not_found.dart
  17. 38
      packages/neon/neon/lib/src/pages/settings.dart
  18. 4
      packages/neon/neon/lib/src/sort_box/sort_box_order_option_values.dart
  19. 4
      packages/neon/neon/lib/src/utils/account_options.dart
  20. 4
      packages/neon/neon/lib/src/utils/confirmation_dialog.dart
  21. 2
      packages/neon/neon/lib/src/utils/exceptions.dart
  22. 48
      packages/neon/neon/lib/src/utils/global_options.dart
  23. 12
      packages/neon/neon/lib/src/utils/global_popups.dart
  24. 8
      packages/neon/neon/lib/src/utils/localizations.dart
  25. 6
      packages/neon/neon/lib/src/utils/validators.dart
  26. 4
      packages/neon/neon/lib/src/widgets/account_switcher_button.dart
  27. 8
      packages/neon/neon/lib/src/widgets/app_bar.dart
  28. 2
      packages/neon/neon/lib/src/widgets/drawer.dart
  29. 24
      packages/neon/neon/lib/src/widgets/error.dart
  30. 2
      packages/neon/neon/lib/src/widgets/nextcloud_logo.dart
  31. 2
      packages/neon/neon/lib/src/widgets/unified_search_results.dart
  32. 1
      packages/neon/neon/lib/utils.dart
  33. 1
      packages/neon/neon_files/l10n.yaml
  34. 7
      packages/neon/neon_files/l10n.yaml
  35. 2
      packages/neon/neon_files/lib/blocs/files.dart
  36. 10
      packages/neon/neon_files/lib/dialogs/choose_create.dart
  37. 6
      packages/neon/neon_files/lib/dialogs/choose_folder.dart
  38. 6
      packages/neon/neon_files/lib/dialogs/create_folder.dart
  39. 38
      packages/neon/neon_files/lib/l10n/localizations.dart
  40. 4
      packages/neon/neon_files/lib/l10n/localizations_en.dart
  41. 4
      packages/neon/neon_files/lib/neon_files.dart
  42. 26
      packages/neon/neon_files/lib/options.dart
  43. 18
      packages/neon/neon_files/lib/pages/details.dart
  44. 2
      packages/neon/neon_files/lib/pages/main.dart
  45. 29
      packages/neon/neon_files/lib/widgets/actions.dart
  46. 2
      packages/neon/neon_files/lib/widgets/file_list_tile.dart
  47. 4
      packages/neon/neon_files/lib/widgets/navigator.dart
  48. 1
      packages/neon/neon_news/l10n.yaml
  49. 7
      packages/neon/neon_news/l10n.yaml
  50. 4
      packages/neon/neon_news/lib/dialogs/add_feed.dart
  51. 6
      packages/neon/neon_news/lib/dialogs/create_folder.dart
  52. 6
      packages/neon/neon_news/lib/dialogs/feed_show_url.dart
  53. 6
      packages/neon/neon_news/lib/dialogs/feed_update_error.dart
  54. 4
      packages/neon/neon_news/lib/dialogs/move_feed.dart
  55. 38
      packages/neon/neon_news/lib/l10n/localizations.dart
  56. 4
      packages/neon/neon_news/lib/l10n/localizations_en.dart
  57. 4
      packages/neon/neon_news/lib/neon_news.dart
  58. 66
      packages/neon/neon_news/lib/options.dart
  59. 13
      packages/neon/neon_news/lib/pages/article.dart
  60. 6
      packages/neon/neon_news/lib/pages/main.dart
  61. 8
      packages/neon/neon_news/lib/widgets/articles_view.dart
  62. 2
      packages/neon/neon_news/lib/widgets/feed_floating_action_button.dart
  63. 16
      packages/neon/neon_news/lib/widgets/feeds_view.dart
  64. 2
      packages/neon/neon_news/lib/widgets/folder_floating_action_button.dart
  65. 4
      packages/neon/neon_news/lib/widgets/folder_select.dart
  66. 10
      packages/neon/neon_news/lib/widgets/folders_view.dart
  67. 1
      packages/neon/neon_notes/l10n.yaml
  68. 7
      packages/neon/neon_notes/l10n.yaml
  69. 6
      packages/neon/neon_notes/lib/dialogs/create_note.dart
  70. 4
      packages/neon/neon_notes/lib/dialogs/select_category.dart
  71. 38
      packages/neon/neon_notes/lib/l10n/localizations.dart
  72. 4
      packages/neon/neon_notes/lib/l10n/localizations_en.dart
  73. 4
      packages/neon/neon_notes/lib/neon_notes.dart
  74. 34
      packages/neon/neon_notes/lib/options.dart
  75. 2
      packages/neon/neon_notes/lib/pages/category.dart
  76. 4
      packages/neon/neon_notes/lib/pages/main.dart
  77. 6
      packages/neon/neon_notes/lib/pages/note.dart
  78. 2
      packages/neon/neon_notes/lib/utils/exception_handler.dart
  79. 4
      packages/neon/neon_notes/lib/widgets/categories_view.dart
  80. 4
      packages/neon/neon_notes/lib/widgets/category_select.dart
  81. 2
      packages/neon/neon_notes/lib/widgets/notes_floating_action_button.dart
  82. 4
      packages/neon/neon_notes/lib/widgets/notes_view.dart
  83. 1
      packages/neon/neon_notifications/l10n.yaml
  84. 7
      packages/neon/neon_notifications/l10n.yaml
  85. 38
      packages/neon/neon_notifications/lib/l10n/localizations.dart
  86. 4
      packages/neon/neon_notifications/lib/l10n/localizations_en.dart
  87. 4
      packages/neon/neon_notifications/lib/neon_notifications.dart
  88. 6
      packages/neon/neon_notifications/lib/pages/main.dart

4
.husky/pre-commit

@ -1,4 +0,0 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
melos run format:check

6
packages/app/l10n.yaml

@ -1,6 +0,0 @@
arb-dir: ../neon/neon/lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-dir: ../neon/neon/lib/l10n
nullable-getter: false

1
packages/neon/neon/l10n.yaml

@ -2,5 +2,6 @@ arb-dir: lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-class: NeonLocalizations
output-dir: lib/l10n
nullable-getter: false

38
packages/neon/neon/lib/l10n/localizations.dart

@ -7,10 +7,10 @@ import 'package:intl/intl.dart' as intl;
import 'localizations_en.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of NeonLocalizations
/// returned by `NeonLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// Applications need to include `NeonLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
@ -18,8 +18,8 @@ import 'localizations_en.dart';
/// import 'l10n/localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// localizationsDelegates: NeonLocalizations.localizationsDelegates,
/// supportedLocales: NeonLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
@ -56,18 +56,18 @@ import 'localizations_en.dart';
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// be consistent with the languages listed in the NeonLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
abstract class NeonLocalizations {
NeonLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
static NeonLocalizations of(BuildContext context) {
return Localizations.of<NeonLocalizations>(context, NeonLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
static const LocalizationsDelegate<NeonLocalizations> delegate = _NeonLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -690,29 +690,29 @@ abstract class AppLocalizations {
String get issueTracker;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
class _NeonLocalizationsDelegate extends LocalizationsDelegate<NeonLocalizations> {
const _NeonLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
Future<NeonLocalizations> load(Locale locale) {
return SynchronousFuture<NeonLocalizations>(lookupNeonLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
bool shouldReload(_NeonLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
NeonLocalizations lookupNeonLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
return NeonLocalizationsEn();
}
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
throw FlutterError('NeonLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');

4
packages/neon/neon/lib/l10n/localizations_en.dart

@ -3,8 +3,8 @@ import 'package:intl/intl.dart' as intl;
import 'localizations.dart';
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
class NeonLocalizationsEn extends NeonLocalizations {
NeonLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get nextcloud => 'Nextcloud';

4
packages/neon/neon/lib/src/app.dart

@ -301,13 +301,13 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
return MaterialApp.router(
localizationsDelegates: [
..._appImplementations.map((final app) => app.localizationsDelegate),
...AppLocalizations.localizationsDelegates,
...NeonLocalizations.localizationsDelegates,
],
supportedLocales: {
..._appImplementations
.map((final app) => app.supportedLocales)
.expand((final element) => element),
...AppLocalizations.supportedLocales,
...NeonLocalizations.supportedLocales,
},
themeMode: themeMode,
theme: appTheme.lightTheme,

6
packages/neon/neon/lib/src/models/app_implementation.dart

@ -25,8 +25,8 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
LocalizationsDelegate<Object> get localizationsDelegate;
Iterable<Locale> get supportedLocales;
String nameFromLocalization(final AppLocalizations localizations) => localizations.appImplementationName(id);
String name(final BuildContext context) => nameFromLocalization(AppLocalizations.of(context));
String nameFromLocalization(final NeonLocalizations localizations) => localizations.appImplementationName(id);
String name(final BuildContext context) => nameFromLocalization(NeonLocalizations.of(context));
@protected
late final AppStorage storage = AppStorage(StorageKeys.apps, id);
@ -121,7 +121,7 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
'assets/app.svg.vec',
packageName: 'neon_$id',
),
semanticsLabel: AppLocalizations.of(context).nextcloudLogo,
semanticsLabel: NeonLocalizations.of(context).nextcloudLogo,
);
},
);

14
packages/neon/neon/lib/src/pages/account_settings.dart

@ -41,7 +41,7 @@ class AccountSettingsPage extends StatelessWidget {
onPressed: () async {
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).accountOptionsRemoveConfirm(account.humanReadableID),
NeonLocalizations.of(context).accountOptionsRemoveConfirm(account.humanReadableID),
)) {
final isActive = bloc.activeAccount.valueOrNull == account;
@ -59,19 +59,19 @@ class AccountSettingsPage extends StatelessWidget {
}
}
},
tooltip: AppLocalizations.of(context).accountOptionsRemove,
tooltip: NeonLocalizations.of(context).accountOptionsRemove,
icon: const Icon(Icons.logout),
),
IconButton(
onPressed: () async {
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).settingsResetForConfirmation(name),
NeonLocalizations.of(context).settingsResetForConfirmation(name),
)) {
options.reset();
}
},
tooltip: AppLocalizations.of(context).settingsResetFor(name),
tooltip: NeonLocalizations.of(context).settingsResetFor(name),
icon: const Icon(MdiIcons.cogRefresh),
),
],
@ -82,7 +82,7 @@ class AccountSettingsPage extends StatelessWidget {
builder: (final context, final userDetails) => SettingsList(
categories: [
SettingsCategory(
title: Text(AppLocalizations.of(context).accountOptionsCategoryStorageInfo),
title: Text(NeonLocalizations.of(context).accountOptionsCategoryStorageInfo),
tiles: [
CustomSettingsTile(
title: Column(
@ -97,7 +97,7 @@ class AccountSettingsPage extends StatelessWidget {
height: 10,
),
Text(
AppLocalizations.of(context).accountOptionsQuotaUsedOf(
NeonLocalizations.of(context).accountOptionsQuotaUsedOf(
filesize(userDetails.requireData.quota.used ?? 0, 1),
filesize(userDetails.requireData.quota.total ?? 0, 1),
(userDetails.requireData.quota.relative ?? 0).toString(),
@ -117,7 +117,7 @@ class AccountSettingsPage extends StatelessWidget {
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryGeneral),
title: Text(NeonLocalizations.of(context).optionsCategoryGeneral),
tiles: [
SelectSettingsTile(
option: options.initialApp,

8
packages/neon/neon/lib/src/pages/home.dart

@ -51,7 +51,7 @@ class _HomePageState extends State<HomePage> {
return;
}
final l10n = AppLocalizations.of(context);
final l10n = NeonLocalizations.of(context);
final buffer = StringBuffer()..writeln();
@ -86,7 +86,7 @@ class _HomePageState extends State<HomePage> {
final status = await _account.client.core.getStatus();
if (status.body.maintenance && mounted) {
await _showProblem(
AppLocalizations.of(context).errorServerInMaintenanceMode,
NeonLocalizations.of(context).errorServerInMaintenanceMode,
);
}
} catch (e, s) {
@ -114,7 +114,7 @@ class _HomePageState extends State<HomePage> {
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).actionClose),
child: Text(NeonLocalizations.of(context).actionClose),
),
],
),
@ -142,7 +142,7 @@ class _HomePageState extends State<HomePage> {
if (appImplementations.requireData.isEmpty) {
return Center(
child: Text(
AppLocalizations.of(context).errorNoCompatibleNextcloudAppsFound,
NeonLocalizations.of(context).errorNoCompatibleNextcloudAppsFound,
textAlign: TextAlign.center,
),
);

8
packages/neon/neon/lib/src/pages/login.dart

@ -71,12 +71,12 @@ class _LoginPageState extends State<LoginPage> {
const SizedBox(
height: 10,
),
Text(AppLocalizations.of(context).loginWorksWith),
Text(NeonLocalizations.of(context).loginWorksWith),
const SizedBox(
height: 10,
),
Semantics(
label: AppLocalizations.of(context).nextcloud,
label: NeonLocalizations.of(context).nextcloud,
child: const NextcloudLogo(),
),
],
@ -90,7 +90,7 @@ class _LoginPageState extends State<LoginPage> {
controller: _controller,
decoration: InputDecoration(
hintText: 'https://...',
labelText: AppLocalizations.of(context).loginUsingServerAddress,
labelText: NeonLocalizations.of(context).loginUsingServerAddress,
suffixIcon: IconButton(
icon: const Icon(Icons.arrow_forward),
onPressed: () {
@ -109,7 +109,7 @@ class _LoginPageState extends State<LoginPage> {
height: 50,
),
IconButton(
tooltip: AppLocalizations.of(context).loginUsingQRcode,
tooltip: NeonLocalizations.of(context).loginUsingQRcode,
icon: const Icon(
Icons.qr_code_scanner_rounded,
size: 60,

10
packages/neon/neon/lib/src/pages/login_check_account.dart

@ -71,7 +71,7 @@ class _LoginCheckAccountPageState extends State<LoginCheckAccountPage> {
final details = NeonError.getDetails(state.error);
return NeonValidationTile(
title: details.isUnauthorized
? AppLocalizations.of(context).errorCredentialsForAccountNoLongerMatch
? NeonLocalizations.of(context).errorCredentialsForAccountNoLongerMatch
: details.getText(context),
state: ValidationState.failure,
);
@ -100,8 +100,8 @@ class _LoginCheckAccountPageState extends State<LoginCheckAccountPage> {
},
child: Text(
state.hasData
? AppLocalizations.of(context).actionContinue
: AppLocalizations.of(context).actionRetry,
? NeonLocalizations.of(context).actionContinue
: NeonLocalizations.of(context).actionRetry,
),
),
),
@ -116,7 +116,7 @@ class _LoginCheckAccountPageState extends State<LoginCheckAccountPage> {
Widget _buildAccountTile(final Result<Account> result) {
if (result.hasError) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingAccount,
title: NeonLocalizations.of(context).loginCheckingAccount,
state: ValidationState.canceled,
);
}
@ -129,7 +129,7 @@ class _LoginCheckAccountPageState extends State<LoginCheckAccountPage> {
}
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingAccount,
title: NeonLocalizations.of(context).loginCheckingAccount,
state: ValidationState.loading,
);
}

20
packages/neon/neon/lib/src/pages/login_check_server_status.dart

@ -79,8 +79,8 @@ class _LoginCheckServerStatusPageState extends State<LoginCheckServerStatusPage>
onPressed: success ? _onContinue : bloc.refresh,
child: Text(
success
? AppLocalizations.of(context).actionContinue
: AppLocalizations.of(context).actionRetry,
? NeonLocalizations.of(context).actionContinue
: NeonLocalizations.of(context).actionRetry,
),
),
),
@ -108,27 +108,27 @@ class _LoginCheckServerStatusPageState extends State<LoginCheckServerStatusPage>
Widget _buildServerVersionTile(final Result<core.Status> result) {
if (result.hasError) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingServerVersion,
title: NeonLocalizations.of(context).loginCheckingServerVersion,
state: ValidationState.canceled,
);
}
if (!result.hasData) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingServerVersion,
title: NeonLocalizations.of(context).loginCheckingServerVersion,
state: ValidationState.loading,
);
}
if (result.requireData.isSupported) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginSupportedServerVersion(result.requireData.versionstring),
title: NeonLocalizations.of(context).loginSupportedServerVersion(result.requireData.versionstring),
state: ValidationState.success,
);
}
return NeonValidationTile(
title: AppLocalizations.of(context).loginUnsupportedServerVersion(result.requireData.versionstring),
title: NeonLocalizations.of(context).loginUnsupportedServerVersion(result.requireData.versionstring),
state: ValidationState.failure,
);
}
@ -136,27 +136,27 @@ class _LoginCheckServerStatusPageState extends State<LoginCheckServerStatusPage>
Widget _buildMaintenanceModeTile(final Result<core.Status> result) {
if (result.hasError) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingMaintenanceMode,
title: NeonLocalizations.of(context).loginCheckingMaintenanceMode,
state: ValidationState.canceled,
);
}
if (!result.hasData) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginCheckingMaintenanceMode,
title: NeonLocalizations.of(context).loginCheckingMaintenanceMode,
state: ValidationState.loading,
);
}
if (result.requireData.maintenance) {
return NeonValidationTile(
title: AppLocalizations.of(context).loginMaintenanceModeEnabled,
title: NeonLocalizations.of(context).loginMaintenanceModeEnabled,
state: ValidationState.failure,
);
}
return NeonValidationTile(
title: AppLocalizations.of(context).loginMaintenanceModeDisabled,
title: NeonLocalizations.of(context).loginMaintenanceModeDisabled,
state: ValidationState.success,
);
}

4
packages/neon/neon/lib/src/pages/login_flow.dart

@ -73,13 +73,13 @@ class _LoginFlowPageState extends State<LoginFlowPage> {
onRetry: bloc.refresh,
),
if (init.hasData) ...[
Text(AppLocalizations.of(context).loginSwitchToBrowserWindow),
Text(NeonLocalizations.of(context).loginSwitchToBrowserWindow),
const SizedBox(
height: 10,
),
ElevatedButton(
onPressed: bloc.refresh,
child: Text(AppLocalizations.of(context).loginOpenAgain),
child: Text(NeonLocalizations.of(context).loginOpenAgain),
),
],
],

2
packages/neon/neon/lib/src/pages/login_qr_code.dart

@ -68,6 +68,6 @@ class InvalidQRcodeException extends NeonException {
@override
NeonExceptionDetails get details => NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorInvalidQRcode,
getText: (final context) => NeonLocalizations.of(context).errorInvalidQRcode,
);
}

6
packages/neon/neon/lib/src/pages/nextcloud_app_settings.dart

@ -27,12 +27,12 @@ class NextcloudAppSettingsPage extends StatelessWidget {
onPressed: () async {
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).settingsResetForConfirmation(appImplementation.name(context)),
NeonLocalizations.of(context).settingsResetForConfirmation(appImplementation.name(context)),
)) {
appImplementation.options.reset();
}
},
tooltip: AppLocalizations.of(context).settingsResetFor(appImplementation.name(context)),
tooltip: NeonLocalizations.of(context).settingsResetFor(appImplementation.name(context)),
icon: const Icon(MdiIcons.cogRefresh),
),
],
@ -44,7 +44,7 @@ class NextcloudAppSettingsPage extends StatelessWidget {
if (appImplementation.options.options.where((final option) => option.category == category).isNotEmpty) ...[
SettingsCategory(
title: Text(
category != null ? category.name(context) : AppLocalizations.of(context).optionsCategoryOther,
category != null ? category.name(context) : NeonLocalizations.of(context).optionsCategoryOther,
),
tiles: [
for (final option

2
packages/neon/neon/lib/src/pages/route_not_found.dart

@ -60,7 +60,7 @@ class _RouteNotFoundPageState extends State<RouteNotFoundPage> {
),
),
body: Center(
child: Text(AppLocalizations.of(context).errorRouteNotFound(widget.uri.toString())),
child: Text(NeonLocalizations.of(context).errorRouteNotFound(widget.uri.toString())),
),
);
}

38
packages/neon/neon/lib/src/pages/settings.dart

@ -60,11 +60,11 @@ class _SettingsPageState extends State<SettingsPage> {
final branding = Branding.of(context);
final appBar = AppBar(
title: Text(AppLocalizations.of(context).settings),
title: Text(NeonLocalizations.of(context).settings),
actions: [
IconButton(
onPressed: () async {
if (await showConfirmationDialog(context, AppLocalizations.of(context).settingsResetAllConfirmation)) {
if (await showConfirmationDialog(context, NeonLocalizations.of(context).settingsResetAllConfirmation)) {
globalOptions.reset();
for (final appImplementation in appImplementations) {
@ -76,7 +76,7 @@ class _SettingsPageState extends State<SettingsPage> {
}
}
},
tooltip: AppLocalizations.of(context).settingsResetAll,
tooltip: NeonLocalizations.of(context).settingsResetAll,
icon: const Icon(MdiIcons.cogRefresh),
),
],
@ -99,7 +99,7 @@ class _SettingsPageState extends State<SettingsPage> {
initialCategory: widget.initialCategory?.name,
categories: [
SettingsCategory(
title: Text(AppLocalizations.of(context).settingsApps),
title: Text(NeonLocalizations.of(context).settingsApps),
key: ValueKey(SettingsCategories.apps.name),
tiles: <SettingsTile>[
for (final appImplementation in appImplementations) ...[
@ -116,7 +116,7 @@ class _SettingsPageState extends State<SettingsPage> {
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryTheme),
title: Text(NeonLocalizations.of(context).optionsCategoryTheme),
key: ValueKey(SettingsCategories.theme.name),
tiles: [
SelectSettingsTile(
@ -131,7 +131,7 @@ class _SettingsPageState extends State<SettingsPage> {
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryNavigation),
title: Text(NeonLocalizations.of(context).optionsCategoryNavigation),
key: ValueKey(SettingsCategories.navigation.name),
tiles: [
SelectSettingsTile(
@ -141,12 +141,12 @@ class _SettingsPageState extends State<SettingsPage> {
),
if (NeonPlatform.instance.canUsePushNotifications) ...[
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryPushNotifications),
title: Text(NeonLocalizations.of(context).optionsCategoryPushNotifications),
key: ValueKey(SettingsCategories.pushNotifications.name),
tiles: [
if (!globalOptions.pushNotificationsEnabled.enabled) ...[
TextSettingsTile(
text: AppLocalizations.of(context).globalOptionsPushNotificationsEnabledDisabledNotice,
text: NeonLocalizations.of(context).globalOptionsPushNotificationsEnabledDisabledNotice,
style: TextStyle(
fontWeight: FontWeight.w600,
fontStyle: FontStyle.italic,
@ -165,7 +165,7 @@ class _SettingsPageState extends State<SettingsPage> {
],
if (NeonPlatform.instance.canUseWindowManager) ...[
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryStartup),
title: Text(NeonLocalizations.of(context).optionsCategoryStartup),
key: ValueKey(SettingsCategories.startup.name),
tiles: [
ToggleSettingsTile(
@ -179,7 +179,7 @@ class _SettingsPageState extends State<SettingsPage> {
],
if (NeonPlatform.instance.canUseWindowManager && NeonPlatform.instance.canUseSystemTray) ...[
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategorySystemTray),
title: Text(NeonLocalizations.of(context).optionsCategorySystemTray),
key: ValueKey(SettingsCategories.systemTray.name),
tiles: [
ToggleSettingsTile(
@ -192,7 +192,7 @@ class _SettingsPageState extends State<SettingsPage> {
),
],
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryAccounts),
title: Text(NeonLocalizations.of(context).optionsCategoryAccounts),
key: ValueKey(SettingsCategories.accounts.name),
tiles: [
if (accountsSnapshot.requireData.length > 1) ...[
@ -215,13 +215,13 @@ class _SettingsPageState extends State<SettingsPage> {
title: ElevatedButton.icon(
onPressed: () async => const LoginRoute().push(context),
icon: const Icon(MdiIcons.accountPlus),
label: Text(AppLocalizations.of(context).globalOptionsAccountsAdd),
label: Text(NeonLocalizations.of(context).globalOptionsAccountsAdd),
),
),
],
),
SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryOther),
title: Text(NeonLocalizations.of(context).optionsCategoryOther),
key: ValueKey(SettingsCategories.other.name),
tiles: <SettingsTile>[
if (branding.sourceCodeURL != null)
@ -230,7 +230,7 @@ class _SettingsPageState extends State<SettingsPage> {
Icons.code,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).sourceCode),
title: Text(NeonLocalizations.of(context).sourceCode),
onTap: () async {
await launchUrlString(
branding.sourceCodeURL!,
@ -244,7 +244,7 @@ class _SettingsPageState extends State<SettingsPage> {
MdiIcons.textBoxEditOutline,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).issueTracker),
title: Text(NeonLocalizations.of(context).issueTracker),
onTap: () async {
await launchUrlString(
branding.issueTrackerURL!,
@ -257,7 +257,7 @@ class _SettingsPageState extends State<SettingsPage> {
MdiIcons.scriptText,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).licenses),
title: Text(NeonLocalizations.of(context).licenses),
onTap: () async {
showLicensePage(
context: context,
@ -273,7 +273,7 @@ class _SettingsPageState extends State<SettingsPage> {
MdiIcons.export,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).settingsExport),
title: Text(NeonLocalizations.of(context).settingsExport),
onTap: () async {
final settingsExportHelper = _buildSettingsExportHelper(context);
@ -296,7 +296,7 @@ class _SettingsPageState extends State<SettingsPage> {
MdiIcons.import,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).settingsImport),
title: Text(NeonLocalizations.of(context).settingsImport),
onTap: () async {
final settingsExportHelper = _buildSettingsExportHelper(context);
@ -313,7 +313,7 @@ class _SettingsPageState extends State<SettingsPage> {
if (mounted) {
NeonError.showSnackbar(
context,
AppLocalizations.of(context).settingsImportWrongFileExtension,
NeonLocalizations.of(context).settingsImportWrongFileExtension,
);
}
return;

4
packages/neon/neon/lib/src/sort_box/sort_box_order_option_values.dart

@ -4,6 +4,6 @@ import 'package:sort_box/sort_box.dart';
/// Sort box order labels used in an `SelectOption`.
final sortBoxOrderOptionValues = <SortBoxOrder, LabelBuilder>{
SortBoxOrder.ascending: (final context) => AppLocalizations.of(context).optionsSortOrderAscending,
SortBoxOrder.descending: (final context) => AppLocalizations.of(context).optionsSortOrderDescending,
SortBoxOrder.ascending: (final context) => NeonLocalizations.of(context).optionsSortOrderAscending,
SortBoxOrder.descending: (final context) => NeonLocalizations.of(context).optionsSortOrderDescending,
};

4
packages/neon/neon/lib/src/utils/account_options.dart

@ -18,7 +18,7 @@ class AccountSpecificOptions extends OptionsCollection {
}
initialApp.values = {
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic,
null: (final context) => NeonLocalizations.of(context).accountOptionsAutomatic,
}..addEntries(result.requireData.map((final app) => MapEntry(app.id, app.name)));
});
}
@ -33,7 +33,7 @@ class AccountSpecificOptions extends OptionsCollection {
late final initialApp = SelectOption<String?>(
storage: storage,
key: AccountOptionKeys.initialApp,
label: (final context) => AppLocalizations.of(context).accountOptionsInitialApp,
label: (final context) => NeonLocalizations.of(context).accountOptionsInitialApp,
defaultValue: null,
values: {},
);

4
packages/neon/neon/lib/src/utils/confirmation_dialog.dart

@ -17,7 +17,7 @@ Future<bool> showConfirmationDialog(final BuildContext context, final String tit
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text(AppLocalizations.of(context).actionNo),
child: Text(NeonLocalizations.of(context).actionNo),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
@ -27,7 +27,7 @@ Future<bool> showConfirmationDialog(final BuildContext context, final String tit
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text(AppLocalizations.of(context).actionYes),
child: Text(NeonLocalizations.of(context).actionYes),
),
],
),

2
packages/neon/neon/lib/src/utils/exceptions.dart

@ -43,6 +43,6 @@ class MissingPermissionException extends NeonException {
@override
NeonExceptionDetails get details => NeonExceptionDetails(
getText: (final context) =>
AppLocalizations.of(context).errorMissingPermission(permission.toString().split('.')[1]),
NeonLocalizations.of(context).errorMissingPermission(permission.toString().split('.')[1]),
);
}

48
packages/neon/neon/lib/src/utils/global_options.dart

@ -52,18 +52,18 @@ class GlobalOptions extends OptionsCollection {
late final _distributorsMap = <String, LabelBuilder>{
_packageInfo.packageName: (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorFirebaseEmbedded,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorFirebaseEmbedded,
'com.github.gotify.up': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorGotifyUP,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorGotifyUP,
'eu.siacs.conversations': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorConversations,
'io.heckel.ntfy': (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNtfy,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorConversations,
'io.heckel.ntfy': (final context) => NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorNtfy,
'org.unifiedpush.distributor.fcm': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorFCMUP,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorFCMUP,
unifiedPushNextPushID: (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNextPush,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorNextPush,
'org.unifiedpush.distributor.noprovider2push': (final context) =>
AppLocalizations.of(context).globalOptionsPushNotificationsDistributorNoProvider2Push,
NeonLocalizations.of(context).globalOptionsPushNotificationsDistributorNoProvider2Push,
};
@override
@ -120,40 +120,40 @@ class GlobalOptions extends OptionsCollection {
late final themeMode = SelectOption(
storage: storage,
key: GlobalOptionKeys.themeMode,
label: (final context) => AppLocalizations.of(context).globalOptionsThemeMode,
label: (final context) => NeonLocalizations.of(context).globalOptionsThemeMode,
defaultValue: ThemeMode.system,
values: {
ThemeMode.light: (final context) => AppLocalizations.of(context).globalOptionsThemeModeLight,
ThemeMode.dark: (final context) => AppLocalizations.of(context).globalOptionsThemeModeDark,
ThemeMode.system: (final context) => AppLocalizations.of(context).globalOptionsThemeModeAutomatic,
ThemeMode.light: (final context) => NeonLocalizations.of(context).globalOptionsThemeModeLight,
ThemeMode.dark: (final context) => NeonLocalizations.of(context).globalOptionsThemeModeDark,
ThemeMode.system: (final context) => NeonLocalizations.of(context).globalOptionsThemeModeAutomatic,
},
);
late final themeOLEDAsDark = ToggleOption(
storage: storage,
key: GlobalOptionKeys.themeOLEDAsDark,
label: (final context) => AppLocalizations.of(context).globalOptionsThemeOLEDAsDark,
label: (final context) => NeonLocalizations.of(context).globalOptionsThemeOLEDAsDark,
defaultValue: false,
);
late final themeKeepOriginalAccentColor = ToggleOption(
storage: storage,
key: GlobalOptionKeys.themeKeepOriginalAccentColor,
label: (final context) => AppLocalizations.of(context).globalOptionsThemeKeepOriginalAccentColor,
label: (final context) => NeonLocalizations.of(context).globalOptionsThemeKeepOriginalAccentColor,
defaultValue: false,
);
late final pushNotificationsEnabled = ToggleOption(
storage: storage,
key: GlobalOptionKeys.pushNotificationsEnabled,
label: (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsEnabled,
label: (final context) => NeonLocalizations.of(context).globalOptionsPushNotificationsEnabled,
defaultValue: false,
);
late final pushNotificationsDistributor = SelectOption<String?>.depend(
storage: storage,
key: GlobalOptionKeys.pushNotificationsDistributor,
label: (final context) => AppLocalizations.of(context).globalOptionsPushNotificationsDistributor,
label: (final context) => NeonLocalizations.of(context).globalOptionsPushNotificationsDistributor,
defaultValue: null,
values: {},
enabled: pushNotificationsEnabled,
@ -162,14 +162,14 @@ class GlobalOptions extends OptionsCollection {
late final startupMinimized = ToggleOption(
storage: storage,
key: GlobalOptionKeys.startupMinimized,
label: (final context) => AppLocalizations.of(context).globalOptionsStartupMinimized,
label: (final context) => NeonLocalizations.of(context).globalOptionsStartupMinimized,
defaultValue: false,
);
late final startupMinimizeInsteadOfExit = ToggleOption(
storage: storage,
key: GlobalOptionKeys.startupMinimizeInsteadOfExit,
label: (final context) => AppLocalizations.of(context).globalOptionsStartupMinimizeInsteadOfExit,
label: (final context) => NeonLocalizations.of(context).globalOptionsStartupMinimizeInsteadOfExit,
defaultValue: false,
);
@ -178,14 +178,14 @@ class GlobalOptions extends OptionsCollection {
late final systemTrayEnabled = ToggleOption(
storage: storage,
key: GlobalOptionKeys.systemTrayEnabled,
label: (final context) => AppLocalizations.of(context).globalOptionsSystemTrayEnabled,
label: (final context) => NeonLocalizations.of(context).globalOptionsSystemTrayEnabled,
defaultValue: false,
);
late final systemTrayHideToTrayWhenMinimized = ToggleOption.depend(
storage: storage,
key: GlobalOptionKeys.systemTrayHideToTrayWhenMinimized,
label: (final context) => AppLocalizations.of(context).globalOptionsSystemTrayHideToTrayWhenMinimized,
label: (final context) => NeonLocalizations.of(context).globalOptionsSystemTrayHideToTrayWhenMinimized,
defaultValue: true,
enabled: systemTrayEnabled,
);
@ -193,14 +193,14 @@ class GlobalOptions extends OptionsCollection {
late final rememberLastUsedAccount = ToggleOption(
storage: storage,
key: GlobalOptionKeys.rememberLastUsedAccount,
label: (final context) => AppLocalizations.of(context).globalOptionsAccountsRememberLastUsedAccount,
label: (final context) => NeonLocalizations.of(context).globalOptionsAccountsRememberLastUsedAccount,
defaultValue: true,
);
late final initialAccount = SelectOption<String?>(
storage: storage,
key: GlobalOptionKeys.initialAccount,
label: (final context) => AppLocalizations.of(context).globalOptionsAccountsInitialAccount,
label: (final context) => NeonLocalizations.of(context).globalOptionsAccountsInitialAccount,
defaultValue: null,
values: {},
);
@ -208,13 +208,13 @@ class GlobalOptions extends OptionsCollection {
late final navigationMode = SelectOption(
storage: storage,
key: GlobalOptionKeys.navigationMode,
label: (final context) => AppLocalizations.of(context).globalOptionsNavigationMode,
label: (final context) => NeonLocalizations.of(context).globalOptionsNavigationMode,
defaultValue: Platform.isAndroid || Platform.isIOS ? NavigationMode.drawer : NavigationMode.drawerAlwaysVisible,
values: {
NavigationMode.drawer: (final context) => AppLocalizations.of(context).globalOptionsNavigationModeDrawer,
NavigationMode.drawer: (final context) => NeonLocalizations.of(context).globalOptionsNavigationModeDrawer,
if (!Platform.isAndroid && !Platform.isIOS)
NavigationMode.drawerAlwaysVisible: (final context) =>
AppLocalizations.of(context).globalOptionsNavigationModeDrawerAlwaysVisible,
NeonLocalizations.of(context).globalOptionsNavigationModeDrawerAlwaysVisible,
},
);
}

12
packages/neon/neon/lib/src/utils/global_popups.dart

@ -58,9 +58,9 @@ class GlobalPopups {
ScaffoldMessenger.of(_context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(_context).firstLaunchGoToSettingsToEnablePushNotifications),
content: Text(NeonLocalizations.of(_context).firstLaunchGoToSettingsToEnablePushNotifications),
action: SnackBarAction(
label: AppLocalizations.of(_context).settings,
label: NeonLocalizations.of(_context).settings,
onPressed: () {
const SettingsRoute(initialCategory: SettingsCategories.pushNotifications).go(_context);
},
@ -77,14 +77,14 @@ class GlobalPopups {
await showDialog<void>(
context: _context,
builder: (final context) => AlertDialog(
title: Text(AppLocalizations.of(context).nextPushSupported),
content: Text(AppLocalizations.of(context).nextPushSupportedText),
title: Text(NeonLocalizations.of(context).nextPushSupported),
content: Text(NeonLocalizations.of(context).nextPushSupportedText),
actions: [
OutlinedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).actionNo),
child: Text(NeonLocalizations.of(context).actionNo),
),
ElevatedButton(
onPressed: () {
@ -94,7 +94,7 @@ class GlobalPopups {
mode: LaunchMode.externalApplication,
);
},
child: Text(AppLocalizations.of(context).nextPushSupportedInstall),
child: Text(NeonLocalizations.of(context).nextPushSupportedInstall),
),
],
),

8
packages/neon/neon/lib/src/utils/localizations.dart

@ -4,16 +4,16 @@ import 'package:intl/intl_standalone.dart';
import 'package:meta/meta.dart';
import 'package:neon/l10n/localizations.dart';
/// Loads the [AppLocalizations] for the system [Locale].
/// Loads the [NeonLocalizations] for the system [Locale].
///
/// When the system locale is not supported [fallbackLocale] will be used.
@internal
Future<AppLocalizations> appLocalizationsFromSystem([final Locale fallbackLocale = const Locale('en', 'US')]) async {
Future<NeonLocalizations> appLocalizationsFromSystem([final Locale fallbackLocale = const Locale('en', 'US')]) async {
final systemLocale = await findSystemLocale();
final parts = systemLocale.split('_').map((final a) => a.split('.')).expand((final e) => e).toList();
final locale = Locale(parts[0], parts.length > 1 ? parts[1] : null);
final isSupported = AppLocalizations.delegate.isSupported(locale);
final isSupported = NeonLocalizations.delegate.isSupported(locale);
return AppLocalizations.delegate.load(isSupported ? locale : fallbackLocale);
return NeonLocalizations.delegate.load(isSupported ? locale : fallbackLocale);
}

6
packages/neon/neon/lib/src/utils/validators.dart

@ -7,7 +7,7 @@ String? validateHttpUrl(
final bool httpsOnly = false,
}) {
if (input == null || input.isEmpty) {
return AppLocalizations.of(context).errorInvalidURL;
return NeonLocalizations.of(context).errorInvalidURL;
}
final uri = Uri.tryParse(input);
@ -21,12 +21,12 @@ String? validateHttpUrl(
}
}
return AppLocalizations.of(context).errorInvalidURL;
return NeonLocalizations.of(context).errorInvalidURL;
}
String? validateNotEmpty(final BuildContext context, final String? input) {
if (input == null || input.isEmpty) {
return AppLocalizations.of(context).errorEmptyField;
return NeonLocalizations.of(context).errorEmptyField;
}
return null;

4
packages/neon/neon/lib/src/widgets/account_switcher_button.dart

@ -25,7 +25,7 @@ class AccountSwitcherButton extends StatelessWidget {
children: [
ListTile(
leading: const Icon(Icons.settings),
title: Text(AppLocalizations.of(context).settingsAccountManage),
title: Text(NeonLocalizations.of(context).settingsAccountManage),
onTap: () {
Navigator.of(context).pop();
const SettingsRoute(initialCategory: SettingsCategories.accounts).push<void>(context);
@ -47,7 +47,7 @@ class AccountSwitcherButton extends StatelessWidget {
return IconButton(
onPressed: () async => _onPressed(context),
tooltip: AppLocalizations.of(context).settingsAccount,
tooltip: NeonLocalizations.of(context).settingsAccount,
icon: NeonUserAvatar(
account: account,
),

8
packages/neon/neon/lib/src/widgets/app_bar.dart

@ -120,7 +120,7 @@ class _NeonAppBarState extends State<NeonAppBar> {
Flexible(
child: SearchBar(
focusNode: _searchBarFocusNode,
hintText: AppLocalizations.of(context).search,
hintText: NeonLocalizations.of(context).search,
padding: const MaterialStatePropertyAll(EdgeInsets.only(left: 16)),
onChanged: _searchTermController.add,
trailing: [
@ -128,7 +128,7 @@ class _NeonAppBarState extends State<NeonAppBar> {
onPressed: () {
unifiedSearchBloc.disable();
},
tooltip: AppLocalizations.of(context).searchCancel,
tooltip: NeonLocalizations.of(context).searchCancel,
icon: const Icon(
Icons.close,
),
@ -160,7 +160,7 @@ class SearchIconButton extends StatelessWidget {
onPressed: () {
NeonProvider.of<AccountsBloc>(context).activeUnifiedSearchBloc.enable();
},
tooltip: AppLocalizations.of(context).search,
tooltip: NeonLocalizations.of(context).search,
icon: const Icon(
Icons.search,
),
@ -256,7 +256,7 @@ class _NotificationIconButtonState extends State<NotificationIconButton> {
onPressed: () async {
await _openNotifications(notificationsImplementationData);
},
tooltip: AppLocalizations.of(context).appImplementationName(notificationsImplementationData.id),
tooltip: NeonLocalizations.of(context).appImplementationName(notificationsImplementationData.id),
icon: StreamBuilder<int>(
stream: notificationsImplementationData.getUnreadCounter(notificationBloc),
builder: (final context, final unreadCounterSnapshot) => NeonAppImplementationIcon(

2
packages/neon/neon/lib/src/widgets/drawer.dart

@ -103,7 +103,7 @@ class __NeonDrawerState extends State<_NeonDrawer> {
...appDestinations,
NavigationDrawerDestination(
icon: const Icon(Icons.settings),
label: Text(AppLocalizations.of(context).settings),
label: Text(NeonLocalizations.of(context).settings),
),
],
);

24
packages/neon/neon/lib/src/widgets/error.dart

@ -55,7 +55,7 @@ class NeonError extends StatelessWidget {
content: Text(details.getText(context)),
action: details.isUnauthorized
? SnackBarAction(
label: AppLocalizations.of(context).loginAgain,
label: NeonLocalizations.of(context).loginAgain,
onPressed: () => _openLoginPage(context),
)
: null,
@ -79,7 +79,7 @@ class NeonError extends StatelessWidget {
);
final message =
details.isUnauthorized ? AppLocalizations.of(context).loginAgain : AppLocalizations.of(context).actionRetry;
details.isUnauthorized ? NeonLocalizations.of(context).loginAgain : NeonLocalizations.of(context).actionRetry;
final onPressed = details.isUnauthorized ? () => _openLoginPage(context) : onRetry;
@ -143,41 +143,41 @@ class NeonError extends StatelessWidget {
case DynamiteApiException():
if (error.statusCode == 401) {
return NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorCredentialsForAccountNoLongerMatch,
getText: (final context) => NeonLocalizations.of(context).errorCredentialsForAccountNoLongerMatch,
isUnauthorized: true,
);
}
if (error.statusCode >= 500 && error.statusCode <= 599) {
return NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorServerHadAProblemProcessingYourRequest,
getText: (final context) => NeonLocalizations.of(context).errorServerHadAProblemProcessingYourRequest,
);
}
case SocketException():
return NeonExceptionDetails(
getText: (final context) => error.address != null
? AppLocalizations.of(context).errorUnableToReachServerAt(error.address!.host)
: AppLocalizations.of(context).errorUnableToReachServer,
? NeonLocalizations.of(context).errorUnableToReachServerAt(error.address!.host)
: NeonLocalizations.of(context).errorUnableToReachServer,
);
case ClientException():
return NeonExceptionDetails(
getText: (final context) => error.uri != null
? AppLocalizations.of(context).errorUnableToReachServerAt(error.uri!.host)
: AppLocalizations.of(context).errorUnableToReachServer,
? NeonLocalizations.of(context).errorUnableToReachServerAt(error.uri!.host)
: NeonLocalizations.of(context).errorUnableToReachServer,
);
case HttpException():
return NeonExceptionDetails(
getText: (final context) => error.uri != null
? AppLocalizations.of(context).errorUnableToReachServerAt(error.uri!.host)
: AppLocalizations.of(context).errorUnableToReachServer,
? NeonLocalizations.of(context).errorUnableToReachServerAt(error.uri!.host)
: NeonLocalizations.of(context).errorUnableToReachServer,
);
case TimeoutException():
return NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorConnectionTimedOut,
getText: (final context) => NeonLocalizations.of(context).errorConnectionTimedOut,
);
}
return NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorSomethingWentWrongTryAgainLater,
getText: (final context) => NeonLocalizations.of(context).errorSomethingWentWrongTryAgainLater,
);
}

2
packages/neon/neon/lib/src/widgets/nextcloud_logo.dart

@ -25,6 +25,6 @@ class NextcloudLogo extends StatelessWidget {
'assets/logo_nextcloud.svg.vec',
packageName: 'neon',
),
semanticsLabel: AppLocalizations.of(context).nextcloudLogo,
semanticsLabel: NeonLocalizations.of(context).nextcloudLogo,
);
}

2
packages/neon/neon/lib/src/widgets/unified_search_results.dart

@ -86,7 +86,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
Icons.close,
size: largeIconSize,
),
title: Text(AppLocalizations.of(context).searchNoResults),
title: Text(NeonLocalizations.of(context).searchNoResults),
),
],
for (final entry in entries) ...[

1
packages/neon/neon/lib/utils.dart

@ -1,3 +1,4 @@
export 'package:neon/l10n/localizations.dart';
export 'package:neon/src/utils/app_route.dart';
export 'package:neon/src/utils/confirmation_dialog.dart';
export 'package:neon/src/utils/exceptions.dart';

1
packages/neon/neon_files/l10n.yaml

@ -1 +0,0 @@
../neon/l10n.yaml

7
packages/neon/neon_files/l10n.yaml

@ -0,0 +1,7 @@
arb-dir: lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-class: FilesLocalizations
output-dir: lib/l10n
nullable-getter: false

2
packages/neon/neon_files/lib/blocs/files.dart

@ -223,6 +223,6 @@ class UnableToOpenFileException extends NeonException {
@override
NeonExceptionDetails get details => NeonExceptionDetails(
getText: (final context) => AppLocalizations.of(context).errorUnableToOpenFile,
getText: (final context) => FilesLocalizations.of(context).errorUnableToOpenFile,
);
}

10
packages/neon/neon_files/lib/dialogs/choose_create.dart

@ -34,7 +34,7 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
if (stat.size > sizeWarning) {
if (!(await showConfirmationDialog(
context,
AppLocalizations.of(context).uploadConfirmSizeWarning(
FilesLocalizations.of(context).uploadConfirmSizeWarning(
filesize(sizeWarning),
filesize(stat.size),
),
@ -54,7 +54,7 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
MdiIcons.filePlus,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).uploadFiles),
title: Text(FilesLocalizations.of(context).uploadFiles),
onTap: () async {
await uploadFromPick(FileType.any);
@ -68,7 +68,7 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
MdiIcons.fileImagePlus,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).uploadImages),
title: Text(FilesLocalizations.of(context).uploadImages),
onTap: () async {
await uploadFromPick(FileType.image);
@ -83,7 +83,7 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
MdiIcons.cameraPlus,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).uploadCamera),
title: Text(FilesLocalizations.of(context).uploadCamera),
onTap: () async {
Navigator.of(context).pop();
@ -100,7 +100,7 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
MdiIcons.folderPlus,
color: Theme.of(context).colorScheme.primary,
),
title: Text(AppLocalizations.of(context).folderCreate),
title: Text(FilesLocalizations.of(context).folderCreate),
onTap: () async {
Navigator.of(context).pop();

6
packages/neon/neon_files/lib/dialogs/choose_folder.dart

@ -15,7 +15,7 @@ class FilesChooseFolderDialog extends StatelessWidget {
@override
Widget build(final BuildContext context) => AlertDialog(
title: Text(AppLocalizations.of(context).folderChoose),
title: Text(FilesLocalizations.of(context).folderChoose),
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: double.maxFinite,
@ -46,13 +46,13 @@ class FilesChooseFolderDialog extends StatelessWidget {
bloc.createFolder([...pathSnapshot.requireData, ...result]);
}
},
child: Text(AppLocalizations.of(context).folderCreate),
child: Text(FilesLocalizations.of(context).folderCreate),
),
ElevatedButton(
onPressed: !(const ListEquality<String>().equals(originalPath, pathSnapshot.data))
? () => Navigator.of(context).pop(pathSnapshot.data)
: null,
child: Text(AppLocalizations.of(context).folderChoose),
child: Text(FilesLocalizations.of(context).folderChoose),
),
],
),

6
packages/neon/neon_files/lib/dialogs/create_folder.dart

@ -28,7 +28,7 @@ class _FilesCreateFolderDialogState extends State<FilesCreateFolderDialog> {
@override
Widget build(final BuildContext context) => NeonDialog(
title: Text(AppLocalizations.of(context).folderCreate),
title: Text(FilesLocalizations.of(context).folderCreate),
children: [
Form(
key: formKey,
@ -38,7 +38,7 @@ class _FilesCreateFolderDialogState extends State<FilesCreateFolderDialog> {
TextFormField(
controller: controller,
decoration: InputDecoration(
hintText: AppLocalizations.of(context).folderName,
hintText: FilesLocalizations.of(context).folderName,
),
autofocus: true,
validator: (final input) => validateNotEmpty(context, input),
@ -48,7 +48,7 @@ class _FilesCreateFolderDialogState extends State<FilesCreateFolderDialog> {
),
ElevatedButton(
onPressed: submit,
child: Text(AppLocalizations.of(context).folderCreate),
child: Text(FilesLocalizations.of(context).folderCreate),
),
],
),

38
packages/neon/neon_files/lib/l10n/localizations.dart

@ -7,10 +7,10 @@ import 'package:intl/intl.dart' as intl;
import 'localizations_en.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of FilesLocalizations
/// returned by `FilesLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// Applications need to include `FilesLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
@ -18,8 +18,8 @@ import 'localizations_en.dart';
/// import 'l10n/localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// localizationsDelegates: FilesLocalizations.localizationsDelegates,
/// supportedLocales: FilesLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
@ -56,18 +56,18 @@ import 'localizations_en.dart';
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// be consistent with the languages listed in the FilesLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
abstract class FilesLocalizations {
FilesLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
static FilesLocalizations of(BuildContext context) {
return Localizations.of<FilesLocalizations>(context, FilesLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
static const LocalizationsDelegate<FilesLocalizations> delegate = _FilesLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -360,29 +360,29 @@ abstract class AppLocalizations {
String get optionsSizeWarningDisabled;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
class _FilesLocalizationsDelegate extends LocalizationsDelegate<FilesLocalizations> {
const _FilesLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
Future<FilesLocalizations> load(Locale locale) {
return SynchronousFuture<FilesLocalizations>(lookupFilesLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
bool shouldReload(_FilesLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
FilesLocalizations lookupFilesLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
return FilesLocalizationsEn();
}
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
throw FlutterError('FilesLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');

4
packages/neon/neon_files/lib/l10n/localizations_en.dart

@ -1,8 +1,8 @@
import 'localizations.dart';
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
class FilesLocalizationsEn extends FilesLocalizations {
FilesLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get actionYes => 'Yes';

4
packages/neon/neon_files/lib/neon_files.dart

@ -53,10 +53,10 @@ class FilesApp extends AppImplementation<FilesBloc, FilesAppSpecificOptions> {
final String id = AppIDs.files;
@override
final LocalizationsDelegate<AppLocalizations> localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate<FilesLocalizations> localizationsDelegate = FilesLocalizations.delegate;
@override
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = FilesLocalizations.supportedLocales;
@override
late final FilesAppSpecificOptions options = FilesAppSpecificOptions(storage);

26
packages/neon/neon_files/lib/options.dart

@ -18,20 +18,20 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
}
final generalCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).general,
name: (final context) => FilesLocalizations.of(context).general,
);
late final filesSortPropertyOption = SelectOption<FilesSortProperty>(
storage: super.storage,
category: generalCategory,
key: FilesOptionKeys.sortProperty,
label: (final context) => AppLocalizations.of(context).optionsFilesSortProperty,
label: (final context) => FilesLocalizations.of(context).optionsFilesSortProperty,
defaultValue: FilesSortProperty.name,
values: {
FilesSortProperty.name: (final context) => AppLocalizations.of(context).optionsFilesSortPropertyName,
FilesSortProperty.name: (final context) => FilesLocalizations.of(context).optionsFilesSortPropertyName,
FilesSortProperty.modifiedDate: (final context) =>
AppLocalizations.of(context).optionsFilesSortPropertyModifiedDate,
FilesSortProperty.size: (final context) => AppLocalizations.of(context).optionsFilesSortPropertySize,
FilesLocalizations.of(context).optionsFilesSortPropertyModifiedDate,
FilesSortProperty.size: (final context) => FilesLocalizations.of(context).optionsFilesSortPropertySize,
},
);
@ -39,7 +39,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: generalCategory,
key: FilesOptionKeys.sortOrder,
label: (final context) => AppLocalizations.of(context).optionsFilesSortOrder,
label: (final context) => FilesLocalizations.of(context).optionsFilesSortOrder,
defaultValue: SortBoxOrder.ascending,
values: sortBoxOrderOptionValues,
);
@ -48,7 +48,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: generalCategory,
key: FilesOptionKeys.showHiddenFiles,
label: (final context) => AppLocalizations.of(context).optionsShowHiddenFiles,
label: (final context) => FilesLocalizations.of(context).optionsShowHiddenFiles,
defaultValue: false,
);
@ -56,7 +56,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: generalCategory,
key: FilesOptionKeys.showPreviews,
label: (final context) => AppLocalizations.of(context).optionsShowPreviews,
label: (final context) => FilesLocalizations.of(context).optionsShowPreviews,
defaultValue: true,
);
@ -64,7 +64,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: storage,
category: generalCategory,
key: FilesOptionKeys.uploadQueueParallelism,
label: (final context) => AppLocalizations.of(context).optionsUploadQueueParallelism,
label: (final context) => FilesLocalizations.of(context).optionsUploadQueueParallelism,
defaultValue: 4,
values: {
for (var i = 1; i <= 16; i = i * 2) ...{
@ -77,7 +77,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: storage,
category: generalCategory,
key: FilesOptionKeys.downloadQueueParallelism,
label: (final context) => AppLocalizations.of(context).optionsDownloadQueueParallelism,
label: (final context) => FilesLocalizations.of(context).optionsDownloadQueueParallelism,
defaultValue: 4,
values: {
for (var i = 1; i <= 16; i = i * 2) ...{
@ -87,7 +87,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
);
late final _sizeWarningValues = <int?, LabelBuilder>{
null: (final context) => AppLocalizations.of(context).optionsSizeWarningDisabled,
null: (final context) => FilesLocalizations.of(context).optionsSizeWarningDisabled,
for (final i in [
1,
10,
@ -107,7 +107,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: storage,
category: generalCategory,
key: FilesOptionKeys.uploadSizeWarning,
label: (final context) => AppLocalizations.of(context).optionsUploadSizeWarning,
label: (final context) => FilesLocalizations.of(context).optionsUploadSizeWarning,
defaultValue: _mb(10),
values: _sizeWarningValues,
);
@ -116,7 +116,7 @@ class FilesAppSpecificOptions extends NextcloudAppOptions {
storage: storage,
category: generalCategory,
key: FilesOptionKeys.downloadSizeWarning,
label: (final context) => AppLocalizations.of(context).optionsDownloadSizeWarning,
label: (final context) => FilesLocalizations.of(context).optionsDownloadSizeWarning,
defaultValue: _mb(10),
values: _sizeWarningValues,
);

18
packages/neon/neon_files/lib/pages/details.dart

@ -41,23 +41,23 @@ class FilesDetailsPage extends StatelessWidget {
rows: [
for (final entry in {
details.isDirectory
? AppLocalizations.of(context).detailsFolderName
: AppLocalizations.of(context).detailsFileName: details.name,
AppLocalizations.of(context).detailsParentFolder:
? FilesLocalizations.of(context).detailsFolderName
: FilesLocalizations.of(context).detailsFileName: details.name,
FilesLocalizations.of(context).detailsParentFolder:
details.path.length == 1 ? '/' : details.path.sublist(0, details.path.length - 1).join('/'),
if (details.size != null) ...{
details.isDirectory
? AppLocalizations.of(context).detailsFolderSize
: AppLocalizations.of(context).detailsFileSize: filesize(details.size, 1),
? FilesLocalizations.of(context).detailsFolderSize
: FilesLocalizations.of(context).detailsFileSize: filesize(details.size, 1),
},
if (details.lastModified != null) ...{
AppLocalizations.of(context).detailsLastModified:
FilesLocalizations.of(context).detailsLastModified:
details.lastModified!.toLocal().toIso8601String(),
},
if (details.isFavorite != null) ...{
AppLocalizations.of(context).detailsIsFavorite: details.isFavorite!
? AppLocalizations.of(context).actionYes
: AppLocalizations.of(context).actionNo,
FilesLocalizations.of(context).detailsIsFavorite: details.isFavorite!
? FilesLocalizations.of(context).actionYes
: FilesLocalizations.of(context).actionNo,
},
}.entries) ...[
DataRow(

2
packages/neon/neon_files/lib/pages/main.dart

@ -38,7 +38,7 @@ class _FilesMainPageState extends State<FilesMainPage> {
),
);
},
tooltip: AppLocalizations.of(context).uploadFiles,
tooltip: FilesLocalizations.of(context).uploadFiles,
child: const Icon(Icons.add),
),
);

29
packages/neon/neon_files/lib/widgets/actions.dart

@ -40,8 +40,9 @@ class FileActions extends StatelessWidget {
}
final result = await showRenameDialog(
context: context,
title:
details.isDirectory ? AppLocalizations.of(context).folderRename : AppLocalizations.of(context).fileRename,
title: details.isDirectory
? FilesLocalizations.of(context).folderRename
: FilesLocalizations.of(context).fileRename,
value: details.name,
);
if (result != null) {
@ -91,7 +92,7 @@ class FileActions extends StatelessWidget {
if (sizeWarning != null && details.size != null && details.size! > sizeWarning) {
if (!(await showConfirmationDialog(
context,
AppLocalizations.of(context).downloadConfirmSizeWarning(
FilesLocalizations.of(context).downloadConfirmSizeWarning(
filesize(sizeWarning),
filesize(details.size),
),
@ -107,8 +108,8 @@ class FileActions extends StatelessWidget {
if (await showConfirmationDialog(
context,
details.isDirectory
? AppLocalizations.of(context).folderDeleteConfirm(details.name)
: AppLocalizations.of(context).fileDeleteConfirm(details.name),
? FilesLocalizations.of(context).folderDeleteConfirm(details.name)
: FilesLocalizations.of(context).fileDeleteConfirm(details.name),
)) {
bloc.delete(details.path);
}
@ -121,7 +122,7 @@ class FileActions extends StatelessWidget {
if (!details.isDirectory && NeonPlatform.instance.canUseSharing) ...[
PopupMenuItem(
value: FilesFileAction.share,
child: Text(AppLocalizations.of(context).actionShare),
child: Text(FilesLocalizations.of(context).actionShare),
),
],
if (details.isFavorite != null) ...[
@ -129,37 +130,37 @@ class FileActions extends StatelessWidget {
value: FilesFileAction.toggleFavorite,
child: Text(
details.isFavorite!
? AppLocalizations.of(context).removeFromFavorites
: AppLocalizations.of(context).addToFavorites,
? FilesLocalizations.of(context).removeFromFavorites
: FilesLocalizations.of(context).addToFavorites,
),
),
],
PopupMenuItem(
value: FilesFileAction.details,
child: Text(AppLocalizations.of(context).details),
child: Text(FilesLocalizations.of(context).details),
),
PopupMenuItem(
value: FilesFileAction.rename,
child: Text(AppLocalizations.of(context).actionRename),
child: Text(FilesLocalizations.of(context).actionRename),
),
PopupMenuItem(
value: FilesFileAction.move,
child: Text(AppLocalizations.of(context).actionMove),
child: Text(FilesLocalizations.of(context).actionMove),
),
PopupMenuItem(
value: FilesFileAction.copy,
child: Text(AppLocalizations.of(context).actionCopy),
child: Text(FilesLocalizations.of(context).actionCopy),
),
// TODO: https://github.com/provokateurin/nextcloud-neon/issues/4
if (!details.isDirectory) ...[
PopupMenuItem(
value: FilesFileAction.sync,
child: Text(AppLocalizations.of(context).actionSync),
child: Text(FilesLocalizations.of(context).actionSync),
),
],
PopupMenuItem(
value: FilesFileAction.delete,
child: Text(AppLocalizations.of(context).actionDelete),
child: Text(FilesLocalizations.of(context).actionDelete),
),
],
onSelected: (final action) async => onSelected(context, action),

2
packages/neon/neon_files/lib/widgets/file_list_tile.dart

@ -30,7 +30,7 @@ class FileListTile extends StatelessWidget {
if (sizeWarning != null && details.size != null && details.size! > sizeWarning) {
if (!(await showConfirmationDialog(
context,
AppLocalizations.of(context).downloadConfirmSizeWarning(
FilesLocalizations.of(context).downloadConfirmSizeWarning(
filesize(sizeWarning),
filesize(details.size),
),

4
packages/neon/neon_files/lib/widgets/navigator.dart

@ -27,7 +27,7 @@ class FilesBrowserNavigator extends StatelessWidget {
horizontal: VisualDensity.minimumDensity,
vertical: VisualDensity.minimumDensity,
),
tooltip: AppLocalizations.of(context).goToPath(''),
tooltip: FilesLocalizations.of(context).goToPath(''),
icon: const Icon(Icons.house),
onPressed: () {
bloc.setPath([]);
@ -44,7 +44,7 @@ class FilesBrowserNavigator extends StatelessWidget {
},
child: Text(
path.last,
semanticsLabel: AppLocalizations.of(context).goToPath(label),
semanticsLabel: FilesLocalizations.of(context).goToPath(label),
),
);
},

1
packages/neon/neon_news/l10n.yaml

@ -1 +0,0 @@
../neon/l10n.yaml

7
packages/neon/neon_news/l10n.yaml

@ -0,0 +1,7 @@
arb-dir: lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-class: NewsLocalizations
output-dir: lib/l10n
nullable-getter: false

4
packages/neon/neon_news/lib/dialogs/add_feed.dart

@ -52,7 +52,7 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
Widget build(final BuildContext context) => ResultBuilder<List<news.Folder>>.behaviorSubject(
stream: widget.bloc.folders,
builder: (final context, final folders) => NeonDialog(
title: Text(AppLocalizations.of(context).feedAdd),
title: Text(NewsLocalizations.of(context).feedAdd),
children: [
Form(
key: formKey,
@ -97,7 +97,7 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
],
ElevatedButton(
onPressed: folders.hasData ? submit : null,
child: Text(AppLocalizations.of(context).feedAdd),
child: Text(NewsLocalizations.of(context).feedAdd),
),
],
),

6
packages/neon/neon_news/lib/dialogs/create_folder.dart

@ -28,7 +28,7 @@ class _NewsCreateFolderDialogState extends State<NewsCreateFolderDialog> {
@override
Widget build(final BuildContext context) => NeonDialog(
title: Text(AppLocalizations.of(context).folderCreate),
title: Text(NewsLocalizations.of(context).folderCreate),
children: [
Form(
key: formKey,
@ -39,7 +39,7 @@ class _NewsCreateFolderDialogState extends State<NewsCreateFolderDialog> {
autofocus: true,
controller: controller,
decoration: InputDecoration(
hintText: AppLocalizations.of(context).folderCreateName,
hintText: NewsLocalizations.of(context).folderCreateName,
),
validator: (final input) => validateNotEmpty(context, input),
onFieldSubmitted: (final _) {
@ -48,7 +48,7 @@ class _NewsCreateFolderDialogState extends State<NewsCreateFolderDialog> {
),
ElevatedButton(
onPressed: submit,
child: Text(AppLocalizations.of(context).folderCreate),
child: Text(NewsLocalizations.of(context).folderCreate),
),
],
),

6
packages/neon/neon_news/lib/dialogs/feed_show_url.dart

@ -27,19 +27,19 @@ class _NewsFeedShowURLDialogState extends State<NewsFeedShowURLDialog> {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context).feedCopiedURL),
content: Text(NewsLocalizations.of(context).feedCopiedURL),
),
);
Navigator.of(context).pop();
}
},
child: Text(AppLocalizations.of(context).feedCopyURL),
child: Text(NewsLocalizations.of(context).feedCopyURL),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).actionClose),
child: Text(NewsLocalizations.of(context).actionClose),
),
],
);

6
packages/neon/neon_news/lib/dialogs/feed_update_error.dart

@ -27,19 +27,19 @@ class _NewsFeedUpdateErrorDialogState extends State<NewsFeedUpdateErrorDialog> {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context).feedCopiedErrorMessage),
content: Text(NewsLocalizations.of(context).feedCopiedErrorMessage),
),
);
Navigator.of(context).pop();
}
},
child: Text(AppLocalizations.of(context).feedCopyErrorMessage),
child: Text(NewsLocalizations.of(context).feedCopyErrorMessage),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).actionClose),
child: Text(NewsLocalizations.of(context).actionClose),
),
],
);

4
packages/neon/neon_news/lib/dialogs/move_feed.dart

@ -27,7 +27,7 @@ class _NewsMoveFeedDialogState extends State<NewsMoveFeedDialog> {
@override
Widget build(final BuildContext context) => NeonDialog(
title: Text(AppLocalizations.of(context).feedMove),
title: Text(NewsLocalizations.of(context).feedMove),
children: [
Form(
key: formKey,
@ -47,7 +47,7 @@ class _NewsMoveFeedDialogState extends State<NewsMoveFeedDialog> {
),
ElevatedButton(
onPressed: submit,
child: Text(AppLocalizations.of(context).feedMove),
child: Text(NewsLocalizations.of(context).feedMove),
),
],
),

38
packages/neon/neon_news/lib/l10n/localizations.dart

@ -7,10 +7,10 @@ import 'package:intl/intl.dart' as intl;
import 'localizations_en.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of NewsLocalizations
/// returned by `NewsLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// Applications need to include `NewsLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
@ -18,8 +18,8 @@ import 'localizations_en.dart';
/// import 'l10n/localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// localizationsDelegates: NewsLocalizations.localizationsDelegates,
/// supportedLocales: NewsLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
@ -56,18 +56,18 @@ import 'localizations_en.dart';
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// be consistent with the languages listed in the NewsLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
abstract class NewsLocalizations {
NewsLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
static NewsLocalizations of(BuildContext context) {
return Localizations.of<NewsLocalizations>(context, NewsLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
static const LocalizationsDelegate<NewsLocalizations> delegate = _NewsLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -426,29 +426,29 @@ abstract class AppLocalizations {
String get optionsDefaultFolderViewType;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
class _NewsLocalizationsDelegate extends LocalizationsDelegate<NewsLocalizations> {
const _NewsLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
Future<NewsLocalizations> load(Locale locale) {
return SynchronousFuture<NewsLocalizations>(lookupNewsLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
bool shouldReload(_NewsLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
NewsLocalizations lookupNewsLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
return NewsLocalizationsEn();
}
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
throw FlutterError('NewsLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');

4
packages/neon/neon_news/lib/l10n/localizations_en.dart

@ -1,8 +1,8 @@
import 'localizations.dart';
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
class NewsLocalizationsEn extends NewsLocalizations {
NewsLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get actionClose => 'Close';

4
packages/neon/neon_news/lib/neon_news.dart

@ -61,10 +61,10 @@ class NewsApp extends AppImplementation<NewsBloc, NewsAppSpecificOptions> {
final String id = AppIDs.news;
@override
final LocalizationsDelegate<AppLocalizations> localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate<NewsLocalizations> localizationsDelegate = NewsLocalizations.delegate;
@override
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = NewsLocalizations.supportedLocales;
@override
late final NewsAppSpecificOptions options = NewsAppSpecificOptions(storage);

66
packages/neon/neon_news/lib/options.dart

@ -24,31 +24,31 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
}
final generalCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).general,
name: (final context) => NewsLocalizations.of(context).general,
);
final articlesCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).articles,
name: (final context) => NewsLocalizations.of(context).articles,
);
final foldersCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).folders,
name: (final context) => NewsLocalizations.of(context).folders,
);
final feedsCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).feeds,
name: (final context) => NewsLocalizations.of(context).feeds,
);
late final defaultCategoryOption = SelectOption<DefaultCategory>(
storage: super.storage,
category: generalCategory,
key: NewsOptionKeys.defaultCategory,
label: (final context) => AppLocalizations.of(context).optionsDefaultCategory,
label: (final context) => NewsLocalizations.of(context).optionsDefaultCategory,
defaultValue: DefaultCategory.articles,
values: {
DefaultCategory.articles: (final context) => AppLocalizations.of(context).articles,
DefaultCategory.folders: (final context) => AppLocalizations.of(context).folders,
DefaultCategory.feeds: (final context) => AppLocalizations.of(context).feeds,
DefaultCategory.articles: (final context) => NewsLocalizations.of(context).articles,
DefaultCategory.folders: (final context) => NewsLocalizations.of(context).folders,
DefaultCategory.feeds: (final context) => NewsLocalizations.of(context).feeds,
},
);
@ -56,15 +56,15 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: articlesCategory,
key: NewsOptionKeys.articleViewType,
label: (final context) => AppLocalizations.of(context).optionsArticleViewType,
label: (final context) => NewsLocalizations.of(context).optionsArticleViewType,
defaultValue: ArticleViewType.direct,
values: {
ArticleViewType.direct: (final context) => AppLocalizations.of(context).optionsArticleViewTypeDirect,
ArticleViewType.direct: (final context) => NewsLocalizations.of(context).optionsArticleViewTypeDirect,
if (NeonPlatform.instance.canUseWebView)
ArticleViewType.internalBrowser: (final context) =>
AppLocalizations.of(context).optionsArticleViewTypeInternalBrowser,
NewsLocalizations.of(context).optionsArticleViewTypeInternalBrowser,
ArticleViewType.externalBrowser: (final context) =>
AppLocalizations.of(context).optionsArticleViewTypeExternalBrowser,
NewsLocalizations.of(context).optionsArticleViewTypeExternalBrowser,
},
);
@ -72,7 +72,7 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: articlesCategory,
key: NewsOptionKeys.articleDisableMarkAsReadTimeout,
label: (final context) => AppLocalizations.of(context).optionsArticleDisableMarkAsReadTimeout,
label: (final context) => NewsLocalizations.of(context).optionsArticleDisableMarkAsReadTimeout,
defaultValue: false,
);
@ -80,12 +80,12 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: articlesCategory,
key: NewsOptionKeys.defaultArticlesFilter,
label: (final context) => AppLocalizations.of(context).optionsDefaultArticlesFilter,
label: (final context) => NewsLocalizations.of(context).optionsDefaultArticlesFilter,
defaultValue: FilterType.unread,
values: {
FilterType.all: (final context) => AppLocalizations.of(context).articlesFilterAll,
FilterType.unread: (final context) => AppLocalizations.of(context).articlesFilterUnread,
FilterType.starred: (final context) => AppLocalizations.of(context).articlesFilterStarred,
FilterType.all: (final context) => NewsLocalizations.of(context).articlesFilterAll,
FilterType.unread: (final context) => NewsLocalizations.of(context).articlesFilterUnread,
FilterType.starred: (final context) => NewsLocalizations.of(context).articlesFilterStarred,
},
);
@ -93,14 +93,14 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: articlesCategory,
key: NewsOptionKeys.articlesSortProperty,
label: (final context) => AppLocalizations.of(context).optionsArticlesSortProperty,
label: (final context) => NewsLocalizations.of(context).optionsArticlesSortProperty,
defaultValue: ArticlesSortProperty.publishDate,
values: {
ArticlesSortProperty.publishDate: (final context) =>
AppLocalizations.of(context).optionsArticlesSortPropertyPublishDate,
NewsLocalizations.of(context).optionsArticlesSortPropertyPublishDate,
ArticlesSortProperty.alphabetical: (final context) =>
AppLocalizations.of(context).optionsArticlesSortPropertyAlphabetical,
ArticlesSortProperty.byFeed: (final context) => AppLocalizations.of(context).optionsArticlesSortPropertyFeed,
NewsLocalizations.of(context).optionsArticlesSortPropertyAlphabetical,
ArticlesSortProperty.byFeed: (final context) => NewsLocalizations.of(context).optionsArticlesSortPropertyFeed,
},
);
@ -108,7 +108,7 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: articlesCategory,
key: NewsOptionKeys.articlesSortBoxOrder,
label: (final context) => AppLocalizations.of(context).optionsArticlesSortOrder,
label: (final context) => NewsLocalizations.of(context).optionsArticlesSortOrder,
defaultValue: SortBoxOrder.descending,
values: sortBoxOrderOptionValues,
);
@ -117,13 +117,13 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: foldersCategory,
key: NewsOptionKeys.foldersSortProperty,
label: (final context) => AppLocalizations.of(context).optionsFoldersSortProperty,
label: (final context) => NewsLocalizations.of(context).optionsFoldersSortProperty,
defaultValue: FoldersSortProperty.alphabetical,
values: {
FoldersSortProperty.alphabetical: (final context) =>
AppLocalizations.of(context).optionsFoldersSortPropertyAlphabetical,
NewsLocalizations.of(context).optionsFoldersSortPropertyAlphabetical,
FoldersSortProperty.unreadCount: (final context) =>
AppLocalizations.of(context).optionsFoldersSortPropertyUnreadCount,
NewsLocalizations.of(context).optionsFoldersSortPropertyUnreadCount,
},
);
@ -131,7 +131,7 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: foldersCategory,
key: NewsOptionKeys.foldersSortBoxOrder,
label: (final context) => AppLocalizations.of(context).optionsFoldersSortOrder,
label: (final context) => NewsLocalizations.of(context).optionsFoldersSortOrder,
defaultValue: SortBoxOrder.ascending,
values: sortBoxOrderOptionValues,
);
@ -140,11 +140,11 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: foldersCategory,
key: NewsOptionKeys.defaultFolderViewType,
label: (final context) => AppLocalizations.of(context).optionsDefaultFolderViewType,
label: (final context) => NewsLocalizations.of(context).optionsDefaultFolderViewType,
defaultValue: DefaultFolderViewType.articles,
values: {
DefaultFolderViewType.articles: (final context) => AppLocalizations.of(context).articles,
DefaultFolderViewType.feeds: (final context) => AppLocalizations.of(context).feeds,
DefaultFolderViewType.articles: (final context) => NewsLocalizations.of(context).articles,
DefaultFolderViewType.feeds: (final context) => NewsLocalizations.of(context).feeds,
},
);
@ -152,13 +152,13 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: feedsCategory,
key: NewsOptionKeys.feedsSortProperty,
label: (final context) => AppLocalizations.of(context).optionsFeedsSortProperty,
label: (final context) => NewsLocalizations.of(context).optionsFeedsSortProperty,
defaultValue: FeedsSortProperty.alphabetical,
values: {
FeedsSortProperty.alphabetical: (final context) =>
AppLocalizations.of(context).optionsFeedsSortPropertyAlphabetical,
NewsLocalizations.of(context).optionsFeedsSortPropertyAlphabetical,
FeedsSortProperty.unreadCount: (final context) =>
AppLocalizations.of(context).optionsFeedsSortPropertyUnreadCount,
NewsLocalizations.of(context).optionsFeedsSortPropertyUnreadCount,
},
);
@ -166,7 +166,7 @@ class NewsAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: feedsCategory,
key: NewsOptionKeys.feedsSortBoxOrder,
label: (final context) => AppLocalizations.of(context).optionsFeedsSortOrder,
label: (final context) => NewsLocalizations.of(context).optionsFeedsSortOrder,
defaultValue: SortBoxOrder.ascending,
values: sortBoxOrderOptionValues,
);

13
packages/neon/neon_news/lib/pages/article.dart

@ -120,8 +120,9 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
widget.bloc.starArticle();
}
},
tooltip:
starred ? AppLocalizations.of(context).articleUnstar : AppLocalizations.of(context).articleStar,
tooltip: starred
? NewsLocalizations.of(context).articleUnstar
: NewsLocalizations.of(context).articleStar,
icon: Icon(starred ? Icons.star : Icons.star_outline),
);
},
@ -139,8 +140,8 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
}
},
tooltip: unread
? AppLocalizations.of(context).articleMarkRead
: AppLocalizations.of(context).articleMarkUnread,
? NewsLocalizations.of(context).articleMarkRead
: NewsLocalizations.of(context).articleMarkUnread,
icon: Icon(unread ? MdiIcons.email : MdiIcons.emailMarkAsUnread),
);
},
@ -153,14 +154,14 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
mode: LaunchMode.externalApplication,
);
},
tooltip: AppLocalizations.of(context).articleOpenLink,
tooltip: NewsLocalizations.of(context).articleOpenLink,
icon: const Icon(Icons.open_in_new),
),
IconButton(
onPressed: () async {
await Share.share(await _getURL());
},
tooltip: AppLocalizations.of(context).articleShare,
tooltip: NewsLocalizations.of(context).articleShare,
icon: const Icon(Icons.share),
),
],

6
packages/neon/neon_news/lib/pages/main.dart

@ -56,15 +56,15 @@ class _NewsMainPageState extends State<NewsMainPage> {
items: [
BottomNavigationBarItem(
icon: const Icon(Icons.newspaper),
label: AppLocalizations.of(context).articles,
label: NewsLocalizations.of(context).articles,
),
BottomNavigationBarItem(
icon: const Icon(Icons.folder),
label: AppLocalizations.of(context).folders,
label: NewsLocalizations.of(context).folders,
),
BottomNavigationBarItem(
icon: const Icon(Icons.rss_feed),
label: AppLocalizations.of(context).feeds,
label: NewsLocalizations.of(context).feeds,
),
],
),

8
packages/neon/neon_news/lib/widgets/articles_view.dart

@ -73,11 +73,11 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
late final String label;
switch (a) {
case FilterType.all:
label = AppLocalizations.of(context).articlesFilterAll;
label = NewsLocalizations.of(context).articlesFilterAll;
case FilterType.unread:
label = AppLocalizations.of(context).articlesFilterUnread;
label = NewsLocalizations.of(context).articlesFilterUnread;
case FilterType.starred:
label = AppLocalizations.of(context).articlesFilterStarred;
label = NewsLocalizations.of(context).articlesFilterStarred;
default:
throw Exception('FilterType $a should not be shown');
}
@ -167,7 +167,7 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
}
},
tooltip:
article.starred ? AppLocalizations.of(context).articleUnstar : AppLocalizations.of(context).articleStar,
article.starred ? NewsLocalizations.of(context).articleUnstar : NewsLocalizations.of(context).articleStar,
icon: Icon(
article.starred ? Icons.star : Icons.star_outline,
color: Theme.of(context).colorScheme.primary,

2
packages/neon/neon_news/lib/widgets/feed_floating_action_button.dart

@ -25,7 +25,7 @@ class NewsFeedFloatingActionButton extends StatelessWidget {
bloc.addFeed(url, folderId);
}
},
tooltip: AppLocalizations.of(context).feedAdd,
tooltip: NewsLocalizations.of(context).feedAdd,
child: const Icon(Icons.add),
);
}

16
packages/neon/neon_news/lib/widgets/feeds_view.dart

@ -51,7 +51,7 @@ class NewsFeedsView extends StatelessWidget {
: null,
),
subtitle: feed.unreadCount! > 0
? Text(AppLocalizations.of(context).articlesUnread(feed.unreadCount!))
? Text(NewsLocalizations.of(context).articlesUnread(feed.unreadCount!))
: const SizedBox(),
leading: NewsFeedIcon(feed: feed),
trailing: Row(
@ -67,7 +67,7 @@ class NewsFeedsView extends StatelessWidget {
),
);
},
tooltip: AppLocalizations.of(context).feedShowErrorMessage,
tooltip: NewsLocalizations.of(context).feedShowErrorMessage,
iconSize: 30,
icon: Text(
feed.updateErrorCount.toString(),
@ -81,20 +81,20 @@ class NewsFeedsView extends StatelessWidget {
itemBuilder: (final context) => [
PopupMenuItem(
value: NewsFeedAction.showURL,
child: Text(AppLocalizations.of(context).feedShowURL),
child: Text(NewsLocalizations.of(context).feedShowURL),
),
PopupMenuItem(
value: NewsFeedAction.delete,
child: Text(AppLocalizations.of(context).actionDelete),
child: Text(NewsLocalizations.of(context).actionDelete),
),
PopupMenuItem(
value: NewsFeedAction.rename,
child: Text(AppLocalizations.of(context).actionRename),
child: Text(NewsLocalizations.of(context).actionRename),
),
if (folders.isNotEmpty) ...[
PopupMenuItem(
value: NewsFeedAction.move,
child: Text(AppLocalizations.of(context).actionMove),
child: Text(NewsLocalizations.of(context).actionMove),
),
],
],
@ -113,7 +113,7 @@ class NewsFeedsView extends StatelessWidget {
}
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).feedRemoveConfirm(feed.title),
NewsLocalizations.of(context).feedRemoveConfirm(feed.title),
)) {
bloc.removeFeed(feed.id);
}
@ -123,7 +123,7 @@ class NewsFeedsView extends StatelessWidget {
}
final result = await showRenameDialog(
context: context,
title: AppLocalizations.of(context).feedRename,
title: NewsLocalizations.of(context).feedRename,
value: feed.title,
);
if (result != null) {

2
packages/neon/neon_news/lib/widgets/folder_floating_action_button.dart

@ -19,7 +19,7 @@ class NewsFolderFloatingActionButton extends StatelessWidget {
bloc.createFolder(result);
}
},
tooltip: AppLocalizations.of(context).folderCreate,
tooltip: NewsLocalizations.of(context).folderCreate,
child: const Icon(Icons.add),
);
}

4
packages/neon/neon_news/lib/widgets/folder_select.dart

@ -15,12 +15,12 @@ class NewsFolderSelect extends StatelessWidget {
@override
Widget build(final BuildContext context) => DropdownButtonFormField<news.Folder>(
decoration: InputDecoration(
hintText: AppLocalizations.of(context).folder,
hintText: NewsLocalizations.of(context).folder,
),
value: value,
items: [
DropdownMenuItem(
child: Text(AppLocalizations.of(context).folderRoot),
child: Text(NewsLocalizations.of(context).folderRoot),
),
...folders.map(
(final f) => DropdownMenuItem<news.Folder>(

10
packages/neon/neon_news/lib/widgets/folders_view.dart

@ -53,7 +53,7 @@ class NewsFoldersView extends StatelessWidget {
? Theme.of(context).textTheme.titleMedium!.copyWith(color: Theme.of(context).disabledColor)
: null,
),
subtitle: unreadCount > 0 ? Text(AppLocalizations.of(context).articlesUnread(unreadCount)) : const SizedBox(),
subtitle: unreadCount > 0 ? Text(NewsLocalizations.of(context).articlesUnread(unreadCount)) : const SizedBox(),
leading: SizedBox.square(
dimension: largeIconSize,
child: Stack(
@ -78,11 +78,11 @@ class NewsFoldersView extends StatelessWidget {
itemBuilder: (final context) => [
PopupMenuItem(
value: NewsFolderAction.delete,
child: Text(AppLocalizations.of(context).actionDelete),
child: Text(NewsLocalizations.of(context).actionDelete),
),
PopupMenuItem(
value: NewsFolderAction.rename,
child: Text(AppLocalizations.of(context).actionRename),
child: Text(NewsLocalizations.of(context).actionRename),
),
],
onSelected: (final action) async {
@ -90,7 +90,7 @@ class NewsFoldersView extends StatelessWidget {
case NewsFolderAction.delete:
if (await showConfirmationDialog(
context,
AppLocalizations.of(context).folderDeleteConfirm(folder.name),
NewsLocalizations.of(context).folderDeleteConfirm(folder.name),
)) {
bloc.deleteFolder(folder.id);
}
@ -100,7 +100,7 @@ class NewsFoldersView extends StatelessWidget {
}
final result = await showRenameDialog(
context: context,
title: AppLocalizations.of(context).folderRename,
title: NewsLocalizations.of(context).folderRename,
value: folder.name,
);
if (result != null) {

1
packages/neon/neon_notes/l10n.yaml

@ -1 +0,0 @@
../neon/l10n.yaml

7
packages/neon/neon_notes/l10n.yaml

@ -0,0 +1,7 @@
arb-dir: lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-class: NotesLocalizations
output-dir: lib/l10n
nullable-getter: false

6
packages/neon/neon_notes/lib/dialogs/create_note.dart

@ -35,7 +35,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: widget.bloc.notesList,
builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).noteCreate),
title: Text(NotesLocalizations.of(context).noteCreate),
children: [
Form(
key: formKey,
@ -46,7 +46,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
autofocus: true,
controller: controller,
decoration: InputDecoration(
hintText: AppLocalizations.of(context).noteTitle,
hintText: NotesLocalizations.of(context).noteTitle,
),
validator: (final input) => validateNotEmpty(context, input),
onFieldSubmitted: (final _) {
@ -77,7 +77,7 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
],
ElevatedButton(
onPressed: submit,
child: Text(AppLocalizations.of(context).noteCreate),
child: Text(NotesLocalizations.of(context).noteCreate),
),
],
),

4
packages/neon/neon_notes/lib/dialogs/select_category.dart

@ -29,7 +29,7 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
Widget build(final BuildContext context) => ResultBuilder<List<notes.Note>>.behaviorSubject(
stream: widget.bloc.notesList,
builder: (final context, final notes) => NeonDialog(
title: Text(AppLocalizations.of(context).category),
title: Text(NotesLocalizations.of(context).category),
children: [
Form(
key: formKey,
@ -59,7 +59,7 @@ class _NotesSelectCategoryDialogState extends State<NotesSelectCategoryDialog> {
],
ElevatedButton(
onPressed: submit,
child: Text(AppLocalizations.of(context).noteSetCategory),
child: Text(NotesLocalizations.of(context).noteSetCategory),
),
],
),

38
packages/neon/neon_notes/lib/l10n/localizations.dart

@ -7,10 +7,10 @@ import 'package:intl/intl.dart' as intl;
import 'localizations_en.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of NotesLocalizations
/// returned by `NotesLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// Applications need to include `NotesLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
@ -18,8 +18,8 @@ import 'localizations_en.dart';
/// import 'l10n/localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// localizationsDelegates: NotesLocalizations.localizationsDelegates,
/// supportedLocales: NotesLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
@ -56,18 +56,18 @@ import 'localizations_en.dart';
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// be consistent with the languages listed in the NotesLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
abstract class NotesLocalizations {
NotesLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
static NotesLocalizations of(BuildContext context) {
return Localizations.of<NotesLocalizations>(context, NotesLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
static const LocalizationsDelegate<NotesLocalizations> delegate = _NotesLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -264,29 +264,29 @@ abstract class AppLocalizations {
String get optionsCategoriesSortPropertyNotesCount;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
class _NotesLocalizationsDelegate extends LocalizationsDelegate<NotesLocalizations> {
const _NotesLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
Future<NotesLocalizations> load(Locale locale) {
return SynchronousFuture<NotesLocalizations>(lookupNotesLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
bool shouldReload(_NotesLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
NotesLocalizations lookupNotesLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
return NotesLocalizationsEn();
}
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
throw FlutterError('NotesLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');

4
packages/neon/neon_notes/lib/l10n/localizations_en.dart

@ -1,8 +1,8 @@
import 'localizations.dart';
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
class NotesLocalizationsEn extends NotesLocalizations {
NotesLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get errorChangedOnServer => 'The note has been changed on the server. Please refresh and try again';

4
packages/neon/neon_notes/lib/neon_notes.dart

@ -50,10 +50,10 @@ class NotesApp extends AppImplementation<NotesBloc, NotesAppSpecificOptions> {
final String id = AppIDs.notes;
@override
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = NotesLocalizations.supportedLocales;
@override
final LocalizationsDelegate<AppLocalizations> localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate<NotesLocalizations> localizationsDelegate = NotesLocalizations.delegate;
@override
late final NotesAppSpecificOptions options = NotesAppSpecificOptions(storage);

34
packages/neon/neon_notes/lib/options.dart

@ -18,26 +18,26 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
}
final generalCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).general,
name: (final context) => NotesLocalizations.of(context).general,
);
final notesCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).notes,
name: (final context) => NotesLocalizations.of(context).notes,
);
final categoriesCategory = OptionsCategory(
name: (final context) => AppLocalizations.of(context).categories,
name: (final context) => NotesLocalizations.of(context).categories,
);
late final defaultCategoryOption = SelectOption<DefaultCategory>(
storage: super.storage,
category: generalCategory,
key: NotesOptionKeys.defaultCategory,
label: (final context) => AppLocalizations.of(context).optionsDefaultCategory,
label: (final context) => NotesLocalizations.of(context).optionsDefaultCategory,
defaultValue: DefaultCategory.notes,
values: {
DefaultCategory.notes: (final context) => AppLocalizations.of(context).notes,
DefaultCategory.categories: (final context) => AppLocalizations.of(context).categories,
DefaultCategory.notes: (final context) => NotesLocalizations.of(context).notes,
DefaultCategory.categories: (final context) => NotesLocalizations.of(context).categories,
},
);
@ -45,11 +45,11 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: generalCategory,
key: NotesOptionKeys.defaultNoteViewType,
label: (final context) => AppLocalizations.of(context).optionsDefaultNoteViewType,
label: (final context) => NotesLocalizations.of(context).optionsDefaultNoteViewType,
defaultValue: DefaultNoteViewType.preview,
values: {
DefaultNoteViewType.preview: (final context) => AppLocalizations.of(context).optionsDefaultNoteViewTypePreview,
DefaultNoteViewType.edit: (final context) => AppLocalizations.of(context).optionsDefaultNoteViewTypeEdit,
DefaultNoteViewType.preview: (final context) => NotesLocalizations.of(context).optionsDefaultNoteViewTypePreview,
DefaultNoteViewType.edit: (final context) => NotesLocalizations.of(context).optionsDefaultNoteViewTypeEdit,
},
);
@ -57,13 +57,13 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: notesCategory,
key: NotesOptionKeys.notesSortProperty,
label: (final context) => AppLocalizations.of(context).optionsNotesSortProperty,
label: (final context) => NotesLocalizations.of(context).optionsNotesSortProperty,
defaultValue: NotesSortProperty.lastModified,
values: {
NotesSortProperty.lastModified: (final context) =>
AppLocalizations.of(context).optionsNotesSortPropertyLastModified,
NotesLocalizations.of(context).optionsNotesSortPropertyLastModified,
NotesSortProperty.alphabetical: (final context) =>
AppLocalizations.of(context).optionsNotesSortPropertyAlphabetical,
NotesLocalizations.of(context).optionsNotesSortPropertyAlphabetical,
},
);
@ -71,7 +71,7 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: notesCategory,
key: NotesOptionKeys.notesSortBoxOrder,
label: (final context) => AppLocalizations.of(context).optionsNotesSortOrder,
label: (final context) => NotesLocalizations.of(context).optionsNotesSortOrder,
defaultValue: SortBoxOrder.descending,
values: sortBoxOrderOptionValues,
);
@ -80,13 +80,13 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: categoriesCategory,
key: NotesOptionKeys.categoriesSortProperty,
label: (final context) => AppLocalizations.of(context).optionsCategoriesSortProperty,
label: (final context) => NotesLocalizations.of(context).optionsCategoriesSortProperty,
defaultValue: CategoriesSortProperty.alphabetical,
values: {
CategoriesSortProperty.alphabetical: (final context) =>
AppLocalizations.of(context).optionsCategoriesSortPropertyAlphabetical,
NotesLocalizations.of(context).optionsCategoriesSortPropertyAlphabetical,
CategoriesSortProperty.notesCount: (final context) =>
AppLocalizations.of(context).optionsCategoriesSortPropertyNotesCount,
NotesLocalizations.of(context).optionsCategoriesSortPropertyNotesCount,
},
);
@ -94,7 +94,7 @@ class NotesAppSpecificOptions extends NextcloudAppOptions {
storage: super.storage,
category: categoriesCategory,
key: NotesOptionKeys.categoriesSortBoxOrder,
label: (final context) => AppLocalizations.of(context).optionsCategoriesSortOrder,
label: (final context) => NotesLocalizations.of(context).optionsCategoriesSortOrder,
defaultValue: SortBoxOrder.ascending,
values: sortBoxOrderOptionValues,
);

2
packages/neon/neon_notes/lib/pages/category.dart

@ -14,7 +14,7 @@ class NotesCategoryPage extends StatelessWidget {
Widget build(final BuildContext context) => Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(category.name.isNotEmpty ? category.name : AppLocalizations.of(context).categoryUncategorized),
title: Text(category.name.isNotEmpty ? category.name : NotesLocalizations.of(context).categoryUncategorized),
),
body: NotesView(
bloc: bloc,

4
packages/neon/neon_notes/lib/pages/main.dart

@ -52,11 +52,11 @@ class _NotesMainPageState extends State<NotesMainPage> {
items: [
BottomNavigationBarItem(
icon: const Icon(Icons.note),
label: AppLocalizations.of(context).notes,
label: NotesLocalizations.of(context).notes,
),
BottomNavigationBarItem(
icon: const Icon(MdiIcons.tag),
label: AppLocalizations.of(context).categories,
label: NotesLocalizations.of(context).categories,
),
],
),

6
packages/neon/neon_notes/lib/pages/note.dart

@ -107,8 +107,8 @@ class _NotesNotePageState extends State<NotesNotePage> {
}
},
tooltip: _showEditor
? AppLocalizations.of(context).noteShowPreview
: AppLocalizations.of(context).noteShowEditor,
? NotesLocalizations.of(context).noteShowPreview
: NotesLocalizations.of(context).noteShowEditor,
icon: Icon(
_showEditor ? Icons.visibility : Icons.edit,
),
@ -131,7 +131,7 @@ class _NotesNotePageState extends State<NotesNotePage> {
widget.bloc.updateCategory(result);
}
},
tooltip: AppLocalizations.of(context).noteChangeCategory,
tooltip: NotesLocalizations.of(context).noteChangeCategory,
icon: Icon(
MdiIcons.tag,
color: category.isNotEmpty ? NotesCategoryColor.compute(category) : null,

2
packages/neon/neon_notes/lib/utils/exception_handler.dart

@ -2,7 +2,7 @@ part of '../neon_notes.dart';
void handleNotesException(final BuildContext context, final Object error) {
if (error is DynamiteApiException && error.statusCode == 412) {
NeonError.showSnackbar(context, AppLocalizations.of(context).errorChangedOnServer);
NeonError.showSnackbar(context, NotesLocalizations.of(context).errorChangedOnServer);
} else {
NeonError.showSnackbar(context, error);
}

4
packages/neon/neon_notes/lib/widgets/categories_view.dart

@ -44,8 +44,8 @@ class NotesCategoriesView extends StatelessWidget {
final NoteCategory category,
) =>
ListTile(
title: Text(category.name.isNotEmpty ? category.name : AppLocalizations.of(context).categoryUncategorized),
subtitle: Text(AppLocalizations.of(context).categoryNotesCount(category.count)),
title: Text(category.name.isNotEmpty ? category.name : NotesLocalizations.of(context).categoryUncategorized),
subtitle: Text(NotesLocalizations.of(context).categoryNotesCount(category.count)),
leading: category.name.isNotEmpty
? Icon(
MdiIcons.tag,

4
packages/neon/neon_notes/lib/widgets/category_select.dart

@ -47,7 +47,7 @@ class NotesCategorySelect extends StatelessWidget {
controller: textEditingController,
focusNode: focusNode,
decoration: InputDecoration(
hintText: AppLocalizations.of(context).category,
hintText: NotesLocalizations.of(context).category,
),
onFieldSubmitted: (final value) {
onChanged(value);
@ -74,7 +74,7 @@ class NotesCategorySelect extends StatelessWidget {
color: option.isNotEmpty ? NotesCategoryColor.compute(option) : null,
),
title: Text(
option.isNotEmpty ? option : AppLocalizations.of(context).categoryUncategorized,
option.isNotEmpty ? option : NotesLocalizations.of(context).categoryUncategorized,
),
onTap: () {
onSelected(option);

2
packages/neon/neon_notes/lib/widgets/notes_floating_action_button.dart

@ -28,7 +28,7 @@ class NotesFloatingActionButton extends StatelessWidget {
);
}
},
tooltip: AppLocalizations.of(context).noteCreate,
tooltip: NotesLocalizations.of(context).noteCreate,
child: const Icon(Icons.add),
);
}

4
packages/neon/neon_notes/lib/widgets/notes_view.dart

@ -69,7 +69,7 @@ class NotesView extends StatelessWidget {
favorite: !note.favorite,
);
},
tooltip: note.favorite ? AppLocalizations.of(context).noteUnstar : AppLocalizations.of(context).noteStar,
tooltip: note.favorite ? NotesLocalizations.of(context).noteUnstar : NotesLocalizations.of(context).noteStar,
icon: Icon(
note.favorite ? Icons.star : Icons.star_outline,
color: Theme.of(context).colorScheme.primary,
@ -91,7 +91,7 @@ class NotesView extends StatelessWidget {
onLongPress: () async {
final result = await showConfirmationDialog(
context,
AppLocalizations.of(context).noteDeleteConfirm(note.title),
NotesLocalizations.of(context).noteDeleteConfirm(note.title),
);
if (result) {
bloc.deleteNote(note.id);

1
packages/neon/neon_notifications/l10n.yaml

@ -1 +0,0 @@
../neon/l10n.yaml

7
packages/neon/neon_notifications/l10n.yaml

@ -0,0 +1,7 @@
arb-dir: lib/l10n
template-arb-file: en.arb
output-localization-file: localizations.dart
synthetic-package: false
output-class: NotificationsLocalizations
output-dir: lib/l10n
nullable-getter: false

38
packages/neon/neon_notifications/lib/l10n/localizations.dart

@ -7,10 +7,10 @@ import 'package:intl/intl.dart' as intl;
import 'localizations_en.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of NotificationsLocalizations
/// returned by `NotificationsLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// Applications need to include `NotificationsLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
@ -18,8 +18,8 @@ import 'localizations_en.dart';
/// import 'l10n/localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// localizationsDelegates: NotificationsLocalizations.localizationsDelegates,
/// supportedLocales: NotificationsLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
@ -56,18 +56,18 @@ import 'localizations_en.dart';
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// be consistent with the languages listed in the NotificationsLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
abstract class NotificationsLocalizations {
NotificationsLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
static NotificationsLocalizations of(BuildContext context) {
return Localizations.of<NotificationsLocalizations>(context, NotificationsLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
static const LocalizationsDelegate<NotificationsLocalizations> delegate = _NotificationsLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -108,29 +108,29 @@ abstract class AppLocalizations {
String get notificationAppNotImplementedYet;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
class _NotificationsLocalizationsDelegate extends LocalizationsDelegate<NotificationsLocalizations> {
const _NotificationsLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
Future<NotificationsLocalizations> load(Locale locale) {
return SynchronousFuture<NotificationsLocalizations>(lookupNotificationsLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
bool shouldReload(_NotificationsLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
NotificationsLocalizations lookupNotificationsLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
return NotificationsLocalizationsEn();
}
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
throw FlutterError('NotificationsLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');

4
packages/neon/neon_notifications/lib/l10n/localizations_en.dart

@ -1,8 +1,8 @@
import 'localizations.dart';
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
class NotificationsLocalizationsEn extends NotificationsLocalizations {
NotificationsLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get actionClose => 'Close';

4
packages/neon/neon_notifications/lib/neon_notifications.dart

@ -32,10 +32,10 @@ class NotificationsApp extends AppImplementation<NotificationsBloc, Notification
final String id = AppIDs.notifications;
@override
final LocalizationsDelegate<AppLocalizations> localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate<NotificationsLocalizations> localizationsDelegate = NotificationsLocalizations.delegate;
@override
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = NotificationsLocalizations.supportedLocales;
@override
late final NotificationsAppSpecificOptions options = NotificationsAppSpecificOptions(storage);

6
packages/neon/neon_notifications/lib/pages/main.dart

@ -34,7 +34,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
final unreadCount = snapshot.data ?? 0;
return FloatingActionButton(
onPressed: unreadCount > 0 ? bloc.deleteAllNotifications : null,
tooltip: AppLocalizations.of(context).notificationsDismissAll,
tooltip: NotificationsLocalizations.of(context).notificationsDismissAll,
child: const Icon(MdiIcons.checkAll),
);
},
@ -101,7 +101,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
await showDialog<void>(
context: context,
builder: (final context) => AlertDialog(
title: Text(AppLocalizations.of(context).notificationAppNotImplementedYet),
title: Text(NotificationsLocalizations.of(context).notificationAppNotImplementedYet),
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
@ -111,7 +111,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).actionClose),
child: Text(NotificationsLocalizations.of(context).actionClose),
),
],
),

Loading…
Cancel
Save