Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TYS-13: multi language feature #29

Merged
merged 5 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
- run: flutter pub get
- name: Get flutter packages
run: flutter pub get
- name: Generate localization
run: flutter gen-l10n
- name: Analyze project source
run: dart analyze
- name: Run tests
Expand Down
6 changes: 3 additions & 3 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PODS:
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- sqflite (0.0.2):
- sqflite (0.0.3):
- Flutter
- FMDB (>= 2.7.5)
- Toast (4.0.0)
Expand Down Expand Up @@ -37,9 +37,9 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196

PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
Expand Down
3 changes: 3 additions & 0 deletions lib/l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
22 changes: 22 additions & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"bottomBarDepartures": "Abfahrten",
"bottomBarNews": "Neuigkeiten",
"bottomBarSettings": "Einstellungen",
"departureEmptyText": "Noch keine Stationen augewählt.",
"dialogDone": "Fertig",
"favoriteAppBarAddTooltip": "Favorisierte Station hinzufügen",
"favoriteAppBarTitle": "Favoriten hinzufügen",
"favoriteDestinationSelection": "Wähle bevorzugte Ziele aus:",
"favoriteOriginSelectionError": "Für den angegebenen Namen wurde keine Station gefunden.",
"favoriteOriginSelectionLabel": "Name der Startstation",
"favoriteTransportationFilterWait": "Es wurden noch keine Transportarten gefunden.",
"favoriteTransportationTypeFilter": "Transport-Typ Filter",
"settingsDepartureCountDescription": "Legt fest, wie viele Abfahrtspositionen pro Ziel auf dem Startbildschirm angezeigt werden.",
"settingsDepartureCountSliderTitle": "Anzahl der Abfahrten",
"settingsDepartureCountTitle": "Anzahl der Abfahrten",
"settingsLanguageTitle": "Sprache",
"settingsLanguageValue": "Deutsch",
"settingsSectionCommon": "Allgemein",
"settingsSectionDeparture": "Abfahrten",
"settingsThemeSwitchTitle": "Farbschema Wechseln"
}
22 changes: 22 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"bottomBarDepartures": "Departures",
"bottomBarNews": "News",
"bottomBarSettings": "Settings",
"departureEmptyText": "No stations defined yet.",
"dialogDone": "Done",
"favoriteAppBarAddTooltip": "Add favorite station",
"favoriteAppBarTitle": "Add favorite",
"favoriteDestinationSelection": "Select preferred destinations:",
"favoriteOriginSelectionError": "No station found for provided name.",
"favoriteOriginSelectionLabel": "Name of the origin station",
"favoriteTransportationFilterWait": "No transport types found yet.",
"favoriteTransportationTypeFilter": "Filter for type of transportation",
"settingsDepartureCountDescription": "Defines how manydeparture items per destination are displayed on the start screen.",
"settingsDepartureCountSliderTitle": "Departure count",
"settingsDepartureCountTitle": "Departure Count",
"settingsLanguageTitle": "Language",
"settingsLanguageValue": "English",
"settingsSectionCommon": "Common",
"settingsSectionDeparture": "Departures",
"settingsThemeSwitchTitle": "Switch Theme"
}
5 changes: 4 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logger/logger.dart';
import 'package:track_your_stop/routing/router.dart';
Expand Down Expand Up @@ -70,7 +71,9 @@ class HaltestellenTrackerState extends ConsumerState<HaltestellenTrackerApp>
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Haltestellen Tracker',
title: "TrackYourStop",
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
debugShowCheckedModeBanner: false,
themeMode: ref.watch(themeProvider),
darkTheme: darkTheme,
Expand Down
6 changes: 4 additions & 2 deletions lib/modules/departure/views/departure_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:track_your_stop/modules/settings/provider/departure_settings_pro
import 'package:track_your_stop/utils/app_theme.dart';
import 'package:track_your_stop/utils/transportation_type.util.dart';
import 'package:flutter/material.dart';
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:track_your_stop/constants/colors.dart';
import 'package:track_your_stop/constants/departure_card_choices.dart';
Expand Down Expand Up @@ -172,8 +173,9 @@ class DeparturePage extends HookConsumerWidget {
final Map<String, List<DepartureResponse>> stationMap =
Map.from(snapshot.data);
if (stationMap.isEmpty) {
return const Center(
child: Text("No stations defined yet."));
return Center(
child: Text(
AppLocalizations.of(context)!.departureEmptyText));
}
return buildListView(context, stationMap);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/modules/favorites/ui/favorite_app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:track_your_stop/modules/favorites/database/favorites_database.dart';
import 'package:track_your_stop/modules/favorites/models/favorite.model.dart';
Expand Down Expand Up @@ -31,7 +32,7 @@ class FavoriteAppBar extends ConsumerWidget implements PreferredSizeWidget {
}

return AppBar(
title: const Text('Add favorite'),
title: Text(AppLocalizations.of(context)!.favoriteAppBarTitle),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Expand All @@ -41,7 +42,7 @@ class FavoriteAppBar extends ConsumerWidget implements PreferredSizeWidget {
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_location),
tooltip: 'Add favorite station',
tooltip: AppLocalizations.of(context)!.favoriteAppBarAddTooltip,
onPressed: () {
final selectedOrigin = ref.watch(selectedOriginProvider);
final selectedTransportationTypes =
Expand Down
35 changes: 20 additions & 15 deletions lib/modules/favorites/views/favorite_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:track_your_stop/utils/transportation_type.util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:flutter_image_stack/flutter_image_stack.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
Expand Down Expand Up @@ -87,11 +88,11 @@ class FavoritePage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: TypeAheadField<StationResponse?>(
noItemsFoundBuilder: (context) => const SizedBox(
noItemsFoundBuilder: (context) => SizedBox(
height: 50.0,
child: Center(
child:
Text('No station found for provided name.'))),
child: Text(AppLocalizations.of(context)!
.favoriteOriginSelectionError))),
hideSuggestionsOnKeyboardHide: false,
hideKeyboardOnDrag: true,
debounceDuration: const Duration(milliseconds: 1000),
Expand Down Expand Up @@ -119,10 +120,11 @@ class FavoritePage extends HookConsumerWidget {
},
textFieldConfiguration: TextFieldConfiguration(
controller: ref.watch(stationControllerProvider),
decoration: const InputDecoration(
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.search),
labelText: 'Name of the origin station',
decoration: InputDecoration(
border: const OutlineInputBorder(),
prefixIcon: const Icon(Icons.search),
labelText: AppLocalizations.of(context)!
.favoriteOriginSelectionLabel,
)),
onSuggestionSelected: (StationResponse? selection) {
logger.d('Selected station: ${selection!.toJson()}');
Expand All @@ -143,10 +145,11 @@ class FavoritePage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: TypeAheadField<String>(
noItemsFoundBuilder: (context) => const SizedBox(
noItemsFoundBuilder: (context) => SizedBox(
height: 50.0,
child: Center(
child: Text('No transport types found yet.'))),
child: Text(AppLocalizations.of(context)!
.favoriteTransportationFilterWait))),
hideSuggestionsOnKeyboardHide: false,
hideKeyboardOnDrag: true,
suggestionsCallback: (input) {
Expand Down Expand Up @@ -186,10 +189,11 @@ class FavoritePage extends HookConsumerWidget {
},
textFieldConfiguration: TextFieldConfiguration(
controller: transportationTypeController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.train),
labelText: 'Filter for type of transportation',
decoration: InputDecoration(
border: const OutlineInputBorder(),
prefixIcon: const Icon(Icons.train),
labelText: AppLocalizations.of(context)!
.favoriteTransportationTypeFilter,
)))),
// Chip list containing selected transportation types
Container(
Expand All @@ -205,7 +209,7 @@ class FavoritePage extends HookConsumerWidget {
Align(
alignment: AlignmentDirectional.center,
child: Text(
'Select preferred destinations:',
AppLocalizations.of(context)!.favoriteDestinationSelection,
style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.start,
),
Expand Down Expand Up @@ -268,7 +272,8 @@ class FavoritePage extends HookConsumerWidget {
return Scaffold(
appBar: FavoriteAppBar(),
body: Scrollable(
viewportBuilder: (BuildContext context, ViewportOffset position) => buildBody(),
viewportBuilder: (BuildContext context, ViewportOffset position) =>
buildBody(),
),
);
}
Expand Down
45 changes: 26 additions & 19 deletions lib/modules/settings/views/settings_page.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:track_your_stop/modules/settings/provider/departure_settings_provider.dart';
import 'package:track_your_stop/modules/settings/ui/slider_selection.dart';
import 'package:track_your_stop/utils/app_theme.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:settings_ui/settings_ui.dart';
import 'package:track_your_stop/shared/ui/bottom_app_bar.dart';
import 'package:track_your_stop/utils/logger.dart';
import "package:track_your_stop/modules/settings/provider/departure_settings_provider.dart";
import "package:track_your_stop/modules/settings/ui/slider_selection.dart";
import "package:track_your_stop/utils/app_theme.dart";
import "package:flutter/material.dart";
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:settings_ui/settings_ui.dart";
import "package:track_your_stop/shared/ui/bottom_app_bar.dart";
import "package:track_your_stop/utils/logger.dart";

final logger = getLogger("SettingsPage");

Expand All @@ -23,7 +24,8 @@ class SettingsPage extends HookConsumerWidget {
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Departure count'),
title: Text(AppLocalizations.of(context)!
.settingsDepartureCountSliderTitle),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Expand All @@ -36,7 +38,7 @@ class SettingsPage extends HookConsumerWidget {
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Done'),
child: Text(AppLocalizations.of(context)!.dialogDone),
),
],
);
Expand All @@ -52,30 +54,35 @@ class SettingsPage extends HookConsumerWidget {
lightTheme: lightSettings,
sections: [
SettingsSection(
title: const Text('Common'),
title: Text(AppLocalizations.of(context)!.settingsSectionCommon),
tiles: <SettingsTile>[
SettingsTile.navigation(
SettingsTile(
leading: const Icon(Icons.language),
title: const Text('Language'),
value: const Text('English'),
title:
Text(AppLocalizations.of(context)!.settingsLanguageTitle),
value:
Text(AppLocalizations.of(context)!.settingsLanguageValue),
),
SettingsTile.switchTile(
activeSwitchColor:
Theme.of(context).toggleButtonsTheme.selectedColor,
onToggle: (isActive) => _switchTheme(ref, isActive),
initialValue: isDark,
leading: Icon(isDark ? Icons.brightness_2 : Icons.wb_sunny),
title: const Text('Switch Theme'),
title: Text(
AppLocalizations.of(context)!.settingsThemeSwitchTitle),
),
],
),
SettingsSection(
title: const Text('Departures'),
title:
Text(AppLocalizations.of(context)!.settingsSectionDeparture),
tiles: <SettingsTile>[
SettingsTile(
title: const Text('Departure Count'),
description: const Text(
'Defines how manydeparture items per destination are displayed on the start screen.'),
title: Text(AppLocalizations.of(context)!
.settingsDepartureCountTitle),
description: Text(AppLocalizations.of(context)!
.settingsDepartureCountDescription),
value: Text(ref.watch(departureSettingsProvider).toString()),
leading: const Icon(Icons.train),
onPressed: (BuildContext context) {
Expand Down
15 changes: 8 additions & 7 deletions lib/shared/ui/bottom_app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:track_your_stop/routing/router.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:track_your_stop/utils/logger.dart';
import 'package:track_your_stop/shared/provider/app_bar_selection_provider.dart';
Expand Down Expand Up @@ -35,18 +36,18 @@ class BottomAppNavigationBar extends ConsumerWidget {
final currentIndex = ref.watch(appBarSelectionProvider);
logger.d("Current Index: $currentIndex");
return BottomNavigationBar(
items: const <BottomNavigationBarItem>[
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.train),
label: 'Departures',
icon: const Icon(Icons.train),
label: AppLocalizations.of(context)!.bottomBarDepartures,
),
BottomNavigationBarItem(
icon: Icon(Icons.newspaper),
label: 'News',
icon: const Icon(Icons.newspaper),
label: AppLocalizations.of(context)!.bottomBarNews,
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
icon: const Icon(Icons.settings),
label: AppLocalizations.of(context)!.bottomBarSettings,
),
],
currentIndex: currentIndex,
Expand Down
Loading