diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..76f4ab5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,27 @@ +version: 2 +enable-beta-ecosystems: true +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "khoren93" + - package-ecosystem: "pub" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "khoren93" + - package-ecosystem: "pub" + directory: "/example" + schedule: + interval: "weekly" + reviewers: + - "khoren93" + - package-ecosystem: "pub" + directory: "/zxscanner" + schedule: + interval: "weekly" + reviewers: + - "khoren93" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..176e23d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,37 @@ +name: Flutter CI + +# This workflow is triggered on pushes to the repository. +on: + push: + branches: + - main + +jobs: + build: + # This job will run on ubuntu virtual machine + runs-on: ubuntu-latest + steps: + + # Setup Java environment in order to build the Android app. + - uses: actions/checkout@v3.0.2 + - uses: actions/setup-java@v3.4.0 + with: + java-version: 11 + distribution: temurin + + # Setup the flutter environment. + - uses: subosito/flutter-action@v2.4.0 + with: + channel: 'stable' # 'dev', 'alpha', default to: 'stable' + cache: true + # flutter-version: '1.22.x' # you can also specify exact version of flutter + + # Get flutter dependencies. + - run: flutter pub get + + # Check for any formatting issues in the code. + - run: flutter format . + + # Statically analyze the Dart code for any errors. + - run: flutter analyze . + diff --git a/analysis_options.yaml b/analysis_options.yaml index 5ec54e5..45678fd 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -26,6 +26,7 @@ analyzer: # Turned off until null-safe rollout is complete. unnecessary_null_comparison: warning exclude: + - "zxscanner/**" - "bin/cache/**" # Ignore protoc generated files - "dev/conductor/lib/proto/*" diff --git a/android/build.gradle b/android/build.gradle index f981b04..e6068f8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/zxscanner/analysis_options.yaml b/zxscanner/analysis_options.yaml index 61b6c4d..5ec54e5 100644 --- a/zxscanner/analysis_options.yaml +++ b/zxscanner/analysis_options.yaml @@ -9,21 +9,231 @@ # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml +analyzer: + language: + strict-casts: false + strict-raw-types: true + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # not allowing having TODO comments in the code + # todo: warning + # allow self-reference to deprecated members (we do this because otherwise we have + # to annotate every member in every test, assert, etc, when we deprecate something) + deprecated_member_use_from_same_package: ignore + # Turned off until null-safe rollout is complete. + unnecessary_null_comparison: warning + exclude: + - "bin/cache/**" + # Ignore protoc generated files + - "dev/conductor/lib/proto/*" + - "lib/generated_bindings.dart" + linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options + # This list is derived from the list of all available lints located at + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - 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_annotating_with_dynamic # conflicts with always_specify_types + - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 + # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 + - 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_final_parameters # incompatible with prefer_final_parameters + - avoid_function_literals_in_foreach_calls + - avoid_implementing_value_types + - avoid_init_to_null + - avoid_js_rounded_ints + # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it + - 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 # still violated by some pre-nnbd code that we haven't yet migrated + - avoid_returning_null_for_future + - avoid_returning_null_for_void + # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives + - 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 # conflicts with always_specify_types + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters + - avoid_void_async + # - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # doesn't match the typical style of this repo + - cast_nullable_to_non_nullable + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 + # - conditional_uri_does_not_exist # not yet tested + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not required by flutter style + - depend_on_referenced_packages + - deprecated_consistency + # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) + - directives_ordering + # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic + - empty_catches + - empty_constructor_bodies + - empty_statements + - eol_at_end_of_file + - exhaustive_cases + - file_names + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + - iterable_contains_unrelated_type + # - join_return_with_assignment # not required by flutter style + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + - library_private_types_in_public_api + # - lines_longer_than_80_chars # not required by flutter style + - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 + - missing_whitespace_between_adjacent_strings + - no_adjacent_strings_in_list + - no_default_cases + - no_duplicate_case_values + - no_leading_underscores_for_library_prefixes + - no_leading_underscores_for_local_identifiers + - no_logic_in_create_state + # - no_runtimeType_toString # ok in tests; we enable this only in packages/ + - non_constant_identifier_names + - noop_primitive_operations + - null_check_on_nullable_type_parameter + - null_closures + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_asserts_with_message # not required by flutter style + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # far too many false positives + - prefer_contains + # - prefer_double_quotes # opposite of prefer_single_quotes + - prefer_equal_for_default_values + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + # - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments + - 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_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 + # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere + - prefer_null_aware_operators + - prefer_relative_imports + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 + - secure_pubspec_urls + - sized_box_for_whitespace + # - sized_box_shrink_expand # not yet tested + - slash_for_doc_comments + - sort_child_properties_last + - sort_constructors_first + # - sort_pub_dependencies # prevents separating pinned transitive dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives, especially with the way AnimationController works + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_constructor_name + # - unnecessary_final # conflicts with prefer_final_locals + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_late + - 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_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + - unsafe_html + - use_build_context_synchronously + # - use_colored_box # not yet tested + # - use_decorated_box # not yet tested + # - use_enums # not yet tested + - use_full_hex_values_for_flutter_colors + - use_function_type_syntax_for_parameters + - use_if_null_to_convert_nulls_to_bools + - 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_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + - use_super_parameters + - use_test_throws_matchers + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + - void_checks \ No newline at end of file diff --git a/zxscanner/lib/configs/app_store.dart b/zxscanner/lib/configs/app_store.dart index dd6c6d1..bd5e63c 100644 --- a/zxscanner/lib/configs/app_store.dart +++ b/zxscanner/lib/configs/app_store.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; -import 'package:zxscanner/utils/shared_pref.dart'; +import '../utils/shared_pref.dart'; part 'app_store.g.dart'; @@ -8,11 +8,11 @@ AppStore appStore = AppStore(); class AppStore = AppStoreBase with _$AppStore; -const themeModePref = 'themeModePref'; -const colorSchemeIndexPref = 'colorSchemeIndexPref'; -const isSoundOnPref = 'isSoundOnPref'; -const isVibrationOnPref = 'isVibrationOnPref'; -const languagePref = 'languagePref'; +const String themeModePref = 'themeModePref'; +const String colorSchemeIndexPref = 'colorSchemeIndexPref'; +const String isSoundOnPref = 'isSoundOnPref'; +const String isVibrationOnPref = 'isVibrationOnPref'; +const String languagePref = 'languagePref'; abstract class AppStoreBase with Store { @observable diff --git a/zxscanner/lib/configs/app_store.g.dart b/zxscanner/lib/configs/app_store.g.dart index 012c84e..990004f 100644 --- a/zxscanner/lib/configs/app_store.g.dart +++ b/zxscanner/lib/configs/app_store.g.dart @@ -9,7 +9,7 @@ part of 'app_store.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$AppStore on AppStoreBase, Store { - final _$themeModeAtom = Atom(name: 'AppStoreBase.themeMode'); + final Atom _$themeModeAtom = Atom(name: 'AppStoreBase.themeMode'); @override ThemeMode get themeMode { @@ -24,7 +24,7 @@ mixin _$AppStore on AppStoreBase, Store { }); } - final _$colorSchemeIndexAtom = Atom(name: 'AppStoreBase.colorSchemeIndex'); + final Atom _$colorSchemeIndexAtom = Atom(name: 'AppStoreBase.colorSchemeIndex'); @override int get colorSchemeIndex { @@ -39,7 +39,7 @@ mixin _$AppStore on AppStoreBase, Store { }); } - final _$isSoundOnAtom = Atom(name: 'AppStoreBase.isSoundOn'); + final Atom _$isSoundOnAtom = Atom(name: 'AppStoreBase.isSoundOn'); @override bool get isSoundOn { @@ -54,7 +54,7 @@ mixin _$AppStore on AppStoreBase, Store { }); } - final _$isVibrationOnAtom = Atom(name: 'AppStoreBase.isVibrationOn'); + final Atom _$isVibrationOnAtom = Atom(name: 'AppStoreBase.isVibrationOn'); @override bool get isVibrationOn { @@ -69,7 +69,7 @@ mixin _$AppStore on AppStoreBase, Store { }); } - final _$selectedLanguageAtom = Atom(name: 'AppStoreBase.selectedLanguage'); + final Atom _$selectedLanguageAtom = Atom(name: 'AppStoreBase.selectedLanguage'); @override String get selectedLanguage { @@ -84,14 +84,14 @@ mixin _$AppStore on AppStoreBase, Store { }); } - final _$setThemeModeAsyncAction = AsyncAction('AppStoreBase.setThemeMode'); + final AsyncAction _$setThemeModeAsyncAction = AsyncAction('AppStoreBase.setThemeMode'); @override Future setThemeMode(ThemeMode value) { return _$setThemeModeAsyncAction.run(() => super.setThemeMode(value)); } - final _$setColorSchemeIndexAsyncAction = + final AsyncAction _$setColorSchemeIndexAsyncAction = AsyncAction('AppStoreBase.setColorSchemeIndex'); @override @@ -100,7 +100,7 @@ mixin _$AppStore on AppStoreBase, Store { .run(() => super.setColorSchemeIndex(value)); } - final _$toggleSoundModeAsyncAction = + final AsyncAction _$toggleSoundModeAsyncAction = AsyncAction('AppStoreBase.toggleSoundMode'); @override @@ -109,7 +109,7 @@ mixin _$AppStore on AppStoreBase, Store { .run(() => super.toggleSoundMode(value: value)); } - final _$toggleVibrationModeAsyncAction = + final AsyncAction _$toggleVibrationModeAsyncAction = AsyncAction('AppStoreBase.toggleVibrationMode'); @override @@ -118,7 +118,7 @@ mixin _$AppStore on AppStoreBase, Store { .run(() => super.toggleVibrationMode(value: value)); } - final _$setLanguageAsyncAction = AsyncAction('AppStoreBase.setLanguage'); + final AsyncAction _$setLanguageAsyncAction = AsyncAction('AppStoreBase.setLanguage'); @override Future setLanguage(String aLanguage) { diff --git a/zxscanner/lib/configs/app_theme.dart b/zxscanner/lib/configs/app_theme.dart index 69d2b11..72309a7 100644 --- a/zxscanner/lib/configs/app_theme.dart +++ b/zxscanner/lib/configs/app_theme.dart @@ -8,14 +8,12 @@ class AppTheme { static ThemeData flexLightTheme() => FlexThemeData.light( colors: FlexColor.schemesList[appStore.colorSchemeIndex].light, - tabBarStyle: FlexTabBarStyle.forAppBar, surfaceMode: FlexSurfaceMode.highScaffoldLevelSurface, blendLevel: 12, ); static ThemeData flexDarkTheme() => FlexThemeData.dark( colors: FlexColor.schemesList[appStore.colorSchemeIndex].dark, - tabBarStyle: FlexTabBarStyle.forAppBar, surfaceMode: FlexSurfaceMode.highScaffoldLevelSurface, blendLevel: 6, ); diff --git a/zxscanner/lib/configs/constants.dart b/zxscanner/lib/configs/constants.dart index 3696ffb..e2d7701 100644 --- a/zxscanner/lib/configs/constants.dart +++ b/zxscanner/lib/configs/constants.dart @@ -1,13 +1,13 @@ const String appName = 'ZXScanner'; /// space between widgets -const spaceSmall = 2.0; -const spaceSmall2 = 4.0; -const spaceMedium = 8.0; -const spaceDefault = 16.0; -const spaceLarge = 24.0; -const spaceLarge2 = 32.0; -const spaceLarge3 = 40.0; -const spaceLarge4 = 96.0; +const double spaceSmall = 2.0; +const double spaceSmall2 = 4.0; +const double spaceMedium = 8.0; +const double spaceDefault = 16.0; +const double spaceLarge = 24.0; +const double spaceLarge2 = 32.0; +const double spaceLarge3 = 40.0; +const double spaceLarge4 = 96.0; -const spaceMaxWidth = 736.0; +const double spaceMaxWidth = 736.0; diff --git a/zxscanner/lib/generated/intl/messages_all.dart b/zxscanner/lib/generated/intl/messages_all.dart index 0895730..28be243 100644 --- a/zxscanner/lib/generated/intl/messages_all.dart +++ b/zxscanner/lib/generated/intl/messages_all.dart @@ -18,8 +18,10 @@ import 'package:intl/src/intl_helpers.dart'; import 'messages_en_US.dart' as messages_en_us; typedef Future LibraryLoader(); +// ignore: always_specify_types Map _deferredLibraries = { - 'en_US': () => new Future.value(null), + // ignore: always_specify_types + 'en_US': () => new Future.value(), }; MessageLookupByLibrary? _findExact(String localeName) { @@ -33,17 +35,17 @@ MessageLookupByLibrary? _findExact(String localeName) { /// User programs should call this before using [localeName] for messages. Future initializeMessages(String localeName) async { - var availableLocale = Intl.verifiedLocale( - localeName, (locale) => _deferredLibraries[locale] != null, + final String? availableLocale = Intl.verifiedLocale( + localeName, (String locale) => _deferredLibraries[locale] != null, onFailure: (_) => null); if (availableLocale == null) { - return new Future.value(false); + return new Future.value(false); } - var lib = _deferredLibraries[availableLocale]; - await (lib == null ? new Future.value(false) : lib()); + final LibraryLoader? lib = _deferredLibraries[availableLocale]; + await (lib == null ? new Future.value(false) : lib()); initializeInternalMessageLookup(() => new CompositeMessageLookup()); messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); - return new Future.value(true); + return new Future.value(true); } bool _messagesExistFor(String locale) { @@ -55,8 +57,10 @@ bool _messagesExistFor(String locale) { } MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { - var actualLocale = + final String? actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); - if (actualLocale == null) return null; + if (actualLocale == null) { + return null; + } return _findExact(actualLocale); } diff --git a/zxscanner/lib/generated/intl/messages_en_US.dart b/zxscanner/lib/generated/intl/messages_en_US.dart index 1c42aca..f943842 100644 --- a/zxscanner/lib/generated/intl/messages_en_US.dart +++ b/zxscanner/lib/generated/intl/messages_en_US.dart @@ -13,14 +13,14 @@ import 'package:intl/intl.dart'; import 'package:intl/message_lookup_by_library.dart'; -final messages = new MessageLookup(); +final MessageLookup messages = new MessageLookup(); typedef String MessageIfAbsent(String messageStr, List args); class MessageLookup extends MessageLookupByLibrary { String get localeName => 'en_US'; - final messages = _notInlinedMessages(_notInlinedMessages); + final Map messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { "settingsAppBarTitle": MessageLookupByLibrary.simpleMessage("Settings"), "settingsLanguageTitle": diff --git a/zxscanner/lib/generated/l10n.dart b/zxscanner/lib/generated/l10n.dart index 53f722d..5eb9d82 100644 --- a/zxscanner/lib/generated/l10n.dart +++ b/zxscanner/lib/generated/l10n.dart @@ -26,13 +26,13 @@ class S { static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); static Future load(Locale locale) { - final name = (locale.countryCode?.isEmpty ?? false) + final String name = (locale.countryCode?.isEmpty ?? false) ? locale.languageCode : locale.toString(); - final localeName = Intl.canonicalizedLocale(name); + final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { Intl.defaultLocale = localeName; - final instance = S(); + final S instance = S(); S._current = instance; return instance; @@ -40,7 +40,7 @@ class S { } static S of(BuildContext context) { - final instance = S.maybeOf(context); + final S? instance = S.maybeOf(context); assert(instance != null, 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); return instance!; @@ -56,7 +56,6 @@ class S { 'Settings', name: 'settingsAppBarTitle', desc: '', - args: [], ); } @@ -66,7 +65,6 @@ class S { 'Theme', name: 'settingsThemeModeTitle', desc: '', - args: [], ); } @@ -76,7 +74,6 @@ class S { 'Language', name: 'settingsLanguageTitle', desc: '', - args: [], ); } } @@ -98,7 +95,7 @@ class AppLocalizationDelegate extends LocalizationsDelegate { bool shouldReload(AppLocalizationDelegate old) => false; bool _isSupported(Locale locale) { - for (var supportedLocale in supportedLocales) { + for (Locale supportedLocale in supportedLocales) { if (supportedLocale.languageCode == locale.languageCode) { return true; } diff --git a/zxscanner/lib/main.dart b/zxscanner/lib/main.dart index dcc795f..3a1cdbf 100644 --- a/zxscanner/lib/main.dart +++ b/zxscanner/lib/main.dart @@ -3,16 +3,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:zxscanner/configs/constants.dart'; -import 'package:zxscanner/utils/db_service.dart'; -import 'package:zxscanner/utils/extensions.dart'; -import 'package:zxscanner/utils/shared_pref.dart'; import 'configs/app_store.dart'; import 'configs/app_theme.dart'; +import 'configs/constants.dart'; import 'generated/l10n.dart' as loc; +import 'utils/db_service.dart'; +import 'utils/extensions.dart'; import 'utils/router.dart'; import 'utils/scroll_behavior.dart'; +import 'utils/shared_pref.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -23,14 +23,14 @@ void main() async { } class MyApp extends StatefulWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { - final _appRouter = AppRouter(); + final AppRouter _appRouter = AppRouter(); @override Widget build(BuildContext context) { @@ -40,7 +40,7 @@ class _MyAppState extends State { theme: AppTheme.flexLightTheme(), darkTheme: AppTheme.flexDarkTheme(), themeMode: appStore.themeMode, - localizationsDelegates: const [ + localizationsDelegates: const >[ loc.S.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, diff --git a/zxscanner/lib/models/code.dart b/zxscanner/lib/models/code.dart index 643ace9..b79524e 100644 --- a/zxscanner/lib/models/code.dart +++ b/zxscanner/lib/models/code.dart @@ -5,14 +5,6 @@ part 'code.g.dart'; @HiveType(typeId: 0) class Code extends HiveObject { - @HiveField(0) - bool? isValid; - - @HiveField(1) - int? format; - - @HiveField(2) - String? text; Code(); @@ -21,6 +13,14 @@ class Code extends HiveObject { format = result.format; text = result.textString; } + @HiveField(0) + bool? isValid; + + @HiveField(1) + int? format; + + @HiveField(2) + String? text; String get formatName => barcodeFormatName(format ?? 0); } diff --git a/zxscanner/lib/models/code.g.dart b/zxscanner/lib/models/code.g.dart index a2b169e..824dcdb 100644 --- a/zxscanner/lib/models/code.g.dart +++ b/zxscanner/lib/models/code.g.dart @@ -12,8 +12,8 @@ class CodeAdapter extends TypeAdapter { @override Code read(BinaryReader reader) { - final numOfFields = reader.readByte(); - final fields = { + final int numOfFields = reader.readByte(); + final Map fields = { for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), }; return Code() diff --git a/zxscanner/lib/models/encode.dart b/zxscanner/lib/models/encode.dart index 7e9fa40..dde6eb2 100644 --- a/zxscanner/lib/models/encode.dart +++ b/zxscanner/lib/models/encode.dart @@ -7,6 +7,16 @@ part 'encode.g.dart'; @HiveType(typeId: 1) class Encode extends HiveObject { + + Encode(); + + Encode.fromEncodeResult(EncodeResult result, Uint8List? bytes) { + isValid = result.isValidBool; + format = result.format; + text = result.textString; + data = bytes; + length = result.length; + } @HiveField(0) bool? isValid; @@ -22,15 +32,5 @@ class Encode extends HiveObject { @HiveField(4) int? length; - Encode(); - - Encode.fromEncodeResult(EncodeResult result, Uint8List? bytes) { - isValid = result.isValidBool; - format = result.format; - text = result.textString; - data = bytes; - length = result.length; - } - String get formatName => barcodeFormatName(format ?? 0); } diff --git a/zxscanner/lib/models/encode.g.dart b/zxscanner/lib/models/encode.g.dart index f4f505f..73a329f 100644 --- a/zxscanner/lib/models/encode.g.dart +++ b/zxscanner/lib/models/encode.g.dart @@ -12,8 +12,8 @@ class EncodeAdapter extends TypeAdapter { @override Encode read(BinaryReader reader) { - final numOfFields = reader.readByte(); - final fields = { + final int numOfFields = reader.readByte(); + final Map fields = { for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), }; return Encode() diff --git a/zxscanner/lib/pages/barcodes_page.dart b/zxscanner/lib/pages/barcodes_page.dart index 4fb7cfc..b86f4f1 100644 --- a/zxscanner/lib/pages/barcodes_page.dart +++ b/zxscanner/lib/pages/barcodes_page.dart @@ -2,17 +2,18 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:zxscanner/models/models.dart'; -import 'package:zxscanner/utils/db_service.dart'; -import 'package:zxscanner/utils/router.dart'; -import 'package:zxscanner/widgets/common_widgets.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import '../models/models.dart'; +import '../utils/db_service.dart'; +import '../utils/router.dart'; +import '../widgets/common_widgets.dart'; + class BarcodesPage extends StatefulWidget { const BarcodesPage({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _BarcodesPageState(); @@ -35,11 +36,11 @@ class _BarcodesPageState extends State { ); } - _buildResultList() { + ValueListenableBuilder> _buildResultList() { return ValueListenableBuilder>( valueListenable: DbService.instance.getEncodes().listenable(), - builder: (context, box, _) { - final results = box.values.toList().cast(); + builder: (BuildContext context, Box box, _) { + final List results = box.values.toList().cast(); return results.isEmpty ? const Center( child: Text( @@ -48,8 +49,8 @@ class _BarcodesPageState extends State { )) : ListView.builder( itemCount: results.length, - itemBuilder: (context, index) { - final result = results[index]; + itemBuilder: (BuildContext context, int index) { + final Encode result = results[index]; return ContainerX( child: Card( child: ListTile( @@ -61,7 +62,7 @@ class _BarcodesPageState extends State { subtitle: Text(result.formatName), trailing: ButtonBar( mainAxisSize: MainAxisSize.min, - children: [ + children: [ // Copy button IconButton( icon: const Icon(FontAwesomeIcons.copy), diff --git a/zxscanner/lib/pages/creator_page.dart b/zxscanner/lib/pages/creator_page.dart index 1d90a04..a89f4e7 100644 --- a/zxscanner/lib/pages/creator_page.dart +++ b/zxscanner/lib/pages/creator_page.dart @@ -3,21 +3,22 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:zxscanner/configs/constants.dart'; -import 'package:zxscanner/models/encode.dart'; -import 'package:zxscanner/utils/db_service.dart'; -import 'package:zxscanner/utils/extensions.dart'; -import 'package:zxscanner/widgets/common_widgets.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; +import '../configs/constants.dart'; +import '../models/encode.dart'; +import '../utils/db_service.dart'; +import '../utils/extensions.dart'; +import '../widgets/common_widgets.dart'; + late Directory tempDir; String get tempPath => '${tempDir.path}/zxing.jpg'; class CreatorPage extends StatefulWidget { const CreatorPage({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _CreatorPageState(); @@ -36,8 +37,8 @@ class _CreatorPageState extends State { initStateAsync(); } - void initStateAsync() async { - getTemporaryDirectory().then((value) { + Future initStateAsync() async { + getTemporaryDirectory().then((Directory value) { tempDir = value; }); } @@ -51,14 +52,14 @@ class _CreatorPageState extends State { body: SingleChildScrollView( child: ContainerX( child: Column( - children: [ + children: [ WriterWidget( - onSuccess: (result, bytes) { + onSuccess: (EncodeResult result, Uint8List? bytes) { setState(() { encode = Encode.fromEncodeResult(result, bytes); }); }, - onError: (error) { + onError: (String error) { setState(() { encode = null; }); @@ -75,23 +76,22 @@ class _CreatorPageState extends State { Column buildWriteResult() { return Column( - children: [ + children: [ // Barcode image if (encode?.data != null) Image.memory(encode?.data ?? Uint8List(0)), const SizedBox(height: spaceLarge), // Share button Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ + children: [ ElevatedButton( onPressed: () { // Save image to device - final file = File(tempPath); + final File file = File(tempPath); file.writeAsBytesSync(encode?.data ?? Uint8List(0)); - final path = file.path; + final String path = file.path; // Share image - Share.shareFiles([path]); + Share.shareFiles([path]); }, child: const Text('Share'), ), @@ -99,7 +99,9 @@ class _CreatorPageState extends State { onPressed: () async { if (encode != null) { await DbService.instance.addEncode(encode!); - if (!mounted) return; + if (!mounted) { + return; + } Navigator.of(context).pop(); } }, diff --git a/zxscanner/lib/pages/help_page.dart b/zxscanner/lib/pages/help_page.dart index 6d8516c..b4cdfd8 100644 --- a/zxscanner/lib/pages/help_page.dart +++ b/zxscanner/lib/pages/help_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:zxscanner/configs/constants.dart'; -import 'package:zxscanner/widgets/common_widgets.dart'; +import '../configs/constants.dart'; +import '../widgets/common_widgets.dart'; class HelpPage extends StatelessWidget { - const HelpPage({Key? key}) : super(key: key); + const HelpPage({super.key}); @override Widget build(BuildContext context) { @@ -15,7 +15,7 @@ class HelpPage extends StatelessWidget { ), body: ContainerX( child: Column( - children: [ + children: [ Padding( padding: const EdgeInsets.all(spaceDefault), child: InkWell( @@ -23,10 +23,12 @@ class HelpPage extends StatelessWidget { launchUrlString('https://scanbot.io'); }, child: Column( - children: const [ + children: const [ Text('All information is taken from'), - Text('scanbot.io', - style: TextStyle(fontWeight: FontWeight.bold)), + Text( + 'scanbot.io', + style: TextStyle(fontWeight: FontWeight.bold), + ), ], ), ), @@ -58,7 +60,7 @@ class HelpPage extends StatelessWidget { ), child: ExpansionTile( title: Text(title ?? ''), - children: [ + children: [ Padding( padding: const EdgeInsets.all(spaceDefault), child: MarkdownBody(data: body ?? ''), @@ -70,23 +72,23 @@ class HelpPage extends StatelessWidget { ); } - createSlides(BuildContext context) { - return [ + List createSlides(BuildContext context) { + return [ createSlide( context, title: 'QR Code', - body: """ + body: ''' QR codes are highly versatile and cover a range of applications because they store a large amount of information in a relatively small area. They are particularly popular in advertising, such as on flyers or shop windows, in public transport and airline ticketing, and in parcel delivery. * Defined in the ISO/IEC 18004:2006 and JIS X0510 standards. * 2D barcode that stores a maximum of 7089 digits or 4296 alphanumeric characters. * Can be used free of charge – specifications are available from the Swiss-based International Organization for Standardization. * Automatic error correction recovers damage to up to 30%, depending on the correction level chosen. - """, + ''', ), createSlide( context, title: 'DataMatrix', - body: """ + body: ''' Due to its small size and large storage capacity, the Data Matrix code is most frequently used in the aerospace, automotive, and electronics sectors. Applied through permanent marking, the code can identify spare parts over their whole lifespan. It also has applications in healthcare and postal services. * 2D barcode with L-shaped border and pixel matrix. * Defined in the ISO/IEC 16022 standard. @@ -94,12 +96,12 @@ Due to its small size and large storage capacity, the Data Matrix code is most f * Smallest size: 2.5 mm x 2.5 mm, thus ideal for small units. * Often engraved on items via Direct Part Marking (DPM). * Readable even with low contrast. - """, + ''', ), createSlide( context, title: 'Aztec', - body: """ + body: ''' The transportation sector accounts for most Aztec Code use cases. Lufthansa airline tickets contain this code, as do Deutsche Bahn tickets. The International Union of Railways (UIC) has chosen the Aztec Code as its standard for ticketing. Additionally, Aztec Codes are used in the healthcare sector, notably on patient identification bracelets. * Two-dimensional barcode, standardized in ISO/IEC 24778. * Freely available under US patent number 5591956. @@ -107,7 +109,7 @@ The transportation sector accounts for most Aztec Code use cases. Lufthansa airl * Less widely used than QR and Data Matrix Codes. * Enables both high data density and up to 95% error tolerance. * Pattern resembles a top-down view of an Aztec pyramid - """, + ''', ), createSlide( context, @@ -124,75 +126,75 @@ Ticketing, travel, and logistics are some of the most common areas of applicatio createSlide( context, title: 'UPCA, UPCE', - body: """ + body: ''' The Universal Product Code (UPC) is perfect for retail, warehousing, and distribution. Stores or warehouses use it in combination with their databases to assign individual prices or quantities to the coded products. Since the price is explicitly not part of the barcode, retail stores can set prices independently using their checkout system. * Exclusively used within North America. * One-dimensional barcode that stores exactly 12 numeric characters, which form the Global Trade Item Number (GTIN). * The low data density makes it inadequate for encoding complex data. - """, + ''', ), createSlide( context, title: 'EAN8, EAN13', - body: """ + body: ''' The most important areas of application for EAN codes are retail, distribution, and warehousing. The EAN – short for European Article Number – is used to identify individual products, which can then be linked to quantities or prices in the store’s database. Since they can only store a limited amount of data, EAN codes are not suitable for the kind of complex information seen in ticketing or parcel shipping. * Used worldwide despite the name, except for North America, which uses the UPC standard. * Stores either 13 or 8 digits (EAN-13 vs. EAN-8), which encode a GTIN (Global Trade Identification Number). * The last digit is a mod10 checksum. * EAN codes are defined as GS1 standards. - """, + ''', ), createSlide( context, title: 'Code39', - body: """ + body: ''' Unlike other common barcodes, Code 39 can also encode letters, which makes it indispensable in the industrial sector. A frequent use case is in factory automation in the automotive and electronics industries. In the US, it was standardized and adopted by the AIAG (Automotive Industry Action Group). * One-dimensional barcode that encodes 43 characters: uppercase letters, numeric digits, and a number of special characters. * Self-checking. However, a modulo 43 check digit is sometimes included. * The low data density makes it unsuitable for tiny items. * Standardized as ANSI MH 10.8 M-1983 and ANSI/AIM BC1/1995. - """, + ''', ), createSlide( context, title: 'Code93', - body: """ + body: ''' This barcode symbology can store alphanumeric characters. Its main user, Canada Post, encodes supplementary delivery information with it. * One-dimensional barcode encoding 43 alphanumeric characters and 5 special characters. * In Code 93 Extended, combinations of those characters can represent all 128 ASCII characters. - """, + ''', ), createSlide( context, title: 'Code128', - body: """ + body: ''' The Code 128 barcode is most frequently used in transporting goods, especially to mark containers for distribution, and warehousing. With it, various kinds of information about the respective goods can be flexibly encoded and read with a wide range of conventional scanners or smartphones. Its focus is clearly on non-POS areas. Check out our Barcode Scanner for logistics to learn more about possible application among the transportation area. * A one-dimensional barcode defined in the ISO/IEC 15417 standard. * Can encode all ASCII characters, including special characters. * High data density compared to other 1D barcode formats. - """, + ''', ), createSlide( context, title: 'CodaBar', - body: """ + body: ''' The Codabar barcode is only used in blood banks, libraries, and in laboratories. * 1D (linear) barcode type. * Self-checking, with no need for a check digit. * Encodes alphanumeric characters, as well as six special characters. * Stores up to 16 characters. * Newer barcode types can store more data in less space. - """, + ''', ), createSlide( context, title: 'ITF', - body: """ + body: ''' ITF barcodes are often described as Standard Distribution Codes. They are frequently found on cardboard boxes and other kinds of outer packaging. * One-dimensional barcodes that encode two numerical characters for every five bars. * High data density, as data is stored in both the bars and the gaps.  * Compared to other linear barcodes, more data can be accommodated using the same label size. - """, + ''', ), ]; } @@ -206,4 +208,4 @@ DataBarExpanded MaxiCode -*/ \ No newline at end of file +*/ diff --git a/zxscanner/lib/pages/history_page.dart b/zxscanner/lib/pages/history_page.dart index e9c349b..f8e1ed7 100644 --- a/zxscanner/lib/pages/history_page.dart +++ b/zxscanner/lib/pages/history_page.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:zxscanner/models/code.dart'; -import 'package:zxscanner/utils/db_service.dart'; -import 'package:zxscanner/widgets/common_widgets.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import '../models/code.dart'; +import '../utils/db_service.dart'; +import '../widgets/common_widgets.dart'; + class HistoryPage extends StatefulWidget { const HistoryPage({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _HistoryPageState(); @@ -26,11 +27,11 @@ class _HistoryPageState extends State { ); } - _buildResultList() { + ValueListenableBuilder> _buildResultList() { return ValueListenableBuilder>( valueListenable: DbService.instance.getCodes().listenable(), - builder: (context, box, _) { - final results = box.values.toList().cast(); + builder: (BuildContext context, Box box, _) { + final List results = box.values.toList().cast(); return results.isEmpty ? const Center( child: Text( @@ -39,8 +40,8 @@ class _HistoryPageState extends State { )) : ListView.builder( itemCount: results.length, - itemBuilder: (context, index) { - final result = results[index]; + itemBuilder: (BuildContext context, int index) { + final Code result = results[index]; return ContainerX( child: Card( child: ListTile( @@ -48,7 +49,7 @@ class _HistoryPageState extends State { subtitle: Text(result.formatName), trailing: ButtonBar( mainAxisSize: MainAxisSize.min, - children: [ + children: [ // Copy button IconButton( icon: const Icon(FontAwesomeIcons.copy), diff --git a/zxscanner/lib/pages/home_page.dart b/zxscanner/lib/pages/home_page.dart index 892d31f..e2905a1 100644 --- a/zxscanner/lib/pages/home_page.dart +++ b/zxscanner/lib/pages/home_page.dart @@ -1,29 +1,30 @@ import 'package:convex_bottom_bar/convex_bottom_bar.dart'; import 'package:flutter/material.dart'; -import 'package:zxscanner/pages/barcodes_page.dart'; -import 'package:zxscanner/pages/help_page.dart'; -import 'package:zxscanner/pages/history_page.dart'; -import 'package:zxscanner/pages/scanner_page.dart'; -import 'package:zxscanner/pages/settings_page.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'barcodes_page.dart'; +import 'help_page.dart'; +import 'history_page.dart'; +import 'scanner_page.dart'; +import 'settings_page.dart'; + class HomePage extends StatefulWidget { - const HomePage({Key? key}) : super(key: key); + const HomePage({super.key}); @override State createState() => _HomePageState(); } class _HomePageState extends State { - var selectedIndex = 2; + int selectedIndex = 2; - final barcodesPage = const BarcodesPage(); - final historyPage = const HistoryPage(); - final scannerPage = const ScannerPage(); - final helpPage = const HelpPage(); - final settingsPage = const SettingsPage(); + final BarcodesPage barcodesPage = const BarcodesPage(); + final HistoryPage historyPage = const HistoryPage(); + final ScannerPage scannerPage = const ScannerPage(); + final HelpPage helpPage = const HelpPage(); + final SettingsPage settingsPage = const SettingsPage(); - dynamic pages() => [ + dynamic pages() => [ barcodesPage, historyPage, scannerPage, @@ -31,17 +32,18 @@ class _HomePageState extends State { settingsPage, ]; - dynamic tabItems() => [ - const TabItem(icon: FontAwesomeIcons.barcode), - const TabItem(icon: FontAwesomeIcons.clockRotateLeft), - const TabItem(icon: Icons.qr_code_scanner), - const TabItem(icon: FontAwesomeIcons.circleQuestion), - const TabItem(icon: FontAwesomeIcons.gear), + dynamic tabItems() => >[ + const TabItem(icon: FontAwesomeIcons.barcode), + const TabItem(icon: FontAwesomeIcons.clockRotateLeft), + const TabItem(icon: Icons.qr_code_scanner), + const TabItem(icon: FontAwesomeIcons.circleQuestion), + const TabItem(icon: FontAwesomeIcons.gear), ]; @override Widget build(BuildContext context) { return Scaffold( + // ignore: avoid_dynamic_calls body: pages()[selectedIndex], bottomNavigationBar: ConvexAppBar( style: TabStyle.fixedCircle, @@ -50,7 +52,7 @@ class _HomePageState extends State { activeColor: Theme.of(context).colorScheme.primary, items: tabItems(), initialActiveIndex: selectedIndex, - onTap: (index) { + onTap: (int index) { setState(() { selectedIndex = index; }); diff --git a/zxscanner/lib/pages/scanner_page.dart b/zxscanner/lib/pages/scanner_page.dart index 7b06bff..2b7f45f 100644 --- a/zxscanner/lib/pages/scanner_page.dart +++ b/zxscanner/lib/pages/scanner_page.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:zxscanner/models/models.dart'; -import 'package:zxscanner/utils/db_service.dart'; -import 'package:zxscanner/utils/extensions.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:image_picker/image_picker.dart'; +import '../models/models.dart'; +import '../utils/db_service.dart'; +import '../utils/extensions.dart'; + class ScannerPage extends StatefulWidget { const ScannerPage({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _ScannerPageState(); @@ -25,7 +26,7 @@ class _ScannerPageState extends State { title: const Text('Scanner'), ), body: ReaderWidget( - onScan: (result) async { + onScan: (CodeResult result) async { addCode(result); }, ), @@ -36,6 +37,7 @@ class _ScannerPageState extends State { ); } + // ignore: always_declare_return_types pickImage() async { try { final XFile? file = await _picker.pickImage(source: ImageSource.gallery); @@ -48,18 +50,20 @@ class _ScannerPageState extends State { } } - readCodeFromImage(XFile file) async { + Future readCodeFromImage(XFile file) async { final CodeResult? result = await readBarcodeImagePath(file); if (result != null && result.isValidBool) { addCode(result); } else { - if (!mounted) return; + if (!mounted) { + return; + } context.showToast('No code found'); } } void addCode(CodeResult result) { - Code code = Code.fromCodeResult(result); + final Code code = Code.fromCodeResult(result); DbService.instance.addCode(code); context.showToast('Code added:\n${code.text ?? ''}'); } diff --git a/zxscanner/lib/pages/settings_page.dart b/zxscanner/lib/pages/settings_page.dart index 1fcadf4..6ddd305 100644 --- a/zxscanner/lib/pages/settings_page.dart +++ b/zxscanner/lib/pages/settings_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:zxscanner/configs/app_store.dart'; -import 'package:zxscanner/configs/constants.dart'; -import 'package:zxscanner/generated/l10n.dart'; -import 'package:zxscanner/widgets/common_widgets.dart'; +import '../configs/app_store.dart'; +import '../configs/constants.dart'; +import '../generated/l10n.dart'; +import '../widgets/common_widgets.dart'; // import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -12,7 +12,7 @@ import '../widgets/theme_mode_switch.dart'; import '../widgets/theme_selector.dart'; class SettingsPage extends StatefulWidget { - const SettingsPage({Key? key}) : super(key: key); + const SettingsPage({super.key}); @override State createState() => _SettingsPageState(); @@ -28,7 +28,7 @@ class _SettingsPageState extends State { body: SingleChildScrollView( child: ContainerX( child: Column( - children: [ + children: [ const SizedBox(height: spaceDefault), const Padding( padding: EdgeInsets.symmetric(horizontal: spaceDefault), @@ -40,7 +40,7 @@ class _SettingsPageState extends State { title: S.current.settingsThemeModeTitle, trailing: ThemeModeSwitch( themeMode: appStore.themeMode, - onChanged: (mode) { + onChanged: (ThemeMode mode) { appStore.setThemeMode(mode); setState(() {}); }, diff --git a/zxscanner/lib/utils/db_service.dart b/zxscanner/lib/utils/db_service.dart index fa573e5..dbe9022 100644 --- a/zxscanner/lib/utils/db_service.dart +++ b/zxscanner/lib/utils/db_service.dart @@ -1,6 +1,7 @@ -import 'package:zxscanner/models/models.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import '../models/models.dart'; + class DbService { DbService._privateConstructor(); @@ -17,44 +18,42 @@ class DbService { Box getCodes() => Hive.box('codes'); - Future deleteCodes() async { - var items = getCodes(); + Future deleteCodes() async { + final Box items = getCodes(); await items.deleteAll(items.keys); - return; } - Future addCode(Code value) async { - var items = getCodes(); + Future addCode(Code value) async { + final Box items = getCodes(); if (!items.values.contains(value)) { return items.add(value); } - return; + return -1; } Future deleteCode(Code value) async { - var items = getCodes(); + final Box items = getCodes(); await items.delete(value.key); return; } Box getEncodes() => Hive.box('encodes'); - Future deleteEncodes() async { - var items = getEncodes(); + Future deleteEncodes() async { + final Box items = getEncodes(); await items.deleteAll(items.keys); - return; } - Future addEncode(Encode value) async { - var items = getEncodes(); + Future addEncode(Encode value) async { + final Box items = getEncodes(); if (!items.values.contains(value)) { return items.add(value); } - return; + return -1; } Future deleteEncode(Encode value) async { - var items = getEncodes(); + final Box items = getEncodes(); await items.delete(value.key); return; } diff --git a/zxscanner/lib/utils/extensions.dart b/zxscanner/lib/utils/extensions.dart index 43e9f1e..b4ab25c 100644 --- a/zxscanner/lib/utils/extensions.dart +++ b/zxscanner/lib/utils/extensions.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; extension LocaleParsing on String { Locale parseLocale() { assert(contains('_') == true); - var languageCode = split('_').first; - var countryCode = split('_').last; + final String languageCode = split('_').first; + final String countryCode = split('_').last; return Locale.fromSubtags( languageCode: languageCode, countryCode: countryCode); } diff --git a/zxscanner/lib/utils/router.dart b/zxscanner/lib/utils/router.dart index c53f98a..2f8d194 100644 --- a/zxscanner/lib/utils/router.dart +++ b/zxscanner/lib/utils/router.dart @@ -1,43 +1,43 @@ import 'package:flutter/material.dart'; -import 'package:zxscanner/pages/creator_page.dart'; -import 'package:zxscanner/pages/history_page.dart'; -import 'package:zxscanner/pages/home_page.dart'; -import 'package:zxscanner/pages/scanner_page.dart'; -import 'package:zxscanner/pages/settings_page.dart'; +import '../pages/creator_page.dart'; +import '../pages/history_page.dart'; +import '../pages/home_page.dart'; +import '../pages/scanner_page.dart'; +import '../pages/settings_page.dart'; abstract class AppRoutes { - static const creator = '/creator'; - static const history = '/history'; - static const home = '/'; - static const scanner = '/scanner'; - static const settings = '/settings'; + static const String creator = '/creator'; + static const String history = '/history'; + static const String home = '/'; + static const String scanner = '/scanner'; + static const String settings = '/settings'; } class AppRouter { - Route onGenerateRoute(RouteSettings settings) { + Route onGenerateRoute(RouteSettings settings) { switch (settings.name) { case AppRoutes.creator: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => const CreatorPage(), ); case AppRoutes.history: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => const HistoryPage(), ); case AppRoutes.home: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => const HomePage(), ); case AppRoutes.scanner: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => const ScannerPage(), ); case AppRoutes.settings: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => const SettingsPage(), ); default: - return MaterialPageRoute( + return MaterialPageRoute( builder: (_) => Container(), ); } diff --git a/zxscanner/lib/utils/scroll_behavior.dart b/zxscanner/lib/utils/scroll_behavior.dart index c299410..7a5ab25 100644 --- a/zxscanner/lib/utils/scroll_behavior.dart +++ b/zxscanner/lib/utils/scroll_behavior.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class MyCustomScrollBehavior extends MaterialScrollBehavior { @override - Set get dragDevices => { + Set get dragDevices => { PointerDeviceKind.touch, PointerDeviceKind.mouse, }; diff --git a/zxscanner/lib/utils/shared_pref.dart b/zxscanner/lib/utils/shared_pref.dart index 1a51f02..ca68084 100644 --- a/zxscanner/lib/utils/shared_pref.dart +++ b/zxscanner/lib/utils/shared_pref.dart @@ -2,19 +2,19 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:zxscanner/configs/app_store.dart'; +import '../configs/app_store.dart'; late SharedPreferences sharedPreferences; Future initializePrefs() async { sharedPreferences = await SharedPreferences.getInstance(); - final themeModeString = getPrefString( + final String themeModeString = getPrefString( themeModePref, defaultValue: appStore.themeMode.toString(), ); await appStore.setThemeMode( - ThemeMode.values - .firstWhere((element) => element.toString() == themeModeString), + ThemeMode.values.firstWhere( + (ThemeMode element) => element.toString() == themeModeString), ); await appStore.setColorSchemeIndex( getPrefInt(colorSchemeIndexPref, defaultValue: appStore.colorSchemeIndex), @@ -34,27 +34,28 @@ Future initializePrefs() async { Future setPrefValue(String key, dynamic value, {bool print = true}) async { if (value is String) { - return await sharedPreferences.setString(key, value); + return sharedPreferences.setString(key, value); } else if (value is int) { - return await sharedPreferences.setInt(key, value); + return sharedPreferences.setInt(key, value); } else if (value is bool) { - return await sharedPreferences.setBool(key, value); + return sharedPreferences.setBool(key, value); } else if (value is double) { - return await sharedPreferences.setDouble(key, value); + return sharedPreferences.setDouble(key, value); } else if (value is Map) { - return await sharedPreferences.setString(key, jsonEncode(value)); + return sharedPreferences.setString(key, jsonEncode(value)); } else if (value is List) { - return await sharedPreferences.setStringList(key, value); + return sharedPreferences.setStringList(key, value); } else { throw ArgumentError( - 'Invalid value ${value.runtimeType} - Must be a String, int, bool, double, Map or StringList'); + 'Invalid value ${value.runtimeType} - Must be a String, int, bool, double, Map or StringList', + ); } } /// Returns List of Keys that matches with given Key List getMatchingSharedPrefKeys(String key) { - List keys = []; - sharedPreferences.getKeys().forEach((element) { + final List keys = []; + sharedPreferences.getKeys().forEach((String element) { if (element.contains(key)) { keys.add(element); } @@ -88,13 +89,12 @@ Map getPrefJSON(String key, if (sharedPreferences.containsKey(key)) { return jsonDecode(sharedPreferences.getString(key) ?? ''); } else { - return defaultValue ?? {}; + return defaultValue ?? {}; } } /// remove key from SharedPref -Future removePrefKey(String key) async => - await sharedPreferences.remove(key); +Future removePrefKey(String key) async => sharedPreferences.remove(key); /// clear SharedPref -Future clearSharedPref() async => await sharedPreferences.clear(); +Future clearSharedPref() async => sharedPreferences.clear(); diff --git a/zxscanner/lib/widgets/common_widgets.dart b/zxscanner/lib/widgets/common_widgets.dart index 4a2d2ba..cbb51f5 100644 --- a/zxscanner/lib/widgets/common_widgets.dart +++ b/zxscanner/lib/widgets/common_widgets.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:zxscanner/configs/constants.dart'; +import '../configs/constants.dart'; class ContainerX extends StatelessWidget { - const ContainerX({Key? key, this.child}) : super(key: key); + const ContainerX({super.key, this.child}); final Widget? child; diff --git a/zxscanner/lib/widgets/language_widget.dart b/zxscanner/lib/widgets/language_widget.dart index e5f1e6e..fdbbce5 100644 --- a/zxscanner/lib/widgets/language_widget.dart +++ b/zxscanner/lib/widgets/language_widget.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:zxscanner/configs/app_store.dart'; -import 'package:zxscanner/generated/l10n.dart'; -import 'package:zxscanner/utils/extensions.dart'; +import '../configs/app_store.dart'; +import '../generated/l10n.dart'; +import '../utils/extensions.dart'; class LanguageWidget extends StatelessWidget { - const LanguageWidget({Key? key, required this.onChanged}) : super(key: key); + const LanguageWidget({super.key, required this.onChanged}); final Function(Locale) onChanged; @@ -12,19 +12,17 @@ class LanguageWidget extends StatelessWidget { Widget build(BuildContext context) { return DropdownButton( value: appStore.selectedLanguage.parseLocale(), - isExpanded: false, - isDense: false, underline: const SizedBox(), - onChanged: (value) async { + onChanged: (Locale? value) async { if (value != null) { await S.load(value); appStore.setLanguage(value.toString()); onChanged(value); } }, - selectedItemBuilder: (context) { + selectedItemBuilder: (BuildContext context) { return S.delegate.supportedLocales - .map((e) => DropdownMenuItem( + .map((Locale e) => DropdownMenuItem( value: e, child: SizedBox( width: 80, @@ -38,7 +36,7 @@ class LanguageWidget extends StatelessWidget { .toList(); }, items: S.delegate.supportedLocales - .map((e) => DropdownMenuItem( + .map((Locale e) => DropdownMenuItem( value: e, child: Text(e.countryCode?.toLangName() ?? ''), )) diff --git a/zxscanner/lib/widgets/setting_tile.dart b/zxscanner/lib/widgets/setting_tile.dart index a7a9f9c..76927f1 100644 --- a/zxscanner/lib/widgets/setting_tile.dart +++ b/zxscanner/lib/widgets/setting_tile.dart @@ -3,12 +3,12 @@ import 'package:flutter/material.dart'; class SettingTile extends StatelessWidget { const SettingTile( this.context, { - Key? key, + super.key, this.leading, this.title, this.trailing, this.onTap, - }) : super(key: key); + }); final BuildContext context; final IconData? leading; diff --git a/zxscanner/lib/widgets/theme_mode_switch.dart b/zxscanner/lib/widgets/theme_mode_switch.dart index 032e4fc..7f2f015 100644 --- a/zxscanner/lib/widgets/theme_mode_switch.dart +++ b/zxscanner/lib/widgets/theme_mode_switch.dart @@ -7,10 +7,10 @@ import 'package:flutter/material.dart'; /// can be dropped into any application. class ThemeModeSwitch extends StatelessWidget { const ThemeModeSwitch({ - Key? key, + super.key, required this.themeMode, required this.onChanged, - }) : super(key: key); + }); final ThemeMode themeMode; final ValueChanged onChanged; diff --git a/zxscanner/lib/widgets/theme_selector.dart b/zxscanner/lib/widgets/theme_selector.dart index 49ad4b6..fd55b8e 100644 --- a/zxscanner/lib/widgets/theme_selector.dart +++ b/zxscanner/lib/widgets/theme_selector.dart @@ -1,6 +1,6 @@ import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; -import 'package:zxscanner/configs/app_store.dart'; +import '../configs/app_store.dart'; // The width size of the scrolling button. const double _kWidthOfScrollItem = 71.6; @@ -16,8 +16,8 @@ const double _kWidthOfScrollItem = 71.6; // The theme is controlled via the passed in ThemeController. class ThemeSelector extends StatefulWidget { const ThemeSelector({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _ThemeSelectorState(); @@ -32,7 +32,6 @@ class _ThemeSelectorState extends State { super.initState(); schemeIndex = appStore.colorSchemeIndex; scrollController = ScrollController( - keepScrollOffset: true, initialScrollOffset: _kWidthOfScrollItem * schemeIndex, ); } diff --git a/zxscanner/pubspec.lock b/zxscanner/pubspec.lock index f061340..41b31f9 100644 --- a/zxscanner/pubspec.lock +++ b/zxscanner/pubspec.lock @@ -35,7 +35,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -140,7 +140,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" charcode: dependency: transitive description: @@ -510,14 +510,14 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -552,7 +552,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_provider: dependency: "direct main" description: @@ -795,7 +795,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -823,7 +823,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" term_glyph: dependency: transitive description: