226 lines
8.2 KiB
Dart
226 lines
8.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:absensi_sas/widget/sankbar_widget.dart';
|
|
import 'package:camera/camera.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../../app/constant.dart';
|
|
import '../../provider/camera_controller_provider.dart';
|
|
|
|
class CameraPage extends HookConsumerWidget {
|
|
const CameraPage({
|
|
Key? key,
|
|
required this.filePathParam,
|
|
required this.fileDataBase64Param,
|
|
}) : super(key: key);
|
|
|
|
final ValueNotifier<String> filePathParam;
|
|
final ValueNotifier<String> fileDataBase64Param;
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final controller = ref.watch(cameraControllerProvider);
|
|
// final imagePath = useState<String?>("");
|
|
// final fileDataBase64 = useState<String?>("");
|
|
|
|
// final fileData = useState<XFile?>(null);
|
|
final filePath = useState<String>("");
|
|
final fileDataBase64 = useState<String>("");
|
|
final cameraController = useState<CameraController?>(null);
|
|
|
|
useEffect(() {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
try {
|
|
final cameras = await availableCameras();
|
|
if (cameras.isNotEmpty) {
|
|
final controller =
|
|
CameraController(cameras[0], ResolutionPreset.max);
|
|
await controller.initialize();
|
|
cameraController.value = controller;
|
|
}
|
|
} catch (e) {
|
|
print('Error initializing camera: $e');
|
|
}
|
|
});
|
|
return () {};
|
|
}, []);
|
|
|
|
Future<void> initializeCamera() async {
|
|
try {
|
|
final cameras = await availableCameras();
|
|
if (cameras.isNotEmpty) {
|
|
final controller = CameraController(cameras[0], ResolutionPreset.max);
|
|
await controller.initialize();
|
|
cameraController.value = controller;
|
|
}
|
|
} catch (e) {
|
|
print('Error initializing camera: $e');
|
|
}
|
|
}
|
|
|
|
Future<void> takePicture(
|
|
// ValueNotifier<XFile?> imageFile,
|
|
ValueNotifier<String> base64ImageString,
|
|
ValueNotifier<String> imagePath,
|
|
) async {
|
|
// final flag = ValueNotifier<bool>(false);
|
|
if (cameraController.value != null) {
|
|
try {
|
|
final image = await cameraController.value!.takePicture();
|
|
final bytes = await image.readAsBytes();
|
|
String base64Image = base64Encode(bytes);
|
|
|
|
// imageFile.value = image;
|
|
base64ImageString.value = base64Image;
|
|
imagePath.value = image.path;
|
|
|
|
fileDataBase64Param.value = base64Image;
|
|
filePathParam.value = image.path;
|
|
|
|
// final shared = await SharedPreferences.getInstance();
|
|
// shared.setString("base64Image", base64Image);
|
|
} catch (e) {
|
|
print('Error taking picture: $e');
|
|
// flag.value = false;
|
|
// RespErr(flag: false, message: 'Error taking picture: $e');
|
|
}
|
|
} else {
|
|
print('CameraController is not initialized.');
|
|
}
|
|
}
|
|
|
|
processFoto(BuildContext context) async {
|
|
await takePicture(
|
|
// fileData,
|
|
fileDataBase64,
|
|
filePath,
|
|
);
|
|
|
|
print("fileDataBase64 : ${fileDataBase64.value}");
|
|
|
|
if (fileDataBase64.value != "") {
|
|
// ref.read(imgPhotoWebProvider.notifier).state = fileDataBase64.value;
|
|
Navigator.of(context).pop();
|
|
} else {
|
|
print('Error: Image result is null');
|
|
}
|
|
|
|
// proses base64
|
|
// final shared = await SharedPreferences.getInstance();
|
|
// final imageBase64 = shared.getString("base64Image");
|
|
|
|
// if (imageBase64 != "") {
|
|
// fileDataBase64.value = imageBase64;
|
|
// ref.read(imgPhotoWebProvider.notifier).state = imageBase64;
|
|
// Navigator.of(context).pop();
|
|
// } else {
|
|
// print('Error: Image result is null');
|
|
// }
|
|
}
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Take Photo'),
|
|
),
|
|
body: SafeArea(
|
|
child: Center(
|
|
child: controller == null || !controller.value.isInitialized
|
|
? const CircularProgressIndicator()
|
|
: Padding(
|
|
padding: EdgeInsets.all(20),
|
|
child: Column(
|
|
children: [
|
|
// const SizedBox(height: 50),
|
|
Expanded(
|
|
child: AspectRatio(
|
|
aspectRatio: controller.value.aspectRatio,
|
|
child: CameraPreview(controller),
|
|
),
|
|
),
|
|
SizedBox(
|
|
height:
|
|
Constant.getActualYPhone(context: context, y: 20),
|
|
),
|
|
TextButton(
|
|
onPressed: () async {
|
|
fileDataBase64Param.value = "";
|
|
filePathParam.value = "";
|
|
// cameraController.dispose();
|
|
// await controller.dispose();
|
|
// await initializeCamera();
|
|
},
|
|
child: const Text("Clear Foto"),
|
|
),
|
|
|
|
Spacer(),
|
|
ElevatedButton(
|
|
// onPressed: () {
|
|
// Navigator.of(context).pushNamed(homeRoute);
|
|
// },
|
|
onPressed: () async {
|
|
processFoto(context);
|
|
},
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateColor.resolveWith(
|
|
(st) => (fileDataBase64.value != "")
|
|
? Constant.textDarkGrey
|
|
: Constant.textOrange),
|
|
shape:
|
|
MaterialStateProperty.all<RoundedRectangleBorder>(
|
|
RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
side: BorderSide(
|
|
color: Constant.textOrange,
|
|
),
|
|
),
|
|
),
|
|
shadowColor:
|
|
MaterialStateProperty.all(Color(0xffff48423d)),
|
|
elevation: MaterialStateProperty.all(4.0),
|
|
),
|
|
child: Stack(
|
|
children: [
|
|
(fileDataBase64.value != "")
|
|
? SizedBox(
|
|
width: Constant.getActualXPhone(
|
|
context: context, x: 24),
|
|
height: Constant.getActualYPhone(
|
|
context: context, y: 32),
|
|
child: Center(
|
|
child: CircularProgressIndicator(
|
|
color: Constant.textOrange,
|
|
),
|
|
),
|
|
)
|
|
: Align(
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
'Process Photo',
|
|
style: Constant.titleH1_500_18(
|
|
context: context)
|
|
.copyWith(
|
|
color: Constant.textWhite,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// if (imagePath.value.isNotEmpty)
|
|
// Container(
|
|
// width: 300,
|
|
// height: 300,
|
|
// child: Image.network(imagePath.value),
|
|
// ),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|