Skip to content

Commit

Permalink
feat(localization): 🌐 add localization support
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed Feb 3, 2024
1 parent 6f687d5 commit 0297176
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 105 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ coverage/
.pub-cache/
.pub/
/build/
untranslated_messages.txt

# Web related
lib/generated_plugin_registrant.dart
Expand Down
71 changes: 1 addition & 70 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,83 +5,14 @@ linter:
- avoid_classes_with_only_static_members
- avoid_types_on_closure_parameters
- cancel_subscriptions
# - discarded_futures
- unnecessary_null_aware_operator_on_extension_on_nullable

dart_code_metrics:
metrics:
cyclomatic-complexity: 20
maximum-nesting-level: 5
number-of-arguments: 4
metrics-exclude:
- test/**
rules:
- always-remove-listener
- arguments-ordering:
child-last: true
- avoid-border-all
- avoid-cascade-after-if-null
- avoid-collection-methods-with-unrelated-types
- avoid-double-slash-imports
- avoid-duplicate-exports
- avoid-global-state
- avoid-missing-enum-constant-in-map
- avoid-nested-conditional-expressions:
acceptable-level: 2
- avoid-redundant-async
- avoid-returning-widgets
- avoid-shrink-wrap-in-lists
- avoid-throw-in-catch-block
- avoid-unnecessary-conditionals
- avoid-unnecessary-setstate
- avoid-unnecessary-type-assertions
- avoid-unnecessary-type-casts
- avoid-unrelated-type-assertions
- avoid-expanded-as-spacer
- avoid-wrapping-in-padding
- binary-expression-operand-order
- double-literal-format
- format-comment:
ignored-patterns:
- ^coverage.*
# - member-ordering
- missing-test-assertion
- newline-before-return
- no-boolean-literal-compare
- no-equal-then-else
# - no-magic-number
- prefer-conditional-expressions
- prefer-correct-edge-insets-constructor
- prefer-correct-test-file-name:
exclude:
- lib/**
- bin/**
- "**/main.dart"
- prefer-enums-by-name
# - prefer-extracting-callbacks
- prefer-first
- prefer-immediate-return
- prefer-iterable-of
- prefer-last
- prefer-match-file-name:
exclude:
- test/**
# - prefer-moving-to-variable
- prefer-trailing-comma
- prefer-single-widget-per-file:
ignore-private-widgets: true
- use-setstate-synchronously
anti-patterns:
- long-parameter-list

analyzer:
plugins:
- dart_code_metrics

errors:
avoid_equals_and_hash_code_on_mutable_classes: ignore
public_member_api_docs: ignore
unused_element: ignore # See https://github.com/dart-lang/sdk/issues/49025
no_default_cases: ignore

# Style decisions
always_put_required_named_parameters_first: ignore
Expand Down
5 changes: 5 additions & 0 deletions l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
arb-dir: lib/localization
template-arb-file: app_ca.arb
output-localization-file: app_localizations.dart
untranslated-messages-file: lib/localization/untranslated_messages.txt
nullable-getter: false
31 changes: 31 additions & 0 deletions lib/localization/app_ca.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"@@locale": "ca",
"search": "Cerca",
"myCollection": "La meva coŀlecció",
"firstNResultsAreShown": "Es mostren els primers {n} resultats de l’autocompletat",
"@firstNResultsAreShown": {
"placeholders": {
"n": {
"type": "int",
"example": "20"
}
}
},
"nResults": "{n, plural, =0{Sense resultats} =1{1 resultat} other{{n} resultats}}",
"@nResults": {
"placeholders": {
"n": {
"type": "int",
"example": "7"
}
}
},
"orMore": "o més",
"addToTheCollection": "Afegeix a la coŀlecció",
"removeFromTheCollection": "Treu de la coŀlecció",
"added": "S’ha afegit",
"removed": "S’ha tret",
"toTheCollection": "a la coŀlecció",
"fromTheCollection": "de la coŀlecció",
"showAbbreviation": "Mostra l’abreviatura"
}
10 changes: 3 additions & 7 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:el_meu_diec/src/pages/home_page.dart';
import 'package:el_meu_diec/src/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';

import 'settings/settings_controller.dart';
Expand All @@ -21,12 +21,8 @@ class MyApp extends StatelessWidget {
title: 'DIEC',
debugShowCheckedModeBanner: false,
restorationScopeId: 'el_meu_diec',
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [Locale('ca')],
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: lightThemeData,
darkTheme: darkThemeData,
themeMode: settingsController.themeMode,
Expand Down
5 changes: 4 additions & 1 deletion lib/src/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:el_meu_diec/model.dart';
import 'package:el_meu_diec/src/widgets/autocomplete_entry_card.dart';
import 'package:el_meu_diec/src/widgets/search_bar_results.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_svg/svg.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -58,9 +59,11 @@ class _BookmarksIconButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);

return IconButton(
icon: const Icon(Icons.bookmark),
tooltip: 'La meva coŀlecció',
tooltip: appLocalizations.myCollection,
onPressed: () => (Platform.isAndroid
? showBarModalBottomSheet
: showCupertinoModalBottomSheet)<void>(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/pages/word_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WordPage extends StatelessWidget {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
SelectableText(
word.word,
style: theme.textTheme.displaySmall,
textAlign: TextAlign.start,
Expand Down
46 changes: 27 additions & 19 deletions lib/src/widgets/autocomplete_entries_list_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:el_meu_diec/src/constants.dart';
import 'package:el_meu_diec/src/widgets/autocomplete_entry_future_card.dart';
import 'package:el_meu_diec/src/widgets/equipped_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class AutocompleteEntriesListView extends StatelessWidget {
final String query;
Expand Down Expand Up @@ -81,6 +82,7 @@ class _EntriesList extends StatelessWidget {

@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final theme = Theme.of(context);

return ListView.builder(
Expand All @@ -95,26 +97,32 @@ class _EntriesList extends StatelessWidget {

return Padding(
padding: const EdgeInsetsDirectional.all(32),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${autocompleteEntries.length} resultats'
'${reachedMaxResults ? ' o més' : ''}',
textAlign: TextAlign.center,
style: theme.textTheme.labelLarge,
),
if (reachedMaxResults)
const IconButton(
onPressed: null,
iconSize: 16,
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
padding: EdgeInsets.all(2),
tooltip: 'Es mostren els primers $maxResults '
'resultats de l’autocompletat.',
icon: Icon(Icons.question_mark),
child: TextButton(
onPressed: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
appLocalizations.nResults(autocompleteEntries.length) +
(reachedMaxResults
? ' ${appLocalizations.orMore}'
: ''),
textAlign: TextAlign.center,
style: theme.textTheme.labelLarge,
),
],
if (reachedMaxResults)
IconButton(
onPressed: null,
iconSize: 16,
visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
padding: const EdgeInsets.all(2),
tooltip:
appLocalizations.firstNResultsAreShown(maxResults),
icon: const Icon(Icons.question_mark),
),
],
),
),
);
}
Expand Down
17 changes: 14 additions & 3 deletions lib/src/widgets/autocomplete_entry_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:el_meu_diec/src/theme.dart';
import 'package:el_meu_diec/src/widgets/definition_entry_sense_line.dart';
import 'package:el_meu_diec/src/widgets/equipped_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';

class AutocompleteEntryCard extends StatelessWidget {
Expand Down Expand Up @@ -104,6 +105,7 @@ class _BookmarkButton extends StatelessWidget {
const _BookmarkButton({super.key, required this.word});

void _onPressed(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final bookmarked = Provider.of<BookmarkCollection>(context, listen: false)
.toggleBookmark(word.id);
ScaffoldMessenger.of(context).showSnackBar(
Expand All @@ -112,14 +114,20 @@ class _BookmarkButton extends StatelessWidget {
TextSpan(
children: [
TextSpan(
text: bookmarked ? 'S’ha afegit ' : 'S’ha tret ',
text: bookmarked
? appLocalizations.added
: appLocalizations.removed,
),
const TextSpan(text: ' '),
TextSpan(
text: word.word,
style: const TextStyle(fontWeight: FontWeight.bold),
),
const TextSpan(text: ' '),
TextSpan(
text: bookmarked ? ' a la coŀlecció.' : ' de la coŀlecció.',
text: bookmarked
? appLocalizations.toTheCollection
: appLocalizations.fromTheCollection,
),
],
),
Expand All @@ -131,6 +139,7 @@ class _BookmarkButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final theme = Theme.of(context);
final isBookmarked =
Provider.of<BookmarkCollection>(context).isBookmarked(word.id);
Expand All @@ -141,7 +150,9 @@ class _BookmarkButton extends StatelessWidget {
isBookmarked ? Icons.bookmark : Icons.bookmark_outline,
),
enableFeedback: true,
tooltip: isBookmarked ? 'Treu de la coŀlecció' : 'Afegeix a la coŀlecció',
tooltip: isBookmarked
? appLocalizations.removeFromTheCollection
: appLocalizations.addToTheCollection,
onPressed: () => _onPressed(context),
);
}
Expand Down
5 changes: 4 additions & 1 deletion lib/src/widgets/scope_chip.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:el_meu_diec/model.dart';
import 'package:el_meu_diec/src/widgets/conditional_widget_wrap.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class ScopeChip extends StatelessWidget {
final Scope scope;
Expand All @@ -19,6 +20,8 @@ class ScopeChip extends StatelessWidget {

@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);

return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(4)),
child: Material(
Expand All @@ -31,7 +34,7 @@ class ScopeChip extends StatelessWidget {
condition: isInteractive,
conditionalBuilder: (child) {
return Tooltip(
message: 'Mostra l’abreviatura',
message: appLocalizations.showAbbreviation,
child: InkWell(
onTap: () => _onTap(context),
child: child,
Expand Down
9 changes: 6 additions & 3 deletions lib/src/widgets/search_bar_results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:el_meu_diec/model.dart';
import 'package:el_meu_diec/src/theme.dart';
import 'package:el_meu_diec/src/widgets/autocomplete_entries_list_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class SearchBarResults extends StatefulWidget {
const SearchBarResults({super.key});
Expand Down Expand Up @@ -34,6 +35,8 @@ class _SearchBarResultsState extends State<SearchBarResults> {

@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);

return Stack(
children: [
Padding(
Expand Down Expand Up @@ -105,9 +108,9 @@ class _SearchBarResultsState extends State<SearchBarResults> {
child: TextFormField(
autocorrect: false,
style: const TextStyle(fontSize: 18),
decoration: const InputDecoration(
hintText: 'Cerca',
suffixIcon: Padding(
decoration: InputDecoration(
hintText: appLocalizations.search,
suffixIcon: const Padding(
padding: EdgeInsetsDirectional.only(end: 8),
child: Icon(Icons.search, color: Colors.grey),
),
Expand Down

0 comments on commit 0297176

Please sign in to comment.