import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:food_health/api/endpoints/food_api.dart'; import 'package:food_health/config/theme/custom_colors.dart'; import 'package:food_health/router/config/route_paths.dart'; import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; import 'package:remixicon/remixicon.dart'; class UploadPanel extends StatefulWidget { const UploadPanel({super.key}); @override State createState() => _UploadPanelState(); } class _UploadPanelState extends State { final ImagePicker _picker = ImagePicker(); ///打开相机拍照 void _handTakePhoto() async { var photo = await _picker.pickImage(source: ImageSource.camera); if (photo != null) { _startDetect(photo.path); } } ///选择图片 void _handPickImage() async { var result = await FilePicker.platform.pickFiles( type: FileType.image, allowMultiple: false, ); if (result != null) { _startDetect(result.files[0].path!); } } ///开始检测 void _startDetect(String path) async { //压缩 final result = await FlutterImageCompress.compressWithFile( path, minWidth: 1080, minHeight: 1920, quality: 85, rotate: 0, ); EasyLoading.show( status: 'Checking, please wait...', maskType: EasyLoadingMaskType.clear, ); var res = await foodScanApi(result!); EasyLoading.dismiss(); context.push(RoutePaths.detail, extra: res); } @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(15), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: Color(0x1A000000), spreadRadius: 2, blurRadius: 5, offset: Offset(1, 2), ), ], ), child: Container( padding: EdgeInsets.all(30), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), border: Border.all( color: Theme.of(context).colorScheme.surfaceContainer, width: 1, ), ), child: Column( children: [ Container( width: 70, height: 70, margin: EdgeInsets.only(bottom: 20), decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( colors: [ Theme.of(context).colorScheme.primary, Theme.of(context).colorScheme.primaryEnd, ], ), ), child: Icon( RemixIcons.image_line, color: Colors.white, size: 26, ), ), Text( "Upload Food Photo", style: Theme.of(context).textTheme.titleMedium, ), Container( margin: EdgeInsets.only(top: 5), child: Text( "Take a clear photo of your food and we'll analyze it for safety based on your health profile", style: Theme.of(context).textTheme.bodySmall, textAlign: TextAlign.center, ), ), Container( margin: EdgeInsets.only(top: 40, bottom: 20), child: Column( spacing: 20, children: [ _buttonItem( title: "Take Photo", icon: RemixIcons.camera_line, style: BoxDecoration( gradient: LinearGradient( colors: [ Theme.of(context).colorScheme.primary, Theme.of(context).colorScheme.primaryEnd, ], ), ), onTap: () { _handTakePhoto(); }, ), _buttonItem( title: "Upload File", icon: RemixIcons.upload_2_line, color: Colors.black, style: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainer, ), onTap: () { _handPickImage(); }, ), ], ), ), Text( "Supports JPG, PNG, HEIC formats • Max 10MB", style: Theme.of(context).textTheme.labelSmall, textAlign: TextAlign.center, ), ], ), ), ); } Widget _buttonItem({ required String title, required IconData icon, Color color = Colors.white, required BoxDecoration style, required VoidCallback onTap, }) { return InkWell( onTap: onTap, child: Container( width: 170, padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15), decoration: style.copyWith( borderRadius: BorderRadius.circular(10), ), child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, spacing: 10, children: [ Icon(icon, color: color, size: 20), Text( title, style: TextStyle(color: color), ), ], ), ), ); } }