import 'package:electronic_assistant/base/base_page.dart'; import 'package:electronic_assistant/data/bean/talks.dart'; import 'package:electronic_assistant/resource/assets.gen.dart'; import 'package:electronic_assistant/resource/colors.gen.dart'; import 'package:electronic_assistant/resource/string.gen.dart'; import 'package:electronic_assistant/utils/expand.dart'; import 'package:electronic_assistant/utils/toast_util.dart'; import 'package:electronic_assistant/widget/pull_to_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import '../../data/bean/agenda.dart'; import '../../router/app_pages.dart'; import '../task/task_item_view.dart'; import 'controller.dart'; class HomePage extends BasePage { HomePage({super.key}); BuildContext? todoTargetContext; @override Widget buildBody(BuildContext context) { return Stack( children: [ buildBgBox(), buildTopGradient(), SafeArea( child: Column( children: [ Container( width: 1.sw, padding: const EdgeInsets.all(12).w, child: buildOperationBar(), ), Expanded( child: PullToRefresh( enableRefresh: true, controller: controller.refreshController, onRefresh: () { controller.requestHomeData(); }, child: CustomScrollView( slivers: [ buildTalkRecordTitle(), SliverToBoxAdapter( child: Container( height: 0.3111.sw, margin: EdgeInsets.only(bottom: 15.h), child: buildTalkRecord(), ), ), buildTalkTodoTitle(), SliverAnimatedList( key: controller.agendaList.listKey, itemBuilder: (context, index, animation) { return _buildInsertTodoItem(context, index, animation, controller.agendaList.items[index]); }, initialItemCount: controller.agendaList.length), buildSeeMoreView(), ], ), )) ], ), ) ], ); } @override bool immersive() { return true; } SliverToBoxAdapter buildSeeMoreView() { return SliverToBoxAdapter( child: Container( alignment: Alignment.center, padding: const EdgeInsets.only(top: 12, bottom: 36).w, // child: RichText( // text: TextSpan( // text: StringName.homeTalkTodo1.tr, // style: // TextStyle(color: ColorName.secondaryTextColor, fontSize: 12.sp), // children: [ // TextSpan( // text: StringName.homeTalkTodo2.tr, // style: // TextStyle(color: ColorName.colorPrimary, fontSize: 12.sp), // recognizer: TapGestureRecognizer() // ..onTap = () { // ToastUtil.showToast('点击了全部'); // }), // ], // ), // ), ), ); } SliverToBoxAdapter buildTalkTodoTitle() { return SliverToBoxAdapter( child: Column( children: [ SizedBox(height: 9.w), // buildTitle(StringName.homeTalkTodoTitle.tr, () { // Get.toNamed(RoutePath.task); // }), buildTitle(StringName.homeTalkTodoTitle.tr, null), SizedBox(height: 12.w) ], )); } SliverToBoxAdapter buildTalkRecordTitle() { return SliverToBoxAdapter( child: Column( children: [ SizedBox(height: 7.w), buildTitle(StringName.homeTalkRecord.tr, () { controller.goTalkRecordPage(); }), SizedBox(height: 12.w) ], ), ); } Row buildOperationBar() { return Row(children: [buildGoLogin(), const Spacer(), buildGoStore()]); } GestureDetector buildGoStore() { return GestureDetector( child: DecoratedBox( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2).w, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 28.w, height: 28.w, child: Assets.images.iconCharge.image()), SizedBox(width: 4.w), SizedBox( width: 28.w, child: Assets.images.iconChargeTxt.image()), SizedBox( width: 12.w, height: 12.w, child: Assets.images.iconChargeArrow.image()), ], ), )), onTap: () { ToastUtil.showToast('GoStore'); }); } Widget buildGoLogin() { return Obx(() { return GestureDetector( onTap: () { if (controller.isLogin) { controller.showLoginDrawer(); } else { Get.toNamed(RoutePath.login); } }, child: Row( children: [ SizedBox( width: 36.w, height: 36.w, child: controller.isLogin ? Assets.images.iconHomeLogged.image() : Assets.images.iconHomeNoLogin.image()), SizedBox(width: 8.w), Text(controller.loginTxt, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 15.sp, color: ColorName.primaryTextColor)), SizedBox(width: 6.w), controller.isLogin ? const SizedBox.shrink() : SizedBox( height: 16.w, child: Assets.images.iconGoLoginArrow.image()) ], ), ); }); } Container buildTopGradient() { return Container( width: 1.sw, height: 112.h, decoration: BoxDecoration( gradient: LinearGradient( colors: ['#E8EBFF'.toColor(), '#00E8EBFF'.toColor()], begin: Alignment.topCenter, end: Alignment.bottomCenter, stops: const [0.3, 1.0], ), ) // 其他子小部件 ); } DecoratedBox buildBgBox() { return DecoratedBox( decoration: BoxDecoration(color: '#F6F6F6'.toColor()), child: Container( height: double.infinity, )); } Widget buildTalkRecord() { return SizedBox( width: 1.sw, child: CustomScrollView( scrollDirection: Axis.horizontal, slivers: [ SliverToBoxAdapter(child: SizedBox(width: 12.w)), buildGoRecordView(), SliverAnimatedList( key: controller.taskList.listKey, itemBuilder: (context, index, animation) { return _buildInsertTalkItem(context, index, animation, controller.taskList.items[index]); }, initialItemCount: controller.taskList.length), ], ), ); } SliverToBoxAdapter buildGoRecordView() { return SliverToBoxAdapter( child: GestureDetector( onTap: () { showUnfinishedRecordPopup(); }, child: Container( margin: EdgeInsets.only(right: 8.w), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: '#EBEBFF'.toColor(), width: 1), borderRadius: BorderRadius.circular(8.0), ), child: SizedBox( width: 100.w, height: double.infinity, child: Stack( children: [ Positioned( right: 0, bottom: 0, child: SizedBox( width: 48.w, child: Assets.images.bgHomeQuickAudio.image(), ), ), Positioned.fill( child: Align( alignment: Alignment.center, child: Column( children: [ SizedBox(height: 20.h), SizedBox( width: 32.w, height: 32.w, child: Assets.images.iconAddTalk.image()), SizedBox(height: 6.h), Text(StringName.homeTalkAudio.tr, style: TextStyle( fontSize: 14.sp, color: ColorName.colorPrimary, fontWeight: FontWeight.bold)), Builder(builder: (context) { todoTargetContext = context; return Text(StringName.homeTalkQuickAudio.tr, style: TextStyle( fontSize: 10.sp, color: ColorName.secondaryTextColor)); }) ], ), )), ], ), ), ), )); } Widget _buildInsertTalkItem(BuildContext context, int index, Animation animation, TalkBean item) { return FadeTransition( opacity: animation, child: _buildTalkView(item), ); } Widget _buildTalkView(TalkBean item) { return Container( width: 258.w, margin: EdgeInsets.only(right: 8.w), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: '#F0F0F0'.toColor(), width: 1), borderRadius: BorderRadius.circular(8), ), height: double.infinity, padding: EdgeInsets.symmetric(horizontal: 12.w), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Visibility( visible: item.isExample.isTrue, child: Container( padding: const EdgeInsets.symmetric(horizontal: 6).w, decoration: BoxDecoration( color: '#DFE4FC'.toColor(), borderRadius: BorderRadius.circular(4), ), child: Text( StringName.homeTalkExample.tr, style: TextStyle( fontSize: 12.sp, color: ColorName.colorPrimary), )), ), SizedBox(width: 6.w), Text(item.title.orEmpty, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 15.sp, color: ColorName.colorPrimary, fontWeight: FontWeight.bold)) ], ), SizedBox(height: 5.h), Text( item.summary.orEmpty, style: TextStyle( fontSize: 12.sp, color: ColorName.secondaryTextColor), overflow: TextOverflow.ellipsis, maxLines: 2, ), SizedBox(height: 8.h), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(item.duration.toFormattedDuration(), style: TextStyle( fontSize: 12.sp, color: ColorName.tertiaryTextColor)), SizedBox(width: 6.w), Container( width: 1, height: 9, color: ColorName.tertiaryTextColor), SizedBox(width: 6.w), Text(item.createTime.orEmpty, style: TextStyle( fontSize: 12.sp, color: ColorName.tertiaryTextColor)) ], ) ], )); } Widget _buildInsertTodoItem(BuildContext context, int index, Animation animation, Agenda item) { HomePageController controller = Get.find(); return FadeTransition( opacity: animation, child: taskItemView(item, onCheckClick: () { controller.agendaList.remove( index, (context, animation, item) => _buildRemoveTodoItem(context, index, animation, item)); }), ); } Widget _buildRemoveTodoItem(BuildContext context, int index, Animation animation, Agenda item) { return SizeTransition(sizeFactor: animation, child: taskItemView(item)); } Widget buildTitle(String titleName, VoidCallback? onTap) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 12).w, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(titleName, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 17.sp, color: ColorName.primaryTextColor)), const Spacer(), Visibility( visible: onTap == null ? false : true, child: GestureDetector( onTap: onTap, child: Padding( padding: const EdgeInsets.symmetric(vertical: 6).w, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( StringName.homeTalkSeeAll.tr, style: TextStyle( fontSize: 13.sp, color: ColorName.secondaryTextColor), ), SizedBox( width: 16.w, height: 16.w, child: Assets.images.iconHomeTalkArrow.image()), ], ), ), ), ) ], ), ); } attachDialog(BuildContext? context, Alignment alignment) { SmartDialog.showAttach( targetContext: context, alignment: alignment, animationType: SmartAnimationType.fade, clickMaskDismiss: true, maskColor: Colors.transparent, bindPage: true, builder: (_) => Padding( padding: const EdgeInsets.only(top: 7).h, child: Stack( alignment: Alignment.topCenter, children: [ SizedBox( width: 146.w, height: 66.w, child: Assets.images.bgAudioTodoPopup.image()), Container( alignment: Alignment.center, padding: const EdgeInsets.only(top: 17).w, width: 146.w, child: Text(StringName.homePopupTipsTxt.tr, style: TextStyle(fontSize: 14.sp, color: Colors.white))) ], ), ), ); } void showUnfinishedRecordPopup() { attachDialog(todoTargetContext, Alignment.bottomRight); } }