|
|
@@ -1,19 +1,16 @@
|
|
|
-import 'dart:io';
|
|
|
-
|
|
|
import 'package:clean/base/base_view.dart';
|
|
|
import 'package:clean/module/home/home_controller.dart';
|
|
|
import 'package:clean/module/image_picker/image_picker_util.dart';
|
|
|
import 'package:clean/resource/assets.gen.dart';
|
|
|
import 'package:clean/resource/string.gen.dart';
|
|
|
-import 'package:clean/router/app_pages.dart';
|
|
|
-import 'package:clean/utils/image_util.dart';
|
|
|
-import 'package:get/get.dart';
|
|
|
import 'package:flutter/Material.dart';
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
+import 'package:get/get.dart';
|
|
|
import 'package:lottie/lottie.dart';
|
|
|
-import 'package:syncfusion_flutter_charts/charts.dart';
|
|
|
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
|
|
|
|
|
|
+import '../../widget/multi_segment_circle_indicator.dart';
|
|
|
+
|
|
|
class HomePage extends BaseView<HomeController> {
|
|
|
const HomePage({super.key});
|
|
|
|
|
|
@@ -105,97 +102,26 @@ class HomePage extends BaseView<HomeController> {
|
|
|
|
|
|
Widget circularChartCard() {
|
|
|
return SizedBox(
|
|
|
- width: 120.00.w,
|
|
|
+ width: 120.w,
|
|
|
child: Obx(() {
|
|
|
- return SfCircularChart(
|
|
|
- series: <CircularSeries>[
|
|
|
- DoughnutSeries<PieData, String>(
|
|
|
- dataSource: [
|
|
|
- PieData('photo Space', controller.photoSpacePercentage,
|
|
|
- Colors.blue),
|
|
|
- PieData(
|
|
|
- 'Used Space',
|
|
|
- controller.usedSpacePercentage -
|
|
|
- controller.photoSpacePercentage,
|
|
|
- Colors.red),
|
|
|
- PieData(
|
|
|
- 'Unused Space',
|
|
|
- controller.isStorageScanned.value
|
|
|
- ? controller.freeSpacePercentage
|
|
|
- : 100,
|
|
|
- Colors.white.withValues(alpha: 0.10000000149011612),
|
|
|
- ),
|
|
|
- ],
|
|
|
- xValueMapper: (PieData data, _) => data.label,
|
|
|
- yValueMapper: (PieData data, _) => data.value,
|
|
|
- pointColorMapper: (PieData data, _) => data.color,
|
|
|
- cornerStyle: CornerStyle.bothFlat,
|
|
|
- radius: '100%',
|
|
|
- // 设置饼图的半径
|
|
|
- innerRadius: '80%',
|
|
|
- // 设置饼图的内半径
|
|
|
- startAngle: 0,
|
|
|
- // 设置开始角度
|
|
|
- endAngle: 360, // 设置结束角度
|
|
|
- ),
|
|
|
- ],
|
|
|
- annotations: <CircularChartAnnotation>[
|
|
|
- CircularChartAnnotation(
|
|
|
- widget: Container(
|
|
|
- child: Column(
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
- children: [
|
|
|
- Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
- children: [
|
|
|
- Obx(() {
|
|
|
- return Text(
|
|
|
- controller.isStorageScanned.value
|
|
|
- ? controller.usedSpacePercentage
|
|
|
- .toStringAsFixed(0)
|
|
|
- : "0",
|
|
|
- textAlign: TextAlign.end,
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white
|
|
|
- .withValues(alpha: 0.8999999761581421),
|
|
|
- fontSize: 30.sp,
|
|
|
- height: 1,
|
|
|
- fontWeight: FontWeight.w400,
|
|
|
- ),
|
|
|
- );
|
|
|
- }),
|
|
|
- Text(
|
|
|
- '%',
|
|
|
- textAlign: TextAlign.end,
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white
|
|
|
- .withValues(alpha: 0.8999999761581421),
|
|
|
- fontSize: 14.87.r,
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- Text(
|
|
|
- controller.isStorageScanned.value ? 'used' : 'Scanning...',
|
|
|
- textAlign: TextAlign.center,
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white.withValues(alpha: 0.6000000238418579),
|
|
|
- fontSize:
|
|
|
- controller.isStorageScanned.value ? 14.87.sp : 12.sp,
|
|
|
- height: 1,
|
|
|
- fontWeight: FontWeight.w500,
|
|
|
- ),
|
|
|
- )
|
|
|
- ],
|
|
|
- )),
|
|
|
- horizontalAlignment: ChartAlignment.center,
|
|
|
- verticalAlignment: ChartAlignment.center,
|
|
|
- radius: '0%',
|
|
|
- ),
|
|
|
- ],
|
|
|
+ final isScanned = controller.isStorageScanned.value;
|
|
|
+
|
|
|
+ if (!isScanned) {
|
|
|
+ return MultiSegmentCircleIndicator(
|
|
|
+ strokeWidth: 12.r,
|
|
|
+ segments: [PieData("Scanning", 100, Colors.grey.withOpacity(0.1))],
|
|
|
+ subtitle: "Scanning...",
|
|
|
+ animationDuration: Duration.zero,
|
|
|
+ centerValue: 0,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return MultiSegmentCircleIndicator(
|
|
|
+ key: ValueKey(isScanned),
|
|
|
+ strokeWidth: 12.r,
|
|
|
+ segments: controller.pieDataList,
|
|
|
+ subtitle: "used",
|
|
|
+ centerValue: controller.usedSpacePercentage,
|
|
|
+ animationDuration: const Duration(seconds: 2),
|
|
|
);
|
|
|
}),
|
|
|
);
|
|
|
@@ -372,130 +298,136 @@ class HomePage extends BaseView<HomeController> {
|
|
|
}
|
|
|
|
|
|
Widget similarCard() {
|
|
|
- return GestureDetector(onTap: () {
|
|
|
- controller.similarCleanClick();
|
|
|
- },
|
|
|
+ return GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ controller.similarCleanClick();
|
|
|
+ },
|
|
|
child: Container(
|
|
|
- width: 328.w,
|
|
|
- height: 155.h,
|
|
|
- margin: EdgeInsets.only(top: 20.h),
|
|
|
- padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
- decoration: ShapeDecoration(
|
|
|
- color: Colors.white.withValues(alpha: 0.12),
|
|
|
- shape: RoundedRectangleBorder(
|
|
|
- borderRadius: BorderRadius.circular(16.r),
|
|
|
- ),
|
|
|
- ),
|
|
|
- child: Column(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
- children: [
|
|
|
- SizedBox(height: 12.h),
|
|
|
- Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ width: 328.w,
|
|
|
+ height: 155.h,
|
|
|
+ margin: EdgeInsets.only(top: 20.h),
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white.withValues(alpha: 0.12),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(16.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
- Column(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ SizedBox(height: 12.h),
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
children: [
|
|
|
- Text(
|
|
|
- 'Similar',
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white,
|
|
|
- fontSize: 16.sp,
|
|
|
- fontWeight: FontWeight.w700,
|
|
|
- ),
|
|
|
- ),
|
|
|
- Obx(() {
|
|
|
- return Text.rich(
|
|
|
- TextSpan(
|
|
|
- children: [
|
|
|
- TextSpan(
|
|
|
- text: "${ImagePickerUtil.similarPhotoCount.value}",
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white,
|
|
|
- fontSize: 12.sp,
|
|
|
- fontWeight: FontWeight.w400,
|
|
|
- ),
|
|
|
- ),
|
|
|
+ Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ 'Similar',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 16.sp,
|
|
|
+ fontWeight: FontWeight.w700,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Obx(() {
|
|
|
+ return Text.rich(
|
|
|
TextSpan(
|
|
|
- text: ' duplicate photos detected',
|
|
|
- style: TextStyle(
|
|
|
- color: Colors.white
|
|
|
- .withValues(alpha: 0.800000011920929),
|
|
|
- fontSize: 12.sp,
|
|
|
- fontWeight: FontWeight.w400,
|
|
|
- ),
|
|
|
+ children: [
|
|
|
+ TextSpan(
|
|
|
+ text:
|
|
|
+ "${ImagePickerUtil.similarPhotoCount.value}",
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white,
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ TextSpan(
|
|
|
+ text: ' duplicate photos detected',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.white
|
|
|
+ .withValues(alpha: 0.800000011920929),
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w400,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
- ],
|
|
|
- ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Obx(() {
|
|
|
+ return CleanUpButton(
|
|
|
+ label: !controller.isScanned.value
|
|
|
+ ? 'Scanning...'
|
|
|
+ : 'Clean up',
|
|
|
+ size: ImagePickerUtil.formatFileSize(
|
|
|
+ ImagePickerUtil.similarPhotosSize.value),
|
|
|
+ onTap: () {
|
|
|
+ controller.similarCleanClick();
|
|
|
+ },
|
|
|
);
|
|
|
}),
|
|
|
],
|
|
|
),
|
|
|
+ // SizedBox(height: 19.h),
|
|
|
+ Spacer(),
|
|
|
Obx(() {
|
|
|
- return CleanUpButton(
|
|
|
- label:
|
|
|
- !controller.isScanned.value ? 'Scanning...' : 'Clean up',
|
|
|
- size: ImagePickerUtil.formatFileSize(
|
|
|
- ImagePickerUtil.similarPhotosSize.value),
|
|
|
- onTap: () {
|
|
|
- controller.similarCleanClick();
|
|
|
- },
|
|
|
- );
|
|
|
- }),
|
|
|
- ],
|
|
|
- ),
|
|
|
- // SizedBox(height: 19.h),
|
|
|
- Spacer(),
|
|
|
- Obx(() {
|
|
|
- return Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
- children: List.generate(4, (index) {
|
|
|
- var image = Assets.images.iconHomeNoPhoto.image(
|
|
|
- width: 70.w * 0.45,
|
|
|
- height: 70.w * 0.45,
|
|
|
- );
|
|
|
- if (controller.similarPhotos.length > index) {
|
|
|
- image = AssetEntityImage(
|
|
|
- width: 70.w,
|
|
|
- height: 70.w,
|
|
|
- controller.similarPhotos[index],
|
|
|
- isOriginal: false,
|
|
|
- thumbnailSize: const ThumbnailSize.square(300),
|
|
|
- fit: BoxFit.cover,
|
|
|
- errorBuilder: (context, error, stackTrace) {
|
|
|
+ return Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: List.generate(4, (index) {
|
|
|
+ var image = Assets.images.iconHomeNoPhoto.image(
|
|
|
+ width: 70.w * 0.45,
|
|
|
+ height: 70.w * 0.45,
|
|
|
+ );
|
|
|
+ if (controller.similarPhotos.length > index) {
|
|
|
+ image = AssetEntityImage(
|
|
|
+ width: 70.w,
|
|
|
+ height: 70.w,
|
|
|
+ controller.similarPhotos[index],
|
|
|
+ isOriginal: false,
|
|
|
+ thumbnailSize: const ThumbnailSize.square(300),
|
|
|
+ fit: BoxFit.cover,
|
|
|
+ errorBuilder: (context, error, stackTrace) {
|
|
|
return Assets.images.iconHomeNoPhoto.image(
|
|
|
width: 70.w * 0.45,
|
|
|
height: 70.w * 0.45,
|
|
|
);
|
|
|
});
|
|
|
- }
|
|
|
- return ImageContainer(
|
|
|
- size: 70.w,
|
|
|
- image: Opacity(
|
|
|
- opacity: 0.22,
|
|
|
- child: const CircularProgressIndicator(color: Colors.white38,)
|
|
|
- ),
|
|
|
- // AssetEntityImage(
|
|
|
- // width: 70.w,
|
|
|
- // height: 70.w,
|
|
|
- // controller.similarPhotos[index],
|
|
|
- // isOriginal: false,
|
|
|
- // thumbnailSize: const ThumbnailSize.square(300),
|
|
|
- // fit: BoxFit.cover,
|
|
|
- // errorBuilder: (context, error, stackTrace) {
|
|
|
- // return Assets.images.iconHomeNoPhoto.image(
|
|
|
- // width: 70.w * 0.45,
|
|
|
- // height: 70.w * 0.45,
|
|
|
- // );
|
|
|
- // },
|
|
|
+ }
|
|
|
+ return controller.similarPhotos.isNotEmpty
|
|
|
+ ? image
|
|
|
+ : ImageContainer(
|
|
|
+ size: 70.w,
|
|
|
+ image: Opacity(
|
|
|
+ opacity: 0.22,
|
|
|
+ child: Lottie.asset(Assets.anim.animNoPhoto,
|
|
|
+ repeat: true, width: 100.w, height: 100.w),
|
|
|
+ ),
|
|
|
+ // AssetEntityImage(
|
|
|
+ // width: 70.w,
|
|
|
+ // height: 70.w,
|
|
|
+ // controller.similarPhotos[index],
|
|
|
+ // isOriginal: false,
|
|
|
+ // thumbnailSize: const ThumbnailSize.square(300),
|
|
|
+ // fit: BoxFit.cover,
|
|
|
+ // errorBuilder: (context, error, stackTrace) {
|
|
|
+ // return Assets.images.iconHomeNoPhoto.image(
|
|
|
+ // width: 70.w * 0.45,
|
|
|
+ // height: 70.w * 0.45,
|
|
|
+ // );
|
|
|
+ // },
|
|
|
+ );
|
|
|
+ }),
|
|
|
);
|
|
|
}),
|
|
|
- );
|
|
|
- }),
|
|
|
- Spacer(),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ));
|
|
|
+ Spacer(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ));
|
|
|
}
|
|
|
|
|
|
Widget quickPhotoCard() {
|
|
|
@@ -571,10 +503,15 @@ class HomePage extends BaseView<HomeController> {
|
|
|
});
|
|
|
}
|
|
|
return ImageContainer(
|
|
|
- image: Opacity(
|
|
|
- opacity: 0.22,
|
|
|
- child: const CircularProgressIndicator(color: Colors.white38,),
|
|
|
- ),
|
|
|
+ image: controller.peoplePhotos.isNotEmpty
|
|
|
+ ? image
|
|
|
+ : Opacity(
|
|
|
+ opacity: 0.22,
|
|
|
+ child: Lottie.asset(Assets.anim.animNoPhoto,
|
|
|
+ repeat: true,
|
|
|
+ width: 140.w,
|
|
|
+ height: 140.w),
|
|
|
+ ),
|
|
|
size: 146.w,
|
|
|
// Image.file(
|
|
|
// width: 146.w,
|
|
|
@@ -657,7 +594,8 @@ class HomePage extends BaseView<HomeController> {
|
|
|
child: controller.locationPhoto.value == null
|
|
|
? Opacity(
|
|
|
opacity: 0.22,
|
|
|
- child: const CircularProgressIndicator(color: Colors.white38,),
|
|
|
+ child: Lottie.asset(Assets.anim.animNoPhoto,
|
|
|
+ repeat: true, width: 160.w, height: 160.w),
|
|
|
)
|
|
|
: AssetEntityImage(
|
|
|
width: 304.w,
|
|
|
@@ -722,7 +660,9 @@ class HomePage extends BaseView<HomeController> {
|
|
|
controller.screenshotPhoto.value == null
|
|
|
? Opacity(
|
|
|
opacity: 0.22,
|
|
|
- child: const CircularProgressIndicator(color: Colors.white38,),
|
|
|
+ child: const CircularProgressIndicator(
|
|
|
+ color: Colors.white38,
|
|
|
+ ),
|
|
|
)
|
|
|
: AssetEntityImage(
|
|
|
width: 144.w,
|
|
|
@@ -750,7 +690,8 @@ class HomePage extends BaseView<HomeController> {
|
|
|
controller.blurryPhoto.value == null
|
|
|
? Opacity(
|
|
|
opacity: 0.22,
|
|
|
- child: const CircularProgressIndicator(color: Colors.white38,),
|
|
|
+ child: Lottie.asset(Assets.anim.animNoPhoto,
|
|
|
+ repeat: true, width: 100.w, height: 100.w),
|
|
|
)
|
|
|
: AssetEntityImage(
|
|
|
width: 144.w,
|
|
|
@@ -927,11 +868,3 @@ class ImageContainer extends StatelessWidget {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-class PieData {
|
|
|
- final String label;
|
|
|
- final double value;
|
|
|
- final Color color;
|
|
|
-
|
|
|
- PieData(this.label, this.value, this.color);
|
|
|
-}
|