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,
);
},
),
],
),
),
);
},
),
),
);
}
}