import 'package:clean/base/base_page.dart'; import 'package:clean/module/calendar/calendar_month_controller.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import '../../data/bean/photos_type.dart'; import '../../resource/assets.gen.dart'; import '../../router/app_pages.dart'; import '../../utils/styles.dart'; import '../people_photo/photo_group.dart'; import 'calendar_state.dart'; class CalendarMonthPage extends BasePage { const CalendarMonthPage({Key? key}); static void start({required PhotoGroup photoGroup}) { Get.toNamed(RoutePath.calendarMonth, arguments: { "photoGroup": photoGroup, }); } @override bool statusBarDarkFont() { return false; } @override bool immersive() { return true; } @override Widget buildBody(BuildContext context) { return Stack(children: [ PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) { return; } controller.isSelectMode.value ? controller.isSelectMode.value = false : controller.clickBack(); }, child: SafeArea( child: Obx(() { if (controller.photoGroup.value.images.isEmpty) { return _noNoPicturesCard(); } return Column( children: [ _titleCard(), Expanded( child: Obx(() { debugPrint( "CalendarMonthPage buildBody ${controller.photoGroup .value.images.length}"); return GridView.builder( padding: EdgeInsets.symmetric(horizontal: 16.w), scrollDirection: Axis.vertical, // 设置为垂直方向滚动 physics: BouncingScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, // 每行显示 3 个元素 mainAxisSpacing: 8.w, // 垂直间距 crossAxisSpacing: 8.h, // 水平间距 ), itemCount: controller.photoGroup.value.images.length, itemBuilder: _buildPhotoItem( controller.photoGroup.value.images)); }), ), Obx(() { return controller.isSelectMode.value ? controller .photoGroup.value.selectedPhotosIds.isNotEmpty ? _bottomBarCard() : Container() : Container(); }), SizedBox(height: 8.h), ], ); }), )), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ]); } Widget _titleCard() { return Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ controller.isSelectMode.value ? GestureDetector( onTap: () { controller.isSelectMode.value = false; }, child: Container( width: 71.w, height: 30.h, decoration: ShapeDecoration( color: Color(0xFF2A3E55), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(83.r), ), ), child: Center( child: Text( 'Cancel', style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ), )) : GestureDetector( onTap: controller.clickBack, child: Assets.images.iconBackArrow.image( width: 28.w, height: 28.h, ), ), controller.photoGroup.value.images.isEmpty ? Container() : GestureDetector( onTap: () => controller.isSelectMode.value ? controller.toggleGroupSelection( controller.photoGroup.value.images) : null, child: Obx(() => controller.isSelectMode.value ? Text( controller.photoGroup.value.isSelected.value ? 'Deselect All' : 'Select All', style: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 14.sp, fontWeight: FontWeight.w400, ), ) : GestureDetector( onTap: () { controller.isSelectMode.value = true; }, child: Container( width: 71.w, height: 30.h, alignment: Alignment.center, decoration: ShapeDecoration( color: Color(0xFF1F2D3F), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(83.r), ), ), child: Text( 'Select', style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ), )), ), ], ); }), controller.photoGroup.value.images.isEmpty ? Container() : Column( children: [ SizedBox(height: 12.h), Text( CalendarState.formatMonth( controller.photoGroup.value.month ?? ""), style: TextStyle( color: Colors.white, fontSize: 24.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 20.h), ], ), ], ), ); } Widget Function(BuildContext, int) _buildPhotoItem( List images) => (context, index) { return Obx(() { final photoId = controller.photoGroup.value.images[index].id; final isSelected = controller.photoGroup.value.selectedPhotosIds.contains(photoId); return GestureDetector( onTap: () => controller.clickImage(index), child: Stack( children: [ Container( width: 104.w, height: 104.w, decoration: ShapeDecoration( color: Colors.white.withValues(alpha: 0.12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(9.27.sp), ), ), child: ClipRRect( borderRadius: BorderRadius.circular(9.27.sp), child: AssetEntityImage( controller.photoGroup.value.images[index], thumbnailSize: const ThumbnailSize.square(300), width: 104.w, height: 104.w,fit: BoxFit.cover, isOriginal: false,frameBuilder: Styles.customFrameBuilder(), ),) ), if (controller.photoGroup.value.images[index].type == AssetType.video) Positioned( bottom: 8.h, left: 8.w, child: Container( padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h), decoration: BoxDecoration( color: Colors.black54, borderRadius: BorderRadius.circular(6.r), ), child: Text( CalendarState.formatDuration(controller.photoGroup.value.images[index].duration), style: TextStyle(color: Colors.white, fontSize: 12.sp), ), ), ), Positioned( right: 8.w, bottom: 8.h, child: Visibility( visible: controller.isSelectMode.value, child: GestureDetector( onTap: () => controller.toggleImageSelection(index), child: Container( child: isSelected ? Center( child: Assets.images.iconSelected.image( width: 20.w, height: 20.h, ), ) : Center( child: Assets.images.iconUnselected.image( width: 20.w, height: 20.h, )), ))), ), ], )); }); }; Widget _bottomBarCard() { return GestureDetector( onTap: () { controller.clickDelete(); }, child: Container( width: 328.w, height: 48.h, decoration: ShapeDecoration( color: Color(0xFF0279FB), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.r), ), ), padding: EdgeInsets.symmetric(horizontal: 16.w), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.images.iconDelete.image( width: 18.w, height: 18.h, ), SizedBox(width: 5.w), Obx(() { return Text( 'delete ${controller .selectedFilesSizeString}', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ); }), ], ), )); } Widget _noNoPicturesCard() { return Column( children: [ _titleCard(), SizedBox( height: 170.h, ), Container( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 70.w, height: 70.h, clipBehavior: Clip.antiAlias, decoration: BoxDecoration(), child: Assets.images.iconNoPictures.image(), ), SizedBox(height: 22.h), Text( 'No pictures found', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 20.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 12.h), Text( 'No pictures available at the moment', textAlign: TextAlign.center, style: TextStyle( color: Colors.white.withValues(alpha: 0.6), fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ], ), ), ], ); } }