|
|
|
|
@ -3,6 +3,7 @@ import 'dart:math';
|
|
|
|
|
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
|
|
|
import 'package:lottie/lottie.dart';
|
|
|
|
|
import 'package:vital_sign_camera/vital_sign_camera.dart';
|
|
|
|
|
|
|
|
|
|
// import 'package:wakelock/wakelock.dart';
|
|
|
|
|
@ -14,20 +15,18 @@ import 'components/start_button.dart';
|
|
|
|
|
import 'result_screen.dart';
|
|
|
|
|
// import 'package:lottie/lottie.dart';
|
|
|
|
|
|
|
|
|
|
final UserInfo userInfo = UserInfo(
|
|
|
|
|
age: 30,
|
|
|
|
|
gender: Gender.male,
|
|
|
|
|
weight: 75,
|
|
|
|
|
// kg, Optional
|
|
|
|
|
height: 164,
|
|
|
|
|
// cm, Optional
|
|
|
|
|
waistCircumference: 83,
|
|
|
|
|
// cm Optional
|
|
|
|
|
userId: 'dbd13e86-47f4-4a43-85f6-cf62fa750117');
|
|
|
|
|
|
|
|
|
|
final VitalSignCameraConfig config = VitalSignCameraConfig(
|
|
|
|
|
apiKey: 'nIsZO45woSXSfIxsL1t79MWeIpsnGQr6B941MSF2',
|
|
|
|
|
serverId: ServerId.awsEnterpriseProd);
|
|
|
|
|
// final UserInfo userInfo = UserInfo(
|
|
|
|
|
// age: 30,
|
|
|
|
|
// gender: Gender.male,
|
|
|
|
|
// weight: 75,
|
|
|
|
|
// // kg, Optional
|
|
|
|
|
// height: 164,
|
|
|
|
|
// // cm, Optional
|
|
|
|
|
// waistCircumference: 83,
|
|
|
|
|
// // cm Optional
|
|
|
|
|
// userId: 'dbd13e86-47f4-4a43-85f6-cf62fa750117');
|
|
|
|
|
|
|
|
|
|
final VitalSignCameraConfig config = VitalSignCameraConfig(apiKey: 'nIsZO45woSXSfIxsL1t79MWeIpsnGQr6B941MSF2', serverId: ServerId.awsEnterpriseProd);
|
|
|
|
|
|
|
|
|
|
class VitalSigns extends StatefulWidget {
|
|
|
|
|
const VitalSigns({super.key, required this.userInfo});
|
|
|
|
|
@ -56,10 +55,8 @@ class _VitalSignsState extends State<VitalSigns> with RouteAware {
|
|
|
|
|
return queryCameraDevice(CameraPosition.front);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool startedScanning =
|
|
|
|
|
false; // set true when start button is pressed, set false when health result is tapped or error occurs
|
|
|
|
|
bool isAllConditionsMet =
|
|
|
|
|
false; // check for the 6 scan conditions before enabling the start button
|
|
|
|
|
bool startedScanning = false; // set true when start button is pressed, set false when health result is tapped or error occurs
|
|
|
|
|
bool isAllConditionsMet = false; // check for the 6 scan conditions before enabling the start button
|
|
|
|
|
|
|
|
|
|
ScanConditions? _conditions;
|
|
|
|
|
GetHealthStage? _scanningStage;
|
|
|
|
|
@ -105,39 +102,27 @@ class _VitalSignsState extends State<VitalSigns> with RouteAware {
|
|
|
|
|
final deviceSize = MediaQuery.of(context).size;
|
|
|
|
|
return Stack(
|
|
|
|
|
children: [
|
|
|
|
|
VitalSignCamera(
|
|
|
|
|
onCreated: _onVitalSignCameraCreated,
|
|
|
|
|
isActive: isCameraActive,
|
|
|
|
|
userInfo: widget.userInfo,
|
|
|
|
|
config: config,
|
|
|
|
|
device: cameraDevice,
|
|
|
|
|
onVideoFrameProcessed: _onVideoFrameProcessed),
|
|
|
|
|
if (_scanningStage !=
|
|
|
|
|
GetHealthStage.idle) // show remaining time count down during scan
|
|
|
|
|
VitalSignCamera(onCreated: _onVitalSignCameraCreated, isActive: isCameraActive, userInfo: widget.userInfo, config: config, device: cameraDevice, onVideoFrameProcessed: _onVideoFrameProcessed),
|
|
|
|
|
if (_scanningStage != GetHealthStage.idle) // show remaining time count down during scan
|
|
|
|
|
Align(
|
|
|
|
|
alignment: Alignment.bottomCenter,
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(bottom: 16.0),
|
|
|
|
|
child: ScanStatus(
|
|
|
|
|
stage: _scanningStage, remainingTime: _remainingTime),
|
|
|
|
|
child: ScanStatus(stage: _scanningStage, remainingTime: _remainingTime),
|
|
|
|
|
)),
|
|
|
|
|
if (mounted)
|
|
|
|
|
Column(children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: CircularOverlay(
|
|
|
|
|
state: (_scanningStage == null ||
|
|
|
|
|
_scanningStage == GetHealthStage.idle)
|
|
|
|
|
? AnimationState.stop
|
|
|
|
|
: AnimationState.playing,
|
|
|
|
|
state: (_scanningStage == null || _scanningStage == GetHealthStage.idle) ? AnimationState.stop : AnimationState.playing,
|
|
|
|
|
)),
|
|
|
|
|
if (_conditions != null)
|
|
|
|
|
ScanConditionChecklist(
|
|
|
|
|
deviceSize: deviceSize, conditions: _conditions!),
|
|
|
|
|
// Lottie.asset('assets/breathing.json', width: 200, height: 200, fit: BoxFit.fill),
|
|
|
|
|
if (_conditions != null) ScanConditionChecklist(deviceSize: deviceSize, conditions: _conditions!),
|
|
|
|
|
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 16,
|
|
|
|
|
),
|
|
|
|
|
if (_scanningStage == GetHealthStage.idle &&
|
|
|
|
|
isCameraActive) // show start button only when it is not scanning
|
|
|
|
|
if (_scanningStage == GetHealthStage.idle && isCameraActive) // show start button only when it is not scanning
|
|
|
|
|
...{
|
|
|
|
|
StartButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
@ -248,9 +233,7 @@ class _VitalSignsState extends State<VitalSigns> with RouteAware {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _onVideoFrameProcessed(VideoFrameProcessedEvent event) {
|
|
|
|
|
if (!_showedHealthResult &&
|
|
|
|
|
_healthResult == null &&
|
|
|
|
|
event.healthResult?.health != null) {
|
|
|
|
|
if (!_showedHealthResult && _healthResult == null && event.healthResult?.health != null) {
|
|
|
|
|
_showedHealthResult = true;
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
@ -304,15 +287,13 @@ enum AnimationState { playing, stop }
|
|
|
|
|
class CircularOverlay extends StatefulWidget {
|
|
|
|
|
final AnimationState state;
|
|
|
|
|
|
|
|
|
|
const CircularOverlay({Key? key, this.state = AnimationState.stop})
|
|
|
|
|
: super(key: key);
|
|
|
|
|
const CircularOverlay({Key? key, this.state = AnimationState.stop}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<CircularOverlay> createState() => _CircularOverlayState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CircularOverlayState extends State<CircularOverlay>
|
|
|
|
|
with SingleTickerProviderStateMixin {
|
|
|
|
|
class _CircularOverlayState extends State<CircularOverlay> with SingleTickerProviderStateMixin {
|
|
|
|
|
late AnimationController _controller;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
@ -361,8 +342,7 @@ class _CircularOverlayState extends State<CircularOverlay>
|
|
|
|
|
builder: (context, child) {
|
|
|
|
|
return CustomPaint(
|
|
|
|
|
painter: CircularBarsPainter(animationValue: _controller.value),
|
|
|
|
|
size: Size(MediaQuery.sizeOf(context).width * .9,
|
|
|
|
|
MediaQuery.sizeOf(context).height * .8),
|
|
|
|
|
size: Size(MediaQuery.sizeOf(context).width * .9, MediaQuery.sizeOf(context).height * .8),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|