Untitled
dart
a month ago
7.4 kB
3
Indexable
Never
import 'dart:async'; import 'package:app/features/home/controller/home_list_controller.dart'; import 'package:app/features/home/screen/sections/list/dispensary_list_item.dart'; import 'package:app/model/response/dispensary_dto.dart'; import 'package:app/uikit/assets/icon_path.dart'; import 'package:app/uikit/token/app_color.dart'; import 'package:app/uikit/token/app_radius.dart'; import 'package:app/uikit/token/app_spacing.dart'; import 'package:app/uikit/token/app_text_style.dart'; import 'package:app/uikit/widget/handle_bar.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; class HomeDispensaryList extends GetView<HomeListController> { final double collapsedSize; final List<DispensaryDTO> dispensaryList; final Function() onChangeLocationPressed; final Function(DispensaryDTO?) onListItemClick; final Function(bool isExpanded) onScrollStateChanged; final DraggableScrollableController scrollableController = DraggableScrollableController(); HomeDispensaryList({ super.key, required this.collapsedSize, required this.dispensaryList, required bool isExpanded, required this.onChangeLocationPressed, required this.onListItemClick, required this.onScrollStateChanged, }) { controller.isExpanded(isExpanded); } void _setScrollListener() { WidgetsBinding.instance.addPostFrameCallback((_) { scrollableController.addListener(_scrollListener); _handleInitialScrollState(); }); } void _removeScrollListener() { scrollableController.removeListener(_scrollListener); } void _scrollListener() { var offset = scrollableController.size; controller.timerTask?.cancel(); controller.timerTask = Timer( const Duration(milliseconds: 150), () => onScrollStateChanged.call(offset >= 0.85), ); } void _handleInitialScrollState() { if (controller.isExpanded.isTrue) { _expandSheet(); } else { _collapsedSheet(); } } void _collapsedSheet() { scrollableController.animateTo( collapsedSize, duration: const Duration(milliseconds: 300), curve: Curves.easeInCubic, ); } void _expandSheet() { scrollableController.animateTo( 1, duration: const Duration(milliseconds: 300), curve: Curves.easeInCubic, ); } BorderRadiusGeometry _getTopCornerRadius() { return controller.isExpanded.isTrue ? BorderRadius.circular(0) : const BorderRadius.only( topLeft: Radius.circular(AppRadius.radius20), topRight: Radius.circular(AppRadius.radius20), ); } List<BoxShadow> _getSheetShadow() { return controller.isExpanded.isTrue ? [] : [ BoxShadow( color: const Color(0xFF254C5B).withOpacity(0.3), offset: const Offset(-1, 0), spreadRadius: 0, blurRadius: 10, ), ]; } Widget _buildHeaderSheet() { int listSize = dispensaryList.length; return Row( children: [ const SizedBox(width: AppSpacing.spacing20), Expanded( child: Text( listSize == 0 ? 'header_empty_dispensary_nearby'.tr : listSize == 1 ? 'header_1_dispensary_nearby'.tr : listSize.toString() + 'header_many_dispensary_nearby'.tr, maxLines: 1, overflow: TextOverflow.ellipsis, style: AppTextStyle.labelLarge.apply( color: AppColor.neutral, ), textAlign: controller.isExpanded.isTrue ? TextAlign.left : TextAlign.center, ), ), Visibility( visible: controller.isExpanded.isTrue, child: Padding( padding: const EdgeInsets.only( left: AppSpacing.spacing10, ), child: Material( child: InkWell( onTap: onChangeLocationPressed, child: Text( 'btn_change_location'.tr, style: AppTextStyle.bodyLarge.apply( color: AppColor.primary, ), ), ), ), ), ), const SizedBox(width: AppSpacing.spacing20), ], ); } Widget _buildEmptyListView() { return Visibility( visible: dispensaryList.isEmpty, child: Column( children: [ const SizedBox(height: AppSpacing.spacing60), Text( 'no_dispensary_nearby'.tr, textAlign: TextAlign.center, style: AppTextStyle.bodyLarge, ), const SizedBox(height: AppSpacing.spacing20), SvgPicture.asset( IconPath.emptyDispensary, height: 60, width: 60, ), ], ), ); } @override Widget build(BuildContext context) { _removeScrollListener(); return Container( margin: const EdgeInsets.only(top: AppSpacing.spacing10), height: MediaQuery.of(context).size.height, child: Obx( () => DraggableScrollableSheet( controller: scrollableController, snap: true, expand: false, minChildSize: collapsedSize, maxChildSize: 1, initialChildSize: controller.isExpanded.isTrue ? 1 : collapsedSize, builder: (BuildContext context, scrollController) { _setScrollListener(); return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: _getTopCornerRadius(), boxShadow: _getSheetShadow(), ), child: SingleChildScrollView( controller: scrollController, child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox( height: 80, width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox(height: AppSpacing.spacing10), const HandleBar(), const SizedBox(height: AppSpacing.spacing20), _buildHeaderSheet(), const SizedBox(height: AppSpacing.spacing20), ], ), ), _buildEmptyListView(), ListView.builder( physics: const NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, itemCount: dispensaryList.length, itemBuilder: (context, index) { return DispensaryListItem( data: dispensaryList.elementAt(index), onItemClick: onListItemClick, ); }, ), ], ), ), ); }, ), ), ); } }