import 'package:electronic_assistant/base/base_page.dart'; import 'package:electronic_assistant/module/talk/controller.dart'; import 'package:electronic_assistant/resource/colors.gen.dart'; import 'package:electronic_assistant/utils/expand.dart'; import 'package:electronic_assistant/utils/fixed_size_tab_indicator.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../../data/bean/talks.dart'; import '../../resource/assets.gen.dart'; import '../../resource/string.gen.dart'; import '../../router/app_pages.dart'; import '../../utils/common_style.dart'; import 'common_view.dart'; class TalkPage extends BasePage { const TalkPage({super.key}); static void start(TalkBean item) { Get.toNamed(RoutePath.talkDetail, arguments: item); } @override Widget buildBody(BuildContext context) { return DefaultTabController( length: controller.tabBeans.length, child: Stack( children: [ buildTopGradient(), Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( systemOverlayStyle: SystemUiOverlayStyle.dark, backgroundColor: Colors.transparent, leading: IconButton( icon: SizedBox( width: 24.w, height: 24.w, child: Assets.images.iconBack.image()), // Custom icon onPressed: () { Get.back(); }, ), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.symmetric(horizontal: 12.w), child: Obx(() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 8.h), Text(controller.talkBean.value?.title.value ?? '', style: TextStyle( fontSize: 22.sp, fontWeight: FontWeight.bold, color: ColorName.primaryTextColor)), SizedBox(height: 4.h), Text(controller.talkBean.value?.createTime ?? '', style: TextStyle( fontSize: 12.sp, color: ColorName.secondaryTextColor)), SizedBox(height: 14.h), ], ); }), ), buildTabBar(), Divider( height: 1, color: const Color(0xFFf6f6f6), indent: 12.w, endIndent: 12.w), SizedBox(height: 8.h), buildTalkContentView() ], ), ), buildBottomView(), buildAIAnalysisView() ], ), ); } Container buildTabBar() { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(12), topRight: Radius.circular(12), )), child: TabBar( labelStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold), unselectedLabelStyle: TextStyle(fontSize: 14.sp), labelColor: ColorName.primaryTextColor, unselectedLabelColor: ColorName.secondaryTextColor, labelPadding: EdgeInsets.only(top: 4.h), dividerHeight: 0, indicator: FixedSizeTabIndicator( width: 16.w, height: 3.w, radius: 3, color: ColorName.colorPrimary), tabs: controller.tabBeans.map((txt) => Tab(text: txt)).toList()), ); } @override bool immersive() { return true; } Container buildTopGradient() { return Container( width: 1.sw, height: 180.h, decoration: BoxDecoration( gradient: LinearGradient( colors: ['#E1E9FF'.toColor(), '#F9FAFE'.toColor()], begin: Alignment.topCenter, end: Alignment.bottomCenter, stops: const [0.3, 1.0], ), )); } Widget buildTalkContentView() { return Obx(() { if (controller.talkBean.value?.status.value == TalkStatus.notAnalysis) { if (controller.isShowElectricLow.value) { return buildElectricLowView(); } else if (controller.isUploading.value == true) { return buildElectricUploading(); } else { return buildNotAnalysisView(); } } else { return buildTabContentView(); } }); } Widget buildElectricUploading() { return getTalkUploadingView(); } Widget buildTabContentView() { return Expanded( child: TabBarView( children: controller.pages, ), ); } Widget buildNotAnalysisView() { return SizedBox( width: double.infinity, child: Column( children: [ SizedBox(height: 119.h), SizedBox( width: 100.w, height: 100.w, child: Assets.images.iconTalkSummaryUnanalyzed.image()), SizedBox(height: 4.h), Text(StringName.talkUnAnalyzed.tr, style: TextStyle( fontSize: 15.sp, color: ColorName.primaryTextColor)), SizedBox(height: 2.h), Text(StringName.talkUnAnalyzedTips.tr, style: TextStyle( fontSize: 12.sp, color: ColorName.secondaryTextColor)), SizedBox(height: 24.h), GestureDetector( onTap: () { controller.checkCanAnalyze(); }, child: Container( decoration: getPrimaryBtnDecoration(8), width: 240.w, height: 48.w, child: Center( child: Text( StringName.talkAnalyzedBtnTxt.tr, style: TextStyle(fontSize: 16.sp, color: ColorName.white), ), ), ), ) ], ), ); } Widget buildElectricLowView() { return GestureDetector( onTap: () { controller.onGoElectricStore(); }, child: Container( color: const Color(0xFFDFE4FC), padding: EdgeInsets.only(left: 16.w, right: 12.w, top: 8.h, bottom: 8.h), child: Row( children: [ SizedBox( width: 46.w, height: 56.w, child: Assets.images.iconTalkElectricLow.image()), SizedBox(width: 10.w), IntrinsicHeight( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 90.w, height: 21.w, child: Assets.images.iconTalkElectricLowTxt.image()), SizedBox(width: 1.w), Text(StringName.talkElectricLow.tr, style: TextStyle( fontSize: 12.sp, color: ColorName.secondaryTextColor)), ], ), ), const Spacer(), Container( decoration: getPrimaryBtnDecoration(8), width: 100.w, height: 36.w, child: Center( child: Text(StringName.talkGoStore.tr, style: TextStyle(fontSize: 16.sp, color: ColorName.white)), )) ], ), ), ); } Widget buildBottomView() { return Align( alignment: Alignment.bottomCenter, child: Container( margin: EdgeInsets.only(bottom: 20.h), // 设置底部偏移距离 child: IntrinsicHeight( child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Obx(() { return Visibility( visible: controller.talkBean.value?.status.value == TalkStatus.analysisSuccess, child: GestureDetector( onTap: () { controller.clickAIAnalysis(); }, child: Container( margin: EdgeInsets.only(right: 8.w), width: 64.w, height: 64.w, child: Assets.images.iconTalkLogo.image()), ), ); }), SizedBox(height: 24.h), buildAudioView() ], ), ), ), ); } buildAIAnalysisView() { return Container(); } buildAudioView() { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100), boxShadow: [ BoxShadow( color: ColorName.black5.withOpacity(0.1), spreadRadius: 2, blurRadius: 12, offset: const Offset(0, 3), ), ], ), margin: EdgeInsets.symmetric(horizontal: 12.w), padding: EdgeInsets.symmetric(vertical: 6.w), child: Row( children: [ SizedBox(width: 9.w), GestureDetector( onTap: () { controller.clickPlayAudio(); }, child: Obx(() { return SizedBox( width: 36.w, height: 36.w, child: (controller.isAudioPlaying.value) ? Assets.images.iconTalkAudioPlaying.image() : Assets.images.iconTalkAudioPause.image()); }), ), SizedBox(width: 15.w), Builder(builder: (context) { return SizedBox( width: 226.w, height: 18.w, child: Obx(() { return SliderTheme( data: SliderTheme.of(context).copyWith( thumbColor: Colors.white, overlayShape: SliderComponentShape.noOverlay, trackHeight: 8, activeTrackColor: "#8A89E9".toColor(), inactiveTrackColor: "#F6F5F8".toColor(), trackShape: CustomTrackShape(), ), child: Slider( value: controller.audioProgressValue.value, min: 0.0, max: controller.sliderMax, onChanged: (value) { controller.updateProgress(value); }, ), ); }), ); }), SizedBox(width: 11.w), Obx(() { return Text(controller.audioDuration.value.toFormattedString(), style: TextStyle( fontSize: 10.sp, color: ColorName.secondaryTextColor)); }) ], ), ); } } class CustomTrackShape extends RoundedRectSliderTrackShape { @override Rect getPreferredRect({ required RenderBox parentBox, Offset offset = Offset.zero, required SliderThemeData sliderTheme, bool isEnabled = false, bool isDiscrete = false, }) { final trackHeight = sliderTheme.trackHeight; final trackLeft = offset.dx; final trackTop = offset.dy + (parentBox.size.height - trackHeight!) / 2; final trackWidth = parentBox.size.width; return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); } }