import 'dart:io'; import 'package:clean/model/asset_info.dart'; import 'package:clean/module/privacy/privacy_controller.dart'; import 'package:clean/module/privacy/privacy_state.dart'; import 'package:clean/router/app_pages.dart'; import 'package:clean/utils/expand.dart'; import 'package:clean/utils/file_utils.dart'; import 'package:clean/utils/image_util.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../../base/base_view.dart'; import '../../dialog/privacy_lock_dialog.dart'; import '../../resource/assets.gen.dart'; import 'dart:typed_data'; class PrivacyPage extends BaseView { const PrivacyPage({super.key}); @override Widget buildBody(BuildContext context) { return Obx(() { return Stack( children: [ !controller.isUnlock.value ? _buildPasswordPage() : _buildPrivacySpace(context), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ], ); }); } // 输入密码界面 Widget _buildPasswordPage() { return SafeArea( child: Container( padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ GestureDetector( onTap: () { Get.back(); }, child: Assets.images.iconCommonBack.image(width: 28.w, height: 28.w), ), SizedBox( height: 28.h, ), Align( child: Column( children: [ Assets.images.iconPrivacyLock .image(width: 70.w, height: 70.w), Text( controller.passwordTitle.value, style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w700, ), ), SizedBox( height: 28.h, ), Obx(() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 32.h, height: 32.h, decoration: BoxDecoration( border: Border.all( color: "#0279FB".color, width: 2.w, ), borderRadius: BorderRadius.all(Radius.circular(16.h)), color: controller.passwordStr.value.isNotEmpty ? "#0279FB".color : Colors.transparent), ), Container( margin: EdgeInsets.only(left: 16.w), width: 32.h, height: 32.h, decoration: BoxDecoration( border: Border.all( color: "#0279FB".color, width: 2.w, ), borderRadius: BorderRadius.all(Radius.circular(16.h)), color: controller.passwordStr.value.length >= 2 ? "#0279FB".color : Colors.transparent), ), Container( margin: EdgeInsets.only(left: 16.w), width: 32.h, height: 32.h, decoration: BoxDecoration( border: Border.all( color: "#0279FB".color, width: 2.w, ), borderRadius: BorderRadius.all(Radius.circular(16.h)), color: controller.passwordStr.value.length >= 3 ? "#0279FB".color : Colors.transparent), ), Container( margin: EdgeInsets.only(left: 16.w), width: 32.h, height: 32.h, decoration: BoxDecoration( border: Border.all( color: "#0279FB".color, width: 2.w, ), borderRadius: BorderRadius.all(Radius.circular(16.h)), color: controller.passwordStr.value.length >= 4 ? "#0279FB".color : Colors.transparent), ), ], ); }), SizedBox( height: 67.h, ), _buildPasswordInput(), ], ), ) ], ), ), ); } Widget _buildPasswordInput() { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildNumberBtn("1"), _buildNumberBtn("2"), _buildNumberBtn("3"), ], ), SizedBox(height: 20.h), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildNumberBtn("4"), _buildNumberBtn("5"), _buildNumberBtn("6"), ], ), SizedBox(height: 20.h), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildNumberBtn("7"), _buildNumberBtn("8"), _buildNumberBtn("9"), ], ), SizedBox(height: 20.h), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildNumberBtn(""), _buildNumberBtn("0"), _buildDeleteBtn(), ], ), ], ); } Widget _buildNumberBtn(String num) { return Opacity( opacity: num.isEmpty ? 0 : 1, child: GestureDetector( onTap: () { controller.inputPassword(num); }, child: Container( width: 76.w, height: 76.w, decoration: BoxDecoration( color: "#FFFFFF".color.withOpacity(0.12), borderRadius: BorderRadius.all(Radius.circular(38.w)), ), child: Align( child: Text( num, style: TextStyle( color: Colors.white, fontSize: 20.sp, fontWeight: FontWeight.w700, ), ), ), ), ), ); } Widget _buildDeleteBtn() { return GestureDetector( onTap: () { if (controller.passwordStr.isNotEmpty) { controller.passwordStr.value = controller.passwordStr.value .substring(0, controller.passwordStr.value.length - 1); } }, child: Container( width: 76.w, height: 76.w, decoration: BoxDecoration( color: "#FFFFFF".color.withOpacity(0.12), borderRadius: BorderRadius.all(Radius.circular(38.w)), ), child: Center( child: Assets.images.iconPrivacyDelete.image(width: 34.w, height: 24.h), ), ), ); } Widget _buildPrivacySpace(BuildContext context) { return SafeArea( child: Container( padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Obx(() { return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ !controller.isEdit.value ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { Get.back(); }, child: Assets.images.iconCommonBack .image(width: 28.w, height: 28.w), ), Obx(() { return Visibility( visible: PrivacyState.imageList.isNotEmpty, child: GestureDetector( onTap: () { controller.isEdit.value = true; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Select", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), ); }), ], ) : Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { controller.isEdit.value = false; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Cancel", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), Obx(() { return Visibility( visible: PrivacyState.imageList.isNotEmpty, child: GestureDetector( onTap: () { controller.toggleSelectAll(); }, child: Text( controller.isAllSelected.value ? "Deselect all" : "Select All", style: TextStyle( color: Colors.white.withOpacity(0.65), fontSize: 14.sp, ), ), ), ); }), ], ), SizedBox( height: 12.h, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Privacy Space", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 24.sp, ), ), GestureDetector( onTap: () { showDialog( context: context, builder: (context) => PrivacyLockDialog( isPrivacyOn: controller.isPrivacyExistPasswd.value, onResetPassword: () { // 处理重置密码 controller.dialogSetPassword(); Navigator.pop(context); }, onSetPublic: () { // 处理设为公开 controller.setPublic(); Navigator.pop(context); }, ), ); }, child: controller.isPrivacyExistPasswd.value ? Assets.images.iconPrivacyLock .image(width: 34.w, height: 34.w) : Assets.images.iconPrivacyUnlock .image(width: 34.w, height: 34.w), ), ], ), PrivacyState.imageList.isEmpty ? _buildEmptyPhotoView(context) : _buildPhotoView(), ], ); }), ), ); } _buildEmptyPhotoView(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( height: 130.h, ), Assets.images.iconPrivacyEmptyImage.image(width: 70.w, height: 70.w), SizedBox( height: 22.h, ), Text( "Upload Files to Privacy Space", style: TextStyle( color: Colors.white.withOpacity(0.9), fontWeight: FontWeight.w500, fontSize: 18.sp, ), ), SizedBox( height: 116.h, ), GestureDetector( onTap: () { controller.uploadBtnClick(); }, child: Container( width: 180.w, height: 48.h, decoration: BoxDecoration( color: "#0279FB".color, borderRadius: BorderRadius.all( Radius.circular(10.r), ), ), child: Center( child: Text( "Upload", style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ), ], ), ); } Widget _buildPhotoView() { return Expanded( child: Column( children: [ SizedBox( height: 20.h, ), Expanded( child: ListView.builder( shrinkWrap: true, itemCount: controller.monthCount, itemBuilder: (context, index) { final monthAssets = ImageUtil.getMonthAssets(controller.assetsByMonth, index); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( ImageUtil.getMonthText(controller.assetsByMonth, index), style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, color: Colors.white), ), SizedBox( height: 11.h, ), GridView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: monthAssets.length, itemBuilder: (context, index) { var asset = monthAssets[index]; return _buildAssetItem(asset); }, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, // 每行有 4 列 mainAxisSpacing: 8.w, // 主轴(垂直)上的间距 crossAxisSpacing: 8.w, // 交叉轴(水平)上的间距 childAspectRatio: 1.0, // 子项宽高比 ), ), SizedBox( height: 24.h, ), ], ); }, ), ), !controller.isEdit.value ? GestureDetector( onTap: () { controller.uploadBtnClick(); }, child: Container( width: 328.w, height: 48.h, decoration: BoxDecoration( color: "#0279FB".color, borderRadius: BorderRadius.all( Radius.circular(10.r), ), ), child: Center( child: Text( "Upload", style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ) : GestureDetector( onTap: () { controller.deleteBtnClick(); }, child: Container( width: 328.w, height: 48.h, decoration: BoxDecoration( color: "#0279FB".color, borderRadius: BorderRadius.all( Radius.circular(10.r), ), ), child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.images.iconPrivacyPhotoDelete .image(width: 18.w, height: 18.h), SizedBox( width: 5.w, ), Text( controller.formatFileSize( controller.selectedTotalSize.value), style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ], ), ), ), ) ], ), ); } // 构建图片项 Widget _buildAssetItem(AssetInfo asset) { return GestureDetector( onTap: () async { // 获取当前资产在列表中的索引 final index = PrivacyState.imageList.indexWhere((item) => item.id == asset.id); if (index != -1) { // 确保找到了索引 final result = await Get.toNamed(RoutePath.photoInfo, arguments: { "type": "privacy", "list": PrivacyState.imageList, "index": index, }); // 检查返回结果并刷新 if (result != null && result['deleted'] == true) { controller.loadAssets(); } } }, child: Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(8.r), child: FutureBuilder( future: ImageUtil.getImageThumbnail(FileType.privacy, asset), builder: (context, snapshot) { if (snapshot.data != null) { return Image.memory( snapshot.data!, width: double.infinity, height: double.infinity, fit: BoxFit.cover, gaplessPlayback: true, ); } else { return Container(); } }, ), ), // 删除按钮 Visibility( visible: controller.isEdit.value, child: Positioned( right: 4.w, bottom: 4.h, child: GestureDetector( onTap: () { controller.toggleSelectAsset(asset.id); }, child: Container( child: controller.selectedAssets.contains(asset.id) ? Center( child: Assets.images.iconSelected.image( width: 16.w, height: 16.h, ), ) : Center( child: Assets.images.iconUnselected.image( width: 16.w, height: 16.h, ), ), ), ), ), ), ], ), ); } }