From 3a2616741e79f00c8bdfcbe4e1e4430112cd2cbf Mon Sep 17 00:00:00 2001 From: Kristen McWilliam <9575627+Merrit@users.noreply.github.com> Date: Mon, 30 Jan 2023 17:43:58 -0500 Subject: [PATCH] feat: add support for localizations --- l10n.yaml | 3 + lib/app.dart | 3 + lib/apps_list/widgets/window_tile.dart | 27 ++-- lib/core/widgets/input_dialog.dart | 9 +- lib/localization/app_en.arb | 153 ++++++++++++++++++ lib/logs/log_page.dart | 12 +- lib/settings/settings_page.dart | 13 +- lib/settings/widgets/about_section.dart | 17 +- lib/settings/widgets/behaviour_section.dart | 47 ++++-- lib/settings/widgets/donate.dart | 17 +- lib/settings/widgets/integration_section.dart | 19 ++- lib/settings/widgets/theme_section.dart | 17 +- lib/theme/styles.dart | 4 + pubspec.lock | 15 +- pubspec.yaml | 6 +- 15 files changed, 305 insertions(+), 57 deletions(-) create mode 100644 l10n.yaml create mode 100644 lib/localization/app_en.arb diff --git a/l10n.yaml b/l10n.yaml new file mode 100644 index 00000000..bfbe7c06 --- /dev/null +++ b/l10n.yaml @@ -0,0 +1,3 @@ +arb-dir: lib/localization +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart diff --git a/lib/app.dart b/lib/app.dart index 6bd3ea11..2c4c5e87 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:tray_manager/tray_manager.dart'; import 'package:window_manager/window_manager.dart'; @@ -70,6 +71,8 @@ class _AppState extends State with TrayListener, WindowListener { title: 'Nyrna', debugShowCheckedModeBanner: false, theme: state.themeData, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, routes: { LoadingPage.id: (context) => const LoadingPage(), LogPage.id: (context) => LogPage(), diff --git a/lib/apps_list/widgets/window_tile.dart b/lib/apps_list/widgets/window_tile.dart index 17b46362..f8d6c348 100644 --- a/lib/apps_list/widgets/window_tile.dart +++ b/lib/apps_list/widgets/window_tile.dart @@ -1,6 +1,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:helpers/helpers.dart'; import 'package:libadwaita/libadwaita.dart'; @@ -187,29 +188,37 @@ class _DetailsDialog extends StatelessWidget { @override Widget build(BuildContext context) { return GtkDialog( - title: const Center(child: Text('Details')), + title: Center( + child: Text( + AppLocalizations.of(context)!.detailsDialogTitle, + ), + ), padding: const EdgeInsets.all(12), children: [ _ErrorMessage(interactionError), ListTile( - title: const Text('Window Title'), + title: Text( + AppLocalizations.of(context)!.detailsDialogWindowTitle, + ), subtitle: SelectableText(window.title), - // trailing: Text(window.title), ), ListTile( - title: const Text('Executable Name'), + title: Text( + AppLocalizations.of(context)!.detailsDialogExecutableName, + ), subtitle: SelectableText(window.process.executable), - // trailing: Text(window.title), ), ListTile( - title: const Text('PID'), + title: Text( + AppLocalizations.of(context)!.detailsDialogPID, + ), subtitle: SelectableText(window.process.pid.toString()), - // trailing: Text(window.title), ), ListTile( - title: const Text('Current Status'), + title: Text( + AppLocalizations.of(context)!.detailsDialogCurrentStatus, + ), subtitle: SelectableText(window.process.status.name), - // trailing: Text(window.title), ), ], ); diff --git a/lib/core/widgets/input_dialog.dart b/lib/core/widgets/input_dialog.dart index 094045b0..dd477e03 100644 --- a/lib/core/widgets/input_dialog.dart +++ b/lib/core/widgets/input_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; /// Allows to easily specify dialog properties such as the text field only /// accepting input as a double, which type of soft keyboard to show, etc. @@ -124,11 +125,15 @@ class InputDialog extends StatelessWidget { actions: [ TextButton( onPressed: () => Navigator.pop(context), - child: const Text('Cancel'), + child: Text( + AppLocalizations.of(context)!.cancel, + ), ), TextButton( onPressed: () => Navigator.pop(context, controller.text), - child: const Text('Confirm'), + child: Text( + AppLocalizations.of(context)!.confirm, + ), ), ], ), diff --git a/lib/localization/app_en.arb b/lib/localization/app_en.arb new file mode 100644 index 00000000..63b62041 --- /dev/null +++ b/lib/localization/app_en.arb @@ -0,0 +1,153 @@ +{ + "cancel": "Cancel", + "@cancel": { + "description": "Label for a cancel button" + }, + "confirm": "Confirm", + "@confirm": { + "description": "Label for a confirm button" + }, + "@_DETAILS_DIALOG": {}, + "detailsDialogTitle": "Details", + "@detailsDialogTitle": { + "description": "The title of the details dialog" + }, + "detailsDialogWindowTitle": "Window Title", + "@detailsDialogWindowTitle": { + "description": "Label for the window title field in the details dialog" + }, + "detailsDialogExecutableName": "Executable Name", + "@detailsDialogExecutableName": { + "description": "Label for the executable name field in the details dialog" + }, + "detailsDialogPID": "PID", + "@detailsDialogPID": { + "description": "Label for the PID field in the details dialog" + }, + "detailsDialogCurrentStatus": "Current Status", + "@detailsDialogCurrentStatus": { + "description": "Label for the current status field in the details dialog" + }, + "@_LOGS_PAGE": {}, + "copyLogs": "Copy logs", + "@copyLogs": { + "description": "Label for the copy logs button" + }, + "logsCopiedNotification": "Logs copied to clipboard", + "@logsCopiedNotification": { + "description": "Notification displayed when logs are copied to clipboard" + }, + "@_SETTINGS": {}, + "donate": "Donate", + "@donate": { + "description": "Label for the donate button" + }, + "donateMessage": "If you like this application, please consider donating to support its development.", + "@donateMessage": { + "description": "Message displayed on the donate page" + }, + "madeBy": "Made with 💙 by ", + "@madeBy": { + "description": "Introduction to application author" + }, + "settingsTitle": "Settings", + "@settingsTitle": { + "description": "The title of the settings page" + }, + "@_SETTINGS_BEHAVIOUR_SECTION": {}, + "behaviourTitle": "Behaviour", + "@behaviourTitle": { + "description": "The title of the behaviour section of the settings page." + }, + "autoRefresh": "Auto Refresh", + "@autoRefresh": { + "description": "Label for the auto refresh setting" + }, + "autoRefreshDescription": "Update window & process info automatically", + "@autoRefreshDescription": { + "description": "Description for the auto refresh setting" + }, + "autoRefreshInterval": "Auto Refresh Interval", + "@autoRefreshInterval": { + "description": "Label for the auto refresh interval setting" + }, + "autoRefreshIntervalAmount": "{interval} seconds", + "@autoRefreshIntervalAmount": { + "description": "The amount of time between auto refreshes", + "placeholders": { + "interval": { + "type": "int", + "example": "5" + } + } + }, + "closeToTray": "Close to tray", + "@closeToTray": { + "description": "Label for the close to tray setting" + }, + "minimizeAndRestoreWindows": "Minimize / restore windows", + "@minimizeAndRestoreWindows": { + "description": "Label for the minimize / restore windows setting" + }, + "showHiddenWindows": "Show hidden windows", + "@showHiddenWindows": { + "description": "Label for the show hidden windows setting" + }, + "showHiddenWindowsTooltip": "Includes windows from other virtual desktops and special windows that are not normally detected.", + "@showHiddenWindowsTooltip": { + "description": "Tooltip for the show hidden windows setting" + }, + "@_SETTINGS_THEME_SECTION": {}, + "themeTitle": "Theme", + "dark": "Dark", + "@dark": { + "description": "Label for the dark theme setting" + }, + "light": "Light", + "@light": { + "description": "Label for the light theme setting" + }, + "pitchBlack": "Pitch Black", + "@pitchBlack": { + "description": "Label for the pitch black theme setting" + }, + "@_SETTINGS_INTEGRATION_SECTION": {}, + "systemIntegrationTitle": "System Integration", + "@systemIntegrationTitle": { + "description": "The title of the system integration section of the settings page." + }, + "startAutomatically": "Start automatically at system boot", + "@startAutomatically": { + "description": "Label for the start automatically at system boot setting" + }, + "startInTray": "Start hidden in system tray", + "@startInTray": { + "description": "Label for the start hidden in system tray setting" + }, + "@_SETTINGS_TROUBLESHOOTING_SECTION": {}, + "troubleshootingTitle": "Troubleshooting", + "@troubleshootingTitle": { + "description": "The title of the troubleshooting section of the settings page." + }, + "logs": "Logs", + "@logs": { + "description": "Label for the logs button" + }, + "@_SETTINGS_ABOUT_SECTION": {}, + "aboutTitle": "About", + "@aboutTitle": { + "description": "The title of the about section of the settings page." + }, + "version": "Nyrna version", + "@version": { + "description": "Label for the version number" + }, + "homepage": "Nyrna homepage", + "@homepage": { + "description": "Label for the homepage link" + }, + "repository": "GitHub repository", + "@repository": { + "description": "Label for the repository link" + } +} diff --git a/lib/logs/log_page.dart b/lib/logs/log_page.dart index 3d8f4e63..bf5022f9 100644 --- a/lib/logs/log_page.dart +++ b/lib/logs/log_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'logs.dart'; @@ -26,6 +27,7 @@ class LogPage extends StatelessWidget { builder: (context, state) { return ElevatedButton( onPressed: () async { + final appLocalizations = AppLocalizations.of(context)!; final scaffoldMessenger = ScaffoldMessenger.of(context); // Copy the visible logs to user's clipboard. await Clipboard.setData( @@ -33,12 +35,16 @@ class LogPage extends StatelessWidget { ); scaffoldMessenger.showSnackBar( - const SnackBar( - content: Text('Logs copied to clipboard'), + SnackBar( + content: Text( + appLocalizations.logsCopiedNotification, + ), ), ); }, - child: const Text('Copy logs'), + child: Text( + AppLocalizations.of(context)!.copyLogs, + ), ); }, ), diff --git a/lib/settings/settings_page.dart b/lib/settings/settings_page.dart index a2e14cb8..5d3ea4a7 100644 --- a/lib/settings/settings_page.dart +++ b/lib/settings/settings_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../logs/logs.dart'; import '../theme/styles.dart'; @@ -14,7 +15,9 @@ class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text('Settings')), + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.settingsTitle), + ), body: Scrollbar( controller: scrollController, thumbVisibility: true, @@ -32,10 +35,14 @@ class SettingsPage extends StatelessWidget { const ThemeSection(), const IntegrationSection(), Spacers.verticalMedium, - const Text('Troubleshooting'), + Text( + AppLocalizations.of(context)!.troubleshootingTitle, + ), ListTile( leading: const Icon(Icons.article_outlined), - title: const Text('Logs'), + title: Text( + AppLocalizations.of(context)!.logs, + ), onTap: () => Navigator.pushNamed(context, LogPage.id), ), Spacers.verticalMedium, diff --git a/lib/settings/widgets/about_section.dart b/lib/settings/widgets/about_section.dart index 1a02b7c5..fc42a64d 100644 --- a/lib/settings/widgets/about_section.dart +++ b/lib/settings/widgets/about_section.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../app/app.dart'; import '../../apps_list/apps_list.dart'; @@ -12,10 +13,14 @@ class AboutSection extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('About'), + Text( + AppLocalizations.of(context)!.aboutTitle, + ), ListTile( leading: const Icon(Icons.info_outline), - title: const Text('Nyrna version'), + title: Text( + AppLocalizations.of(context)!.version, + ), subtitle: BlocBuilder( builder: (context, state) { return Text(state.runningVersion); @@ -24,14 +29,18 @@ class AboutSection extends StatelessWidget { ), ListTile( leading: const Icon(Icons.launch), - title: const Text('Nyrna homepage'), + title: Text( + AppLocalizations.of(context)!.homepage, + ), onTap: () => AppCubit.instance.launchURL( 'https://nyrna.merritt.codes', ), ), ListTile( leading: const Icon(Icons.launch), - title: const Text('GitHub repository'), + title: Text( + AppLocalizations.of(context)!.repository, + ), onTap: () => AppCubit.instance.launchURL( 'https://github.com/Merrit/nyrna', ), diff --git a/lib/settings/widgets/behaviour_section.dart b/lib/settings/widgets/behaviour_section.dart index d0f1d094..245f669a 100644 --- a/lib/settings/widgets/behaviour_section.dart +++ b/lib/settings/widgets/behaviour_section.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; import '../../core/core.dart'; @@ -17,12 +18,18 @@ class BehaviourSection extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('Behaviour'), + Text( + AppLocalizations.of(context)!.behaviourTitle, + ), Spacers.verticalXtraSmall, ListTile( - title: const Text('Auto Refresh'), + title: Text( + AppLocalizations.of(context)!.autoRefresh, + ), leading: const Icon(Icons.refresh), - subtitle: const Text('Update window & process info automatically'), + subtitle: Text( + AppLocalizations.of(context)!.autoRefreshDescription, + ), trailing: BlocBuilder( builder: (context, state) { return Switch( @@ -38,8 +45,13 @@ class BehaviourSection extends StatelessWidget { builder: (context, state) { return ListTile( leading: const Icon(Icons.timelapse), - title: const Text('Auto Refresh Interval'), - trailing: Text('${state.refreshInterval} seconds'), + title: Text( + AppLocalizations.of(context)!.autoRefreshInterval, + ), + trailing: Text( + AppLocalizations.of(context)! + .autoRefreshIntervalAmount(state.refreshInterval), + ), enabled: state.autoRefresh, onTap: () => _showRefreshIntervalDialog(context), ); @@ -47,7 +59,9 @@ class BehaviourSection extends StatelessWidget { ), const HotkeyConfigWidget(), ListTile( - title: const Text('Close to tray'), + title: Text( + AppLocalizations.of(context)!.closeToTray, + ), leading: const Icon(Icons.bedtime), trailing: BlocBuilder( builder: (context, state) { @@ -61,7 +75,9 @@ class BehaviourSection extends StatelessWidget { ), ), ListTile( - title: const Text('Minimize / restore windows'), + title: Text( + AppLocalizations.of(context)!.minimizeAndRestoreWindows, + ), leading: const Icon(Icons.minimize), trailing: BlocBuilder( builder: (context, state) { @@ -84,7 +100,7 @@ class BehaviourSection extends StatelessWidget { final result = await showInputDialog( context: context, type: InputDialogs.onlyInt, - title: 'Auto Refresh Interval', + title: AppLocalizations.of(context)!.autoRefreshInterval, initialValue: settingsCubit.state.refreshInterval.toString(), ); if (result == null) return; @@ -215,17 +231,16 @@ class ShowHiddenTile extends StatelessWidget { @override Widget build(BuildContext context) { return ListTile( - // title: const Text('Show hidden windows'), - title: const Text.rich( + title: Text.rich( TextSpan( children: [ - TextSpan(text: 'Show hidden windows '), + TextSpan( + text: '${AppLocalizations.of(context)!.showHiddenWindows} ', + ), WidgetSpan( child: Tooltip( - message: 'Includes windows from other virtual desktops ' - 'and special windows that are not normally detected.', - // textStyle: TextStyle(fontSize: 16), - child: Icon( + message: AppLocalizations.of(context)!.showHiddenWindowsTooltip, + child: const Icon( Icons.help_outline, size: 18, ), @@ -235,8 +250,6 @@ class ShowHiddenTile extends StatelessWidget { ), ), leading: const Icon(Icons.refresh), - // subtitle: const Text('Includes windows from other virtual desktops ' - // 'and special windows that are not normally detected'), trailing: BlocBuilder( builder: (context, state) { return Switch( diff --git a/lib/settings/widgets/donate.dart b/lib/settings/widgets/donate.dart index c6b66de9..3d8246f5 100644 --- a/lib/settings/widgets/donate.dart +++ b/lib/settings/widgets/donate.dart @@ -1,5 +1,6 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../app/app.dart'; import '../../theme/styles.dart'; @@ -18,8 +19,12 @@ class Donate extends StatelessWidget { Text.rich( TextSpan( children: [ - const TextSpan( - text: 'Nyrna is free software, made with 💙 by '), + TextSpan( + text: AppLocalizations.of(context)!.madeBy, + style: const TextStyle( + fontFamily: emojiFont, + ), + ), TextSpan( text: 'Kristen McWilliam', style: const TextStyle(color: Colors.lightBlueAccent), @@ -32,6 +37,10 @@ class Donate extends StatelessWidget { ], ), ), + Text( + AppLocalizations.of(context)!.donateMessage, + textAlign: TextAlign.center, + ), Spacers.verticalXtraSmall, FilledButton.icon( onPressed: () { @@ -41,7 +50,9 @@ class Donate extends StatelessWidget { Icons.favorite, color: Colors.red, ), - label: const Text('Donate'), + label: Text( + AppLocalizations.of(context)!.donate, + ), ), ], ), diff --git a/lib/settings/widgets/integration_section.dart b/lib/settings/widgets/integration_section.dart index e7a4df71..383342c6 100644 --- a/lib/settings/widgets/integration_section.dart +++ b/lib/settings/widgets/integration_section.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../theme/styles.dart'; import '../settings.dart'; @@ -12,12 +13,14 @@ class IntegrationSection extends StatelessWidget { Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: const [ + children: [ Spacers.verticalMedium, - Text('System Integration'), + Text( + AppLocalizations.of(context)!.systemIntegrationTitle, + ), Spacers.verticalXtraSmall, - _AutostartTile(), - _StartHiddenTile(), + const _AutostartTile(), + const _StartHiddenTile(), ], ); } @@ -32,7 +35,9 @@ class _AutostartTile extends StatelessWidget { builder: (context, state) { return SwitchListTile( secondary: const Icon(Icons.start), - title: const Text('Start automatically at system boot'), + title: Text( + AppLocalizations.of(context)!.startAutomatically, + ), value: state.autoStart, onChanged: (value) async { await settingsCubit.updateAutoStart(value); @@ -56,7 +61,9 @@ class _StartHiddenTile extends StatelessWidget { return SwitchListTile( secondary: const Icon(Icons.auto_awesome), - title: const Text('Start hidden in system tray'), + title: Text( + AppLocalizations.of(context)!.startInTray, + ), value: state.startHiddenInTray, onChanged: (value) async { await settingsCubit.updateStartHiddenInTray(value); diff --git a/lib/settings/widgets/theme_section.dart b/lib/settings/widgets/theme_section.dart index cd9bd878..e574e026 100644 --- a/lib/settings/widgets/theme_section.dart +++ b/lib/settings/widgets/theme_section.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../theme/theme.dart'; @@ -28,21 +29,29 @@ class _ThemeChooser extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('Theme'), + Text( + AppLocalizations.of(context)!.themeTitle, + ), RadioListTile( - title: const Text('Dark'), + title: Text( + AppLocalizations.of(context)!.dark, + ), groupValue: state.appTheme, value: AppTheme.dark, onChanged: (value) => themeCubit.changeTheme(value!), ), RadioListTile( - title: const Text('Pitch Black'), + title: Text( + AppLocalizations.of(context)!.pitchBlack, + ), groupValue: state.appTheme, value: AppTheme.pitchBlack, onChanged: (value) => themeCubit.changeTheme(value!), ), RadioListTile( - title: const Text('Light'), + title: Text( + AppLocalizations.of(context)!.light, + ), groupValue: state.appTheme, value: AppTheme.light, onChanged: (value) => themeCubit.changeTheme(value!), diff --git a/lib/theme/styles.dart b/lib/theme/styles.dart index 138ddab3..eddb7f46 100644 --- a/lib/theme/styles.dart +++ b/lib/theme/styles.dart @@ -8,6 +8,10 @@ abstract class BorderRadii { static BorderRadius gentlyRounded = BorderRadius.circular(10); } +/// It is required to use the emoji font, otherwise emojis +/// all appear as simple black and white glyphs. +const emojiFont = 'Noto Color Emoji'; + abstract class Spacers { static const horizontalSmall = SizedBox(width: 20); diff --git a/pubspec.lock b/pubspec.lock index 0055e13b..70925a5a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -179,8 +179,8 @@ packages: dependency: "direct dev" description: path: "." - ref: "5253d9d368f8bc6ea43a81492e711d9dabaa23b6" - resolved-ref: "5253d9d368f8bc6ea43a81492e711d9dabaa23b6" + ref: "1ff10c3b097396ad138d6dcabe160497a1e81b44" + resolved-ref: "1ff10c3b097396ad138d6dcabe160497a1e81b44" url: "https://github.com/Merrit/flutter_app_builder.git" source: git version: "1.0.0" @@ -205,6 +205,11 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_markdown: dependency: "direct main" description: @@ -348,13 +353,13 @@ packages: source: sdk version: "0.0.0" intl: - dependency: transitive + dependency: "direct main" description: name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" url: "https://pub.dev" source: hosted - version: "0.18.0" + version: "0.17.0" io: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8dc40149..f93da67b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,8 @@ dependencies: flutter: sdk: flutter flutter_bloc: ^8.0.0 + flutter_localizations: + sdk: flutter flutter_markdown: ^0.6.9+1 flutter_window_close: ^0.2.2 hive_flutter: ^1.1.0 @@ -30,6 +32,7 @@ dependencies: url: https://github.com/leanflutter/hotkey_manager.git ref: 604523dd6edfb54e643f577512ea698c8debb96d # hotkey_manager: ^0.1.7 + intl: any http: ^0.13.3 libadwaita: ^1.2.5 logger: ^1.1.0 @@ -51,7 +54,7 @@ dev_dependencies: flutter_app_builder: git: url: https://github.com/Merrit/flutter_app_builder.git - ref: 5253d9d368f8bc6ea43a81492e711d9dabaa23b6 + ref: 1ff10c3b097396ad138d6dcabe160497a1e81b44 flutter_lints: ^2.0.1 flutter_test: sdk: flutter @@ -63,6 +66,7 @@ dev_dependencies: flutter: uses-material-design: true + generate: true assets: - assets/icons/ - packaging/linux/codes.merritt.Nyrna.desktop