app-starlock/lib/talk/starChart/views/imageTransmission/image_transmission_page.dart

257 lines
7.6 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_colors.dart';
import 'package:star_lock/talk/call/callTalk.dart';
import 'package:star_lock/talk/starChart/constant/talk_status.dart';
import 'package:star_lock/talk/starChart/star_chart_manage.dart';
import 'package:star_lock/talk/starChart/views/imageTransmission/image_transmission_logic.dart';
import 'package:star_lock/talk/starChart/views/imageTransmission/image_transmission_state.dart';
import 'package:star_lock/tools/titleAppBar.dart';
import 'package:slide_to_act/slide_to_act.dart';
// 可选:引入第三方滑动解锁库
// import 'package:flutter_slider_button/flutter_slider_button.dart';
class ImageTransmissionPage extends StatefulWidget {
const ImageTransmissionPage();
@override
State<ImageTransmissionPage> createState() => _ImageTransmissionPageState();
}
class _ImageTransmissionPageState extends State<ImageTransmissionPage>
with TickerProviderStateMixin {
final ImageTransmissionLogic logic = Get.put(ImageTransmissionLogic());
final ImageTransmissionState state = Get.find<ImageTransmissionLogic>().state;
final startChartManage = StartChartManage();
@override
void initState() {
super.initState();
state.animationController = AnimationController(
vsync: this, // 确保使用的TickerProvider是当前Widget
duration: const Duration(seconds: 1),
);
state.animationController.repeat();
state.animationController.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
state.animationController.reset();
state.animationController.forward();
} else if (status == AnimationStatus.dismissed) {
state.animationController.reset();
state.animationController.forward();
}
});
}
@override
void dispose() {
state.animationController.dispose();
CallTalk().finishAVData();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.mainBackgroundColor,
resizeToAvoidBottomInset: false,
appBar: TitleAppBar(
barTitle: '图传'.tr,
haveBack: true,
backgroundColor: AppColors.mainColor,
backAction: () {
logic.udpHangUpAction();
},
actionsList: [
Visibility(
visible: state.currentLanguage == 'zh_CN' && Platform.isAndroid,
child: IconButton(
icon: Icon(
Icons.notification_add_sharp,
size: 32.w,
color: Colors.white,
),
onPressed: () {
Get.toNamed(Routers.permissionGuidancePage);
},
),
)
],
),
body: Obx(() => Column(
children: [
SizedBox(height: 24.h),
SizedBox(
height: 0.6.sh,
child: state.listData.value.isEmpty
? _buildWaitingView()
: _buildVideoView(),
),
SizedBox(height: 30.h),
_buildBottomToolBar(),
SizedBox(height: 30.h),
],
)),
);
}
Widget _buildWaitingView() {
double barWidth = MediaQuery.of(context).size.width - 60.w;
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30.h),
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: barWidth,
height: double.infinity,
child: Image.asset(
'images/main/monitorBg.png',
fit: BoxFit.cover,
),
),
RotationTransition(
turns: state.animationController,
child: Image.asset(
'images/main/realTime_connecting.png',
width: 300.w,
height: 300.w,
fit: BoxFit.contain,
),
),
],
),
),
);
}
Widget _buildVideoView() {
double barWidth = MediaQuery.of(context).size.width - 60.w;
return PopScope(
canPop: false,
child: RepaintBoundary(
key: state.globalKey,
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30.h),
child: Container(
width: barWidth,
height: double.infinity,
child: RotatedBox(
quarterTurns: startChartManage.rotateAngle ~/ 90,
child: RawImage(
image: state.currentImage.value,
fit: BoxFit.cover,
filterQuality: FilterQuality.high,
),
),
),
),
),
),
);
}
Widget _buildBottomToolBar() {
return Container(
margin: EdgeInsets.symmetric(horizontal: 30.w),
padding: EdgeInsets.symmetric(vertical: 28.h, horizontal: 20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30.h),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 12,
offset: Offset(0, 4),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_circleButton(
icon: Icons.call,
color: Colors.green,
onTap: () {
if (state.talkStatus.value ==
TalkStatus.passiveCallWaitingAnswer) {
// 接听
logic.initiateAnswerCommand();
}
},
),
_circleButton(
icon: Icons.call_end,
color: Colors.red,
onTap: () {
logic.udpHangUpAction();
},
),
_circleButton(
icon: Icons.camera_alt,
color: Colors.blue,
onTap: () async {
await logic.captureAndSavePng();
},
),
],
),
SizedBox(height: 36.h),
SlideAction(
height: 64.h,
borderRadius: 24.h,
elevation: 0,
innerColor: Colors.amber,
outerColor: Colors.amber.withOpacity(0.15),
sliderButtonIcon: Icon(Icons.lock, color: Colors.white, size: 40.w),
text: '滑动解锁',
textStyle: TextStyle(
fontSize: 26.sp,
color: Colors.black54,
fontWeight: FontWeight.bold),
onSubmit: () {
// TODO: 实现滑动解锁逻辑
logic.remoteOpenLock();
},
),
],
),
);
}
Widget _circleButton(
{required IconData icon,
required Color color,
required VoidCallback onTap}) {
return GestureDetector(
onTap: onTap,
child: Container(
width: 90.w,
height: 90.w,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: color.withOpacity(0.3),
blurRadius: 10,
offset: Offset(0, 4),
),
],
),
child: Icon(icon, color: Colors.white, size: 48.w),
),
);
}
}