import 'package:electronic_assistant/base/base_page.dart'; import 'package:electronic_assistant/data/bean/talks.dart'; import 'package:electronic_assistant/data/repositories/account_repository.dart'; import 'package:electronic_assistant/dialog/rename_dialog.dart'; import 'package:electronic_assistant/dialog/talk_delete_dialog.dart'; import 'package:electronic_assistant/module/chat/view.dart'; import 'package:electronic_assistant/popup/talk_popup.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/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 '../talk/view.dart'; import '../task/task_item_view.dart'; import 'controller.dart'; class HomePage extends BasePage { const HomePage({super.key}); @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(), Obx(() { return SliverList.builder( itemBuilder: _builderAgendaItem, itemCount: controller.agendaList.length >= 10 ? 10 : 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: () { // accountRepository.logout(); // ToastUtil.showToast('GoStore'); Get.toNamed(RoutePath.store); }); } 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(), Obx(() { return SliverList.builder( itemBuilder: _builderTalkItem, itemCount: controller.talkList.length >= 10 ? 10 : controller.talkList.length); }), ], ), ); } Widget _builderTalkItem(BuildContext context, int index) { return Obx(() { TalkBean? item = controller.talkList[index]; return _buildTalkView(item, onLongPressStart: (details) { if (!accountRepository.isLogin.value) { return; } showTalkPopup(details.globalPosition, Alignment.bottomRight, onRename: () { showRenameTalkDialog(item); }, onDelete: () { showDeleteTalkDialog(item); }); }, onItemClick: () { TalkPage.start(item); }); }); } Widget _builderAgendaItem(BuildContext context, int index) { return Obx(() { Agenda item = controller.agendaList[index]; return taskItemView( item, onThinkingClick: () { ChatPage.startByTalkId(item.talkId, agenda: item); }, onCheckClick: () { controller.agendaComplete(item); }, ); }); } SliverToBoxAdapter buildGoRecordView() { return SliverToBoxAdapter( child: GestureDetector( onTap: () => Get.toNamed(RoutePath.record), 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) { controller.todoTargetContext = context; return Text(StringName.homeTalkQuickAudio.tr, style: TextStyle( fontSize: 10.sp, color: ColorName.secondaryTextColor)); }) ], ), )), ], ), ), ), )); } Widget _buildTalkView(TalkBean item, {VoidCallback? onItemClick, GestureLongPressStartCallback? onLongPressStart}) { return GestureDetector( onTap: onItemClick, onLongPressStart: onLongPressStart, child: 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: [ _buildTag(item), Text(item.title.value.orEmpty, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 15.sp, color: ColorName.primaryTextColor, fontWeight: FontWeight.bold)) ], ), SizedBox(height: 5.h), Text( item.summary.value.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 _buildTag(TalkBean item) { return Visibility( visible: item.isExample.isTrue || item.status.value == TalkStatus.analysing || item.status.value == TalkStatus.waitAnalysis, child: Container( margin: EdgeInsets.only(right: 6.w), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3).w, decoration: BoxDecoration( color: '#DFE4FC'.toColor(), borderRadius: BorderRadius.circular(4), ), child: Text( textAlign: TextAlign.center, (item.isExample.isTrue) ? StringName.homeTalkExample.tr : StringName.analysis.tr, style: TextStyle( height: 1.0, fontSize: 12.sp, color: ColorName.colorPrimary), )), ); } 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), ), Container( margin: const EdgeInsets.only(bottom: 1), width: 16.w, height: 16.w, child: Assets.images.iconHomeTalkArrow.image()), ], ), ), ), ) ], ), ); } void showUnfinishedRecordPopup() { SmartDialog.showAttach( targetContext: controller.todoTargetContext, alignment: Alignment.bottomRight, 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 showRenameTalkDialog(TalkBean item) { reNameDialog(StringName.talkRenameTitle.tr, item.title.value, hintTxt: StringName.talkRenameTitleHint.tr, maxLength: 15, returnBuilder: (newName) { controller.requestName(newName, item); }); } void showDeleteTalkDialog(TalkBean item) { talkDeleteDialog(item.id, item.title.value, returnBuilder: () { controller.requestDelete(item); }); } }