mobdr/lib/core/components/custom_camera_preview.dart

199 lines
5.9 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:mobdr/service/shared_prefs.dart';
class CustomCameraPreview extends StatefulWidget {
final List<File> photoFiles;
final CameraController cameraController;
CustomCameraPreview(
{Key? key, required this.photoFiles, required this.cameraController})
: super(key: key);
@override
_CustomCameraPreviewState createState() => _CustomCameraPreviewState();
}
class _CustomCameraPreviewState extends State<CustomCameraPreview> {
final AudioPlayer _audioPlayer = AudioPlayer();
bool isTakingPhoto = false;
@override
Widget build(BuildContext context) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
Positioned.fill(
child: AspectRatio(
aspectRatio: widget.cameraController.value.aspectRatio,
child: CameraPreview(widget.cameraController),
),
),
Positioned(
bottom: 5,
child: FloatingActionButton(
heroTag: "camera",
backgroundColor: Colors.white,
onPressed: () async {
if (widget.photoFiles.length != 10 && !isTakingPhoto) {
setState(() {
isTakingPhoto = true;
});
try {
var dirCacheXFile =
await widget.cameraController.takePicture();
/// move jpg file to photo directory
final dirPhotoFile =
await moveFromCacheToPhotosDir(File(dirCacheXFile.path));
widget.photoFiles.add(dirPhotoFile);
if (SharedPrefs().photoSound) {
await _audioPlayer.setVolume((0.5));
await _audioPlayer.play(
AssetSource('sounds/camera-shutter-click.mp3'),
);
}
} finally {
setState(() {
isTakingPhoto = false;
});
}
}
},
child: const Icon(
Icons.camera_alt,
color: Colors.black,
),
),
),
_confirmButton(),
_rejectButton(),
Positioned(
bottom: 80,
child: SizedBox(
height: 80,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return GestureDetector(
onVerticalDragEnd: (details) {
if (details.primaryVelocity! < 0) {
setState(() {
widget.photoFiles.removeAt(index);
});
}
},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 2.0),
decoration: BoxDecoration(
border: Border.all(width: 2.0, color: Colors.white),
),
child: index >= widget.photoFiles.length
? Container(color: Colors.white, width: 100)
: Image.file(
widget.photoFiles[index],
fit: BoxFit.cover,
height: 100,
width: 100,
),
),
);
},
itemCount: widget.photoFiles.length,
),
),
),
],
);
}
Positioned _rejectButton() {
return Positioned(
bottom: 5,
left: 5,
child: FloatingActionButton(
heroTag: "close",
backgroundColor: Colors.black,
onPressed: !isTakingPhoto
? () {
Navigator.pop(context, false);
}
: null,
child: const Icon(
Icons.close,
color: Colors.white,
),
),
);
}
Positioned _confirmButton() {
return Positioned(
bottom: 5,
right: 5,
child: FloatingActionButton(
heroTag: "confirm",
backgroundColor: Colors.black,
onPressed: !isTakingPhoto
? () {
Navigator.pop(context, true);
}
: null,
child: const Icon(
Icons.check,
color: Colors.white,
),
),
);
}
// Moves a temporary file to the photos directory in the app's document directory.
///
/// Returns a `File` object for the new file in the photos directory.
///
/// Parameters:
/// * `tempFile`: The temporary `File` object to move to the photos directory.
///
/// Throws a `FileSystemException` if there is an error renaming the file.
Future<File> moveFromCacheToPhotosDir(File tempFile) async {
// Set the new file path with the original file name
final String newPath =
'${SharedPrefs().photosDir}/${tempFile.path.split('/').last}';
// Create a new File object with the new path
final newFile = File(newPath);
final bool photoResizing = SharedPrefs().photoResizing;
final int? minWidth = photoResizing ? 1024 : null;
final int? minHeight = photoResizing ? 768 : null;
final fixedImageBytes = await FlutterImageCompress.compressWithFile(
tempFile.path,
minWidth: minWidth!,
minHeight: minHeight!,
rotate: 0,
quality: 100,
keepExif: false,
autoCorrectionAngle: true,
format: CompressFormat.jpeg,
);
// Write the compressed image bytes to the new file
await newFile.writeAsBytes(fixedImageBytes!);
// deleting the temporary file
await tempFile.delete();
// Create and return a new File object for the new file
return File(newPath);
}
}