From 6c2a4bceed8f6b6a0b049cf7f5cf4ac26fa5d592 Mon Sep 17 00:00:00 2001 From: Alex Li Date: Thu, 12 May 2022 23:03:06 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Migrate=20to=20Flutter=203=20(#3?= =?UTF-8?q?17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 + analysis_options.yaml | 140 ++++++++------ example/lib/constants/picker_method.dart | 19 +- example/lib/customs/custom_picker_page.dart | 13 +- .../pickers/directory_file_asset_picker.dart | 68 +++---- .../pickers/multi_tabs_assets_picker.dart | 68 +++---- example/lib/main.dart | 4 +- example/lib/pages/home_page.dart | 6 +- example/lib/pages/multi_assets_page.dart | 4 +- example/lib/pages/single_assets_page.dart | 4 +- example/lib/pages/splash_page.dart | 4 +- example/lib/widgets/asset_widget_builder.dart | 4 +- example/lib/widgets/method_list_view.dart | 10 +- .../widgets/selected_assets_list_view.dart | 4 +- example/pubspec.yaml | 10 +- lib/src/constants/custom_scroll_physics.dart | 8 +- .../asset_picker_builder_delegate.dart | 181 ++++++++---------- lib/src/delegates/asset_picker_delegate.dart | 16 +- .../delegates/asset_picker_text_delegate.dart | 2 +- .../asset_picker_viewer_builder_delegate.dart | 117 +++++------ lib/src/provider/asset_picker_provider.dart | 50 ++--- lib/src/widget/asset_picker.dart | 6 +- lib/src/widget/asset_picker_app_bar.dart | 26 +-- lib/src/widget/asset_picker_viewer.dart | 4 +- .../asset_entity_grid_item_builder.dart | 5 +- .../widget/builder/audio_page_builder.dart | 2 +- .../widget/builder/fade_image_builder.dart | 2 +- .../widget/builder/image_page_builder.dart | 28 ++- .../builder/locally_available_builder.dart | 6 +- .../builder/value_listenable_builder_2.dart | 4 +- .../widget/builder/video_page_builder.dart | 6 +- lib/src/widget/gaps.dart | 26 ++- .../widget/platform_progress_indicator.dart | 4 +- lib/src/widget/scale_text.dart | 7 +- pubspec.yaml | 15 +- test/delegates/builder_delegate_test.dart | 8 +- 36 files changed, 417 insertions(+), 468 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97678947..4dc77acc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ that can be found in the LICENSE file. --> # Changelog +## 7.3.0 + +Migrate to Flutter 3, drop supports for previous Flutter versions. + ## 7.2.0 ### New features diff --git a/analysis_options.yaml b/analysis_options.yaml index 3dd900e2..ff85861b 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,39 +1,35 @@ # Specify analysis options. # -# Until there are meta linter rules, each desired lint must be explicitly enabled. -# See: https://github.com/dart-lang/linter/issues/288 -# # For a list of lints, see: http://dart-lang.github.io/linter/lints/ # See the configuration guide for more -# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer # # There are other similar analysis options files in the flutter repos, # which should be kept in sync with this file: # # - analysis_options.yaml (this file) -# - packages/flutter/lib/analysis_options_user.yaml # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml # - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# - https://github.com/flutter/packages/blob/master/analysis_options.yaml # -# This file contains the analysis options used by Flutter tools, such as IntelliJ, -# Android Studio, and the `flutter analyze` command. +# This file contains the analysis options used for code in the flutter/flutter +# repository. analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false + language: + strict-casts: true + 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 - # allow having TODOs in the code + # allow having TODO comments in the code todo: ignore linter: rules: - # these rules are documented on and in the same order as - # the Dart Lint rules page to make maintenance easier + # 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 @@ -43,62 +39,68 @@ linter: # - always_use_package_imports # we do this commonly - annotate_overrides # - avoid_annotating_with_dynamic # conflicts with always_specify_types - # - avoid_as # required for implicit-casts: true - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses # we do this commonly - # - avoid_catching_errors # we do this commonly + # - 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 # only useful when targeting JS runtime + - avoid_double_and_int_checks + - avoid_dynamic_calls - avoid_empty_else - avoid_equals_and_hash_code_on_mutable_classes - # - avoid_escaping_inner_quotes # not yet tested + - 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 # not yet tested + - avoid_implementing_value_types - avoid_init_to_null - # - avoid_js_rounded_ints # only useful when targeting JS runtime + - 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 # not yet tested - # - avoid_print # not yet tested + # - 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 # not yet tested + - avoid_redundant_argument_values - avoid_relative_lib_imports - avoid_renaming_method_parameters - avoid_return_types_on_setters - # - avoid_returning_null # there are plenty of valid reasons to return null - # - avoid_returning_null_for_future # not yet tested + # - 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 plenty of valid reasons to return this - # - avoid_setters_without_getters # not yet tested + # - 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 # we do this commonly + - avoid_type_to_string - avoid_types_as_parameter_names # - avoid_types_on_closure_parameters # conflicts with always_specify_types - # - avoid_unnecessary_containers # not yet tested + - avoid_unnecessary_containers - avoid_unused_constructor_parameters - avoid_void_async - # - avoid_web_libraries_in_flutter # not yet tested + # - 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 # not yet tested + # - 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/flutter/flutter/issues/20765 + # - 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 - # - diagnostic_describe_all_properties # not yet tested + - 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 # we do this commonly + # - 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 # not yet tested + - file_names - flutter_style_todos - hash_and_equals - implementation_imports @@ -108,24 +110,28 @@ linter: - 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/sdk/issues/34181 - # - missing_whitespace_between_adjacent_strings # not yet tested + # - 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 # too many false positives + - 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 # not required by flutter style + - null_closures # - omit_local_variable_types # opposite of always_specify_types # - one_member_abstracts # too many false positives - # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - 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 # non conforming packages in sdk + - package_names - package_prefixed_library_names # - parameter_assignments # we do this commonly - prefer_adjacent_string_concatenation @@ -145,34 +151,38 @@ linter: - 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 # not yet tested + - 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 # not yet tested - # - prefer_interpolation_to_compose_strings # not yet tested + # - 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 # https://github.com/dart-lang/language/issues/32 - # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 - # - prefer_relative_imports # not yet tested + # - 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 # not yet tested + - 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 - # - sized_box_for_whitespace # not yet tested + # - 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 # not yet tested + - sort_child_properties_last - sort_constructors_first # - sort_pub_dependencies # prevents separating pinned transitive dependencies - sort_unnamed_constructors_first @@ -181,36 +191,46 @@ linter: - tighten_type_of_initializing_formals # - type_annotate_public_apis # subset of always_specify_types - type_init_formals - # - unawaited_futures # too many false positives - # - unnecessary_await_in_return # not yet tested + # - 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 # not yet tested + - unnecessary_null_checks - unnecessary_null_in_if_null_operators - unnecessary_nullable_for_final_variable_declarations - unnecessary_overrides - unnecessary_parenthesis - # - unnecessary_raw_strings # not yet tested + # - 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 # not yet tested + - 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 # not yet tested + - 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 # not yet tested + - 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 # not yet tested + - 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 + - void_checks diff --git a/example/lib/constants/picker_method.dart b/example/lib/constants/picker_method.dart index 4f96030b..909306f3 100644 --- a/example/lib/constants/picker_method.dart +++ b/example/lib/constants/picker_method.dart @@ -92,7 +92,6 @@ class PickMethod { pickerConfig: AssetPickerConfig( maxAssets: maxAssetsCount, selectedAssets: assets, - requestType: RequestType.common, specialItemPosition: SpecialItemPosition.prepend, specialItemBuilder: ( BuildContext context, @@ -140,7 +139,6 @@ class PickMethod { pickerConfig: AssetPickerConfig( maxAssets: maxAssetsCount, selectedAssets: assets, - requestType: RequestType.common, specialItemPosition: SpecialItemPosition.prepend, specialItemBuilder: ( BuildContext context, @@ -168,7 +166,7 @@ class PickMethod { final DefaultAssetPickerProvider p = builder.provider; p.currentPath = await p.currentPath!.obtainForNewProperties(); - await p.switchPath(p.currentPath!); + await p.switchPath(p.currentPath); p.selectAsset(result); }, child: const Center( @@ -194,7 +192,6 @@ class PickMethod { pickerConfig: AssetPickerConfig( maxAssets: maxAssetsCount, selectedAssets: assets, - requestType: RequestType.common, ), ); }, @@ -260,7 +257,6 @@ class PickMethod { pickerConfig: AssetPickerConfig( maxAssets: maxAssetsCount, selectedAssets: assets, - requestType: RequestType.common, specialItemPosition: SpecialItemPosition.prepend, specialItemBuilder: ( BuildContext context, @@ -288,7 +284,6 @@ class PickMethod { pickerConfig: AssetPickerConfig( maxAssets: maxAssetsCount, selectedAssets: assets, - requestType: RequestType.common, specialPickerType: SpecialPickerType.noPreview, ), ); @@ -306,13 +301,11 @@ class PickMethod { name: 'Keep scroll offset', description: 'Pick assets from same scroll position.', method: (BuildContext context, List assets) async { - final PermissionState _ps = - await PhotoManager.requestPermissionExtend(); - if (_ps != PermissionState.authorized && - _ps != PermissionState.limited) { - throw StateError('Permission state error with $_ps.'); + final PermissionState ps = await PhotoManager.requestPermissionExtend(); + if (ps != PermissionState.authorized && ps != PermissionState.limited) { + throw StateError('Permission state error with $ps.'); } - onPermission(_ps); + onPermission(ps); return AssetPicker.pickAssetsWithDelegate( context, delegate: delegate(), @@ -353,7 +346,7 @@ class PickMethod { maxAssets: maxAssetsCount, selectedAssets: assets, selectPredicate: (BuildContext c, AssetEntity a, bool isSelected) { - print('Asset title: ${a.title}'); + debugPrint('Asset title: ${a.title}'); return a.title?.endsWith('.gif') != true; }, ), diff --git a/example/lib/customs/custom_picker_page.dart b/example/lib/customs/custom_picker_page.dart index 852617f7..a136341d 100644 --- a/example/lib/customs/custom_picker_page.dart +++ b/example/lib/customs/custom_picker_page.dart @@ -9,8 +9,10 @@ import 'pickers/directory_file_asset_picker.dart'; import 'pickers/multi_tabs_assets_picker.dart'; class CustomPickersPage extends StatefulWidget { + const CustomPickersPage({super.key}); + @override - _CustomPickerPageState createState() => _CustomPickerPageState(); + State createState() => _CustomPickerPageState(); } class _CustomPickerPageState extends State @@ -68,10 +70,9 @@ class _CustomPickerPageState extends State } class _MethodListView extends StatelessWidget { - const _MethodListView({ - Key? key, - required this.pickMethods, - }) : super(key: key); + // TODO(Alex): Tracking if it's a false-positive: https://github.com/dart-lang/linter/issues/3386 + // ignore: unused_element + const _MethodListView({super.key, required this.pickMethods}); final List pickMethods; @@ -93,7 +94,7 @@ class _MethodListView extends StatelessWidget { child: Center( child: Text( model.icon, - style: const TextStyle(fontSize: 24.0), + style: const TextStyle(fontSize: 28.0), ), ), ), diff --git a/example/lib/customs/pickers/directory_file_asset_picker.dart b/example/lib/customs/pickers/directory_file_asset_picker.dart index 32197bb6..b7fefb6e 100644 --- a/example/lib/customs/pickers/directory_file_asset_picker.dart +++ b/example/lib/customs/pickers/directory_file_asset_picker.dart @@ -29,10 +29,10 @@ const List imagesExtensions = [ ]; class DirectoryFileAssetPicker extends StatefulWidget { - const DirectoryFileAssetPicker({Key? key}) : super(key: key); + const DirectoryFileAssetPicker({super.key}); @override - _DirectoryFileAssetPickerState createState() => + State createState() => _DirectoryFileAssetPickerState(); } @@ -261,7 +261,7 @@ class _DirectoryFileAssetPickerState extends State { 'This is a custom picker built for `File`.\n' 'By browsing this picker, we want you to know that ' 'you can build your own picker components using ' - 'the entity\'s type you desired.', + "the entity's type you desired.", ), paddingText( 'In this page, picker will grab files from ' @@ -343,14 +343,14 @@ class FileAssetPickerProvider extends AssetPickerProvider { @override void unSelectAsset(File item) { - final List _set = List.from(selectedAssets); - _set.removeWhere((File f) => f.path == item.path); - selectedAssets = _set; + final List set = List.from(selectedAssets); + set.removeWhere((File f) => f.path == item.path); + selectedAssets = set; } @override Future loadMoreAssets() { - return Future.value(null); + return Future.value(); } @override @@ -369,8 +369,8 @@ class FileAssetPickerBuilder extends AssetPickerBuilderDelegate { FileAssetPickerBuilder({ required this.provider, - Locale? locale, - }) : super(initialPermission: PermissionState.authorized, locale: locale); + super.locale, + }) : super(initialPermission: PermissionState.authorized); final FileAssetPickerProvider provider; @@ -595,13 +595,13 @@ class FileAssetPickerBuilder return LayoutBuilder( builder: (BuildContext c, BoxConstraints constraints) { - final double _itemSize = constraints.maxWidth / gridCount; + final double itemSize = constraints.maxWidth / gridCount; // Use [ScrollView.anchor] to determine where is the first place of // the [SliverGrid]. Each row needs [dividedSpacing] to calculate, // then minus one times of [itemSpacing] because spacing's count in the // cross axis is always less than the rows. final double anchor = math.min( - (row * (_itemSize + dividedSpacing) + topPadding - itemSpacing) / + (row * (itemSize + dividedSpacing) + topPadding - itemSpacing) / constraints.maxHeight, 1, ); @@ -735,6 +735,12 @@ class FileAssetPickerBuilder shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3.0), ), + onPressed: () { + if (provider.isSelectedNotEmpty) { + Navigator.of(context).pop(provider.selectedAssets); + } + }, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: Text( provider.isSelectedNotEmpty && !isSingleAssetMode ? '${textDelegate.confirm}' @@ -748,12 +754,6 @@ class FileAssetPickerBuilder fontWeight: FontWeight.normal, ), ), - onPressed: () { - if (provider.isSelectedNotEmpty) { - Navigator.of(context).pop(provider.selectedAssets); - } - }, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); }, ), @@ -908,7 +908,6 @@ class FileAssetPickerBuilder builder: (_, bool isSwitchingPath, Widget? w) { return Transform.rotate( angle: isSwitchingPath ? math.pi : 0.0, - alignment: Alignment.center, child: w, ); }, @@ -1183,7 +1182,7 @@ class FileAssetPickerBuilder } class FileAssetPickerViewerProvider extends AssetPickerViewerProvider { - FileAssetPickerViewerProvider(List assets) : super(assets); + FileAssetPickerViewerProvider(List super.assets); @override void unSelectAssetEntity(File entity) { @@ -1196,19 +1195,13 @@ class FileAssetPickerViewerProvider extends AssetPickerViewerProvider { class FileAssetPickerViewerBuilderDelegate extends AssetPickerViewerBuilderDelegate { FileAssetPickerViewerBuilderDelegate({ - required List previewAssets, - required ThemeData themeData, - required int currentIndex, - List? selectedAssets, - AssetPickerProvider? selectorProvider, - AssetPickerViewerProvider? provider, + required super.previewAssets, + required super.themeData, + required super.currentIndex, + super.selectedAssets, + super.selectorProvider, + super.provider, }) : super( - provider: provider, - previewAssets: previewAssets, - themeData: themeData, - currentIndex: currentIndex, - selectedAssets: selectedAssets, - selectorProvider: selectorProvider, maxAssets: selectorProvider?.maxAssets, ); @@ -1417,7 +1410,6 @@ class FileAssetPickerViewerBuilderDelegate currentIndex = index; pageStreamController.add(index); }, - scrollDirection: Axis.horizontal, ), ), appBar(context), @@ -1450,6 +1442,12 @@ class FileAssetPickerViewerBuilderDelegate shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3.0), ), + onPressed: () { + if (provider.isSelectedNotEmpty) { + Navigator.of(context).pop(provider.currentlySelectedAssets); + } + }, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: Text( () { if (provider.isSelectedNotEmpty) { @@ -1470,12 +1468,6 @@ class FileAssetPickerViewerBuilderDelegate fontWeight: FontWeight.normal, ), ), - onPressed: () { - if (provider.isSelectedNotEmpty) { - Navigator.of(context).pop(provider.currentlySelectedAssets); - } - }, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); }, ), diff --git a/example/lib/customs/pickers/multi_tabs_assets_picker.dart b/example/lib/customs/pickers/multi_tabs_assets_picker.dart index 14a0fd18..934372c0 100644 --- a/example/lib/customs/pickers/multi_tabs_assets_picker.dart +++ b/example/lib/customs/pickers/multi_tabs_assets_picker.dart @@ -13,10 +13,10 @@ import 'package:wechat_assets_picker/wechat_assets_picker.dart'; const Color _themeColor = Color(0xfff2223a); class MultiTabAssetPicker extends StatefulWidget { - const MultiTabAssetPicker({Key? key}) : super(key: key); + const MultiTabAssetPicker({super.key}); @override - _MultiTabAssetPickerState createState() => _MultiTabAssetPickerState(); + State createState() => _MultiTabAssetPickerState(); } class _MultiTabAssetPickerState extends State { @@ -28,7 +28,7 @@ class _MultiTabAssetPickerState extends State { bool isDisplayingDetail = true; Future callPicker(BuildContext context) async { - final PermissionState _ps = await AssetPicker.permissionCheck(); + final PermissionState ps = await AssetPicker.permissionCheck(); final DefaultAssetPickerProvider provider = DefaultAssetPickerProvider( selectedAssets: entities, @@ -38,7 +38,6 @@ class _MultiTabAssetPickerState extends State { DefaultAssetPickerProvider( selectedAssets: entities, maxAssets: maxAssets, - requestType: RequestType.image, ); final DefaultAssetPickerProvider videosProvider = DefaultAssetPickerProvider( @@ -50,7 +49,7 @@ class _MultiTabAssetPickerState extends State { provider: provider, imagesProvider: imagesProvider, videosProvider: videosProvider, - initialPermission: _ps, + initialPermission: ps, pickerTheme: theme, locale: Localizations.maybeLocaleOf(context), ); @@ -261,25 +260,16 @@ class _MultiTabAssetPickerState extends State { class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { MultiTabAssetPickerBuilder({ - required DefaultAssetPickerProvider provider, + required super.provider, required this.videosProvider, required this.imagesProvider, - required PermissionState initialPermission, - int gridCount = 3, - ThemeData? pickerTheme, - Color? themeColor, - AssetPickerTextDelegate? textDelegate, - Locale? locale, - }) : super( - provider: provider, - initialPermission: initialPermission, - gridCount: gridCount, - pickerTheme: pickerTheme, - themeColor: themeColor, - textDelegate: textDelegate, - locale: locale, - shouldRevertGrid: false, - ); + required super.initialPermission, + super.gridCount = 3, + super.pickerTheme, + super.themeColor, + super.textDelegate, + super.locale, + }) : super(shouldRevertGrid: false); final DefaultAssetPickerProvider videosProvider; final DefaultAssetPickerProvider imagesProvider; @@ -300,7 +290,7 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { @override Widget pathEntitySelector(BuildContext context) { - final WidgetBuilder selector = (BuildContext context) { + Widget selector(BuildContext context) { return UnconstrainedBox( child: GestureDetector( onTap: () { @@ -351,7 +341,6 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { builder: (_, bool isSwitchingPath, Widget? w) { return Transform.rotate( angle: isSwitchingPath ? math.pi : 0, - alignment: Alignment.center, child: w, ); }, @@ -367,25 +356,26 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { ), ), ); - }; + } + return ChangeNotifierProvider.value( value: _tabController, builder: (_, __) => Selector( selector: (_, TabController p) => p.index, builder: (_, int index, __) { - final DefaultAssetPickerProvider _provider; + final DefaultAssetPickerProvider pickerProvider; switch (index) { case 1: - _provider = videosProvider; + pickerProvider = videosProvider; break; case 2: - _provider = imagesProvider; + pickerProvider = imagesProvider; break; default: - _provider = provider; + pickerProvider = provider; } return ChangeNotifierProvider.value( - value: _provider, + value: pickerProvider, builder: (BuildContext c, _) => selector(c), ); }, @@ -406,6 +396,10 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3), ), + onPressed: p.isSelectedNotEmpty + ? () => Navigator.of(context).maybePop(p.selectedAssets) + : null, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: Text( p.isSelectedNotEmpty && !isSingleAssetMode ? '${textDelegate.confirm}' @@ -419,10 +413,6 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { fontWeight: FontWeight.normal, ), ), - onPressed: p.isSelectedNotEmpty - ? () => Navigator.of(context).maybePop(p.selectedAssets) - : null, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); }, ); @@ -431,19 +421,19 @@ class MultiTabAssetPickerBuilder extends DefaultAssetPickerBuilderDelegate { builder: (_, __) => Selector( selector: (_, TabController p) => p.index, builder: (_, int index, __) { - final DefaultAssetPickerProvider _provider; + final DefaultAssetPickerProvider pickerProvider; switch (index) { case 1: - _provider = videosProvider; + pickerProvider = videosProvider; break; case 2: - _provider = imagesProvider; + pickerProvider = imagesProvider; break; default: - _provider = provider; + pickerProvider = provider; } return ChangeNotifierProvider.value( - value: _provider, + value: pickerProvider, builder: (_, __) => button, ); }, diff --git a/example/lib/main.dart b/example/lib/main.dart index e52ed6ca..53ba6925 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,7 +16,7 @@ const Color themeColor = Color(0xff00bc56); String? packageVersion; void main() { - runApp(MyApp()); + runApp(const MyApp()); SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle.dark.copyWith(statusBarColor: Colors.transparent), ); @@ -24,6 +24,8 @@ void main() { } class MyApp extends StatelessWidget { + const MyApp({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 664efa99..cc64c8b6 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -16,10 +16,10 @@ bool get currentIsDark => Screens.mediaQuery.platformBrightness == Brightness.dark; class HomePage extends StatefulWidget { - const HomePage({Key? key}) : super(key: key); + const HomePage({super.key}); @override - _HomePageState createState() => _HomePageState(); + State createState() => _HomePageState(); } class _HomePageState extends State { @@ -108,7 +108,7 @@ class _HomePageState extends State { Expanded( child: PageView( controller: controller, - children: [ + children: const [ MultiAssetsPage(), SingleAssetPage(), CustomPickersPage(), diff --git a/example/lib/pages/multi_assets_page.dart b/example/lib/pages/multi_assets_page.dart index 83225d77..d581c5da 100644 --- a/example/lib/pages/multi_assets_page.dart +++ b/example/lib/pages/multi_assets_page.dart @@ -9,8 +9,10 @@ import '../constants/page_mixin.dart'; import '../constants/picker_method.dart'; class MultiAssetsPage extends StatefulWidget { + const MultiAssetsPage({super.key}); + @override - _MultiAssetsPageState createState() => _MultiAssetsPageState(); + State createState() => _MultiAssetsPageState(); } class _MultiAssetsPageState extends State diff --git a/example/lib/pages/single_assets_page.dart b/example/lib/pages/single_assets_page.dart index d4b1078c..c733b8f2 100644 --- a/example/lib/pages/single_assets_page.dart +++ b/example/lib/pages/single_assets_page.dart @@ -10,8 +10,10 @@ import '../constants/page_mixin.dart'; import '../constants/picker_method.dart'; class SingleAssetPage extends StatefulWidget { + const SingleAssetPage({super.key}); + @override - _SingleAssetPageState createState() => _SingleAssetPageState(); + State createState() => _SingleAssetPageState(); } class _SingleAssetPageState extends State diff --git a/example/lib/pages/splash_page.dart b/example/lib/pages/splash_page.dart index a8cc6b9b..ea607130 100644 --- a/example/lib/pages/splash_page.dart +++ b/example/lib/pages/splash_page.dart @@ -9,10 +9,10 @@ import '../main.dart'; import 'home_page.dart'; class SplashPage extends StatefulWidget { - const SplashPage(); + const SplashPage({super.key}); @override - _SplashPageState createState() => _SplashPageState(); + State createState() => _SplashPageState(); } class _SplashPageState extends State { diff --git a/example/lib/widgets/asset_widget_builder.dart b/example/lib/widgets/asset_widget_builder.dart index 517b63a6..154fdc18 100644 --- a/example/lib/widgets/asset_widget_builder.dart +++ b/example/lib/widgets/asset_widget_builder.dart @@ -8,10 +8,10 @@ import 'package:wechat_assets_picker/wechat_assets_picker.dart' class AssetWidgetBuilder extends StatelessWidget { const AssetWidgetBuilder({ - Key? key, + super.key, required this.entity, required this.isDisplayingDetail, - }) : super(key: key); + }); final AssetEntity entity; final bool isDisplayingDetail; diff --git a/example/lib/widgets/method_list_view.dart b/example/lib/widgets/method_list_view.dart index 1d0f0c00..cc45ed77 100644 --- a/example/lib/widgets/method_list_view.dart +++ b/example/lib/widgets/method_list_view.dart @@ -8,16 +8,16 @@ import '../constants/picker_method.dart'; class MethodListView extends StatefulWidget { const MethodListView({ - Key? key, + super.key, required this.pickMethods, required this.onSelectMethod, - }) : super(key: key); + }); final List pickMethods; final void Function(PickMethod method) onSelectMethod; @override - _MethodListViewState createState() => _MethodListViewState(); + State createState() => _MethodListViewState(); } class _MethodListViewState extends State { @@ -42,7 +42,7 @@ class _MethodListViewState extends State { child: Center( child: Text( model.icon, - style: const TextStyle(fontSize: 24.0), + style: const TextStyle(fontSize: 28.0), ), ), ), @@ -84,7 +84,7 @@ class _MethodListViewState extends State { ).copyWith(bottom: 10.0), child: Scrollbar( controller: _controller, - isAlwaysShown: true, + thumbVisibility: true, radius: const Radius.circular(999), child: ListView.builder( controller: _controller, diff --git a/example/lib/widgets/selected_assets_list_view.dart b/example/lib/widgets/selected_assets_list_view.dart index 6f3b3e6a..d130cea6 100644 --- a/example/lib/widgets/selected_assets_list_view.dart +++ b/example/lib/widgets/selected_assets_list_view.dart @@ -11,12 +11,12 @@ import 'asset_widget_builder.dart'; class SelectedAssetsListView extends StatelessWidget { const SelectedAssetsListView({ - Key? key, + super.key, required this.assets, required this.isDisplayingDetail, required this.onResult, required this.onRemoveAsset, - }) : super(key: key); + }); final List assets; final ValueNotifier isDisplayingDetail; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bda83370..a8e98b6c 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,11 +1,11 @@ name: wechat_assets_picker_demo description: The demo project for the wechat_assets_picker package. -version: 7.2.0+16 +version: 7.3.0+17 publish_to: none environment: - sdk: '>=2.15.0 <3.0.0' - flutter: '>=2.8.0' + sdk: '>=2.17.0 <3.0.0' + flutter: '>=3.0.0' dependencies: flutter: @@ -15,10 +15,10 @@ dependencies: wechat_assets_picker: path: ../ - wechat_camera_picker: ^3.0.0 + wechat_camera_picker: ^3.2.0 meta: ^1.7.0 - package_info_plus: ^1.3.0 + package_info_plus: ^1.4.2 path: ^1.8.0 path_provider: ^2.0.8 provider: ^6.0.2 diff --git a/lib/src/constants/custom_scroll_physics.dart b/lib/src/constants/custom_scroll_physics.dart index 148d245b..9acf2387 100644 --- a/lib/src/constants/custom_scroll_physics.dart +++ b/lib/src/constants/custom_scroll_physics.dart @@ -7,8 +7,8 @@ import 'package:flutter/physics.dart'; class CustomBouncingScrollPhysics extends BouncingScrollPhysics { const CustomBouncingScrollPhysics({ - ScrollPhysics? parent, - }) : super(parent: parent); + super.parent, + }); @override CustomBouncingScrollPhysics applyTo(ScrollPhysics? ancestor) { @@ -27,8 +27,8 @@ class CustomBouncingScrollPhysics extends BouncingScrollPhysics { class CustomClampingScrollPhysics extends ClampingScrollPhysics { const CustomClampingScrollPhysics({ - ScrollPhysics? parent, - }) : super(parent: parent); + super.parent, + }); @override CustomClampingScrollPhysics applyTo(ScrollPhysics? ancestor) { diff --git a/lib/src/delegates/asset_picker_builder_delegate.dart b/lib/src/delegates/asset_picker_builder_delegate.dart index 0402fe75..aa26c9c5 100644 --- a/lib/src/delegates/asset_picker_builder_delegate.dart +++ b/lib/src/delegates/asset_picker_builder_delegate.dart @@ -10,7 +10,6 @@ import 'dart:ui' as ui; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; import 'package:flutter/semantics.dart'; import 'package:flutter/services.dart'; import 'package:photo_manager/photo_manager.dart'; @@ -461,14 +460,14 @@ abstract class AssetPickerBuilderDelegate { /// By default, the direction will be reversed if it's iOS/macOS. /// 默认情况下,在 iOS/macOS 上方向会反向。 TextDirection effectiveGridDirection(BuildContext context) { - final TextDirection _od = Directionality.of(context); + final TextDirection od = Directionality.of(context); if (effectiveShouldRevertGrid) { - if (_od == TextDirection.ltr) { + if (od == TextDirection.ltr) { return TextDirection.rtl; } return TextDirection.ltr; } - return _od; + return od; } /// The tip widget displays when the access is limited. @@ -561,7 +560,7 @@ abstract class AssetPickerBuilderDelegate { /// The overlay when the permission is limited on iOS. Widget iOSPermissionOverlay(BuildContext context) { final Size size = context.mediaQuery.size; - final Widget _closeButton = Container( + final Widget closeButton = Container( margin: const EdgeInsetsDirectional.only(start: 16, top: 4), alignment: AlignmentDirectional.centerStart, child: IconButton( @@ -573,7 +572,7 @@ abstract class AssetPickerBuilderDelegate { ), ); - final Widget _limitedTips = Padding( + final Widget limitedTips = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -595,7 +594,7 @@ abstract class AssetPickerBuilderDelegate { ), ); - final Widget _goToSettingsButton = MaterialButton( + final Widget goToSettingsButton = MaterialButton( elevation: 0, minWidth: size.width / 2, height: appBarItemHeight * 1.25, @@ -604,16 +603,16 @@ abstract class AssetPickerBuilderDelegate { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), + onPressed: PhotoManager.openSetting, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: ScaleText( textDelegate.goToSystemSettings, style: const TextStyle(fontSize: 17), semanticsLabel: semanticsTextDelegate.goToSystemSettings, ), - onPressed: PhotoManager.openSetting, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); - final Widget _accessLimitedButton = GestureDetector( + final Widget accessLimitedButton = GestureDetector( onTap: () => permissionOverlayDisplay.value = false, child: ScaleText( textDelegate.accessLimitedAssets, @@ -637,11 +636,11 @@ abstract class AssetPickerBuilderDelegate { color: context.themeData.canvasColor, child: Column( children: [ - _closeButton, - Expanded(child: _limitedTips), - _goToSettingsButton, + closeButton, + Expanded(child: limitedTips), + goToSettingsButton, SizedBox(height: size.height / 18), - _accessLimitedButton, + accessLimitedButton, ], ), ), @@ -656,38 +655,24 @@ class DefaultAssetPickerBuilderDelegate extends AssetPickerBuilderDelegate { DefaultAssetPickerBuilderDelegate({ required this.provider, - required PermissionState initialPermission, - int gridCount = 4, - ThemeData? pickerTheme, - SpecialItemPosition specialItemPosition = SpecialItemPosition.none, - SpecialItemBuilder? specialItemBuilder, - LoadingIndicatorBuilder? loadingIndicatorBuilder, - AssetSelectPredicate? selectPredicate, - bool? shouldRevertGrid, - LimitedPermissionOverlayPredicate? limitedPermissionOverlayPredicate, - PathNameBuilder? pathNameBuilder, + required super.initialPermission, + super.gridCount, + super.pickerTheme, + super.specialItemPosition, + super.specialItemBuilder, + super.loadingIndicatorBuilder, + super.selectPredicate, + super.shouldRevertGrid, + super.limitedPermissionOverlayPredicate, + super.pathNameBuilder, + super.themeColor, + super.textDelegate, + super.locale, this.gridThumbnailSize = defaultAssetGridPreviewSize, this.previewThumbnailSize, this.specialPickerType, this.keepScrollOffset = false, - Color? themeColor, - AssetPickerTextDelegate? textDelegate, - Locale? locale, - }) : super( - initialPermission: initialPermission, - gridCount: gridCount, - pickerTheme: pickerTheme, - specialItemPosition: specialItemPosition, - specialItemBuilder: specialItemBuilder, - loadingIndicatorBuilder: loadingIndicatorBuilder, - selectPredicate: selectPredicate, - shouldRevertGrid: shouldRevertGrid, - limitedPermissionOverlayPredicate: limitedPermissionOverlayPredicate, - pathNameBuilder: pathNameBuilder, - themeColor: themeColor, - textDelegate: textDelegate, - locale: locale, - ) { + }) { // Add the listener if [keepScrollOffset] is true. if (keepScrollOffset) { gridScrollController.addListener(keepScrollOffsetListener); @@ -815,7 +800,7 @@ class DefaultAssetPickerBuilderDelegate if (!isPermissionLimited) { return; } - final AssetPathEntity? _currentPathEntity = provider.currentPath; + final AssetPathEntity? currentPathEntity = provider.currentPath; if (call.arguments is Map) { final Map arguments = call.arguments as Map; @@ -827,13 +812,13 @@ class DefaultAssetPickerBuilderDelegate ..isAssetsEmpty = true; return; } - if (_currentPathEntity == null) { + if (currentPathEntity == null) { await provider.getPaths(); } } - if (_currentPathEntity != null) { + if (currentPathEntity != null) { final AssetPathEntity newPath = - await _currentPathEntity.obtainForNewProperties(); + await currentPathEntity.obtainForNewProperties(); provider ..currentPath = newPath ..hasAssetsToDisplay = newPath.assetCount != 0 @@ -868,34 +853,34 @@ class DefaultAssetPickerBuilderDelegate if (selectedAllAndNotSelected() || selectedPhotosAndIsVideo()) { return; } - final List _current; - final List? _selected; - final int _index; + final List current; + final List? selected; + final int effectiveIndex; if (isWeChatMoment) { if (asset.type == AssetType.video) { - _current = [asset]; - _selected = null; - _index = 0; + current = [asset]; + selected = null; + effectiveIndex = 0; } else { - _current = provider.currentAssets + current = provider.currentAssets .where((AssetEntity e) => e.type == AssetType.image) .toList(); - _selected = provider.selectedAssets; - _index = _current.indexOf(asset); + selected = provider.selectedAssets; + effectiveIndex = current.indexOf(asset); } } else { - _current = provider.currentAssets; - _selected = provider.selectedAssets; - _index = index; + current = provider.currentAssets; + selected = provider.selectedAssets; + effectiveIndex = index; } final List? result = await AssetPickerViewer.pushToViewer( context, - currentIndex: _index, - previewAssets: _current, + currentIndex: effectiveIndex, + previewAssets: current, themeData: theme, previewThumbnailSize: previewThumbnailSize, selectPredicate: selectPredicate, - selectedAssets: _selected, + selectedAssets: selected, selectorProvider: provider, specialPickerType: specialPickerType, maxAssets: provider.maxAssets, @@ -994,11 +979,11 @@ class DefaultAssetPickerBuilderDelegate Positioned.fill( child: Consumer( builder: (_, DefaultAssetPickerProvider p, __) { - final Widget _child; + final Widget child; final bool shouldDisplayAssets = p.hasAssetsToDisplay || shouldBuildSpecialItem; if (shouldDisplayAssets) { - _child = Stack( + child = Stack( children: [ _gridLayout(context), pathEntityListBackdrop(context), @@ -1006,11 +991,11 @@ class DefaultAssetPickerBuilderDelegate ], ); } else { - _child = loadingIndicator(context); + child = loadingIndicator(context); } return AnimatedSwitcher( duration: switchingPathDuration, - child: _child, + child: child, ); }, ), @@ -1039,21 +1024,21 @@ class DefaultAssetPickerBuilderDelegate builder: (BuildContext context, AssetPathEntity? path, __) { // First, we need the count of the assets. int totalCount = path?.assetCount ?? 0; - final Widget? _specialItem; + final Widget? specialItem; // If user chose a special item's position, add 1 count. if (specialItemPosition != SpecialItemPosition.none) { - _specialItem = specialItemBuilder?.call( + specialItem = specialItemBuilder?.call( context, path, totalCount, ); - if (_specialItem != null) { + if (specialItem != null) { totalCount += 1; } } else { - _specialItem = null; + specialItem = null; } - if (totalCount == 0 && _specialItem == null) { + if (totalCount == 0 && specialItem == null) { return loadingIndicatorBuilder?.call(context, true) ?? Center(child: emptyIndicator(context)); } @@ -1093,7 +1078,7 @@ class DefaultAssetPickerBuilderDelegate context, index, assets, - specialItem: _specialItem, + specialItem: specialItem, ), ), ); @@ -1103,7 +1088,7 @@ class DefaultAssetPickerBuilderDelegate context: context, assets: assets, placeholderCount: placeholderCount, - specialItem: _specialItem, + specialItem: specialItem, ), findChildIndexCallback: (Key? key) { if (key is ValueKey) { @@ -1160,7 +1145,7 @@ class DefaultAssetPickerBuilderDelegate selector: (_, DefaultAssetPickerProvider p) => p.currentAssets, builder: (_, List assets, __) { - final SliverGap _bottomGap = SliverGap.v( + final SliverGap bottomGap = SliverGap.v( context.bottomPadding + bottomSectionHeight, ); return CustomScrollView( @@ -1173,14 +1158,13 @@ class DefaultAssetPickerBuilderDelegate SliverGap.v(context.topPadding + kToolbarHeight), _sliverGrid(_, assets), // Ignore the gap when the [anchor] is not equal to 1. - if (effectiveShouldRevertGrid && anchor == 1) - _bottomGap, + if (effectiveShouldRevertGrid && anchor == 1) bottomGap, if (effectiveShouldRevertGrid) SliverToBoxAdapter( key: gridRevertKey, child: const SizedBox.shrink(), ), - if (isAppleOS && !effectiveShouldRevertGrid) _bottomGap, + if (isAppleOS && !effectiveShouldRevertGrid) bottomGap, ], ); }, @@ -1213,7 +1197,7 @@ class DefaultAssetPickerBuilderDelegate List currentAssets, { Widget? specialItem, }) { - final int _length = currentAssets.length; + final int length = currentAssets.length; final AssetPathEntity? currentPathEntity = context.select( (DefaultAssetPickerProvider p) => p.currentPath, @@ -1221,7 +1205,7 @@ class DefaultAssetPickerBuilderDelegate if (specialItem != null) { if ((index == 0 && specialItemPosition == SpecialItemPosition.prepend) || - (index == _length && + (index == length && specialItemPosition == SpecialItemPosition.append)) { return specialItem; } @@ -1242,7 +1226,7 @@ class DefaultAssetPickerBuilderDelegate final bool hasMoreToLoad = context.select( (DefaultAssetPickerProvider p) => p.hasMoreToLoad, ); - if (index == _length - gridCount * 3 && hasMoreToLoad) { + if (index == length - gridCount * 3 && hasMoreToLoad) { context.read().loadMoreAssets(); } @@ -1260,7 +1244,7 @@ class DefaultAssetPickerBuilderDelegate builder = const SizedBox.shrink(); break; } - final Widget _content = Stack( + final Widget content = Stack( key: ValueKey(asset.id), children: [ builder, @@ -1270,7 +1254,7 @@ class DefaultAssetPickerBuilderDelegate itemBannedIndicator(context, asset), ], ); - return assetGridItemSemanticsBuilder(context, index, asset, _content); + return assetGridItemSemanticsBuilder(context, index, asset, content); } int semanticIndex(int index) { @@ -1309,7 +1293,7 @@ class DefaultAssetPickerBuilderDelegate asset.videoDuration, ); } - if (asset.title?.isNotEmpty == true) { + if (asset.title?.isNotEmpty ?? false) { hint += ', ${asset.title}'; } return Semantics( @@ -1380,7 +1364,7 @@ class DefaultAssetPickerBuilderDelegate context.select( (DefaultAssetPickerProvider p) => p.currentPath, ); - final int _length = assets.length + placeholderCount; + final int length = assets.length + placeholderCount; // Return 1 if the [specialItem] build something. if (currentPathEntity == null && specialItem != null) { @@ -1390,14 +1374,14 @@ class DefaultAssetPickerBuilderDelegate // Return actual length if the current path is all. // 如果当前目录是全部内容,则返回实际的内容数量。 if (currentPathEntity?.isAll != true) { - return _length; + return length; } switch (specialItemPosition) { case SpecialItemPosition.none: - return _length; + return length; case SpecialItemPosition.prepend: case SpecialItemPosition.append: - return _length + 1; + return length + 1; } } @@ -1480,6 +1464,10 @@ class DefaultAssetPickerBuilderDelegate shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3), ), + onPressed: p.isSelectedNotEmpty + ? () => Navigator.of(context).maybePop(p.selectedAssets) + : null, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: ScaleText( p.isSelectedNotEmpty && !isSingleAssetMode ? '${textDelegate.confirm}' @@ -1497,10 +1485,6 @@ class DefaultAssetPickerBuilderDelegate ' (${p.selectedAssets.length}/${p.maxAssets})' : semanticsTextDelegate.confirm, ), - onPressed: p.isSelectedNotEmpty - ? () => Navigator.of(context).maybePop(p.selectedAssets) - : null, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); }, ); @@ -1776,7 +1760,6 @@ class DefaultAssetPickerBuilderDelegate builder: (_, bool isSwitchingPath, Widget? w) { return Transform.rotate( angle: isSwitchingPath ? math.pi : 0, - alignment: Alignment.center, child: w, ); }, @@ -1919,22 +1902,21 @@ class DefaultAssetPickerBuilderDelegate Future _onTap() async { final DefaultAssetPickerProvider p = context.read(); - final List _selectedAssets = p.selectedAssets; - final List _selected; + final List selectedAssets = p.selectedAssets; + final List selected; if (isWeChatMoment) { - _selected = _selectedAssets + selected = selectedAssets .where((AssetEntity e) => e.type == AssetType.image) .toList(); } else { - _selected = _selectedAssets; + selected = selectedAssets; } final List? result = await AssetPickerViewer.pushToViewer( context, - currentIndex: 0, - previewAssets: _selected, + previewAssets: selected, previewThumbnailSize: previewThumbnailSize, selectPredicate: selectPredicate, - selectedAssets: _selected, + selectedAssets: selected, selectorProvider: provider, themeData: theme, maxAssets: p.maxAssets, @@ -2131,7 +2113,6 @@ class DefaultAssetPickerBuilderDelegate ), ), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, children: [ const Icon(Icons.videocam, size: 22, color: Colors.white), Expanded( @@ -2166,7 +2147,7 @@ class DefaultAssetPickerBuilderDelegate // Schedule the scroll position's restoration callback if this feature // is enabled and offsets are different. if (keepScrollOffset && Singleton.scrollPosition != null) { - SchedulerBinding.instance!.addPostFrameCallback((_) { + WidgetsBinding.instance.addPostFrameCallback((_) { // Update only if the controller has clients. if (gridScrollController.hasClients) { gridScrollController.jumpTo(Singleton.scrollPosition!.pixels); diff --git a/lib/src/delegates/asset_picker_delegate.dart b/lib/src/delegates/asset_picker_delegate.dart index ebcd37a2..c4c59720 100644 --- a/lib/src/delegates/asset_picker_delegate.dart +++ b/lib/src/delegates/asset_picker_delegate.dart @@ -33,11 +33,11 @@ class AssetPickerDelegate { /// * [PermissionState] which defined all states of required permissions. /// {@endtemplate} Future permissionCheck() async { - final PermissionState _ps = await PhotoManager.requestPermissionExtend(); - if (_ps != PermissionState.authorized && _ps != PermissionState.limited) { - throw StateError('Permission state error with $_ps.'); + final PermissionState ps = await PhotoManager.requestPermissionExtend(); + if (ps != PermissionState.authorized && ps != PermissionState.limited) { + throw StateError('Permission state error with $ps.'); } - return _ps; + return ps; } /// {@template wechat_assets_picker.delegates.AssetPickerDelegate.pickAssets} @@ -66,7 +66,7 @@ class AssetPickerDelegate { bool useRootNavigator = true, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) async { - final PermissionState _ps = await permissionCheck(); + final PermissionState ps = await permissionCheck(); final DefaultAssetPickerProvider provider = DefaultAssetPickerProvider( maxAssets: pickerConfig.maxAssets, pageSize: pickerConfig.pageSize, @@ -80,7 +80,7 @@ class AssetPickerDelegate { key: Singleton.pickerKey, builder: DefaultAssetPickerBuilderDelegate( provider: provider, - initialPermission: _ps, + initialPermission: ps, gridCount: pickerConfig.gridCount, pickerTheme: pickerConfig.pickerTheme, gridThumbnailSize: pickerConfig.gridThumbnailSize, @@ -221,7 +221,7 @@ class AssetPickerDelegate { buttonTheme: ButtonThemeData(buttonColor: themeColor), colorScheme: ColorScheme( primary: Colors.grey[50]!, - primaryVariant: Colors.grey[50]!, + primaryVariant: Colors.grey[50], secondary: themeColor, secondaryVariant: themeColor, background: Colors.grey[50]!, @@ -262,7 +262,7 @@ class AssetPickerDelegate { buttonTheme: ButtonThemeData(buttonColor: themeColor), colorScheme: ColorScheme( primary: Colors.grey[900]!, - primaryVariant: Colors.grey[900]!, + primaryVariant: Colors.grey[900], secondary: themeColor, secondaryVariant: themeColor, background: Colors.grey[900]!, diff --git a/lib/src/delegates/asset_picker_text_delegate.dart b/lib/src/delegates/asset_picker_text_delegate.dart index 53a8bbe6..3e738979 100644 --- a/lib/src/delegates/asset_picker_text_delegate.dart +++ b/lib/src/delegates/asset_picker_text_delegate.dart @@ -786,7 +786,7 @@ class FrenchAssetPickerTextDelegate extends AssetPickerTextDelegate { @override String get unableToAccessAll => - 'Impossible d\'accéder aux médias de votre appareil'; + "Impossible d'accéder aux médias de votre appareil"; @override String get viewingLimitedAssetsTip => diff --git a/lib/src/delegates/asset_picker_viewer_builder_delegate.dart b/lib/src/delegates/asset_picker_viewer_builder_delegate.dart index 94ea49aa..bec3a0e0 100644 --- a/lib/src/delegates/asset_picker_viewer_builder_delegate.dart +++ b/lib/src/delegates/asset_picker_viewer_builder_delegate.dart @@ -303,22 +303,17 @@ abstract class AssetPickerViewerBuilderDelegate { ExtendedImageState state, { bool hasLoaded = false, }) { - Widget loader; switch (state.extendedImageLoadState) { case LoadState.completed: - loader = state.completedWidget; - if (!hasLoaded) { - loader = FadeImageBuilder(child: loader); + if (hasLoaded) { + return state.completedWidget; } - break; + return FadeImageBuilder(child: state.completedWidget); case LoadState.failed: - loader = failedItemBuilder(context); - break; - default: - loader = const SizedBox.shrink(); - break; + return failedItemBuilder(context); + case LoadState.loading: + return const SizedBox.shrink(); } - return loader; } /// The item widget when [AssetEntity.thumbnailData] load failed. @@ -358,28 +353,18 @@ abstract class AssetPickerViewerBuilderDelegate { class DefaultAssetPickerViewerBuilderDelegate extends AssetPickerViewerBuilderDelegate { DefaultAssetPickerViewerBuilderDelegate({ - required int currentIndex, - required List previewAssets, - AssetPickerProvider? selectorProvider, - required ThemeData themeData, - AssetPickerViewerProvider? provider, - List? selectedAssets, + required super.currentIndex, + required super.previewAssets, + required super.themeData, + super.selectorProvider, + super.provider, + super.selectedAssets, this.previewThumbnailSize, this.specialPickerType, - int? maxAssets, - bool shouldReversePreview = false, - AssetSelectPredicate? selectPredicate, - }) : super( - currentIndex: currentIndex, - previewAssets: previewAssets, - provider: provider, - themeData: themeData, - selectedAssets: selectedAssets, - selectorProvider: selectorProvider, - maxAssets: maxAssets, - shouldReversePreview: shouldReversePreview, - selectPredicate: selectPredicate, - ); + super.maxAssets, + super.shouldReversePreview, + super.selectPredicate, + }); /// Thumb size for the preview of images in the viewer. /// 预览时图片的缩略图大小 @@ -407,27 +392,27 @@ class DefaultAssetPickerViewerBuilderDelegate @override Widget assetPageBuilder(BuildContext context, int index) { final AssetEntity asset = previewAssets.elementAt(index); - final Widget _builder; + final Widget builder; switch (asset.type) { case AssetType.audio: - _builder = AudioPageBuilder(asset: asset); + builder = AudioPageBuilder(asset: asset); break; case AssetType.image: - _builder = ImagePageBuilder( + builder = ImagePageBuilder( asset: asset, delegate: this, previewThumbnailSize: previewThumbnailSize, ); break; case AssetType.video: - _builder = VideoPageBuilder( + builder = VideoPageBuilder( asset: asset, delegate: this, hasOnlyOneVideoAndMoment: isWeChatMoment && hasVideo, ); break; case AssetType.other: - _builder = Center( + builder = Center( child: ScaleText( textDelegate.unSupportedAssetType, semanticsLabel: semanticsTextDelegate.unSupportedAssetType, @@ -443,14 +428,14 @@ class DefaultAssetPickerViewerBuilderDelegate Widget? w, ) { final bool isSelected = - (p?.currentlySelectedAssets ?? selectedAssets)?.contains(asset) == - true; + (p?.currentlySelectedAssets ?? selectedAssets)?.contains(asset) ?? + false; String hint = ''; if (asset.type == AssetType.audio || asset.type == AssetType.video) { hint += '${semanticsTextDelegate.sNameDurationLabel}: '; hint += textDelegate.durationIndicatorBuilder(asset.videoDuration); } - if (asset.title?.isNotEmpty == true) { + if (asset.title?.isNotEmpty ?? false) { hint += ', ${asset.title}'; } return Semantics( @@ -464,7 +449,7 @@ class DefaultAssetPickerViewerBuilderDelegate child: w, ); }, - child: _builder, + child: builder, ), ); } @@ -541,7 +526,7 @@ class DefaultAssetPickerViewerBuilderDelegate @override Widget bottomDetailBuilder(BuildContext context) { - final Color _backgroundColor = themeData.primaryColor.withOpacity(.9); + final Color backgroundColor = themeData.primaryColor.withOpacity(.9); return ValueListenableBuilder2( firstNotifier: isDisplayingDetail, secondNotifier: selectedNotifier, @@ -566,7 +551,7 @@ class DefaultAssetPickerViewerBuilderDelegate builder: (_, int count, __) => Container( width: count > 0 ? double.maxFinite : 0, height: bottomPreviewHeight, - color: _backgroundColor, + color: backgroundColor, child: ListView.builder( controller: previewingListController, scrollDirection: Axis.horizontal, @@ -582,13 +567,8 @@ class DefaultAssetPickerViewerBuilderDelegate padding: const EdgeInsets.symmetric(horizontal: 20.0) .copyWith(bottom: context.bottomPadding), decoration: BoxDecoration( - border: Border( - top: BorderSide( - width: 1.0, - color: themeData.canvasColor, - ), - ), - color: _backgroundColor, + border: Border(top: BorderSide(color: themeData.canvasColor)), + color: backgroundColor, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -645,7 +625,7 @@ class DefaultAssetPickerViewerBuilderDelegate builder: (_, AsyncSnapshot snapshot) { final AssetEntity asset = selectedAssets!.elementAt(index); final bool isViewing = previewAssets[snapshot.data!] == asset; - final Widget _item = () { + final Widget item = () { switch (asset.type) { case AssetType.image: return _imagePreviewItem(asset); @@ -653,7 +633,7 @@ class DefaultAssetPickerViewerBuilderDelegate return _videoPreviewItem(asset); case AssetType.audio: return _audioPreviewItem(asset); - default: + case AssetType.other: return const SizedBox.shrink(); } }(); @@ -670,7 +650,7 @@ class DefaultAssetPickerViewerBuilderDelegate List?>( selector: (_, AssetPickerViewerProvider? p) => p?.currentlySelectedAssets, - child: _item, + child: item, builder: ( _, List? currentlySelectedAssets, @@ -807,7 +787,7 @@ class DefaultAssetPickerViewerBuilderDelegate builder: (_, AssetPickerViewerProvider? provider, __) { assert( isWeChatMoment || provider != null, - 'Viewer provider must not be null' + 'Viewer provider must not be null ' 'when the special type is not WeChat moment.', ); return MaterialButton( @@ -823,6 +803,21 @@ class DefaultAssetPickerViewerBuilderDelegate shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3.0), ), + onPressed: () { + if (isWeChatMoment && hasVideo) { + Navigator.of(context).pop([currentAsset]); + return; + } + if (provider!.isSelectedNotEmpty) { + Navigator.of(context).pop(provider.currentlySelectedAssets); + return; + } + selectAsset(currentAsset); + Navigator.of(context).pop( + selectedAssets ?? [currentAsset], + ); + }, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: ScaleText( () { if (isWeChatMoment && hasVideo) { @@ -854,21 +849,6 @@ class DefaultAssetPickerViewerBuilderDelegate return semanticsTextDelegate.confirm; }(), ), - onPressed: () { - if (isWeChatMoment && hasVideo) { - Navigator.of(context).pop([currentAsset]); - return; - } - if (provider!.isSelectedNotEmpty) { - Navigator.of(context).pop(provider.currentlySelectedAssets); - return; - } - selectAsset(currentAsset); - Navigator.of(context).pop( - selectedAssets ?? [currentAsset], - ); - }, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ); }, ), @@ -985,7 +965,6 @@ class DefaultAssetPickerViewerBuilderDelegate currentIndex = index; pageStreamController.add(index); }, - scrollDirection: Axis.horizontal, ), ); } diff --git a/lib/src/provider/asset_picker_provider.dart b/lib/src/provider/asset_picker_provider.dart index 58a29589..1987f453 100644 --- a/lib/src/provider/asset_picker_provider.dart +++ b/lib/src/provider/asset_picker_provider.dart @@ -26,7 +26,7 @@ abstract class AssetPickerProvider extends ChangeNotifier { this.pathThumbnailSize = defaultPathThumbnailSize, List? selectedAssets, }) { - if (selectedAssets?.isNotEmpty == true) { + if (selectedAssets?.isNotEmpty ?? false) { _selectedAssets = List.from(selectedAssets!); } } @@ -212,36 +212,31 @@ abstract class AssetPickerProvider extends ChangeNotifier { if (selectedAssets.length == maxAssets || selectedAssets.contains(item)) { return; } - final List _set = List.from(selectedAssets); - _set.add(item); - selectedAssets = _set; + final List set = List.from(selectedAssets); + set.add(item); + selectedAssets = set; } /// Un-select asset. /// 取消选中资源 void unSelectAsset(Asset item) { - final List _set = List.from(selectedAssets); - _set.remove(item); - selectedAssets = _set; + final List set = List.from(selectedAssets); + set.remove(item); + selectedAssets = set; } } class DefaultAssetPickerProvider extends AssetPickerProvider { DefaultAssetPickerProvider({ - List? selectedAssets, + super.selectedAssets, + super.maxAssets, + super.pageSize, + super.pathThumbnailSize, this.requestType = RequestType.image, this.sortPathDelegate = SortPathDelegate.common, this.filterOptions, - int maxAssets = 9, - int pageSize = 80, - ThumbnailSize pathThumbnailSize = const ThumbnailSize.square(80), - }) : super( - maxAssets: maxAssets, - pageSize: pageSize, - pathThumbnailSize: pathThumbnailSize, - selectedAssets: selectedAssets, - ) { + }) { Singleton.sortPathDelegate = sortPathDelegate ?? SortPathDelegate.common; // Call [getAssetList] with route duration when constructing. Future(() async { @@ -252,19 +247,14 @@ class DefaultAssetPickerProvider @visibleForTesting DefaultAssetPickerProvider.forTest({ - List? selectedAssets, + super.selectedAssets, this.requestType = RequestType.image, this.sortPathDelegate = SortPathDelegate.common, this.filterOptions, - int maxAssets = 9, - int pageSize = 80, - ThumbnailSize pathThumbnailSize = const ThumbnailSize.square(80), - }) : super( - maxAssets: maxAssets, - pageSize: pageSize, - pathThumbnailSize: pathThumbnailSize, - selectedAssets: selectedAssets, - ) { + super.maxAssets, + super.pageSize = 80, + super.pathThumbnailSize, + }) { Singleton.sortPathDelegate = sortPathDelegate ?? SortPathDelegate.common; } @@ -328,15 +318,15 @@ class DefaultAssetPickerProvider options.merge(filterOptions!); } - final List _list = await PhotoManager.getAssetPathList( + final List list = await PhotoManager.getAssetPathList( type: requestType, filterOption: options, ); // Sort path using sort path delegate. - Singleton.sortPathDelegate.sort(_list); + Singleton.sortPathDelegate.sort(list); - for (final AssetPathEntity pathEntity in _list) { + for (final AssetPathEntity pathEntity in list) { // Use sync method to avoid unnecessary wait. _pathsList[pathEntity] = null; getThumbnailFromPath(pathEntity); diff --git a/lib/src/widget/asset_picker.dart b/lib/src/widget/asset_picker.dart index 303a994a..4f236f2c 100644 --- a/lib/src/widget/asset_picker.dart +++ b/lib/src/widget/asset_picker.dart @@ -15,7 +15,7 @@ import 'asset_picker_page_route.dart'; AssetPickerDelegate _pickerDelegate = const AssetPickerDelegate(); class AssetPicker extends StatefulWidget { - const AssetPicker({Key? key, required this.builder}) : super(key: key); + const AssetPicker({super.key, required this.builder}); final AssetPickerBuilderDelegate builder; @@ -91,7 +91,7 @@ class AssetPickerState extends State> @override void initState() { super.initState(); - WidgetsBinding.instance!.addObserver(this); + WidgetsBinding.instance.addObserver(this); AssetPicker.registerObserve(_onLimitedAssetsUpdated); widget.builder.initState(this); } @@ -108,7 +108,7 @@ class AssetPickerState extends State> @override void dispose() { - WidgetsBinding.instance!.removeObserver(this); + WidgetsBinding.instance.removeObserver(this); AssetPicker.unregisterObserve(_onLimitedAssetsUpdated); widget.builder.dispose(); super.dispose(); diff --git a/lib/src/widget/asset_picker_app_bar.dart b/lib/src/widget/asset_picker_app_bar.dart index a2288bf7..d82d20af 100644 --- a/lib/src/widget/asset_picker_app_bar.dart +++ b/lib/src/widget/asset_picker_app_bar.dart @@ -12,7 +12,7 @@ import 'package:flutter/services.dart'; /// 自定义的顶栏 class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { const AssetPickerAppBar({ - Key? key, + super.key, this.automaticallyImplyLeading = true, this.automaticallyImplyActions = true, this.brightness, @@ -28,7 +28,7 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { this.blurRadius = 0, this.iconTheme, this.semanticsBuilder, - }) : super(key: key); + }); /// Title widget. Typically a [Text] widget. /// 标题部件 @@ -99,9 +99,9 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { - Widget? _title = title; + Widget? titleWidget = title; if (centerTitle) { - _title = Center(child: _title); + titleWidget = Center(child: title); } Widget child = Container( width: double.maxFinite, @@ -115,7 +115,7 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { bottom: 0.0, child: leading ?? const BackButton(), ), - if (_title != null) + if (titleWidget != null) PositionedDirectional( top: 0.0, bottom: 0.0, @@ -126,7 +126,6 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { ? Alignment.center : AlignmentDirectional.centerStart, child: DefaultTextStyle( - child: _title, style: Theme.of(context) .textTheme .headline6! @@ -134,6 +133,7 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { maxLines: 1, softWrap: false, overflow: TextOverflow.ellipsis, + child: titleWidget, ), ), ), @@ -168,11 +168,11 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { } // Set [SystemUiOverlayStyle] according to the brightness. - final Brightness _effectiveBrightness = brightness ?? + final Brightness effectiveBrightness = brightness ?? Theme.of(context).appBarTheme.systemOverlayStyle?.statusBarBrightness ?? Theme.of(context).brightness; child = AnnotatedRegion( - value: _effectiveBrightness == Brightness.dark + value: effectiveBrightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, child: Column( @@ -184,7 +184,7 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { ), ); - final Widget _result = Material( + final Widget result = Material( // Wrap to ensure the child rendered correctly color: Color.lerp( backgroundColor ?? Theme.of(context).colorScheme.surface, @@ -194,8 +194,8 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { elevation: elevation, child: child, ); - return semanticsBuilder?.call(_result) ?? - Semantics(sortKey: const OrdinalSortKey(0), child: _result); + return semanticsBuilder?.call(result) ?? + Semantics(sortKey: const OrdinalSortKey(0), child: result); } } @@ -203,10 +203,10 @@ class AssetPickerAppBar extends StatelessWidget implements PreferredSizeWidget { /// 顶栏封装。防止内容块层级高于顶栏导致遮挡阴影。 class AssetPickerAppBarWrapper extends StatelessWidget { const AssetPickerAppBarWrapper({ - Key? key, + super.key, required this.appBar, required this.body, - }) : super(key: key); + }); final AssetPickerAppBar appBar; final Widget body; diff --git a/lib/src/widget/asset_picker_viewer.dart b/lib/src/widget/asset_picker_viewer.dart index 280d717d..7372aa16 100644 --- a/lib/src/widget/asset_picker_viewer.dart +++ b/lib/src/widget/asset_picker_viewer.dart @@ -16,9 +16,9 @@ import 'asset_picker.dart'; class AssetPickerViewer extends StatefulWidget { const AssetPickerViewer({ - Key? key, + super.key, required this.builder, - }) : super(key: key); + }); final AssetPickerViewerBuilderDelegate builder; diff --git a/lib/src/widget/builder/asset_entity_grid_item_builder.dart b/lib/src/widget/builder/asset_entity_grid_item_builder.dart index 4e5fbf71..13eafcb7 100644 --- a/lib/src/widget/builder/asset_entity_grid_item_builder.dart +++ b/lib/src/widget/builder/asset_entity_grid_item_builder.dart @@ -11,10 +11,10 @@ import '../../widget/scale_text.dart'; class AssetEntityGridItemBuilder extends StatefulWidget { const AssetEntityGridItemBuilder({ - Key? key, + super.key, required this.image, required this.failedItemBuilder, - }) : super(key: key); + }); final AssetEntityImageProvider image; final WidgetBuilder failedItemBuilder; @@ -63,7 +63,6 @@ class AssetEntityGridItemWidgetState extends State { } @override - @mustCallSuper Widget build(BuildContext context) { child ??= newChild; return child!; diff --git a/lib/src/widget/builder/audio_page_builder.dart b/lib/src/widget/builder/audio_page_builder.dart index e685cc51..464d5fef 100644 --- a/lib/src/widget/builder/audio_page_builder.dart +++ b/lib/src/widget/builder/audio_page_builder.dart @@ -14,7 +14,7 @@ import '../../internal/singleton.dart'; import '../scale_text.dart'; class AudioPageBuilder extends StatefulWidget { - const AudioPageBuilder({Key? key, required this.asset}) : super(key: key); + const AudioPageBuilder({super.key, required this.asset}); /// Asset currently displayed. /// 展示的资源 diff --git a/lib/src/widget/builder/fade_image_builder.dart b/lib/src/widget/builder/fade_image_builder.dart index 0efe763f..2695e5d1 100644 --- a/lib/src/widget/builder/fade_image_builder.dart +++ b/lib/src/widget/builder/fade_image_builder.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; class FadeImageBuilder extends StatelessWidget { - const FadeImageBuilder({Key? key, required this.child}) : super(key: key); + const FadeImageBuilder({super.key, required this.child}); final Widget child; diff --git a/lib/src/widget/builder/image_page_builder.dart b/lib/src/widget/builder/image_page_builder.dart index 1f8fda7d..d75eb4ab 100644 --- a/lib/src/widget/builder/image_page_builder.dart +++ b/lib/src/widget/builder/image_page_builder.dart @@ -15,11 +15,11 @@ import 'locally_available_builder.dart'; class ImagePageBuilder extends StatefulWidget { const ImagePageBuilder({ - Key? key, + super.key, required this.asset, required this.delegate, this.previewThumbnailSize, - }) : super(key: key); + }); /// Asset currently displayed. /// 展示的资源 @@ -30,7 +30,7 @@ class ImagePageBuilder extends StatefulWidget { final ThumbnailSize? previewThumbnailSize; @override - _ImagePageBuilderState createState() => _ImagePageBuilderState(); + State createState() => _ImagePageBuilderState(); } class _ImagePageBuilderState extends State { @@ -73,7 +73,7 @@ class _ImagePageBuilderState extends State { } void _play() { - if (_controller?.value.isInitialized == true) { + if (_controller?.value.isInitialized ?? false) { // Only impact when initialized. HapticFeedback.lightImpact(); _controller?.play(); @@ -95,17 +95,13 @@ class _ImagePageBuilderState extends State { fit: BoxFit.contain, mode: ExtendedImageMode.gesture, onDoubleTap: widget.delegate.updateAnimation, - initGestureConfigHandler: (ExtendedImageState state) { - return GestureConfig( - initialScale: 1.0, - minScale: 1.0, - maxScale: 3.0, - animationMinScale: 0.6, - animationMaxScale: 4.0, - cacheGesture: false, - inPageView: true, - ); - }, + initGestureConfigHandler: (ExtendedImageState state) => GestureConfig( + minScale: 1.0, + maxScale: 3.0, + animationMinScale: 0.6, + animationMaxScale: 4.0, + inPageView: true, + ), loadStateChanged: (ExtendedImageState state) { return widget.delegate.previewWidgetLoadStateChanged( context, @@ -119,7 +115,7 @@ class _ImagePageBuilderState extends State { Widget _buildLivePhotosWrapper(BuildContext context, AssetEntity asset) { return Stack( children: [ - if (_controller?.value.isInitialized == true) + if (_controller?.value.isInitialized ?? false) Center( child: AspectRatio( aspectRatio: _controller!.value.aspectRatio, diff --git a/lib/src/widget/builder/locally_available_builder.dart b/lib/src/widget/builder/locally_available_builder.dart index ed1429c4..fa89e4b3 100644 --- a/lib/src/widget/builder/locally_available_builder.dart +++ b/lib/src/widget/builder/locally_available_builder.dart @@ -13,18 +13,18 @@ import '../scale_text.dart'; class LocallyAvailableBuilder extends StatefulWidget { const LocallyAvailableBuilder({ - Key? key, + super.key, required this.asset, required this.builder, this.isOriginal = true, - }) : super(key: key); + }); final AssetEntity asset; final Widget Function(BuildContext context, AssetEntity asset) builder; final bool isOriginal; @override - _LocallyAvailableBuilderState createState() => + State createState() => _LocallyAvailableBuilderState(); } diff --git a/lib/src/widget/builder/value_listenable_builder_2.dart b/lib/src/widget/builder/value_listenable_builder_2.dart index 05be09de..e23ef04f 100644 --- a/lib/src/widget/builder/value_listenable_builder_2.dart +++ b/lib/src/widget/builder/value_listenable_builder_2.dart @@ -6,12 +6,12 @@ import 'package:flutter/material.dart'; class ValueListenableBuilder2 extends StatelessWidget { const ValueListenableBuilder2({ - Key? key, + super.key, required this.firstNotifier, required this.secondNotifier, required this.builder, this.child, - }) : super(key: key); + }); final ValueNotifier firstNotifier; final ValueNotifier secondNotifier; diff --git a/lib/src/widget/builder/video_page_builder.dart b/lib/src/widget/builder/video_page_builder.dart index 590cfa96..f9d39225 100644 --- a/lib/src/widget/builder/video_page_builder.dart +++ b/lib/src/widget/builder/video_page_builder.dart @@ -16,11 +16,11 @@ import 'locally_available_builder.dart'; class VideoPageBuilder extends StatefulWidget { const VideoPageBuilder({ - Key? key, + super.key, required this.asset, required this.delegate, this.hasOnlyOneVideoAndMoment = false, - }) : super(key: key); + }); /// Asset currently displayed. /// 展示的资源 @@ -33,7 +33,7 @@ class VideoPageBuilder extends StatefulWidget { final bool hasOnlyOneVideoAndMoment; @override - _VideoPageBuilderState createState() => _VideoPageBuilderState(); + State createState() => _VideoPageBuilderState(); } class _VideoPageBuilderState extends State { diff --git a/lib/src/widget/gaps.dart b/lib/src/widget/gaps.dart index 74bb037e..16e51b09 100644 --- a/lib/src/widget/gaps.dart +++ b/lib/src/widget/gaps.dart @@ -7,21 +7,19 @@ import 'package:flutter/material.dart'; class Gap extends StatelessWidget { const Gap.h( double width, { - Key? key, + super.key, double? height, this.color, }) : _width = width, - _height = height, - super(key: key); + _height = height; const Gap.v( double height, { - Key? key, + super.key, double? width, this.color, }) : _width = width, - _height = height, - super(key: key); + _height = height; final double? _width; final double? _height; @@ -29,32 +27,30 @@ class Gap extends StatelessWidget { @override Widget build(BuildContext context) { - Widget _w = SizedBox(width: _width, height: _height); + Widget w = SizedBox(width: _width, height: _height); if (color != null) { - _w = ColoredBox(color: color!, child: _w); + w = ColoredBox(color: color!, child: w); } - return _w; + return w; } } class SliverGap extends StatelessWidget { const SliverGap.h( double width, { - Key? key, + super.key, double? height, this.color, }) : _width = width, - _height = height, - super(key: key); + _height = height; const SliverGap.v( double height, { - Key? key, + super.key, double? width, this.color, }) : _width = width, - _height = height, - super(key: key); + _height = height; final double? _width; final double? _height; diff --git a/lib/src/widget/platform_progress_indicator.dart b/lib/src/widget/platform_progress_indicator.dart index b473f6fb..1665710f 100644 --- a/lib/src/widget/platform_progress_indicator.dart +++ b/lib/src/widget/platform_progress_indicator.dart @@ -10,14 +10,14 @@ import 'package:flutter/material.dart'; /// Progress Indicator. Used in loading data. class PlatformProgressIndicator extends StatelessWidget { const PlatformProgressIndicator({ - Key? key, + super.key, this.strokeWidth = 4.0, this.radius = 10.0, this.size = 48.0, this.color, this.value, this.brightness, - }) : super(key: key); + }); final double strokeWidth; final double radius; diff --git a/lib/src/widget/scale_text.dart b/lib/src/widget/scale_text.dart index 26fa123e..b7d503b6 100644 --- a/lib/src/widget/scale_text.dart +++ b/lib/src/widget/scale_text.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; class ScaleText extends StatelessWidget { const ScaleText( this.text, { + super.key, this.style, this.strutStyle, this.maxLines, @@ -33,8 +34,10 @@ class ScaleText extends StatelessWidget { @override Widget build(BuildContext context) { final MediaQueryData mqd = MediaQuery.of(context); - final double effectiveFactor = - mqd.textScaleFactor.clamp(minScaleFactor, maxScaleFactor).toDouble(); + final double effectiveFactor = mqd.textScaleFactor.clamp( + minScaleFactor, + maxScaleFactor, + ); return MediaQuery( data: mqd.copyWith(textScaleFactor: effectiveFactor), child: Text( diff --git a/pubspec.yaml b/pubspec.yaml index 86fa49d6..bbc11a8c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,21 +1,20 @@ name: wechat_assets_picker description: An audio/video/image picker in pure Dart which is the same with WeChat, support multi picking. -version: 7.2.0 +version: 7.3.0 homepage: https://github.com/fluttercandies/flutter_wechat_assets_picker environment: - sdk: '>=2.15.0 <3.0.0' - flutter: '>=2.8.0' + sdk: '>=2.17.0 <3.0.0' + flutter: '>=3.0.0' dependencies: flutter: sdk: flutter - extended_image: ^6.0.2+1 - meta: ^1.7.0 - photo_manager: ^2.0.7 - provider: ^6.0.1 - video_player: ^2.2.14 + extended_image: ^6.2.0 + photo_manager: ^2.1.0+1 + provider: ^6.0.2 + video_player: ^2.4.0 dev_dependencies: flutter_test: diff --git a/test/delegates/builder_delegate_test.dart b/test/delegates/builder_delegate_test.dart index e6e16872..45a3434e 100644 --- a/test/delegates/builder_delegate_test.dart +++ b/test/delegates/builder_delegate_test.dart @@ -11,7 +11,7 @@ void main() { PhotoManager.withPlugin(TestPhotoManagerPlugin()); AssetPicker.setPickerDelegate(TestAssetPickerDelegate()); - final Finder _defaultButtonFinder = find.byType(TextButton); + final Finder defaultButtonFinder = find.byType(TextButton); Widget _defaultApp({void Function(BuildContext)? onButtonPressed}) { return MaterialApp( @@ -41,7 +41,7 @@ void main() { }, ), ); - await tester.tap(_defaultButtonFinder); + await tester.tap(defaultButtonFinder); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.keyboard_arrow_down)); await tester.pumpAndSettle(); @@ -71,7 +71,7 @@ class TestAssetPickerDelegate extends AssetPickerDelegate { bool useRootNavigator = true, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) async { - final PermissionState _ps = await permissionCheck(); + final PermissionState ps = await permissionCheck(); final AssetPathEntity pathEntity = AssetPathEntity( id: 'test', name: 'pathEntity', @@ -96,7 +96,7 @@ class TestAssetPickerDelegate extends AssetPickerDelegate { final Widget picker = AssetPicker( builder: DefaultAssetPickerBuilderDelegate( provider: provider, - initialPermission: _ps, + initialPermission: ps, gridCount: pickerConfig.gridCount, pickerTheme: pickerConfig.pickerTheme, gridThumbnailSize: pickerConfig.gridThumbnailSize,