Skip to content

Commit

Permalink
feat: add support for localizations
Browse files Browse the repository at this point in the history
  • Loading branch information
Merrit committed Jan 31, 2023
1 parent d2ec965 commit 3a26167
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 57 deletions.
3 changes: 3 additions & 0 deletions l10n.yaml
@@ -0,0 +1,3 @@
arb-dir: lib/localization
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
3 changes: 3 additions & 0 deletions 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';

Expand Down Expand Up @@ -70,6 +71,8 @@ class _AppState extends State<App> 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(),
Expand Down
27 changes: 18 additions & 9 deletions 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';
Expand Down Expand Up @@ -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),
),
],
);
Expand Down
9 changes: 7 additions & 2 deletions 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.
Expand Down Expand Up @@ -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,
),
),
],
),
Expand Down
153 changes: 153 additions & 0 deletions 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"
}
}
12 changes: 9 additions & 3 deletions 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';

Expand All @@ -26,19 +27,24 @@ 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(
ClipboardData(text: state.logsText),
);

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,
),
);
},
),
Expand Down
13 changes: 10 additions & 3 deletions 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';
Expand All @@ -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,
Expand All @@ -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,
Expand Down
17 changes: 13 additions & 4 deletions 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';
Expand All @@ -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<AppsListCubit, AppsListState>(
builder: (context, state) {
return Text(state.runningVersion);
Expand All @@ -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',
),
Expand Down

0 comments on commit 3a26167

Please sign in to comment.