diff --git a/analysis_options.yaml b/analysis_options.yaml index 0bb3ca73..93113879 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -41,92 +41,6 @@ linter: require_trailing_commas: true eol_at_end_of_file: true - ####### - # - prefer_if_elements_to_conditional_expressions # Disabled because this rule decreases productivity by disturbing flow. - # - prefer_foreach # Disabled because this rule decreases productivity by disturbing flow. - # - always_require_non_null_named_parameters # Obsolete because of NNBD. - # - prefer_void_to_null # Obsolete because of NNBD. - # - camel_case_extensions # Disabled because an underscore is useful to represent domains in generated code. - # - omit_local_variable_types # Too pedantic. - # - prefer_adjacent_string_concatenation # No comment. - # - prefer_single_quotes # Too pedantic. - # - always_put_control_body_on_new_line # Too pedantic. - # - always_specify_types # Too pedantic. - # - avoid_as # Too pedantic. - # - unnecessary_this # Too many false positives. - # - prefer_bool_in_asserts # No comment. - # - use_to_and_as_if_applicable # Too pedantic. - # - use_super_parameters # Super parameters make inheritance more convenient, but inheritance should be avoided and composition should be preferred. Even if you need inheritance, you should declare an interface and mixins, and not use super constructors. - # - prefer_function_declarations_over_variables # With variables, the return type can be omitted safely which is useful in FP-style code. - # - always_use_package_imports # Prefer relative imports - # - avoid_annotating_with_dynamic # It is better to always be explicit about dynamic. - # - avoid_bool_literals_in_conditional_expressions # bool literals in conditional expressions make it easier to reason about them. X ? Y : Z is easier for humans than e.g. X || Z - # - avoid_classes_with_only_static_members # Classes with static members don't pollute the global namespace. - # - avoid_escaping_inner_quotes # Too pedantic. - # - avoid_function_literals_in_foreach_calls # Disabled because this rule decreases productivity by disturbing flow. - # - avoid_equals_and_hash_code_on_mutable_classes # @immutable depends on meta. - # - avoid_positional_boolean_parameters # Too pedantic. - # - avoid_print # Too pedantic. - # - avoid_redundant_argument_values # Too pedantic. - # - avoid_renaming_method_parameters # Too pedantic. - # - avoid_setters_without_getters # Too pedantic. - # - avoid_types_on_closure_parameters # Too pedantic. - # - avoid_unnecessary_containers # Disabled because this rule decreases productivity by disturbing flow. - # - camel_case_types # Underscores can be useful in generated code. - # - cascade_invocations # Too pedantic. - # - constant_identifier_names # Too pedantic. - # - deprecated_consistency # Too pedantic. - # - diagnostic_describe_all_properties # Too pedantic. - # - flutter_style_todos # Too pedantic. - # - do_not_use_environment # Too pedantic. - # - leading_newlines_in_multiline_strings # Too pedantic. - # - library_private_types_in_public_api # Too pedantic. - # - lines_longer_than_80_chars # Too pedantic. - # - missing_whitespace_between_adjacent_strings # Too pedantic. - # - non_constant_identifier_names # Too pedantic. - # - no_runtimeType_toString # Too pedantic. - # - one_member_abstracts # Too pedantic. - # - prefer_const_literals_to_create_immutables # Too pedantic. - # - prefer_constructors_over_static_methods # Too pedantic. - # - prefer_double_quotes # Too pedantic. - # - prefer_expression_function_bodies # Too pedantic. - # - prefer_interpolation_to_compose_strings # Too pedantic. - # - prefer_int_literals # Too pedantic. - # - prefer_is_not_operator # Too pedantic. - # - public_member_api_docs # Too pedantic. - # - sort_constructors_first # Too pedantic. - # - super_goes_last # Deprecated - # - unnecessary_brace_in_string_interps # Too pedantic. - # - unnecessary_final # final tells the reader 'This variable won't be mutated.' - # - unnecessary_lambdas # In rare cases it is possible for this to introduce bugs. - # - unnecessary_null_checks # Too pedantic. - # - unnecessary_raw_strings # Too pedantic. - # - unnecessary_string_escapes # Too pedantic. - # - unnecessary_string_interpolations # Too pedantic. - # - use_if_null_to_convert_nulls_to_bools # Too pedantic. - # - use_key_in_widget_constructors # Too pedantic. - # - use_late_for_private_fields_and_variables # Too pedantic. - # - use_named_constants # There could be multiple constants with the same value but different identifiers. - # - use_raw_strings # Too pedantic. - # - use_setters_to_change_properties # Too pedantic. - # - null_check_on_nullable_type_parameter # Too many false positives. - # - require_trailing_commas # Too pedantic. - # - avoid_field_initializers_in_const_classes # Too pedantic. - # - avoid_returning_null # Obsolete because of NNBD. - # - depend_on_referenced_packages # Disabled because this rule decreases productivity by disturbing flow. - # - eol_at_end_of_file # Too pedantic. - # - no_leading_underscores_for_library_prefixes # Too pedantic. - # - no_leading_underscores_for_local_identifiers # Too pedantic. - # - avoid_final_parameters # No comment. - # - sized_box_shrink_expand # Disabled because this rule decreases productivity by disturbing flow. - # - avoid_private_typedef_functions # Too pedantic. - # - avoid_multiple_declarations_per_line # Has false positives. - # - use_decorated_box # Disabled because this rule decreases productivity by disturbing flow. - # - use_test_throws_matchers # Too pedantic. - # - sized_box_for_whitespace # Disabled because this rule decreases productivity by disturbing flow. - # - invariant_booleans # Too many false positives. - # - sort_child_properties_last # Too pedantic. - analyzer: ### extra_pedantic ### diff --git a/lib/core/polkawallet/app_service.dart b/lib/core/polkawallet/app_service.dart index b0776e37..e1badba1 100644 --- a/lib/core/polkawallet/app_service.dart +++ b/lib/core/polkawallet/app_service.dart @@ -18,7 +18,7 @@ class AppService { balance = ValueNotifier(BalanceData()); final ValueNotifier balance; - final ValueNotifier bestNumber = ValueNotifier(''); + // final ValueNotifier bestNumber = ValueNotifier(''); final Keyring keyring; final NetworkStateData networkStateData; final PolkawalletPlugin plugin; diff --git a/lib/core/polkawallet/bloc/app_service_cubit.dart b/lib/core/polkawallet/bloc/app_service_cubit.dart index c3e299d5..ea643f2e 100644 --- a/lib/core/polkawallet/bloc/app_service_cubit.dart +++ b/lib/core/polkawallet/bloc/app_service_cubit.dart @@ -13,7 +13,6 @@ import 'package:threedpass/core/polkawallet/plugins/d3p_core_plugin.dart'; import 'package:threedpass/core/polkawallet/plugins/d3p_live_net_plugin.dart'; import 'package:threedpass/core/polkawallet/plugins/d3p_test_net_plugin.dart'; import 'package:threedpass/features/accounts/domain/account_info.dart'; -import 'package:threedpass/features/scan_page/bloc/object_from_file_cubit.dart'; import 'package:threedpass/features/settings_page/bloc/settings_page_cubit.dart'; import 'package:threedpass/features/settings_page/domain/entities/global_settings.dart'; import 'package:threedpass/features/settings_page/domain/entities/wallet_settings.dart'; @@ -26,7 +25,6 @@ import 'package:threedpass/features/settings_page/domain/entities/wallet_setting class AppServiceLoaderCubit extends Cubit { AppServiceLoaderCubit({ required this.settingsConfigCubit, - required this.bestNumberAvaliableCubit, }) : super( AppService( plugin: D3pLiveNetPlugin(), @@ -38,7 +36,6 @@ class AppServiceLoaderCubit extends Cubit { } final SettingsConfigCubit settingsConfigCubit; - final BestNumberAvaliableCubit bestNumberAvaliableCubit; Future> importAccount({ required final AccountInfo account, @@ -164,13 +161,12 @@ class AppServiceLoaderCubit extends Cubit { final newAppService = await _buildNewAppServiceWithProperties(service); - unawaited( - newAppService.plugin.sdk.api.setting - .subscribeBestNumber((final String value) { - newAppService.bestNumber.value = value; - bestNumberAvaliableCubit.setValue(true); - }), - ); + // unawaited( + // newAppService.plugin.sdk.api.setting + // .subscribeBestNumber((final String value) { + // newAppService.bestNumber.value = value; + // }), + // ); unawaited(subscribeToBalance(newAppService)); diff --git a/lib/core/utils/random_hex.dart b/lib/core/utils/random_hex.dart new file mode 100644 index 00000000..2f1c851d --- /dev/null +++ b/lib/core/utils/random_hex.dart @@ -0,0 +1,15 @@ +import 'dart:math'; + +class RandomHex { + static const _chars = '1234567890abcdef'; + static final Random _rnd = Random(); + + static String generate(final int length) => String.fromCharCodes( + Iterable.generate( + length, + (final _) => _chars.codeUnitAt( + _rnd.nextInt(_chars.length), + ), + ), + ); +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/create_account_from_object.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/create_account_from_object.dart index 15ae084b..d936dfe3 100644 --- a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/create_account_from_object.dart +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/create_account_from_object.dart @@ -9,13 +9,19 @@ import 'package:threedpass/core/widgets/buttons/elevated_button.dart'; import 'package:threedpass/core/widgets/paddings.dart'; import 'package:threedpass/features/accounts/bloc/account_store_bloc/account_store_bloc.dart'; import 'package:threedpass/features/accounts/presentation/pages/account_page_template.dart'; -import 'package:threedpass/features/accounts/presentation/pages/create_account/create_account_info_page.dart'; +import 'package:threedpass/features/accounts/presentation/widgets/header_info.dart'; +import 'package:threedpass/features/accounts/presentation/widgets/text_info.dart'; import 'package:threedpass/features/hashes_list/bloc/hashes_list_bloc.dart'; import 'package:threedpass/features/hashes_list/domain/entities/hash_object.dart'; import 'package:threedpass/router/router.gr.dart'; part './widgets/create_account_stateful.dart'; part './widgets/submit_button.dart'; +part './widgets/object_account_info.dart'; +part './widgets/choose_hash_title.dart'; +part './widgets/choose_hash_dropdown.dart'; +part './widgets/choose_object_title.dart'; +part './widgets/choose_object_dropdown.dart'; class CreateAccountFromObject extends StatelessWidget { const CreateAccountFromObject({final Key? key}) : super(key: key); diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_dropdown.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_dropdown.dart new file mode 100644 index 00000000..a1185055 --- /dev/null +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_dropdown.dart @@ -0,0 +1,45 @@ +part of '../create_account_from_object.dart'; + +class _ChooseHashDropdown extends StatelessWidget { + const _ChooseHashDropdown({ + required this.objectValueNotifier, + required this.chosenHash, + }); + + final ValueNotifier objectValueNotifier; + final ValueNotifier chosenHash; + + void onHashChoose(final String? value) { + if (value != null) { + chosenHash.value = value; + } + } + + @override + Widget build(final BuildContext context) { + return ValueListenableBuilder( + valueListenable: objectValueNotifier, + builder: (final ___, final _, final __) => ValueListenableBuilder( + valueListenable: chosenHash, + builder: (final context, final _, final __) => DropdownButton( + isExpanded: true, + style: Theme.of(context).textTheme.bodyText1, + value: chosenHash.value, + items: objectValueNotifier.value.stableHashes + .map( + (final e) => DropdownMenuItem( + value: e, + child: Text( + e, + maxLines: 3, + style: Theme.of(context).textTheme.bodyText1, + ), + ), + ) + .toList(), + onChanged: (final String? modelChosen) => onHashChoose(modelChosen), + ), + ), + ); + } +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_title.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_title.dart new file mode 100644 index 00000000..371bc00f --- /dev/null +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_hash_title.dart @@ -0,0 +1,19 @@ +part of '../create_account_from_object.dart'; + +class _ChooseHashTitle extends StatelessWidget { + const _ChooseHashTitle(); + + @override + Widget build(final BuildContext context) => Text.rich( + TextSpan( + text: 'create_from_object_text2'.tr(), + style: Theme.of(context).textTheme.headline6, + children: [ + TextSpan( + text: '\n' + 'create_from_object_text2_hint'.tr(), + style: Theme.of(context).textTheme.bodyText1, + ), + ], + ), + ); +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_dropdown.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_dropdown.dart new file mode 100644 index 00000000..5ead8809 --- /dev/null +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_dropdown.dart @@ -0,0 +1,44 @@ +part of '../create_account_from_object.dart'; + +class _ChooseObjectDropdown extends StatelessWidget { + const _ChooseObjectDropdown({ + required this.objectValueNotifier, + required this.objectsToUse, + required this.chosenHash, + }); + + final ValueNotifier objectValueNotifier; + final List objectsToUse; + final ValueNotifier chosenHash; + + void onObjectChoose(final HashObject? hashObject) { + if (hashObject != null) { + objectValueNotifier.value = hashObject; + chosenHash.value = hashObject.stableHashes.first; + } + } + + @override + Widget build(final BuildContext context) { + return ValueListenableBuilder( + valueListenable: objectValueNotifier, + builder: (final context, final _, final __) => DropdownButton( + style: Theme.of(context).textTheme.bodyText1, + value: objectValueNotifier.value, + items: objectsToUse + .map( + (final e) => DropdownMenuItem( + value: e, + child: Text( + e.name.cutWithEllipsis(20), + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodyText1, + ), + ), + ) + .toList(), + onChanged: (final modelChosen) => onObjectChoose(modelChosen), + ), + ); + } +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_title.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_title.dart new file mode 100644 index 00000000..96ca9d6d --- /dev/null +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/choose_object_title.dart @@ -0,0 +1,11 @@ +part of '../create_account_from_object.dart'; + +class _ChooseObjectTitle extends StatelessWidget { + const _ChooseObjectTitle(); + + @override + Widget build(final BuildContext context) => Text( + 'create_from_object_text1'.tr(), + style: Theme.of(context).textTheme.headline6, + ); +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/create_account_stateful.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/create_account_stateful.dart index c5e3b08c..d83bb2c3 100644 --- a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/create_account_stateful.dart +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/create_account_stateful.dart @@ -9,7 +9,6 @@ class _CreateAccountStateful extends StatefulWidget { class _MainState extends State<_CreateAccountStateful> { late final ValueNotifier objectValueNotifier; - // late final ValueNotifier snapshotToUse; late final List objectsToUse; final ValueNotifier chosenHash = ValueNotifier(''); @@ -43,19 +42,6 @@ class _MainState extends State<_CreateAccountStateful> { super.initState(); } - void onObjectChoose(final HashObject? hashObject) { - if (hashObject != null) { - objectValueNotifier.value = hashObject; - chosenHash.value = hashObject.stableHashes.first; - } - } - - void onHashChoose(final String? value) { - if (value != null) { - chosenHash.value = value; - } - } - @override Widget build(final BuildContext context) { return Column( @@ -65,83 +51,22 @@ class _MainState extends State<_CreateAccountStateful> { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - 'create_from_object_text1'.tr(), - style: Theme.of(context).textTheme.headline6, - ), + const _ChooseObjectTitle(), const SizedBox8(), - DropdownButton( - style: Theme.of(context).textTheme.bodyText1, - value: objectValueNotifier.value, - items: objectsToUse - .map( - (final e) => DropdownMenuItem( - value: e, - child: Text( - e.name.cutWithEllipsis(20), - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodyText1, - ), - ), - ) - .toList(), - onChanged: (final modelChosen) => onObjectChoose(modelChosen), + _ChooseObjectDropdown( + objectValueNotifier: objectValueNotifier, + objectsToUse: objectsToUse, + chosenHash: chosenHash, ), const SizedBox24(), - Text.rich( - TextSpan( - text: 'create_from_object_text2'.tr(), - style: Theme.of(context).textTheme.headline6, - children: [ - TextSpan( - text: '\n' + 'create_from_object_text2_hint'.tr(), - style: Theme.of(context).textTheme.bodyText1, - ), - ], - ), - ), + const _ChooseHashTitle(), const SizedBox8(), - ValueListenableBuilder( - valueListenable: objectValueNotifier, - builder: (final context, final _, final __) => - DropdownButton( - isExpanded: true, - style: Theme.of(context).textTheme.bodyText1, - value: chosenHash.value, - items: objectValueNotifier.value.stableHashes - .map( - (final e) => DropdownMenuItem( - value: e, - child: Text( - e, - maxLines: 3, - style: Theme.of(context).textTheme.bodyText1, - ), - ), - ) - .toList(), - onChanged: (final modelChosen) => onHashChoose(modelChosen), - ), + _ChooseHashDropdown( + chosenHash: chosenHash, + objectValueNotifier: objectValueNotifier, ), const SizedBox36(), - HeaderInfo( - text: 'create_warn5_header'.tr(), - ), - TextInfo( - text: 'create_warn5_text'.tr(), - bigBottomPadding: true, - ), - HeaderInfo( - text: 'create_warn6_header'.tr(), - ), - TextInfo( - text: 'create_warn6_text'.tr(), - bigBottomPadding: false, - ), - TextInfo( - text: 'create_warn6_text2'.tr(), - bigBottomPadding: false, - ), + ...const _ObjectAccountInfo().warnInfo(), const SizedBox24(), ], ), diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/object_account_info.dart b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/object_account_info.dart new file mode 100644 index 00000000..253d7349 --- /dev/null +++ b/lib/features/accounts/presentation/pages/create_account/create_account_from_object/widgets/object_account_info.dart @@ -0,0 +1,26 @@ +part of '../create_account_from_object.dart'; + +class _ObjectAccountInfo { + const _ObjectAccountInfo(); + + List warnInfo() => [ + HeaderInfo( + text: 'create_warn5_header'.tr(), + ), + TextInfo( + text: 'create_warn5_text'.tr(), + bigBottomPadding: true, + ), + HeaderInfo( + text: 'create_warn6_header'.tr(), + ), + TextInfo( + text: 'create_warn6_text'.tr(), + bigBottomPadding: false, + ), + TextInfo( + text: 'create_warn6_text2'.tr(), + bigBottomPadding: false, + ), + ]; +} diff --git a/lib/features/accounts/presentation/pages/create_account/create_account_info_page.dart b/lib/features/accounts/presentation/pages/create_account/create_account_info_page.dart index 1ad3dbc3..bdc004c9 100644 --- a/lib/features/accounts/presentation/pages/create_account/create_account_info_page.dart +++ b/lib/features/accounts/presentation/pages/create_account/create_account_info_page.dart @@ -7,6 +7,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:threedpass/core/polkawallet/app_service.dart'; import 'package:threedpass/features/accounts/bloc/account_store_bloc/account_store_bloc.dart'; import 'package:threedpass/features/accounts/presentation/pages/account_page_template.dart'; +import 'package:threedpass/features/accounts/presentation/widgets/header_info.dart'; +import 'package:threedpass/features/accounts/presentation/widgets/text_info.dart'; import 'package:threedpass/router/router.gr.dart'; class CreateAccountInfoPage extends StatelessWidget { @@ -67,47 +69,3 @@ class CreateAccountInfoPage extends StatelessWidget { ); } } - -class HeaderInfo extends StatelessWidget { - const HeaderInfo({ - required this.text, - final Key? key, - }) : super(key: key); - - final String text; - - @override - Widget build(final BuildContext context) { - return Padding( - padding: const EdgeInsets.only(bottom: 10), - child: Text( - text, - style: Theme.of(context) - .textTheme - .headline6 - ?.copyWith(fontWeight: FontWeight.bold), - ), - ); - } -} - -class TextInfo extends StatelessWidget { - const TextInfo({ - required this.text, - required this.bigBottomPadding, - final Key? key, - }) : super(key: key); - - final bool bigBottomPadding; - final String text; - - @override - Widget build(final BuildContext context) { - return Padding( - padding: EdgeInsets.only(bottom: bigBottomPadding ? 32 : 5), - child: Text( - text, - ), - ); - } -} diff --git a/lib/features/accounts/presentation/widgets/header_info.dart b/lib/features/accounts/presentation/widgets/header_info.dart new file mode 100644 index 00000000..addec676 --- /dev/null +++ b/lib/features/accounts/presentation/widgets/header_info.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +class HeaderInfo extends StatelessWidget { + const HeaderInfo({ + required this.text, + final Key? key, + }) : super(key: key); + + final String text; + + @override + Widget build(final BuildContext context) { + return Padding( + padding: const EdgeInsets.only(bottom: 10), + child: Text( + text, + style: Theme.of(context) + .textTheme + .headline6 + ?.copyWith(fontWeight: FontWeight.bold), + ), + ); + } +} diff --git a/lib/features/accounts/presentation/widgets/text_info.dart b/lib/features/accounts/presentation/widgets/text_info.dart new file mode 100644 index 00000000..caaebb99 --- /dev/null +++ b/lib/features/accounts/presentation/widgets/text_info.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class TextInfo extends StatelessWidget { + const TextInfo({ + required this.text, + required this.bigBottomPadding, + final Key? key, + }) : super(key: key); + + final bool bigBottomPadding; + final String text; + + @override + Widget build(final BuildContext context) { + return Padding( + padding: EdgeInsets.only(bottom: bigBottomPadding ? 32 : 5), + child: Text( + text, + ), + ); + } +} diff --git a/lib/features/hashes_list/domain/entities/snapshot_create_from_file/snapshot_create_from_file.dart b/lib/features/hashes_list/domain/entities/snapshot_create_from_file/snapshot_create_from_file.dart index 272b2d7c..05c8a482 100644 --- a/lib/features/hashes_list/domain/entities/snapshot_create_from_file/snapshot_create_from_file.dart +++ b/lib/features/hashes_list/domain/entities/snapshot_create_from_file/snapshot_create_from_file.dart @@ -1,11 +1,10 @@ import 'package:calc/calc.dart'; import 'package:file_picker/file_picker.dart'; import 'package:threedpass/common/logger.dart'; -import 'package:threedpass/core/polkawallet/app_service.dart'; -import 'package:threedpass/core/polkawallet/bloc/app_service_cubit.dart'; import 'package:threedpass/core/utils/formatters.dart'; import 'package:threedpass/core/utils/hash_file.dart'; import 'package:threedpass/core/utils/pair.dart'; +import 'package:threedpass/core/utils/random_hex.dart'; import 'package:threedpass/features/hashes_list/bloc/hashes_list_bloc.dart'; import 'package:threedpass/features/hashes_list/domain/entities/hash_object.dart'; import 'package:threedpass/features/hashes_list/domain/entities/snapshot.dart'; @@ -16,14 +15,12 @@ part './trans_bytes.dart'; class SnapshotFileFactory { final ScanSettings scanSettings; - final AppServiceLoaderCubit appServiceLoaderCubit; final HashesListBloc hashesListBloc; final void Function() showLoader; // final void Function() hideLoader; SnapshotFileFactory({ required this.scanSettings, - required this.appServiceLoaderCubit, required this.hashesListBloc, required this.showLoader, // required this.hideLoader, @@ -40,7 +37,6 @@ class SnapshotFileFactory { final transBytes = await _TransBytes( scanSettings: scanSettings, - appServiceLoaderCubit: appServiceLoaderCubit, ).transBytes(); final hashes = await calcHashes( diff --git a/lib/features/hashes_list/domain/entities/snapshot_create_from_file/trans_bytes.dart b/lib/features/hashes_list/domain/entities/snapshot_create_from_file/trans_bytes.dart index e446676f..8d74c458 100644 --- a/lib/features/hashes_list/domain/entities/snapshot_create_from_file/trans_bytes.dart +++ b/lib/features/hashes_list/domain/entities/snapshot_create_from_file/trans_bytes.dart @@ -2,11 +2,9 @@ part of './snapshot_create_from_file.dart'; class _TransBytes { final ScanSettings scanSettings; - final AppServiceLoaderCubit appServiceLoaderCubit; _TransBytes({ required this.scanSettings, - required this.appServiceLoaderCubit, }); Future transBytes() async { @@ -16,18 +14,7 @@ class _TransBytes { return userTransBytes; } - final AppService appService = appServiceLoaderCubit.state; - final String bestnumber = appService.bestNumber.value; - - if (bestnumber.isNotEmpty) { - final blockHash = await appService.plugin.sdk.api.service.webView! - .evalJavascript('api.rpc.chain.getBlockHash($bestnumber)'); - - // final signedBlock = await appService.plugin.sdk.api.service.webView! - // .evalJavascript('api.rpc.chain.getBlock()'); - return (blockHash as String).substring(2, 10); - } - - throw Exception('Both userTransBytes and bestnumber are empty'); + final randomTransBytes = RandomHex.generate(8); + return randomTransBytes; } } diff --git a/lib/features/scan_page/bloc/object_from_file_cubit.dart b/lib/features/scan_page/bloc/object_from_file_cubit.dart deleted file mode 100644 index 4f6a2498..00000000 --- a/lib/features/scan_page/bloc/object_from_file_cubit.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter_bloc/flutter_bloc.dart'; - -/// Notifies that [AppServiceLoaderCubit.state.bestNumber.value] is not empty -/// It's better not to use [BlocBuilder] because it will -/// require to emit after getting the bestNumber. -/// And consequently, it will cause redundant widget rebuilds or bad logic -class BestNumberAvaliableCubit extends Cubit { - BestNumberAvaliableCubit() : super(false); - - void setValue(final bool value) => emit(value); -} diff --git a/lib/features/scan_page/presentation/widgets/get_object_from_file_button.dart b/lib/features/scan_page/presentation/widgets/get_object_from_file_button.dart index 885976e9..0c4ecaa2 100644 --- a/lib/features/scan_page/presentation/widgets/get_object_from_file_button.dart +++ b/lib/features/scan_page/presentation/widgets/get_object_from_file_button.dart @@ -4,16 +4,12 @@ import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:threedpass/core/polkawallet/bloc/app_service_cubit.dart'; import 'package:threedpass/core/widgets/buttons/elevated_button.dart'; -import 'package:threedpass/core/widgets/progress_indicator/thin_progress_indicator.dart'; import 'package:threedpass/features/hashes_list/bloc/hashes_list_bloc.dart'; import 'package:threedpass/features/hashes_list/domain/entities/snapshot_create_from_file/snapshot_create_from_file.dart'; import 'package:threedpass/features/home_page/bloc/home_context_cubit.dart'; -import 'package:threedpass/features/scan_page/bloc/object_from_file_cubit.dart'; import 'package:threedpass/features/scan_page/presentation/widgets/calc_hash_loading_dialog.dart'; import 'package:threedpass/features/settings_page/bloc/settings_page_cubit.dart'; -import 'package:threedpass/features/settings_page/domain/entities/global_settings.dart'; import 'package:threedpass/router/router.gr.dart'; class GetObjectFromFileFloatingButton extends StatelessWidget { @@ -34,12 +30,16 @@ class GetObjectFromFileFloatingButton extends StatelessWidget { ); } + void hideLoader(final BuildContext context) { + final homeContext = BlocProvider.of(context); + homeContext.hideDialogC(); + } + /// Calc object Future createHashFromFile( final BuildContext context, ) async { final snapFactory = SnapshotFileFactory( - appServiceLoaderCubit: BlocProvider.of(context), showLoader: () => showLoader(context), hashesListBloc: BlocProvider.of(context), scanSettings: @@ -48,6 +48,7 @@ class GetObjectFromFileFloatingButton extends StatelessWidget { try { final pair = await snapFactory.createSnapshotFromFile(); + hideLoader(context); unawaited( context.router.push( PreviewWrapperRoute( @@ -60,53 +61,23 @@ class GetObjectFromFileFloatingButton extends StatelessWidget { } on FilePickerException catch (e) { showSnackBar(e.message, context); } on Exception catch (e) { - final homeContext = BlocProvider.of(context); - homeContext.hideDialogC(); + hideLoader(context); showSnackBar(e.toString(), context); } } - Future Function()? onPressed({ - required final GlobalSettings settingsState, - required final BuildContext context, - required final HomeContextCubit homeContext, - required final bool isBestNumAvaliable, - }) { - return _isButtonDisabled(isBestNumAvaliable, settingsState) - ? null - : () => createHashFromFile( - context, - ); - } - @override Widget build(final BuildContext context) { return Row( children: [ const Spacer(), Flexible( - child: Material( - child: BlocBuilder( - builder: (final context, final settingsState) => - BlocBuilder( - builder: (final context, final isBestNumAvaliable) { - return D3pElevatedButton( - icon: _CustomIcon.build(isBestNumAvaliable, settingsState), - iconData: - _isButtonDisabled(isBestNumAvaliable, settingsState) - ? null - : Icons.folder_open, - text: 'get_from_file_button_label'.tr(), - onPressed: onPressed( - isBestNumAvaliable: isBestNumAvaliable, - settingsState: settingsState, - context: context, - homeContext: BlocProvider.of(context), - ), - ); - }, - ), + child: D3pElevatedButton( + iconData: Icons.folder_open, + text: 'get_from_file_button_label'.tr(), + onPressed: () => createHashFromFile( + context, ), ), ), @@ -114,25 +85,3 @@ class GetObjectFromFileFloatingButton extends StatelessWidget { ); } } - -bool _isButtonDisabled( - final bool isBestNumAvaliable, - final GlobalSettings settingsState, -) { - return settingsState.scanSettings.transBytes.isEmpty && !isBestNumAvaliable; -} - -class _CustomIcon { - static Widget? build( - final bool isBestNumAvaliable, - final GlobalSettings settingsState, - ) { - return _isButtonDisabled(isBestNumAvaliable, settingsState) - ? const SizedBox( - height: 20, - width: 20, - child: ThinProgressIndicator(), - ) - : null; - } -} diff --git a/lib/features/scan_page/presentation/widgets/objects_list.dart b/lib/features/scan_page/presentation/widgets/objects_list.dart index 36aadc8b..bcfbfcfe 100644 --- a/lib/features/scan_page/presentation/widgets/objects_list.dart +++ b/lib/features/scan_page/presentation/widgets/objects_list.dart @@ -16,6 +16,7 @@ class ObjectsList extends StatelessWidget { if (state is HashesListLoaded) { return ListView.builder( padding: const EdgeInsets.only(bottom: 46 * 2), + physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: (state as HashesListLoaded).objects.length, itemBuilder: (final context, final objIndex) { @@ -25,16 +26,12 @@ class ObjectsList extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Padding( - padding: const EdgeInsets.only(top: 16, left: 16, right: 16), - child: Text( - 'object_title_prefix'.tr() + ' ' + currentObject.name, - style: Theme.of(context).textTheme.headline6, + _ObjectTitle(currentObject.name), + Flexible( + child: SnapshotsList( + currentObject: currentObject, ), ), - SnapshotsList( - currentObject: currentObject, - ), ], ); }, @@ -43,3 +40,18 @@ class ObjectsList extends StatelessWidget { return const SizedBox(); } } + +class _ObjectTitle extends StatelessWidget { + const _ObjectTitle(this.title); + + final String title; + + @override + Widget build(final BuildContext context) => Padding( + padding: const EdgeInsets.only(top: 16, left: 16, right: 16), + child: Text( + 'object_title_prefix'.tr() + ' ' + title, + style: Theme.of(context).textTheme.headline6, + ), + ); +} diff --git a/lib/features/scan_page/presentation/widgets/scan_page_content.dart b/lib/features/scan_page/presentation/widgets/scan_page_content.dart index 97a4c9e9..295eb8d0 100644 --- a/lib/features/scan_page/presentation/widgets/scan_page_content.dart +++ b/lib/features/scan_page/presentation/widgets/scan_page_content.dart @@ -17,19 +17,22 @@ class ScanPageContent extends StatelessWidget { if (state.objects.isEmpty) { return const NoSavedObjectsPlaceholder(); } else { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ObjectsListHeader( - state: state, - ), - const SizedBox(height: 4), - Flexible( - child: ObjectsList( + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ObjectsListHeader( state: state, ), - ), - ], + const SizedBox(height: 4), + Flexible( + child: ObjectsList( + state: state, + ), + ), + ], + ), ); } } else { diff --git a/lib/main.dart b/lib/main.dart index cc2628f4..f93ce305 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,6 @@ import 'package:threedpass/core/persistence/hive_setup.dart' as hive_setup; import 'package:threedpass/core/polkawallet/bloc/app_service_cubit.dart'; import 'package:threedpass/core/theme/d3p_theme.dart'; import 'package:threedpass/features/hashes_list/bloc/hashes_list_bloc.dart'; -import 'package:threedpass/features/scan_page/bloc/object_from_file_cubit.dart'; import 'package:threedpass/features/settings_page/bloc/settings_page_cubit.dart'; import 'package:threedpass/router/router.gr.dart'; import 'package:threedpass/setup.dart' as di_setup; @@ -51,9 +50,6 @@ class ThreeDApp extends StatelessWidget { BlocProvider( create: (final _) => di_setup.getIt(), ), - BlocProvider( - create: (final _) => di_setup.getIt(), - ), BlocProvider( create: (final _) => di_setup.getIt(), lazy: false, diff --git a/lib/setup.dart b/lib/setup.dart index 1fcb115d..5b594522 100644 --- a/lib/setup.dart +++ b/lib/setup.dart @@ -4,7 +4,6 @@ import 'package:threedpass/core/polkawallet/bloc/app_service_cubit.dart'; import 'package:threedpass/features/hashes_list/bloc/hashes_list_bloc.dart'; import 'package:threedpass/features/hashes_list/data/repositories/hash_list_store.dart'; import 'package:threedpass/features/hashes_list/domain/repositories/hashes_repository.dart'; -import 'package:threedpass/features/scan_page/bloc/object_from_file_cubit.dart'; import 'package:threedpass/features/settings_page/bloc/settings_page_cubit.dart'; import 'package:threedpass/features/settings_page/data/repositories/settings_store.dart'; import 'package:threedpass/features/settings_page/domain/repositories/settings_repository.dart'; @@ -57,16 +56,9 @@ Future setup() async { ), ); - // It becomes singleton and not factory. But it doesn't matter - final bestNumberAvaliableCubit = BestNumberAvaliableCubit(); - getIt.registerFactory( - () => bestNumberAvaliableCubit, - ); - getIt.registerFactory( () => AppServiceLoaderCubit( settingsConfigCubit: getIt(), - bestNumberAvaliableCubit: bestNumberAvaliableCubit, ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index c6c00181..d8f0d977 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,7 +10,7 @@ publish_to: 'none' # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 2.2.1+7 +version: 2.2.3+8 environment: sdk: ">=2.17.5 <3.0.0"