Initial support for localization
This commit is contained in:
parent
72103e1b48
commit
6f6bc29a72
|
@ -0,0 +1,20 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-09-29 09:59+0200\n"
|
||||
"PO-Revision-Date: 2021-09-29 10:58+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Main menu"
|
||||
msgstr "Main menu"
|
||||
|
||||
msgid "Use dark mode"
|
||||
msgstr "Use dark mode"
|
|
@ -0,0 +1,20 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-09-29 09:59+0200\n"
|
||||
"PO-Revision-Date: 2021-09-29 10:58+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Main menu"
|
||||
msgstr "Menu principal"
|
||||
|
||||
msgid "Use dark mode"
|
||||
msgstr "Utiliser le mode sombre"
|
|
@ -0,0 +1,20 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-09-29 09:59+0200\n"
|
||||
"PO-Revision-Date: 2021-09-29 10:00+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: en\n"
|
||||
|
||||
msgid "Main menu"
|
||||
msgstr ""
|
||||
|
||||
msgid "Use dark mode"
|
||||
msgstr ""
|
|
@ -52,10 +52,12 @@ void main() async {
|
|||
setWindowMaxSize(const Size(692, 580));
|
||||
gOperatingSystems = await loadOperatingSystems(false);
|
||||
AppVersion.packageInfo = await PackageInfo.fromPlatform();
|
||||
runApp(MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => AppTheme()),
|
||||
],
|
||||
builder: (context, _) => const App(),
|
||||
));
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => AppTheme()),
|
||||
],
|
||||
builder: (context, _) => const App(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:quickgui/src/globals.dart';
|
||||
import 'package:quickgui/src/i18n/quickgui_localizations_delegate.dart';
|
||||
import 'package:quickgui/src/mixins/preferences_mixin.dart';
|
||||
import 'package:quickgui/src/model/app_theme.dart';
|
||||
import 'package:quickgui/src/pages/main_page.dart';
|
||||
|
@ -20,7 +22,7 @@ class _AppState extends State<App> with PreferencesMixin {
|
|||
builder: (context, AsyncSnapshot<bool?> snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.data != null) {
|
||||
context.read<AppTheme>().useDarkMode = snapshot.data!;
|
||||
context.read<AppTheme>().useDarkModeSilently = snapshot.data!;
|
||||
}
|
||||
return Consumer<AppTheme>(
|
||||
builder: (context, appTheme, _) => MaterialApp(
|
||||
|
@ -28,6 +30,33 @@ class _AppState extends State<App> with PreferencesMixin {
|
|||
darkTheme: ThemeData.dark(),
|
||||
themeMode: appTheme.themeMode,
|
||||
home: const MainPage(title: 'Quickgui - A Flutter frontend for Quickget and Quickemu'),
|
||||
supportedLocales: const [
|
||||
/// List of locales we have translations for.
|
||||
Locale('en', ''),
|
||||
Locale('fr', ''),
|
||||
Locale('fr', 'CH'),
|
||||
],
|
||||
localizationsDelegates: [
|
||||
QuickguiLocalizationsDelegate(),
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
localeListResolutionCallback: (locales, supportedLocales) {
|
||||
if (locales != null) {
|
||||
for (var locale in locales) {
|
||||
var supportedLocale =
|
||||
supportedLocales.where((element) => element.languageCode == locale.languageCode && element.countryCode == locale.countryCode);
|
||||
if (supportedLocale.isNotEmpty) {
|
||||
return supportedLocale.first;
|
||||
}
|
||||
supportedLocale = supportedLocales.where((element) => element.languageCode == locale.languageCode);
|
||||
if (supportedLocale.isNotEmpty) {
|
||||
return supportedLocale.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:quickgui/src/i18n/quickgui_localizations.dart';
|
||||
|
||||
extension I18nExt on BuildContext {
|
||||
t(String key) => QuickguiLocalizations.of(this).t(key);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gettext/gettext.dart';
|
||||
import 'package:gettext_parser/gettext_parser.dart' as gettext_parser;
|
||||
|
||||
class QuickguiLocalizations {
|
||||
final _gt = Gettext(
|
||||
onWarning: ((message) {
|
||||
if (kDebugMode) {
|
||||
// ignore: avoid_print
|
||||
print('$message\n');
|
||||
final r = RegExp(r'^No translation was found for msgid "(.*)" in msgctxt "(.*)" and domain "(.*)"$');
|
||||
final matches = r.firstMatch(message);
|
||||
var msgid = matches!.group(1);
|
||||
// ignore: avoid_print
|
||||
print('\nmsgid "$msgid"\nmsgstr ""\n \n');
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
QuickguiLocalizations.fromPO(String poContent) {
|
||||
_gt.addLocale(gettext_parser.po.parse(poContent));
|
||||
}
|
||||
|
||||
static QuickguiLocalizations of(BuildContext context) => Localizations.of<QuickguiLocalizations>(context, QuickguiLocalizations)!;
|
||||
|
||||
String t(String key) => _gt.gettext(key);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:quickgui/src/i18n/quickgui_localizations.dart';
|
||||
|
||||
class QuickguiLocalizationsDelegate extends LocalizationsDelegate<QuickguiLocalizations> {
|
||||
@override
|
||||
bool isSupported(Locale locale) => ['fr', 'en'].contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
Future<QuickguiLocalizations> load(Locale locale) async {
|
||||
var poContent = '';
|
||||
try {
|
||||
poContent = await rootBundle.loadString('assets/i18n/${locale.languageCode}_${locale.countryCode}.po');
|
||||
} catch (e) {
|
||||
poContent = await rootBundle.loadString('assets/i18n/${locale.languageCode}.po');
|
||||
}
|
||||
|
||||
return QuickguiLocalizations.fromPO(poContent);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReload(covariant LocalizationsDelegate<QuickguiLocalizations> old) => true;
|
||||
}
|
|
@ -4,8 +4,13 @@ class AppTheme extends ChangeNotifier {
|
|||
ThemeMode? _themeMode;
|
||||
|
||||
ThemeMode get themeMode => _themeMode ?? ThemeMode.system;
|
||||
set useDarkMode(bool useDarkMode) {
|
||||
|
||||
set useDarkModeSilently(bool useDarkMode) {
|
||||
_themeMode = useDarkMode ? ThemeMode.dark : ThemeMode.light;
|
||||
}
|
||||
|
||||
set useDarkMode(bool useDarkMode) {
|
||||
useDarkModeSilently = useDarkMode;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:quickgui/src/widgets/home_page/logo.dart';
|
||||
import 'package:quickgui/src/widgets/home_page/main_menu.dart';
|
||||
import 'package:quickgui/src/widgets/left_menu.dart';
|
||||
import 'package:quickgui/src/i18n/i18n_ext.dart';
|
||||
|
||||
class MainPage extends StatefulWidget {
|
||||
const MainPage({Key? key, required this.title}) : super(key: key);
|
||||
|
@ -17,7 +18,7 @@ class _MainPageState extends State<MainPage> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Main menu'),
|
||||
title: Text(context.t('Main menu')),
|
||||
),
|
||||
drawer: const LeftMenu(),
|
||||
body: Column(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:quickgui/src/globals.dart';
|
|||
import 'package:quickgui/src/mixins/app_version.dart';
|
||||
import 'package:quickgui/src/mixins/preferences_mixin.dart';
|
||||
import 'package:quickgui/src/model/app_theme.dart';
|
||||
import 'package:quickgui/src/i18n/i18n_ext.dart';
|
||||
|
||||
class LeftMenu extends StatelessWidget with PreferencesMixin {
|
||||
const LeftMenu({Key? key}) : super(key: key);
|
||||
|
@ -24,7 +25,7 @@ class LeftMenu extends StatelessWidget with PreferencesMixin {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
const Text('Use dark mode'),
|
||||
Text(context.t('Use dark mode')),
|
||||
Switch(
|
||||
value: Theme.of(context).brightness == Brightness.dark,
|
||||
onChanged: (value) {
|
||||
|
|
|
@ -45,6 +45,11 @@ dependencies:
|
|||
shared_preferences: ^2.0.8
|
||||
package_info_plus: ^1.3.0
|
||||
provider: ^6.0.1
|
||||
intl: ^0.17.0
|
||||
gettext: ^1.2.0
|
||||
gettext_parser: ^0.2.0
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -74,6 +79,7 @@ flutter:
|
|||
# - images/a_dot_ham.jpeg
|
||||
assets:
|
||||
- assets/images/
|
||||
- assets/i18n/
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
name: quickgui
|
||||
adopt-info: quickgui
|
||||
summary: a Flutter frontend for (quickget)[https://github.com/wimpysworld/quickget]
|
||||
description: |
|
||||
The app is a frontend to quickget.
|
||||
grade: stable
|
||||
confinement: classic
|
||||
base: core20
|
||||
|
||||
architectures:
|
||||
- build-on: amd64
|
||||
|
||||
apps:
|
||||
quickgui:
|
||||
command: bin/quickgui
|
||||
environment:
|
||||
PATH: $SNAP/usr/bin:$SNAP/bin:$PATH
|
||||
LIVE_RUN: 1
|
||||
LOG_LEVEL: debug
|
||||
|
||||
parts:
|
||||
quickgui-deps:
|
||||
plugin: nil
|
||||
stage-packages:
|
||||
- libatk1.0-0
|
||||
- libcairo-gobject2
|
||||
- libcairo2
|
||||
- libepoxy0
|
||||
- libgtk-3-0
|
||||
- libpango-1.0-0
|
||||
- libpangocairo-1.0-0
|
||||
|
||||
quickgui:
|
||||
source: .
|
||||
source-type: git
|
||||
plugin: nil
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
snapcraftctl set-version "$(cat pubspec.yaml | grep '^version: ' | cut -c 10- | sed 's/+/-/')"
|
||||
override-build: |
|
||||
set -eux
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/bin/lib
|
||||
flutter channel stable
|
||||
flutter upgrade
|
||||
flutter config --enable-linux-desktop
|
||||
flutter doctor
|
||||
flutter pub get
|
||||
flutter build linux --release -v
|
||||
cp -r build/linux/x64/release/bundle/* $SNAPCRAFT_PART_INSTALL/bin/
|
||||
build-snaps:
|
||||
- flutter/latest/stable
|
||||
after:
|
||||
- quickgui-deps
|
Loading…
Reference in New Issue