From 8811cef86491cc823c4d292cb683735f42cfbc90 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Wed, 1 Dec 2021 23:09:53 +0100 Subject: [PATCH] Update code style --- analysis_options.yaml | 169 ++++++++++++++++++ lib/bloc/database/database_bloc.dart | 10 +- lib/bloc/database/database_event.dart | 2 +- .../database_not_connected_exception.dart | 2 +- lib/bloc/database/database_state.dart | 3 +- lib/bloc/theme/theme_bloc.dart | 13 +- lib/bloc/theme/theme_state.dart | 4 +- lib/main.dart | 64 +++---- lib/models/history/search.dart | 10 +- lib/models/history/word_query.dart | 2 +- lib/models/history/word_result.dart | 4 +- lib/models/themes/dark.dart | 10 +- lib/models/themes/light.dart | 10 +- lib/models/themes/theme.dart | 10 +- lib/router.dart | 38 ++-- lib/services/jisho_api/jisho_search.dart | 4 +- lib/services/jisho_api/kanji_search.dart | 19 +- lib/view/components/common/loading.dart | 8 +- lib/view/components/common/splash.dart | 11 +- lib/view/components/history/date_divider.dart | 29 +-- .../components/history/kanji_search_item.dart | 8 +- .../history/phrase_search_item.dart | 19 +- lib/view/components/history/search_item.dart | 30 ++-- .../components/kanji/kanji_result_body.dart | 89 ++++----- .../kanji/kanji_result_body/examples.dart | 83 ++++----- .../kanji/kanji_result_body/grade.dart | 17 +- .../kanji/kanji_result_body/header.dart | 11 +- .../kanji/kanji_result_body/jlpt_level.dart | 24 +-- .../kanji/kanji_result_body/radical.dart | 18 +- .../kanji/kanji_result_body/rank.dart | 19 +- .../kanji_result_body/stroke_order_gif.dart | 20 ++- .../kanji/kanji_result_body/yomi_chips.dart | 131 +++++++------- .../components/kanji/kanji_search_body.dart | 40 +++-- .../kanji/kanji_search_body/kanji_grid.dart | 9 +- .../kanji_search_body/kanji_search_bar.dart | 24 +-- .../kanji_search_options_bar.dart | 14 +- lib/view/components/opaque_box.dart | 4 +- .../components/search/language_selector.dart | 51 +++--- lib/view/components/search/search_bar.dart | 11 +- .../components/search/search_result_body.dart | 5 +- .../search_results_body/parts/badge.dart | 24 +-- .../parts/common_badge.dart | 17 +- .../search_results_body/parts/header.dart | 17 +- .../search_results_body/parts/jlpt_badge.dart | 22 +-- .../parts/other_forms.dart | 64 +++---- .../search_results_body/parts/senses.dart | 64 +++---- .../parts/wanikani_badge.dart | 4 +- .../search_results_body/search_card.dart | 36 ++-- lib/view/screens/history.dart | 146 ++++++++------- .../screens/search/kanji_result_page.dart | 32 ++-- lib/view/screens/search/kanji_view.dart | 6 +- .../search/search_mechanisms/grid.dart | 32 ++-- .../search_mechanisms/radical_list.dart | 2 +- .../screens/search/search_results_page.dart | 36 ++-- lib/view/screens/search/search_view.dart | 6 +- lib/view/screens/settings.dart | 66 +++---- pubspec.lock | 2 +- test/widget_test.dart | 30 ---- 58 files changed, 955 insertions(+), 700 deletions(-) create mode 100644 analysis_options.yaml delete mode 100644 test/widget_test.dart diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..9974d7f --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,169 @@ +analyzer: + exclude: + - "lib/objectbox.g.dart" + +linter: + rules: + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + # - always_put_control_body_on_new_line # Allow return statements on same line as ifs + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + - always_require_non_null_named_parameters + # - always_specify_types + # - always_use_package_imports # we do this commonly + - annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_classes_with_only_static_members + - avoid_double_and_int_checks + - avoid_dynamic_calls + - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes + - avoid_escaping_inner_quotes + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + - avoid_implementing_value_types + - avoid_init_to_null + - avoid_js_rounded_ints + - avoid_multiple_declarations_per_line + - avoid_null_checks_in_equality_operators + - avoid_positional_boolean_parameters + - avoid_print + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + - avoid_redundant_argument_values + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null + - avoid_returning_null_for_future + - avoid_returning_null_for_void + - avoid_setters_without_getters + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_type_to_string + - avoid_types_as_parameter_names + - avoid_types_on_closure_parameters + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters + - avoid_void_async + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + - cast_nullable_to_non_nullable + - control_flow_in_finally + # - curly_braces_in_flow_control_structures + - depend_on_referenced_packages + - deprecated_consistency + - directives_ordering + - do_not_use_environment + - empty_catches + - empty_constructor_bodies + - empty_statements + - eol_at_end_of_file + - exhaustive_cases + - file_names + # - flutter_style_todos # This is mostly a single person project for the time being + - hash_and_equals + - implementation_imports + - iterable_contains_unrelated_type + - join_return_with_assignment + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + - library_private_types_in_public_api + # - lines_longer_than_80_chars + - list_remove_unrelated_type + - missing_whitespace_between_adjacent_strings + - no_adjacent_strings_in_list + - no_default_cases + - no_duplicate_case_values + - no_logic_in_create_state + # - non_constant_identifier_names # use API names for several variables + - noop_primitive_operations + - null_check_on_nullable_type_parameter + - null_closures + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + # - prefer_final_parameters + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + - prefer_function_declarations_over_variables + - prefer_generic_function_type_aliases + # - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + - prefer_null_aware_operators + - prefer_relative_imports + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + - recursive_getters + - require_trailing_commas + - sized_box_for_whitespace + - slash_for_doc_comments + - sort_child_properties_last + # - sort_constructors_first + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + - type_init_formals + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_constructor_name + - unnecessary_getters_setters + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_checks + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + - unsafe_html + - use_build_context_synchronously + - use_full_hex_values_for_flutter_colors + - use_function_type_syntax_for_parameters + - use_is_even_rather_than_modulo + - use_key_in_widget_constructors + - use_late_for_private_fields_and_variables + - use_named_constants + - use_raw_strings + - use_rethrow_when_possible + - use_setters_to_change_properties + - use_test_throws_matchers + - valid_regexps + - void_checks + \ No newline at end of file diff --git a/lib/bloc/database/database_bloc.dart b/lib/bloc/database/database_bloc.dart index 37d338c..d9b0403 100644 --- a/lib/bloc/database/database_bloc.dart +++ b/lib/bloc/database/database_bloc.dart @@ -1,5 +1,5 @@ -import 'package:bloc/bloc.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import './database_event.dart'; import './database_state.dart'; @@ -7,12 +7,12 @@ import './database_state.dart'; export 'package:flutter_bloc/flutter_bloc.dart'; export './database_event.dart'; -export './database_state.dart'; export './database_not_connected_exception.dart'; +export './database_state.dart'; class DatabaseBloc extends Bloc { - DatabaseBloc() : super(DatabaseDisconnected()); + DatabaseBloc() : super(const DatabaseDisconnected()); @override Stream mapEventToState(DatabaseEvent event) @@ -20,8 +20,8 @@ class DatabaseBloc extends Bloc { if (event is ConnectedToDatabase) { yield DatabaseConnected(event.database); } else { - yield DatabaseDisconnected(); + yield const DatabaseDisconnected(); } } -} \ No newline at end of file +} diff --git a/lib/bloc/database/database_event.dart b/lib/bloc/database/database_event.dart index 0b65487..799860e 100644 --- a/lib/bloc/database/database_event.dart +++ b/lib/bloc/database/database_event.dart @@ -11,4 +11,4 @@ class ConnectedToDatabase extends DatabaseEvent { class DisconnectedFromDatabase extends DatabaseEvent { const DisconnectedFromDatabase(); -} \ No newline at end of file +} diff --git a/lib/bloc/database/database_not_connected_exception.dart b/lib/bloc/database/database_not_connected_exception.dart index d062330..e873be7 100644 --- a/lib/bloc/database/database_not_connected_exception.dart +++ b/lib/bloc/database/database_not_connected_exception.dart @@ -1 +1 @@ -class DatabaseNotConnectedException implements Exception {} \ No newline at end of file +class DatabaseNotConnectedException implements Exception {} diff --git a/lib/bloc/database/database_state.dart b/lib/bloc/database/database_state.dart index 042443f..68d33c4 100644 --- a/lib/bloc/database/database_state.dart +++ b/lib/bloc/database/database_state.dart @@ -1,4 +1,3 @@ - import 'package:objectbox/objectbox.dart'; abstract class DatabaseState { @@ -12,4 +11,4 @@ class DatabaseConnected extends DatabaseState { class DatabaseDisconnected extends DatabaseState { const DatabaseDisconnected(); -} \ No newline at end of file +} diff --git a/lib/bloc/theme/theme_bloc.dart b/lib/bloc/theme/theme_bloc.dart index 49167b7..9db66ac 100644 --- a/lib/bloc/theme/theme_bloc.dart +++ b/lib/bloc/theme/theme_bloc.dart @@ -1,10 +1,11 @@ import 'dart:async'; -import 'package:bloc/bloc.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; -import 'package:meta/meta.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../../models/themes/theme.dart'; + export 'package:flutter_bloc/flutter_bloc.dart'; export 'package:jisho_study_tool/models/themes/theme.dart'; @@ -14,10 +15,10 @@ part 'theme_state.dart'; class ThemeBloc extends Bloc { bool prefsAreLoaded = false; - ThemeBloc() : super(LightThemeState()) { + ThemeBloc() : super(const LightThemeState()) { SharedPreferences.getInstance().then((prefs) { - this.prefsAreLoaded = true; - this.add( + prefsAreLoaded = true; + add( SetTheme( themeIsDark: prefs.getBool('darkThemeEnabled') ?? false, ), diff --git a/lib/bloc/theme/theme_state.dart b/lib/bloc/theme/theme_state.dart index d4bb021..7bb3518 100644 --- a/lib/bloc/theme/theme_state.dart +++ b/lib/bloc/theme/theme_state.dart @@ -14,6 +14,7 @@ class LightThemeState extends ThemeState { const LightThemeState({this.prefsAreLoaded = false}) : super(prefsAreLoaded); + @override AppTheme get theme => LightTheme(); } @@ -22,5 +23,6 @@ class DarkThemeState extends ThemeState { const DarkThemeState({this.prefsAreLoaded = false}) : super(prefsAreLoaded); + @override AppTheme get theme => DarkTheme(); -} \ No newline at end of file +} diff --git a/lib/main.dart b/lib/main.dart index 189d5af..e76989a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,27 +1,26 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; -import 'package:jisho_study_tool/router.dart'; -import 'package:jisho_study_tool/view/components/common/splash.dart'; import 'package:mdi/mdi.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; -import 'package:jisho_study_tool/objectbox.g.dart'; - -import 'package:jisho_study_tool/bloc/database/database_bloc.dart'; - -import 'package:jisho_study_tool/view/screens/search/kanji_view.dart'; -import 'package:jisho_study_tool/view/screens/history.dart'; -import 'package:jisho_study_tool/view/screens/search/search_view.dart'; -import 'package:jisho_study_tool/view/screens/settings.dart'; - +import 'bloc/database/database_bloc.dart'; +import 'bloc/theme/theme_bloc.dart'; import 'models/themes/theme.dart'; +import 'objectbox.g.dart'; +import 'router.dart'; +import 'view/components/common/splash.dart'; +import 'view/screens/history.dart'; +import 'view/screens/search/kanji_view.dart'; +import 'view/screens/search/search_view.dart'; +import 'view/screens/settings.dart'; -void main() => runApp(MyApp()); +void main() => runApp(const MyApp()); DatabaseBloc _databaseBloc = DatabaseBloc(); class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + @override _MyAppState createState() => _MyAppState(); } @@ -50,7 +49,7 @@ class _MyAppState extends State { @override void dispose() { _store.close(); - _databaseBloc.add(DisconnectedFromDatabase()); + _databaseBloc.add(const DisconnectedFromDatabase()); super.dispose(); } @@ -64,13 +63,13 @@ class _MyAppState extends State { child: BlocBuilder( builder: (context, themeState) { if (!(dbConnected && themeState.prefsAreLoaded)) - return SplashScreen(); + return const SplashScreen(); return MaterialApp( title: 'Jisho Study Tool', theme: themeState.theme.getMaterialTheme(), initialRoute: '/', - onGenerateRoute: PageRouter.generateRoute, + onGenerateRoute: generateRoute, ); }, ), @@ -79,6 +78,8 @@ class _MyAppState extends State { } class Home extends StatefulWidget { + const Home({Key? key}) : super(key: key); + @override State createState() => _HomeState(); } @@ -100,11 +101,12 @@ class _HomeState extends State { body: Stack( children: [ Positioned( - child: Image.asset( - 'assets/images/denshi_jisho_background_overlay.png'), right: 30, left: 100, bottom: 30, + child: Image.asset( + 'assets/images/denshi_jisho_background_overlay.png', + ), ), pages[pageNum].content, ], @@ -112,8 +114,8 @@ class _HomeState extends State { bottomNavigationBar: BottomNavigationBar( fixedColor: AppTheme.jishoGreen.background, currentIndex: pageNum, - onTap: (int index) => setState(() { - this.pageNum = index; + onTap: (index) => setState(() { + pageNum = index; }), items: pages.map((p) => p.item).toList(), showSelectedLabels: false, @@ -139,7 +141,7 @@ class _Page { } final List<_Page> pages = [ - _Page( + const _Page( content: SearchView(), titleBar: Text('Search'), item: BottomNavigationBarItem( @@ -147,15 +149,17 @@ final List<_Page> pages = [ icon: Icon(Icons.search), ), ), - _Page( + const _Page( content: KanjiView(), titleBar: Text('Kanji'), item: BottomNavigationBarItem( - label: 'Kanji', icon: Icon(Mdi.ideogramCjk, size: 30)), + label: 'Kanji', + icon: Icon(Mdi.ideogramCjk, size: 30), + ), ), - _Page( + const _Page( content: HistoryView(), - titleBar: Text("History"), + titleBar: Text('History'), item: BottomNavigationBarItem( label: 'History', icon: Icon(Icons.history), @@ -163,15 +167,15 @@ final List<_Page> pages = [ ), _Page( content: Container(), - titleBar: Text("Saved"), - item: BottomNavigationBarItem( + titleBar: const Text('Saved'), + item: const BottomNavigationBarItem( label: 'Saved', icon: Icon(Icons.bookmark), ), ), - _Page( + const _Page( content: SettingsView(), - titleBar: Text("Settings"), + titleBar: Text('Settings'), item: BottomNavigationBarItem( label: 'Settings', icon: Icon(Icons.settings), diff --git a/lib/models/history/search.dart b/lib/models/history/search.dart index f371573..9f37c48 100644 --- a/lib/models/history/search.dart +++ b/lib/models/history/search.dart @@ -16,15 +16,15 @@ class Search { Search({ this.id = 0, - required this.timestamp - }); // { + required this.timestamp, + }); bool isKanji() { // // TODO: better error message - if (this.wordQuery.target == null && this.kanjiQuery.target == null) + if (wordQuery.target == null && kanjiQuery.target == null) throw Exception(); - return this.wordQuery.target == null; + return wordQuery.target == null; } -} \ No newline at end of file +} diff --git a/lib/models/history/word_query.dart b/lib/models/history/word_query.dart index 6041b00..e7d42f2 100644 --- a/lib/models/history/word_query.dart +++ b/lib/models/history/word_query.dart @@ -16,4 +16,4 @@ class WordQuery { this.id = 0, required this.query, }); -} \ No newline at end of file +} diff --git a/lib/models/history/word_result.dart b/lib/models/history/word_result.dart index 75d1f5c..f959f33 100644 --- a/lib/models/history/word_result.dart +++ b/lib/models/history/word_result.dart @@ -1,6 +1,6 @@ import 'package:objectbox/objectbox.dart'; -import 'package:jisho_study_tool/models/history/word_query.dart'; +import 'word_query.dart'; @Entity() class WordResult { @@ -18,4 +18,4 @@ class WordResult { required this.timestamp, required this.word, }); -} \ No newline at end of file +} diff --git a/lib/models/themes/dark.dart b/lib/models/themes/dark.dart index 618fc73..cc7a903 100644 --- a/lib/models/themes/dark.dart +++ b/lib/models/themes/dark.dart @@ -1,34 +1,42 @@ part of './theme.dart'; class DarkTheme extends AppTheme { + @override ColorSet get kanjiResultColor => const ColorSet( foreground: Colors.white, background: Colors.green, ); + @override ColorSet get onyomiColor => const ColorSet( foreground: Colors.white, background: Colors.orange, ); + @override ColorSet get kunyomiColor => const ColorSet( foreground: Colors.white, background: Colors.lightBlue, ); + @override Color get foreground => Colors.black; + @override Color get background => Colors.white; + @override ColorSet get menuGreyLight => ColorSet( foreground: Colors.white, background: Colors.grey.shade700, ); - ColorSet get menuGreyNormal => ColorSet( + @override + ColorSet get menuGreyNormal => const ColorSet( foreground: Colors.white, background: Colors.grey, ); + @override ColorSet get menuGreyDark => ColorSet( foreground: Colors.black, background: Colors.grey.shade300, diff --git a/lib/models/themes/light.dart b/lib/models/themes/light.dart index d1cccc2..6b7fcc1 100644 --- a/lib/models/themes/light.dart +++ b/lib/models/themes/light.dart @@ -1,33 +1,41 @@ part of './theme.dart'; class LightTheme extends AppTheme { + @override ColorSet get kanjiResultColor => const ColorSet( foreground: Colors.white, background: Colors.blue, ); + @override ColorSet get onyomiColor => const ColorSet( foreground: Colors.white, background: Colors.orange, ); + @override ColorSet get kunyomiColor => const ColorSet( foreground: Colors.white, background: Colors.lightBlue, ); + @override Color get foreground => Colors.black; + @override Color get background => Colors.white; + @override ColorSet get menuGreyLight => ColorSet( foreground: Colors.black, background: Colors.grey.shade300, ); - ColorSet get menuGreyNormal => ColorSet( + @override + ColorSet get menuGreyNormal => const ColorSet( foreground: Colors.white, background: Colors.grey, ); + @override ColorSet get menuGreyDark => ColorSet( foreground: Colors.white, background: Colors.grey.shade700, diff --git a/lib/models/themes/theme.dart b/lib/models/themes/theme.dart index d1a591f..76369cc 100644 --- a/lib/models/themes/theme.dart +++ b/lib/models/themes/theme.dart @@ -4,7 +4,6 @@ part 'light.dart'; part 'dark.dart'; abstract class AppTheme { - static const ColorSet jishoGreen = ColorSet( foreground: Colors.white, background: Color(0xFF3EDD00), @@ -49,14 +48,15 @@ class ColorSet { /// Source: https://blog.usejournal.com/creating-a-custom-color-swatch-in-flutter-554bcdcb27f3 MaterialColor createMaterialColor(Color color) { - List strengths = [.05]; + final List strengths = [.05]; final swatch = {}; final int r = color.red, g = color.green, b = color.blue; for (int i = 1; i < 10; i++) { strengths.add(0.1 * i); } - strengths.forEach((strength) { + + for (final strength in strengths) { final double ds = 0.5 - strength; swatch[(strength * 1000).round()] = Color.fromRGBO( r + ((ds < 0 ? r : (255 - r)) * ds).round(), @@ -64,6 +64,6 @@ MaterialColor createMaterialColor(Color color) { b + ((ds < 0 ? b : (255 - b)) * ds).round(), 1, ); - }); + } return MaterialColor(color.value, swatch); -} \ No newline at end of file +} diff --git a/lib/router.dart b/lib/router.dart index cc3452d..a588e5c 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -1,27 +1,31 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/screens/search/kanji_result_page.dart'; -import 'package:jisho_study_tool/view/screens/search/search_results_page.dart'; import 'main.dart'; +import 'view/screens/search/kanji_result_page.dart'; +import 'view/screens/search/search_results_page.dart'; -class PageRouter { - static Route generateRoute(RouteSettings settings) { - final args = settings.arguments; +Route generateRoute(RouteSettings settings) { + final args = settings.arguments; - switch (settings.name) { - case '/': - return MaterialPageRoute(builder: (_) => Home()); + switch (settings.name) { + case '/': + return MaterialPageRoute(builder: (_) => const Home()); - case '/search': - final searchTerm = args as String; - return MaterialPageRoute(builder: (_) => SearchResultsPage(searchTerm: searchTerm)); + case '/search': + final searchTerm = args as String; + return MaterialPageRoute( + builder: (_) => SearchResultsPage(searchTerm: searchTerm), + ); - case '/kanjiSearch': - final searchTerm = args as String; - return MaterialPageRoute(builder: (_) => KanjiResultPage(kanjiSearchTerm: searchTerm)); + case '/kanjiSearch': + final searchTerm = args as String; + return MaterialPageRoute( + builder: (_) => KanjiResultPage(kanjiSearchTerm: searchTerm), + ); - default: - return MaterialPageRoute(builder: (_) => Text("ERROR: this route does not exist")); - } + default: + return MaterialPageRoute( + builder: (_) => const Text('ERROR: this route does not exist'), + ); } } diff --git a/lib/services/jisho_api/jisho_search.dart b/lib/services/jisho_api/jisho_search.dart index 8024a5a..3459bda 100644 --- a/lib/services/jisho_api/jisho_search.dart +++ b/lib/services/jisho_api/jisho_search.dart @@ -2,5 +2,5 @@ import 'package:unofficial_jisho_api/api.dart' as jisho; export 'package:unofficial_jisho_api/api.dart' show JishoAPIResult; Future fetchJishoResults(searchTerm) async { - return await jisho.searchForPhrase(searchTerm); -} \ No newline at end of file + return jisho.searchForPhrase(searchTerm); +} diff --git a/lib/services/jisho_api/kanji_search.dart b/lib/services/jisho_api/kanji_search.dart index 7015894..76e8a31 100644 --- a/lib/services/jisho_api/kanji_search.dart +++ b/lib/services/jisho_api/kanji_search.dart @@ -1,18 +1,19 @@ +import 'package:flutter/material.dart'; import 'package:unofficial_jisho_api/api.dart' as jisho; export 'package:unofficial_jisho_api/api.dart' show KanjiResult; String? _convertGrade(String grade) { const conversionTable = { - "grade 1": "小1", - "grade 2": "小2", - "grade 3": "小3", - "grade 4": "小4", - "grade 5": "小5", - "grade 6": "小6", - "junior high": "中" + 'grade 1': '小1', + 'grade 2': '小2', + 'grade 3': '小3', + 'grade 4': '小4', + 'grade 5': '小5', + 'grade 6': '小6', + 'junior high': '中' }; - print('conversion run: $grade -> ${conversionTable[grade]}'); + debugPrint('conversion run: $grade -> ${conversionTable[grade]}'); return conversionTable[grade]; } @@ -24,4 +25,4 @@ Future fetchKanji(String kanji) async { if (result.data != null && result.data?.taughtIn != null) result.data!.taughtIn = _convertGrade(result.data!.taughtIn!); return result; -} \ No newline at end of file +} diff --git a/lib/view/components/common/loading.dart b/lib/view/components/common/loading.dart index 327c44c..2f30fff 100644 --- a/lib/view/components/common/loading.dart +++ b/lib/view/components/common/loading.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; class LoadingScreen extends StatelessWidget { + const LoadingScreen({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { - return Container( - child: Center( - child: CircularProgressIndicator(), - ), + return const Center( + child: CircularProgressIndicator(), ); } } diff --git a/lib/view/components/common/splash.dart b/lib/view/components/common/splash.dart index 3d05254..e453f34 100644 --- a/lib/view/components/common/splash.dart +++ b/lib/view/components/common/splash.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; + +import '../../../models/themes/theme.dart'; class SplashScreen extends StatelessWidget { const SplashScreen({Key? key}) : super(key: key); @@ -8,9 +9,11 @@ class SplashScreen extends StatelessWidget { Widget build(BuildContext context) { return Container( decoration: BoxDecoration(color: AppTheme.jishoGreen.background), - child: Center( - child: Image(image: AssetImage('assets/images/logo/logo_icon_transparent.png'),) + child: const Center( + child: Image( + image: AssetImage('assets/images/logo/logo_icon_transparent.png'), + ), ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/history/date_divider.dart b/lib/view/components/history/date_divider.dart index 992728e..6d98fc1 100644 --- a/lib/view/components/history/date_divider.dart +++ b/lib/view/components/history/date_divider.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; + +import '../../../bloc/theme/theme_bloc.dart'; +import '../../../models/themes/theme.dart'; class DateDivider extends StatelessWidget { final String? text; @@ -33,31 +34,31 @@ class DateDivider extends StatelessWidget { final int day = date.day; final String month = monthTable[date.month]!; final int year = date.year; - return "$day. $month $year"; + return '$day. $month $year'; } @override Widget build(BuildContext context) { - final Widget header = (this.text != null) - ? Text(this.text!) - : (this.date != null) - ? Text(getHumanReadableDate(this.date!)) - : SizedBox.shrink(); + final Widget header = (text != null) + ? Text(text!) + : (date != null) + ? Text(getHumanReadableDate(date!)) + : const SizedBox.shrink(); final ColorSet _menuColors = BlocProvider.of(context).state.theme.menuGreyNormal; return Container( + decoration: BoxDecoration(color: _menuColors.background), + padding: const EdgeInsets.symmetric( + vertical: 5, + horizontal: 10, + ), + margin: margin, child: DefaultTextStyle.merge( child: header, style: TextStyle(color: _menuColors.foreground), ), - decoration: BoxDecoration(color: _menuColors.background), - padding: EdgeInsets.symmetric( - vertical: 5, - horizontal: 10, - ), - margin: this.margin, ); } } diff --git a/lib/view/components/history/kanji_search_item.dart b/lib/view/components/history/kanji_search_item.dart index 3eed671..5a9d405 100644 --- a/lib/view/components/history/kanji_search_item.dart +++ b/lib/view/components/history/kanji_search_item.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; -import 'package:jisho_study_tool/models/history/kanji_query.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; import './search_item.dart'; +import '../../../bloc/theme/theme_bloc.dart'; +import '../../../models/history/kanji_query.dart'; +import '../../../models/themes/theme.dart'; class _KanjiBox extends StatelessWidget { final String kanji; @@ -19,7 +19,7 @@ class _KanjiBox extends StatelessWidget { child: AspectRatio( aspectRatio: 1, child: Container( - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), decoration: BoxDecoration( color: _menuColors.background, borderRadius: BorderRadius.circular(10.0), diff --git a/lib/view/components/history/phrase_search_item.dart b/lib/view/components/history/phrase_search_item.dart index c0052c7..402a5e0 100644 --- a/lib/view/components/history/phrase_search_item.dart +++ b/lib/view/components/history/phrase_search_item.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:jisho_study_tool/models/history/word_query.dart'; import './search_item.dart'; +import '../../../models/history/word_query.dart'; class PhraseSearchItem extends StatelessWidget { final WordQuery search; @@ -17,15 +17,20 @@ class PhraseSearchItem extends StatelessWidget { @override Widget build(BuildContext context) { return Slidable( - actionPane: SlidableScrollActionPane(), - secondaryActions: [ + actionPane: const SlidableScrollActionPane(), + secondaryActions: const [ IconSlideAction( - caption: "Delete", color: Colors.red, icon: Icons.delete) + caption: 'Delete', + color: Colors.red, + icon: Icons.delete, + ), ], child: SearchItem( - onTap: () { - Navigator.pushNamed(context, '/search', arguments: this.search.query); - }, + onTap: () => Navigator.pushNamed( + context, + '/search', + arguments: search.query, + ), time: timestamp, search: Text(search.query), ), diff --git a/lib/view/components/history/search_item.dart b/lib/view/components/history/search_item.dart index 826a4fa..7025b18 100644 --- a/lib/view/components/history/search_item.dart +++ b/lib/view/components/history/search_item.dart @@ -13,26 +13,24 @@ class SearchItem extends StatelessWidget { }) : super(key: key); String getTime() { - final hours = this.time.hour.toString().padLeft(2, '0'); - final mins = this.time.minute.toString().padLeft(2, '0'); - return "$hours:$mins"; + final hours = time.hour.toString().padLeft(2, '0'); + final mins = time.minute.toString().padLeft(2, '0'); + return '$hours:$mins'; } @override Widget build(BuildContext context) { - return Container( - child: ListTile( - onTap: onTap, - contentPadding: EdgeInsets.zero, - title: Row( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 20), - child: Text(getTime()), - ), - search, - ], - ), + return ListTile( + onTap: onTap, + contentPadding: EdgeInsets.zero, + title: Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text(getTime()), + ), + search, + ], ), ); } diff --git a/lib/view/components/kanji/kanji_result_body.dart b/lib/view/components/kanji/kanji_result_body.dart index 821f643..f94c128 100644 --- a/lib/view/components/kanji/kanji_result_body.dart +++ b/lib/view/components/kanji/kanji_result_body.dart @@ -14,14 +14,13 @@ class KanjiResultBody extends StatelessWidget { late final String query; late final jisho.KanjiResultData resultData; - KanjiResultBody({required jisho.KanjiResult result}) { - + KanjiResultBody({required jisho.KanjiResult result, Key? key}) + : super(key: key) { query = result.query; // TODO: Handle this kind of exception before widget is initialized - if (result.data == null) - throw Exception(); - + if (result.data == null) throw Exception(); + resultData = result.data!; } @@ -30,69 +29,73 @@ class KanjiResultBody extends StatelessWidget { return ListView( children: [ Container( - margin: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 30.0), + margin: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 30.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Flexible( - flex: 1, + const Flexible( fit: FlexFit.tight, child: Center(child: SizedBox()), ), Flexible( - flex: 1, fit: FlexFit.tight, - child: Center(child: Header(query)), + child: Center(child: Header(kanji: query)), ), Flexible( - flex: 1, fit: FlexFit.tight, child: Center( - child: (resultData.radical != null) ? Radical(resultData.radical!) : SizedBox(), + child: (resultData.radical != null) + ? Radical(radical: resultData.radical!) + : const SizedBox(), ), ), ], ), ), - YomiChips(resultData.meaning.split(', '), YomiType.meaning), - resultData.onyomi.length != 0 ? YomiChips(resultData.onyomi, YomiType.onyomi) : SizedBox.shrink(), - resultData.kunyomi.length != 0 ? YomiChips(resultData.kunyomi, YomiType.kunyomi) : SizedBox.shrink(), + YomiChips(yomi: resultData.meaning.split(', '), type: YomiType.meaning), + (resultData.onyomi.isNotEmpty) + ? YomiChips(yomi: resultData.onyomi, type: YomiType.onyomi) + : const SizedBox.shrink(), + (resultData.kunyomi.isNotEmpty) + ? YomiChips(yomi: resultData.kunyomi, type: YomiType.kunyomi) + : const SizedBox.shrink(), IntrinsicHeight( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - StrokeOrderGif(resultData.strokeOrderGifUri), - Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Text("JLPT: ", style: TextStyle(fontSize: 20.0)), - JlptLevel(resultData.jlptLevel ?? "⨉"), - ], - ), - Row( - children: [ - Text("Grade: ", style: TextStyle(fontSize: 20.0)), - Grade(resultData.taughtIn ?? "⨉"), - ], - ), - Row( - children: [ - Text("Rank: ", style: TextStyle(fontSize: 20.0)), - Rank(resultData.newspaperFrequencyRank ?? -1), - ], - ), - ], - ), + StrokeOrderGif(uri: resultData.strokeOrderGifUri), + Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Text('JLPT: ', style: TextStyle(fontSize: 20.0)), + JlptLevel(jlptLevel: resultData.jlptLevel ?? '⨉'), + ], + ), + Row( + children: [ + const Text('Grade: ', style: TextStyle(fontSize: 20.0)), + Grade(grade: resultData.taughtIn ?? '⨉'), + ], + ), + Row( + children: [ + const Text('Rank: ', style: TextStyle(fontSize: 20.0)), + Rank(rank: resultData.newspaperFrequencyRank ?? -1), + ], + ), + ], ), ], ), ), - Examples(resultData.onyomiExamples, resultData.kunyomiExamples), + Examples( + onyomi: resultData.onyomiExamples, + kunyomi: resultData.kunyomiExamples, + ), ], ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/examples.dart b/lib/view/components/kanji/kanji_result_body/examples.dart index 9f4b78e..8740336 100644 --- a/lib/view/components/kanji/kanji_result_body/examples.dart +++ b/lib/view/components/kanji/kanji_result_body/examples.dart @@ -1,15 +1,17 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; import 'package:unofficial_jisho_api/api.dart'; -class Examples extends StatelessWidget { - final List onyomiExamples; - final List kunyomiExamples; +import '../../../../bloc/theme/theme_bloc.dart'; - const Examples( - this.onyomiExamples, - this.kunyomiExamples, - ); +class Examples extends StatelessWidget { + final List onyomi; + final List kunyomi; + + const Examples({ + required this.onyomi, + required this.kunyomi, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -17,20 +19,21 @@ class Examples extends StatelessWidget { children: [ [ Container( - margin: EdgeInsets.symmetric(horizontal: 10), + margin: const EdgeInsets.symmetric(horizontal: 10), alignment: Alignment.centerLeft, - child: Text( + child: const Text( 'Examples:', style: TextStyle(fontSize: 20), ), ) ], - onyomiExamples + onyomi .map((onyomiExample) => _Example(onyomiExample, _KanaType.onyomi)) .toList(), - kunyomiExamples + kunyomi .map( - (kunyomiExample) => _Example(kunyomiExample, _KanaType.kunyomi)) + (kunyomiExample) => _Example(kunyomiExample, _KanaType.kunyomi), + ) .toList(), ].expand((list) => list).toList(), ); @@ -48,68 +51,66 @@ class _Example extends StatelessWidget { @override Widget build(BuildContext context) { final _themeData = BlocProvider.of(context).state.theme; - final _kanaColors = kanaType == _KanaType.kunyomi ? _themeData.kunyomiColor : _themeData.onyomiColor; + final _kanaColors = kanaType == _KanaType.kunyomi + ? _themeData.kunyomiColor + : _themeData.onyomiColor; final _menuColors = _themeData.menuGreyNormal; - return Container( - margin: EdgeInsets.symmetric( + return Container( + margin: const EdgeInsets.symmetric( vertical: 5.0, horizontal: 10.0, ), decoration: BoxDecoration( - color: _menuColors.background, borderRadius: BorderRadius.circular(10.0)), + color: _menuColors.background, + borderRadius: BorderRadius.circular(10.0), + ), child: Row( children: [ Container( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: 10.0, horizontal: 10.0, ), decoration: BoxDecoration( color: _kanaColors.background, - borderRadius: BorderRadius.only( + borderRadius: const BorderRadius.only( topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0), ), ), child: Column( children: [ - Container( - child: Text( - yomiExample.reading, - style: TextStyle( - color: _kanaColors.foreground, - fontSize: 15.0, - ), + Text( + yomiExample.reading, + style: TextStyle( + color: _kanaColors.foreground, + fontSize: 15.0, ), ), - SizedBox( + const SizedBox( height: 5.0, ), - Container( - child: Text( - yomiExample.example, - style: TextStyle( - color: _kanaColors.foreground, - fontSize: 20.0, - ), + Text( + yomiExample.example, + style: TextStyle( + color: _kanaColors.foreground, + fontSize: 20.0, ), ), ], ), ), - SizedBox( + const SizedBox( width: 15.0, ), Expanded( child: Wrap( children: [ - Container( - child: Text( - yomiExample.meaning, - style: TextStyle( - color: _menuColors.foreground, - ), + Text( + yomiExample.meaning, + style: TextStyle( + color: _menuColors.foreground, ), ) ], diff --git a/lib/view/components/kanji/kanji_result_body/grade.dart b/lib/view/components/kanji/kanji_result_body/grade.dart index 12fb36e..abe2443 100644 --- a/lib/view/components/kanji/kanji_result_body/grade.dart +++ b/lib/view/components/kanji/kanji_result_body/grade.dart @@ -1,17 +1,22 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; class Grade extends StatelessWidget { final String grade; - const Grade(this.grade); + const Grade({required this.grade, Key? key}) : super(key: key); @override Widget build(BuildContext context) { final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; return Container( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: _kanjiColors.background, + shape: BoxShape.circle, + ), child: Text( grade, style: TextStyle( @@ -19,10 +24,6 @@ class Grade extends StatelessWidget { fontSize: 20.0, ), ), - decoration: BoxDecoration( - color: _kanjiColors.background, - shape: BoxShape.circle, - ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/header.dart b/lib/view/components/kanji/kanji_result_body/header.dart index d0f999c..c86fb5d 100644 --- a/lib/view/components/kanji/kanji_result_body/header.dart +++ b/lib/view/components/kanji/kanji_result_body/header.dart @@ -1,14 +1,19 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; class Header extends StatelessWidget { final String kanji; - const Header(this.kanji); + const Header({ + required this.kanji, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { - final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; + final _kanjiColors = + BlocProvider.of(context).state.theme.kanjiResultColor; return AspectRatio( aspectRatio: 1, diff --git a/lib/view/components/kanji/kanji_result_body/jlpt_level.dart b/lib/view/components/kanji/kanji_result_body/jlpt_level.dart index 2cc2fe1..f63cbc3 100644 --- a/lib/view/components/kanji/kanji_result_body/jlpt_level.dart +++ b/lib/view/components/kanji/kanji_result_body/jlpt_level.dart @@ -1,18 +1,26 @@ - import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; class JlptLevel extends StatelessWidget { final String jlptLevel; - const JlptLevel(this.jlptLevel); + const JlptLevel({ + required this.jlptLevel, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { - final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; + final _kanjiColors = + BlocProvider.of(context).state.theme.kanjiResultColor; return Container( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _kanjiColors.background, + ), child: Text( jlptLevel, style: TextStyle( @@ -20,10 +28,6 @@ class JlptLevel extends StatelessWidget { fontSize: 20.0, ), ), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _kanjiColors.background, - ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/radical.dart b/lib/view/components/kanji/kanji_result_body/radical.dart index d208e00..aa7ef1e 100644 --- a/lib/view/components/kanji/kanji_result_body/radical.dart +++ b/lib/view/components/kanji/kanji_result_body/radical.dart @@ -1,18 +1,24 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; import 'package:unofficial_jisho_api/api.dart' as jisho; +import '../../../../bloc/theme/theme_bloc.dart'; + class Radical extends StatelessWidget { final jisho.Radical radical; - const Radical(this.radical); + const Radical({required this.radical, Key? key,}) : super(key: key); + @override Widget build(BuildContext context) { final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; return Container( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _kanjiColors.background, + ), child: Text( radical.symbol, style: TextStyle( @@ -20,10 +26,6 @@ class Radical extends StatelessWidget { fontSize: 40.0, ), ), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _kanjiColors.background, - ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/rank.dart b/lib/view/components/kanji/kanji_result_body/rank.dart index 24356fb..89279ac 100644 --- a/lib/view/components/kanji/kanji_result_body/rank.dart +++ b/lib/view/components/kanji/kanji_result_body/rank.dart @@ -1,18 +1,23 @@ - import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; class Rank extends StatelessWidget { final int rank; - const Rank(this.rank); + const Rank({required this.rank, Key? key,}) : super(key: key); + @override Widget build(BuildContext context) { final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; return Container( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: _kanjiColors.background, + ), child: Text( '${rank.toString()} / 2500', style: TextStyle( @@ -20,10 +25,6 @@ class Rank extends StatelessWidget { fontSize: 20.0, ), ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), - color: _kanjiColors.background, - ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/stroke_order_gif.dart b/lib/view/components/kanji/kanji_result_body/stroke_order_gif.dart index ecda698..75fb00d 100644 --- a/lib/view/components/kanji/kanji_result_body/stroke_order_gif.dart +++ b/lib/view/components/kanji/kanji_result_body/stroke_order_gif.dart @@ -1,26 +1,28 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; class StrokeOrderGif extends StatelessWidget { final String uri; - const StrokeOrderGif(this.uri); + const StrokeOrderGif({required this.uri, Key? key,}) : super(key: key); + @override Widget build(BuildContext context) { final _kanjiColors = BlocProvider.of(context).state.theme.kanjiResultColor; return Container( - margin: EdgeInsets.symmetric(vertical: 20.0), - padding: EdgeInsets.all(5.0), - child: ClipRRect( - child: Image.network(uri), - borderRadius: BorderRadius.circular(10.0), - ), + margin: const EdgeInsets.symmetric(vertical: 20.0), + padding: const EdgeInsets.all(5.0), decoration: BoxDecoration( color: _kanjiColors.background, borderRadius: BorderRadius.circular(15.0), ), + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: Image.network(uri), + ), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/kanji/kanji_result_body/yomi_chips.dart b/lib/view/components/kanji/kanji_result_body/yomi_chips.dart index 7ee1757..ce5eb20 100644 --- a/lib/view/components/kanji/kanji_result_body/yomi_chips.dart +++ b/lib/view/components/kanji/kanji_result_body/yomi_chips.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; + +import '../../../../bloc/theme/theme_bloc.dart'; enum YomiType { onyomi, @@ -37,86 +38,88 @@ class YomiChips extends StatelessWidget { final List yomi; final YomiType type; - const YomiChips(this.yomi, this.type); + const YomiChips({ + required this.yomi, + required this.type, + Key? key, + }) : super(key: key); - @override - Widget build(BuildContext context) { - return Container( - margin: EdgeInsets.symmetric( - horizontal: 10.0, - vertical: 5.0, - ), - alignment: Alignment.centerLeft, - child: _yomiWrapper(context), - ); - } + bool get isExpandable => yomi.length > 6; - bool isExpandable() => yomi.length > 6; + Widget yomiCard({ + required BuildContext context, + required String yomi, + required ColorSet colors, + }) => + Container( + margin: const EdgeInsets.symmetric(horizontal: 10.0), + padding: const EdgeInsets.symmetric( + vertical: 10.0, + horizontal: 10.0, + ), + decoration: BoxDecoration( + color: type.getColors(context).background, + borderRadius: BorderRadius.circular(10.0), + ), + child: Text( + yomi, + style: TextStyle( + fontSize: 20.0, + color: colors.foreground, + ), + ), + ); - Widget _yomiWrapper(BuildContext context) { - final yomiCards = this - .yomi - .map((yomi) => _YomiCard( - yomi: yomi, - colors: this.type.getColors(context), - )) + Widget yomiWrapper(BuildContext context) { + final yomiCards = yomi + .map( + (y) => yomiCard( + context: context, + yomi: y, + colors: type.getColors(context), + ), + ) .toList(); - if (!this.isExpandable()) + if (!isExpandable) return Wrap( runSpacing: 10.0, children: yomiCards, ); - - return ExpansionTile( - initiallyExpanded: false, - title: Center( - child: _YomiCard( - yomi: this.type.title, - colors: this.type.getColors(context), + else + return ExpansionTile( + // initiallyExpanded: false, + title: Center( + child: yomiCard( + context: context, + yomi: type.title, + colors: type.getColors(context), + ), ), - ), - children: [ - SizedBox( - height: 20.0, - ), - Wrap( - runSpacing: 10.0, - children: yomiCards, - ), - SizedBox( - height: 25.0, - ), - ], - ); + children: [ + const SizedBox( + height: 20.0, + ), + Wrap( + runSpacing: 10.0, + children: yomiCards, + ), + const SizedBox( + height: 25.0, + ), + ], + ); } -} - -class _YomiCard extends StatelessWidget { - final String yomi; - final ColorSet colors; - - const _YomiCard({required this.yomi, required this.colors}); @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.symmetric(horizontal: 10.0), - padding: EdgeInsets.symmetric( - vertical: 10.0, + margin: const EdgeInsets.symmetric( horizontal: 10.0, + vertical: 5.0, ), - child: Text( - this.yomi, - style: TextStyle( - fontSize: 20.0, - color: colors.foreground, - ), - ), - decoration: BoxDecoration( - color: colors.background, - borderRadius: BorderRadius.circular(10.0), - ), + alignment: Alignment.centerLeft, + child: yomiWrapper(context), ); } } diff --git a/lib/view/components/kanji/kanji_search_body.dart b/lib/view/components/kanji/kanji_search_body.dart index 1a8154f..6f04919 100644 --- a/lib/view/components/kanji/kanji_search_body.dart +++ b/lib/view/components/kanji/kanji_search_body.dart @@ -1,13 +1,13 @@ -import 'package:flutter/material.dart'; import 'package:animated_size_and_fade/animated_size_and_fade.dart'; -import 'package:jisho_study_tool/services/kanji_suggestions.dart'; +import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body/kanji_grid.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body/kanji_search_bar.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body/kanji_search_options_bar.dart'; +import '../../../services/kanji_suggestions.dart'; +import 'kanji_search_body/kanji_grid.dart'; +import 'kanji_search_body/kanji_search_bar.dart'; +import 'kanji_search_body/kanji_search_options_bar.dart'; class KanjiSearchBody extends StatefulWidget { - KanjiSearchBody({Key? key}) : super(key: key); + const KanjiSearchBody({Key? key}) : super(key: key); @override _KanjiSearchBodyState createState() => _KanjiSearchBodyState(); @@ -28,16 +28,18 @@ class _KanjiSearchBodyState extends State _controller = AnimationController( vsync: this, - duration: Duration(milliseconds: 200), + duration: const Duration(milliseconds: 200), ); _searchbarMovementAnimation = AlignmentTween( begin: Alignment.center, end: Alignment.topCenter, - ).animate(CurvedAnimation( - parent: _controller, - curve: Curves.easeInOut, - )); + ).animate( + CurvedAnimation( + parent: _controller, + curve: Curves.easeInOut, + ), + ); } @override @@ -60,15 +62,15 @@ class _KanjiSearchBodyState extends State child: GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( - decoration: BoxDecoration(), + decoration: const BoxDecoration(), alignment: Alignment.center, - padding: EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 20), child: AnimatedBuilder( animation: _searchbarMovementAnimation, - builder: (BuildContext context, _) { + builder: (context, _) { return Container( alignment: _searchbarMovementAnimation.value, - padding: EdgeInsets.symmetric(vertical: 10.0), + padding: const EdgeInsets.symmetric(vertical: 10.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -83,17 +85,17 @@ class _KanjiSearchBodyState extends State child: KanjiSearchBar( key: _kanjiSearchBarState, onChanged: (text) => setState(() { - this.suggestions = kanjiSuggestions(text); + suggestions = kanjiSuggestions(text); }), ), ), AnimatedSizeAndFade( vsync: this, - child: _controller.value == 1 - ? KanjiGrid(this.suggestions) - : KanjiSearchOptionsBar(), fadeDuration: const Duration(milliseconds: 200), sizeDuration: const Duration(milliseconds: 300), + child: _controller.value == 1 + ? KanjiGrid(suggestions: suggestions) + : const KanjiSearchOptionsBar(), ), ], ), diff --git a/lib/view/components/kanji/kanji_search_body/kanji_grid.dart b/lib/view/components/kanji/kanji_search_body/kanji_grid.dart index e80b1eb..8373be9 100644 --- a/lib/view/components/kanji/kanji_search_body/kanji_grid.dart +++ b/lib/view/components/kanji/kanji_search_body/kanji_grid.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; +import '../../../../bloc/theme/theme_bloc.dart'; class KanjiGrid extends StatelessWidget { final List suggestions; - const KanjiGrid(this.suggestions); + + const KanjiGrid({required this.suggestions, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: 20.0, horizontal: 40.0, ), @@ -43,7 +44,7 @@ class _GridItem extends StatelessWidget { borderRadius: BorderRadius.circular(20.0), ), child: Container( - margin: EdgeInsets.all(10.0), + margin: const EdgeInsets.all(10.0), child: FittedBox( child: Text( kanji, diff --git a/lib/view/components/kanji/kanji_search_body/kanji_search_bar.dart b/lib/view/components/kanji/kanji_search_body/kanji_search_bar.dart index 35fdb5c..7f2ef5d 100644 --- a/lib/view/components/kanji/kanji_search_body/kanji_search_bar.dart +++ b/lib/view/components/kanji/kanji_search_body/kanji_search_bar.dart @@ -4,16 +4,16 @@ import 'package:flutter/services.dart'; class KanjiSearchBar extends StatefulWidget { final Function(String)? onChanged; - KanjiSearchBar({this.onChanged, Key? key}) : super(key: key); + const KanjiSearchBar({this.onChanged, Key? key}) : super(key: key); @override - KanjiSearchBarState createState() => new KanjiSearchBarState(this.onChanged); + KanjiSearchBarState createState() => KanjiSearchBarState(this.onChanged); } enum TextFieldButton { clear, paste } class KanjiSearchBarState extends State { - final TextEditingController textController = new TextEditingController(); + final TextEditingController textController = TextEditingController(); TextFieldButton button = TextFieldButton.paste; final Function(String)? onChanged; @@ -33,8 +33,8 @@ class KanjiSearchBarState extends State { runOnChanged(); } - void pasteText() async { - ClipboardData? clipboardData = await Clipboard.getData('text/plain'); + Future pasteText() async { + final ClipboardData? clipboardData = await Clipboard.getData('text/plain'); if (clipboardData != null && clipboardData.text != null) { textController.text = clipboardData.text!; runOnChanged(); @@ -43,24 +43,24 @@ class KanjiSearchBarState extends State { @override Widget build(BuildContext context) { - IconButton clearButton = IconButton( - icon: Icon(Icons.clear), + final IconButton clearButton = IconButton( + icon: const Icon(Icons.clear), onPressed: () => clearText(), ); - IconButton pasteButton = IconButton( - icon: Icon(Icons.content_paste), + final IconButton pasteButton = IconButton( + icon: const Icon(Icons.content_paste), onPressed: () => pasteText(), ); return TextField( controller: textController, onChanged: (text) { - if (this.onChanged != null) this.onChanged!(text); + if (onChanged != null) onChanged!(text); }, onSubmitted: (_) => {}, - decoration: new InputDecoration( - prefixIcon: Icon(Icons.search), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.search), hintText: 'Search', // fillColor: Colors.white, // filled: true, diff --git a/lib/view/components/kanji/kanji_search_body/kanji_search_options_bar.dart b/lib/view/components/kanji/kanji_search_body/kanji_search_options_bar.dart index 4b759ed..23aad34 100644 --- a/lib/view/components/kanji/kanji_search_body/kanji_search_options_bar.dart +++ b/lib/view/components/kanji/kanji_search_body/kanji_search_options_bar.dart @@ -12,22 +12,22 @@ class KanjiSearchOptionsBar extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ _IconButton( - icon: Text( - "部", + icon: const Text( + '部', style: TextStyle( fontWeight: FontWeight.w700, fontSize: 18, ), ), - onPressed: () {} + onPressed: () {}, ), _IconButton( - icon: Icon(Icons.category), - onPressed: () {} + icon: const Icon(Icons.category), + onPressed: () {}, ), _IconButton( - icon: Icon(Icons.mode), - onPressed: () {} + icon: const Icon(Icons.mode), + onPressed: () {}, ), ], ), diff --git a/lib/view/components/opaque_box.dart b/lib/view/components/opaque_box.dart index c8cc7db..87d5ff5 100644 --- a/lib/view/components/opaque_box.dart +++ b/lib/view/components/opaque_box.dart @@ -9,7 +9,7 @@ class OpaqueBox extends StatelessWidget { Widget build(BuildContext context) { return Container( decoration: BoxDecoration(color: Theme.of(context).scaffoldBackgroundColor), - child: this.child, + child: child, ); } -} \ No newline at end of file +} diff --git a/lib/view/components/search/language_selector.dart b/lib/view/components/search/language_selector.dart index b28cbe1..2ee1bf1 100644 --- a/lib/view/components/search/language_selector.dart +++ b/lib/view/components/search/language_selector.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../../../models/themes/theme.dart'; + class LanguageSelector extends StatefulWidget { - const LanguageSelector(); + const LanguageSelector({Key? key}) : super(key: key); @override - _LanguageSelectorState createState() => new _LanguageSelectorState(); + _LanguageSelectorState createState() => _LanguageSelectorState(); } class _LanguageSelectorState extends State { @@ -18,27 +19,26 @@ class _LanguageSelectorState extends State { super.initState(); isSelected = [false, false, false]; - SharedPreferences.getInstance() - .then((prefs) { - this.prefs = prefs; - setState(() { - isSelected = _getSelectedStatus() ?? isSelected; - }); + SharedPreferences.getInstance().then((prefs) { + this.prefs = prefs; + setState(() { + isSelected = _getSelectedStatus() ?? isSelected; }); + }); } - void _updateSelectedStatus() async { - await prefs.setStringList('languageSelectorStatus', - isSelected - .map((b) => b ? '1' : '0') - .toList()); + void _updateSelectedStatus() { + prefs.setStringList( + 'languageSelectorStatus', + isSelected.map((b) => b ? '1' : '0').toList(), + ); } List? _getSelectedStatus() { return prefs - .getStringList('languageSelectorStatus') - ?.map((s) => s == '1') - .toList(); + .getStringList('languageSelectorStatus') + ?.map((s) => s == '1') + .toList(); } @override @@ -46,14 +46,14 @@ class _LanguageSelectorState extends State { return ToggleButtons( selectedColor: AppTheme.jishoGreen.background, isSelected: isSelected, - children: [ - _LanguageOption("Auto"), - _LanguageOption("日本語"), - _LanguageOption("English") + children: const [ + _LanguageOption('Auto'), + _LanguageOption('日本語'), + _LanguageOption('English') ], - onPressed: (int buttonIndex) { + onPressed: (buttonIndex) { setState(() { - for (var i in Iterable.generate(isSelected.length)) { + for (final int i in Iterable.generate(isSelected.length)) { isSelected[i] = i == buttonIndex; } _updateSelectedStatus(); @@ -61,7 +61,6 @@ class _LanguageSelectorState extends State { }, ); } - } class _LanguageOption extends StatelessWidget { @@ -72,8 +71,8 @@ class _LanguageOption extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), + padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), child: Center(child: Text(language)), ); } -} \ No newline at end of file +} diff --git a/lib/view/components/search/search_bar.dart b/lib/view/components/search/search_bar.dart index e9c7d68..9a70692 100644 --- a/lib/view/components/search/search_bar.dart +++ b/lib/view/components/search/search_bar.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/search/language_selector.dart'; + +import 'language_selector.dart'; class SearchBar extends StatelessWidget { - const SearchBar(); + const SearchBar({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.symmetric(horizontal: 20.0), + padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Column( children: [ TextField( @@ -21,10 +22,10 @@ class SearchBar extends StatelessWidget { ), ), ), - SizedBox( + const SizedBox( height: 10.0, ), - LanguageSelector() + const LanguageSelector() ], ), ); diff --git a/lib/view/components/search/search_result_body.dart b/lib/view/components/search/search_result_body.dart index 03ebe65..d00c770 100644 --- a/lib/view/components/search/search_result_body.dart +++ b/lib/view/components/search/search_result_body.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/search/search_results_body/search_card.dart'; import 'package:unofficial_jisho_api/api.dart'; +import 'search_results_body/search_card.dart'; + class SearchResultsBody extends StatelessWidget { final List results; @@ -13,7 +14,7 @@ class SearchResultsBody extends StatelessWidget { @override Widget build(BuildContext context) { return ListView( - children: results.map((result) => SearchResultCard(result)).toList(), + children: results.map((result) => SearchResultCard(result: result)).toList(), ); } } diff --git a/lib/view/components/search/search_results_body/parts/badge.dart b/lib/view/components/search/search_results_body/parts/badge.dart index 3ddf3aa..457fc01 100644 --- a/lib/view/components/search/search_results_body/parts/badge.dart +++ b/lib/view/components/search/search_results_body/parts/badge.dart @@ -1,27 +1,27 @@ import 'package:flutter/material.dart'; class Badge extends StatelessWidget { - final Widget child; + final Widget? child; final Color color; - const Badge(this.child, this.color); + const Badge({this.child, required this.color, Key? key,}) : super(key: key); + @override Widget build(BuildContext context) { return Container( - child: FittedBox( - child: Center( - child: this.child - ), - ), - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), width: 30, height: 30, - margin: EdgeInsets.symmetric(horizontal: 2), + margin: const EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( shape: BoxShape.circle, - color: color + color: color, + ), + child: FittedBox( + child: Center( + child: child, + ), ), ); } - -} \ No newline at end of file +} diff --git a/lib/view/components/search/search_results_body/parts/common_badge.dart b/lib/view/components/search/search_results_body/parts/common_badge.dart index efbf9c0..bdcaad2 100644 --- a/lib/view/components/search/search_results_body/parts/common_badge.dart +++ b/lib/view/components/search/search_results_body/parts/common_badge.dart @@ -4,16 +4,21 @@ import './badge.dart'; class CommonBadge extends StatelessWidget { final bool isCommon; - const CommonBadge(this.isCommon); + const CommonBadge({ + required this.isCommon, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { return Badge( - Text( - "C", - style: TextStyle(color: this.isCommon ? Colors.white : Colors.transparent) + color: isCommon ? Colors.green : Colors.transparent, + child: Text( + 'C', + style: TextStyle( + color: isCommon ? Colors.white : Colors.transparent, + ), ), - this.isCommon ? Colors.green : Colors.transparent ); } -} \ No newline at end of file +} diff --git a/lib/view/components/search/search_results_body/parts/header.dart b/lib/view/components/search/search_results_body/parts/header.dart index 677ae37..46eaba4 100644 --- a/lib/view/components/search/search_results_body/parts/header.dart +++ b/lib/view/components/search/search_results_body/parts/header.dart @@ -3,21 +3,24 @@ import 'package:unofficial_jisho_api/api.dart'; class JapaneseHeader extends StatelessWidget { final JishoJapaneseWord word; - - const JapaneseHeader(this.word); + + const JapaneseHeader({ + required this.word, + Key? key, + }) : super(key: key); + + bool get hasFurigana => word.word != null && word.reading != null; @override Widget build(BuildContext context) { - final hasFurigana = (word.word != null && word.reading != null); - return Container( alignment: Alignment.centerLeft, - padding: EdgeInsets.only(left: 10.0), + padding: const EdgeInsets.only(left: 10.0), child: Column( children: [ // TODO: take a look at this logic - (hasFurigana) ? Text(word.reading!) : Text(''), - (hasFurigana) ? Text(word.word!) : Text(word.reading ?? word.word!), + hasFurigana ? Text(word.reading!) : const Text(''), + hasFurigana ? Text(word.word!) : Text(word.reading ?? word.word!), ], ), ); diff --git a/lib/view/components/search/search_results_body/parts/jlpt_badge.dart b/lib/view/components/search/search_results_body/parts/jlpt_badge.dart index 277b132..77e97c5 100644 --- a/lib/view/components/search/search_results_body/parts/jlpt_badge.dart +++ b/lib/view/components/search/search_results_body/parts/jlpt_badge.dart @@ -4,22 +4,22 @@ import './badge.dart'; class JLPTBadge extends StatelessWidget { final String jlptLevel; - const JLPTBadge(this.jlptLevel); + const JLPTBadge({ + required this.jlptLevel, + Key? key, + }) : super(key: key); - String _extractJlptLevel(String jlptRaw) { - return jlptRaw.isNotEmpty ? jlptRaw.substring(5).toUpperCase() : ''; - } + String get formattedJlptLevel => + jlptLevel.isNotEmpty ? jlptLevel.substring(5).toUpperCase() : ''; @override Widget build(BuildContext context) { return Badge( - Text( - _extractJlptLevel(this.jlptLevel), - style: TextStyle( - color: Colors.white - ), + color: jlptLevel.isNotEmpty ? Colors.blue : Colors.transparent, + child: Text( + formattedJlptLevel, + style: const TextStyle(color: Colors.white), ), - this.jlptLevel.isNotEmpty ? Colors.blue : Colors.transparent ); } -} \ No newline at end of file +} diff --git a/lib/view/components/search/search_results_body/parts/other_forms.dart b/lib/view/components/search/search_results_body/parts/other_forms.dart index 8ea8dc1..d690f8c 100644 --- a/lib/view/components/search/search_results_body/parts/other_forms.dart +++ b/lib/view/components/search/search_results_body/parts/other_forms.dart @@ -1,28 +1,27 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; import 'package:unofficial_jisho_api/api.dart'; -class OtherForms extends StatelessWidget { - final List otherForms; +import '../../../../../bloc/theme/theme_bloc.dart'; - const OtherForms(this.otherForms); +class OtherForms extends StatelessWidget { + final List forms; + + const OtherForms({required this.forms, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Container( - child: Column( - children: this.otherForms.isNotEmpty - ? [ - Text( - 'Other Forms', - style: TextStyle(fontWeight: FontWeight.bold), - ), - Row( - children: otherForms.map((form) => _KanaBox(form)).toList(), - ), - ] - : [], - ), + return Column( + children: forms.isNotEmpty + ? [ + const Text( + 'Other Forms', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Row( + children: forms.map((form) => _KanaBox(form)).toList(), + ), + ] + : [], ); } } @@ -32,28 +31,19 @@ class _KanaBox extends StatelessWidget { const _KanaBox(this.word); + bool get hasFurigana => word.word != null; + @override Widget build(BuildContext context) { - final hasFurigana = (word.word != null); final _menuColors = BlocProvider.of(context).state.theme.menuGreyLight; return Container( - child: DefaultTextStyle.merge( - child: Column( - children: [ - // TODO: take a look at this logic - (hasFurigana) ? Text(word.reading ?? '') : Text(''), - (hasFurigana) ? Text(word.word!) : Text(word.reading ?? ''), - ], - ), - style: TextStyle(color: _menuColors.foreground), - ), - margin: EdgeInsets.symmetric( + margin: const EdgeInsets.symmetric( horizontal: 5.0, vertical: 5.0, ), - padding: EdgeInsets.all(5.0), + padding: const EdgeInsets.all(5.0), decoration: BoxDecoration( color: _menuColors.background, boxShadow: [ @@ -61,10 +51,20 @@ class _KanaBox extends StatelessWidget { color: Colors.grey.withOpacity(0.5), spreadRadius: 1, blurRadius: 0.5, - offset: Offset(1, 1), + offset: const Offset(1, 1), ), ], ), + child: DefaultTextStyle.merge( + child: Column( + children: [ + // TODO: take a look at this logic + hasFurigana ? Text(word.reading ?? '') : const Text(''), + hasFurigana ? Text(word.word!) : Text(word.reading ?? ''), + ], + ), + style: TextStyle(color: _menuColors.foreground), + ), ); } } diff --git a/lib/view/components/search/search_results_body/parts/senses.dart b/lib/view/components/search/search_results_body/parts/senses.dart index 510054d..1bd0ccc 100644 --- a/lib/view/components/search/search_results_body/parts/senses.dart +++ b/lib/view/components/search/search_results_body/parts/senses.dart @@ -3,18 +3,20 @@ import 'package:unofficial_jisho_api/parser.dart'; class Senses extends StatelessWidget { final List senses; - - const Senses(this.senses); + + const Senses({ + required this.senses, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { final List senseWidgets = senses.asMap().entries.map((e) => _Sense(e.key, e.value)).toList(); - return Container( - child: Column( + return Column( children: senseWidgets, - )); + ); } } @@ -26,37 +28,35 @@ class _Sense extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - child: Column( - children: [ - Row( + return Column( + children: [ + Row( + children: [ + Text( + '${index + 1}. ', + style: const TextStyle(color: Colors.grey), + ), + Text( + sense.partsOfSpeech.join(', '), + style: const TextStyle(fontWeight: FontWeight.bold), + textAlign: TextAlign.left, + ), + ], + ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 20), + margin: const EdgeInsets.fromLTRB(0, 5, 0, 15), + child: Row( children: [ - Text( - (index + 1).toString() + '. ', - style: TextStyle(color: Colors.grey), - ), - Text( - sense.partsOfSpeech.join(', '), - style: TextStyle(fontWeight: FontWeight.bold), - textAlign: TextAlign.left, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: + sense.englishDefinitions.map((def) => Text(def)).toList(), ), ], ), - Container( - child: Row( - children:[ - Column( - children: - sense.englishDefinitions.map((def) => Text(def)).toList(), - crossAxisAlignment: CrossAxisAlignment.start, - ), - ] - ), - padding: EdgeInsets.symmetric(horizontal: 20), - margin: EdgeInsets.fromLTRB(0, 5, 0, 15), - ), - ], - ), + ), + ], ); } } diff --git a/lib/view/components/search/search_results_body/parts/wanikani_badge.dart b/lib/view/components/search/search_results_body/parts/wanikani_badge.dart index f724131..3de0ec2 100644 --- a/lib/view/components/search/search_results_body/parts/wanikani_badge.dart +++ b/lib/view/components/search/search_results_body/parts/wanikani_badge.dart @@ -14,13 +14,13 @@ class WKBadge extends StatelessWidget { @override Widget build(BuildContext context) { return Badge( - Text( + child: Text( _extractWkLevel(this.wkLevel), style: TextStyle( color: Colors.white, ), ), - this.wkLevel.isNotEmpty ? Colors.red : Colors.transparent + color: this.wkLevel.isNotEmpty ? Colors.red : Colors.transparent ); } } \ No newline at end of file diff --git a/lib/view/components/search/search_results_body/search_card.dart b/lib/view/components/search/search_results_body/search_card.dart index b53b371..e56b270 100644 --- a/lib/view/components/search/search_results_body/search_card.dart +++ b/lib/view/components/search/search_results_body/search_card.dart @@ -13,10 +13,12 @@ class SearchResultCard extends StatelessWidget { late final JishoJapaneseWord mainWord; late final List otherForms; - SearchResultCard(this.result) { - this.mainWord = result.japanese[0]; - this.otherForms = result.japanese.sublist(1); - } + SearchResultCard({ + required this.result, + Key? key, + }) : mainWord = result.japanese[0], + otherForms = result.japanese.sublist(1), + super(key: key); @override Widget build(BuildContext context) { @@ -24,34 +26,40 @@ class SearchResultCard extends StatelessWidget { return ExpansionTile( collapsedBackgroundColor: backgroundColor, backgroundColor: backgroundColor, - title: - IntrinsicWidth( + title: IntrinsicWidth( child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - JapaneseHeader(mainWord), + JapaneseHeader(word: mainWord), Row( children: [ - WKBadge(result.tags.firstWhere((tag) => tag.contains("wanikani"), orElse: () => '')), - JLPTBadge(result.jlpt.isNotEmpty ? result.jlpt[0] : ''), - CommonBadge(result.isCommon ?? false) + WKBadge( + result.tags.firstWhere( + (tag) => tag.contains('wanikani'), + orElse: () => '', + ), + ), + JLPTBadge( + jlptLevel: result.jlpt.isNotEmpty ? result.jlpt[0] : '', + ), + CommonBadge(isCommon: result.isCommon ?? false) ], ) ], - mainAxisAlignment: MainAxisAlignment.spaceBetween, ), ), children: [ Container( + padding: const EdgeInsets.symmetric(horizontal: 30), child: Column( children: [ - Senses(result.senses), - OtherForms(otherForms), + Senses(senses: result.senses), + OtherForms(forms: otherForms), // Text(result.toJson().toString()), // Text(result.attribution.toJson().toString()), // Text(result.japanese.map((e) => e.toJson().toString()).toList().toString()), ], ), - padding: EdgeInsets.symmetric(horizontal: 30), ) ], ); diff --git a/lib/view/screens/history.dart b/lib/view/screens/history.dart index 0a45b19..faf2901 100644 --- a/lib/view/screens/history.dart +++ b/lib/view/screens/history.dart @@ -1,75 +1,37 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/database/database_bloc.dart'; -import 'package:jisho_study_tool/models/history/search.dart'; -import 'package:jisho_study_tool/view/components/history/kanji_search_item.dart'; -import 'package:jisho_study_tool/view/components/history/phrase_search_item.dart'; -import 'package:jisho_study_tool/view/components/history/date_divider.dart'; -import 'package:jisho_study_tool/objectbox.g.dart'; -import 'package:jisho_study_tool/view/components/opaque_box.dart'; +import '../../bloc/database/database_bloc.dart'; +import '../../models/history/search.dart'; +import '../../objectbox.g.dart'; +import '../components/history/date_divider.dart'; +import '../components/history/kanji_search_item.dart'; +import '../components/history/phrase_search_item.dart'; +import '../components/opaque_box.dart'; class HistoryView extends StatelessWidget { + const HistoryView({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - if (state is DatabaseDisconnected) + if (state is DatabaseDisconnected) { throw DatabaseNotConnectedException(); + } - return StreamBuilder( - stream: ((state as DatabaseConnected).database.box().query() - ..order(Search_.timestamp, flags: Order.descending)) - .watch(triggerImmediately: true) - .map((query) => query.find()), - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (!snapshot.hasData) return Container(); + return StreamBuilder>( + stream: getAsyncStream(state), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return Container(); + } + + final List data = snapshot.data!; return OpaqueBox( child: ListView.separated( - itemCount: snapshot.data.length + 1, - itemBuilder: (context, index) { - if (index == 0) return Container(); - Search search = snapshot.data[index - 1]; - if (search.isKanji()) { - return KanjiSearchItem( - result: search.kanjiQuery.target!, - timestamp: search.timestamp, - ); - } - return PhraseSearchItem( - search: search.wordQuery.target!, - timestamp: search.timestamp, - ); - }, - separatorBuilder: (context, index) { - Function roundToDay = (DateTime date) => - DateTime(date.year, date.month, date.day); - - Search search = snapshot.data[index]; - DateTime searchDate = roundToDay(search.timestamp); - - bool newDate = true; - - EdgeInsets? margin; - if (index != 0) { - Search prevSearch = snapshot.data[index - 1]; - - DateTime prevSearchDate = roundToDay(prevSearch.timestamp); - newDate = prevSearchDate != searchDate; - margin = EdgeInsets.only(bottom: 10); - } - - if (newDate) { - if (searchDate == roundToDay(DateTime.now())) - return DateDivider(text: "Today", margin: margin); - else if (searchDate == - roundToDay( - DateTime.now().subtract(const Duration(days: 1)))) - return DateDivider(text: "Yesterday", margin: margin); - return DateDivider(date: searchDate, margin: margin); - } - - return Divider(); - }, + itemCount: data.length + 1, + itemBuilder: historyEntryWithData(data), + separatorBuilder: historyEntrySeparatorWithData(data), ), ); }, @@ -77,4 +39,68 @@ class HistoryView extends StatelessWidget { }, ); } + + Stream> getAsyncStream(DatabaseState state) => + ((state as DatabaseConnected).database.box().query() + ..order(Search_.timestamp, flags: Order.descending)) + .watch(triggerImmediately: true) + .map((query) => query.find()); + + Widget Function(BuildContext, int) historyEntryWithData(List data) => + (context, index) { + if (index == 0) { + return Container(); + } + + final Search search = data[index - 1]; + + if (search.isKanji()) { + return KanjiSearchItem( + result: search.kanjiQuery.target!, + timestamp: search.timestamp, + ); + } else { + return PhraseSearchItem( + search: search.wordQuery.target!, + timestamp: search.timestamp, + ); + } + }; + + DateTime roundToDay(DateTime date) => + DateTime(date.year, date.month, date.day); + + bool dateChangedFromLastSearch(Search prevSearch, DateTime searchDate) { + final DateTime prevSearchDate = roundToDay(prevSearch.timestamp); + return prevSearchDate != searchDate; + } + + DateTime get today => roundToDay(DateTime.now()); + DateTime get yesterday => + roundToDay(DateTime.now().subtract(const Duration(days: 1))); + + Widget Function(BuildContext, int) historyEntrySeparatorWithData( + List data, + ) => + (context, index) { + final Search search = data[index]; + final DateTime searchDate = roundToDay(search.timestamp); + + EdgeInsets? margin; + if (index != 0) { + margin = const EdgeInsets.only(bottom: 10); + } + + if (index == 0 || + dateChangedFromLastSearch(data[index - 1], searchDate)) { + if (searchDate == today) + return DateDivider(text: 'Today', margin: margin); + else if (searchDate == yesterday) + return DateDivider(text: 'Yesterday', margin: margin); + else + return DateDivider(date: searchDate, margin: margin); + } + + return const Divider(); + }; } diff --git a/lib/view/screens/search/kanji_result_page.dart b/lib/view/screens/search/kanji_result_page.dart index 026a3da..8bef057 100644 --- a/lib/view/screens/search/kanji_result_page.dart +++ b/lib/view/screens/search/kanji_result_page.dart @@ -1,40 +1,40 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/database/database_bloc.dart'; -import 'package:jisho_study_tool/models/history/kanji_query.dart'; -import 'package:jisho_study_tool/models/history/search.dart'; -import 'package:jisho_study_tool/view/components/common/loading.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_result_body.dart'; -import 'package:jisho_study_tool/services/jisho_api/kanji_search.dart'; + +import '../../../bloc/database/database_bloc.dart'; +import '../../../models/history/kanji_query.dart'; +import '../../../models/history/search.dart'; +import '../../../services/jisho_api/kanji_search.dart'; +import '../../components/common/loading.dart'; +import '../../components/kanji/kanji_result_body.dart'; class KanjiResultPage extends StatelessWidget { final String kanjiSearchTerm; bool addedToDatabase = false; - KanjiResultPage({required this.kanjiSearchTerm, Key? key}) - : super(key: key); + KanjiResultPage({required this.kanjiSearchTerm, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), - body: FutureBuilder( - future: fetchKanji(this.kanjiSearchTerm), - builder: (context, snapshot) { + body: FutureBuilder( + future: fetchKanji(kanjiSearchTerm), + builder: ( context, snapshot) { if (!snapshot.hasData) return LoadingScreen(); if (snapshot.hasError) return ErrorWidget(snapshot.error!); - if (!this.addedToDatabase) { + if (!addedToDatabase) { (BlocProvider.of(context).state as DatabaseConnected) .database .box() .put(Search(timestamp: DateTime.now()) ..kanjiQuery.target = KanjiQuery( - kanji: this.kanjiSearchTerm, - )); - this.addedToDatabase = true; + kanji: kanjiSearchTerm, + ),); + addedToDatabase = true; } - return KanjiResultBody(result: (snapshot.data as KanjiResult)); + return KanjiResultBody(result: snapshot.data!); }, ), ); diff --git a/lib/view/screens/search/kanji_view.dart b/lib/view/screens/search/kanji_view.dart index 9859690..04a88d7 100644 --- a/lib/view/screens/search/kanji_view.dart +++ b/lib/view/screens/search/kanji_view.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body.dart'; +import '../../components/kanji/kanji_search_body.dart'; class KanjiView extends StatelessWidget { + const KanjiView({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return KanjiSearchBody(); } -} \ No newline at end of file +} diff --git a/lib/view/screens/search/search_mechanisms/grid.dart b/lib/view/screens/search/search_mechanisms/grid.dart index 0b04f7b..742e0a0 100644 --- a/lib/view/screens/search/search_mechanisms/grid.dart +++ b/lib/view/screens/search/search_mechanisms/grid.dart @@ -1,23 +1,25 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body/kanji_grid.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_body/kanji_search_bar.dart'; + +import '../../../components/kanji/kanji_search_body/kanji_grid.dart'; +import '../../../components/kanji/kanji_search_body/kanji_search_bar.dart'; class SearchGrid extends StatelessWidget { final List suggestions; - const SearchGrid(this.suggestions); + + const SearchGrid({ + required this.suggestions, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { - return - Column( - children: [ - SizedBox(height: 10), - KanjiSearchBar(), - SizedBox(height: 10), - Expanded( - child: KanjiGrid(suggestions) - ) - ], - ); + return Column( + children: [ + const SizedBox(height: 10), + const KanjiSearchBar(), + const SizedBox(height: 10), + Expanded(child: KanjiGrid(suggestions: suggestions)) + ], + ); } -} \ No newline at end of file +} diff --git a/lib/view/screens/search/search_mechanisms/radical_list.dart b/lib/view/screens/search/search_mechanisms/radical_list.dart index 8d93387..a6ed8a2 100644 --- a/lib/view/screens/search/search_mechanisms/radical_list.dart +++ b/lib/view/screens/search/search_mechanisms/radical_list.dart @@ -1 +1 @@ -const List> radicals = [[]]; \ No newline at end of file +const List> radicals = [[]]; diff --git a/lib/view/screens/search/search_results_page.dart b/lib/view/screens/search/search_results_page.dart index aae389d..320ba89 100644 --- a/lib/view/screens/search/search_results_page.dart +++ b/lib/view/screens/search/search_results_page.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/database/database_bloc.dart'; -import 'package:jisho_study_tool/models/history/search.dart'; -import 'package:jisho_study_tool/models/history/word_query.dart'; -import 'package:jisho_study_tool/view/components/common/loading.dart'; -import 'package:jisho_study_tool/view/components/search/search_result_body.dart'; -import 'package:jisho_study_tool/services/jisho_api/jisho_search.dart'; + +import '../../../bloc/database/database_bloc.dart'; +import '../../../models/history/search.dart'; +import '../../../models/history/word_query.dart'; +import '../../../services/jisho_api/jisho_search.dart'; +import '../../components/common/loading.dart'; +import '../../components/search/search_result_body.dart'; class SearchResultsPage extends StatelessWidget { final String searchTerm; @@ -12,34 +13,35 @@ class SearchResultsPage extends StatelessWidget { bool addedToDatabase = false; SearchResultsPage({required this.searchTerm, Key? key}) - : this.results = fetchJishoResults(searchTerm), + : results = fetchJishoResults(searchTerm), super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), - body: FutureBuilder( + body: FutureBuilder( future: results, builder: (context, snapshot) { if (!snapshot.hasData) return LoadingScreen(); - if (snapshot.hasError || - (snapshot.data as JishoAPIResult).data == null) + if (snapshot.hasError || snapshot.data!.data == null) return ErrorWidget(snapshot.error!); - if (!this.addedToDatabase) { + if (!addedToDatabase) { (BlocProvider.of(context).state as DatabaseConnected) .database .box() - .put(Search(timestamp: DateTime.now()) - ..wordQuery.target = WordQuery( - query: this.searchTerm, - )); - this.addedToDatabase = true; + .put( + Search(timestamp: DateTime.now()) + ..wordQuery.target = WordQuery( + query: searchTerm, + ), + ); + addedToDatabase = true; } return SearchResultsBody( - results: (snapshot.data as JishoAPIResult).data!, + results: snapshot.data!.data!, ); }, ), diff --git a/lib/view/screens/search/search_view.dart b/lib/view/screens/search/search_view.dart index 4c8b613..d68be17 100644 --- a/lib/view/screens/search/search_view.dart +++ b/lib/view/screens/search/search_view.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/view/components/search/search_bar.dart'; +import '../../components/search/search_bar.dart'; class SearchView extends StatelessWidget { + const SearchView({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ SearchBar(), ], ); diff --git a/lib/view/screens/settings.dart b/lib/view/screens/settings.dart index 40d4709..43fe5cc 100644 --- a/lib/view/screens/settings.dart +++ b/lib/view/screens/settings.dart @@ -1,15 +1,16 @@ import 'package:confirm_dialog/confirm_dialog.dart'; import 'package:flutter/material.dart'; -import 'package:jisho_study_tool/bloc/database/database_bloc.dart'; -import 'package:jisho_study_tool/bloc/theme/theme_bloc.dart'; -import 'package:jisho_study_tool/models/history/search.dart'; -import 'package:jisho_study_tool/models/themes/theme.dart'; -import 'package:jisho_study_tool/objectbox.g.dart'; import 'package:settings_ui/settings_ui.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../../bloc/database/database_bloc.dart'; +import '../../bloc/theme/theme_bloc.dart'; +import '../../models/history/search.dart'; +import '../../models/themes/theme.dart'; +import '../../objectbox.g.dart'; + class SettingsView extends StatefulWidget { - SettingsView({Key? key}) : super(key: key); + const SettingsView({Key? key}) : super(key: key); @override _SettingsViewState createState() => _SettingsViewState(); @@ -40,25 +41,27 @@ class _SettingsViewState extends State { } /// Update stored preferences with values from setting page state - void _updatePrefs() async { - await prefs.setBool('darkThemeEnabled', darkThemeEnabled); - await prefs.setBool('autoThemeEnabled', autoThemeEnabled); + void _updatePrefs() { + prefs.setBool('darkThemeEnabled', darkThemeEnabled); + prefs.setBool('autoThemeEnabled', autoThemeEnabled); } + @override Widget build(BuildContext context) { final TextStyle _titleTextStyle = TextStyle( - color: BlocProvider.of(context).state is DarkThemeState - ? AppTheme.jishoGreen.background - : null); + color: BlocProvider.of(context).state is DarkThemeState + ? AppTheme.jishoGreen.background + : null, + ); return SettingsList( backgroundColor: Colors.transparent, - contentPadding: EdgeInsets.symmetric(vertical: 10), - sections: [ + contentPadding: const EdgeInsets.symmetric(vertical: 10), + sections: [ SettingsSection( title: 'Theme', titleTextStyle: _titleTextStyle, - tiles: [ + tiles: [ SettingsTile.switchTile( title: 'Automatically determine theme', onToggle: (b) { @@ -74,7 +77,8 @@ class _SettingsViewState extends State { SettingsTile.switchTile( title: 'Dark Theme', onToggle: (b) { - BlocProvider.of(context).add(SetTheme(themeIsDark: b)); + BlocProvider.of(context) + .add(SetTheme(themeIsDark: b)); setState(() { darkThemeEnabled = b; }); @@ -89,7 +93,7 @@ class _SettingsViewState extends State { SettingsSection( title: 'Cache', titleTextStyle: _titleTextStyle, - tiles: [ + tiles: [ SettingsTile.switchTile( title: 'Cache grade 1-7 kanji', switchValue: false, @@ -123,13 +127,13 @@ class _SettingsViewState extends State { SettingsSection( title: 'Data', titleTextStyle: _titleTextStyle, - tiles: [ - SettingsTile( + tiles: [ + const SettingsTile( leading: Icon(Icons.file_download), title: 'Export Data', enabled: false, ), - SettingsTile( + const SettingsTile( leading: Icon(Icons.delete), title: 'Clear History', onPressed: _clearHistory, @@ -137,10 +141,10 @@ class _SettingsViewState extends State { enabled: false, ), SettingsTile( - leading: Icon(Icons.delete), + leading: const Icon(Icons.delete), title: 'Clear Favourites', onPressed: (c) {}, - titleTextStyle: TextStyle(color: Colors.red), + titleTextStyle: const TextStyle(color: Colors.red), enabled: false, ) ], @@ -150,12 +154,14 @@ class _SettingsViewState extends State { } } -void _clearHistory(context) async { - if (await confirm(context)) { - Store db = - (BlocProvider.of(context).state as DatabaseConnected) - .database; - // db.box().query().build().find() - db.box().removeAll(); - } +void _clearHistory(context) { + confirm(context).then((userIsSure) { + if (userIsSure) { + final Store db = + (BlocProvider.of(context).state as DatabaseConnected) + .database; + // db.box().query().build().find() + db.box().removeAll(); + } + }); } diff --git a/pubspec.lock b/pubspec.lock index fd22efb..0907336 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -119,7 +119,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index e8c17e4..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:jisho_study_tool/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -}