view.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/resource/assets.gen.dart';
  3. import 'package:electronic_assistant/resource/colors.gen.dart';
  4. import 'package:electronic_assistant/resource/string.gen.dart';
  5. import 'package:electronic_assistant/utils/expand.dart';
  6. import 'package:electronic_assistant/utils/toast_util.dart';
  7. import 'package:flutter/gestures.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter_screenutil/flutter_screenutil.dart';
  10. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  11. import 'package:get/get.dart';
  12. import 'controller.dart';
  13. class HomePage extends BasePage<HomePageController> {
  14. HomePage({super.key});
  15. BuildContext? todoTargetContext;
  16. @override
  17. Widget buildBody(BuildContext context) {
  18. return Stack(
  19. children: [
  20. buildBgBox(),
  21. buildTopGradient(),
  22. SafeArea(
  23. child: Column(
  24. children: [
  25. Container(
  26. width: 1.sw,
  27. padding: const EdgeInsets.all(12).w,
  28. child: buildOperationBar(),
  29. ),
  30. Expanded(
  31. child: CustomScrollView(
  32. slivers: [
  33. buildTalkRecordTitle(),
  34. SliverToBoxAdapter(
  35. child: Container(
  36. height: 0.3111.sw,
  37. margin: EdgeInsets.only(bottom: 15.h),
  38. child: buildTalkRecord(),
  39. ),
  40. ),
  41. buildTalkTodoTitle(),
  42. SliverAnimatedList(
  43. itemBuilder: _buildTodoItem, initialItemCount: 20),
  44. buildSeeMoreView(),
  45. ],
  46. ))
  47. ],
  48. ),
  49. )
  50. ],
  51. );
  52. }
  53. @override
  54. bool immersive() {
  55. return true;
  56. }
  57. SliverToBoxAdapter buildSeeMoreView() {
  58. return SliverToBoxAdapter(
  59. child: Container(
  60. alignment: Alignment.center,
  61. padding: const EdgeInsets.only(top: 12, bottom: 36).w,
  62. child: RichText(
  63. text: TextSpan(
  64. text: StringName.homeTalkTodo1.tr,
  65. style:
  66. TextStyle(color: ColorName.secondaryTextColor, fontSize: 12.sp),
  67. children: <TextSpan>[
  68. TextSpan(
  69. text: StringName.homeTalkTodo2.tr,
  70. style:
  71. TextStyle(color: ColorName.colorPrimary, fontSize: 12.sp),
  72. recognizer: TapGestureRecognizer()
  73. ..onTap = () {
  74. ToastUtil.showToast('点击了全部');
  75. }),
  76. ],
  77. ),
  78. ),
  79. ),
  80. );
  81. }
  82. SliverToBoxAdapter buildTalkTodoTitle() {
  83. return SliverToBoxAdapter(
  84. child: Column(
  85. children: [
  86. SizedBox(height: 9.w),
  87. buildTitle(StringName.homeTalkTodoTitle.tr, () {
  88. ToastUtil.showToast('待办事项 查看全部');
  89. }),
  90. SizedBox(height: 12.w)
  91. ],
  92. ));
  93. }
  94. SliverToBoxAdapter buildTalkRecordTitle() {
  95. return SliverToBoxAdapter(
  96. child: Column(
  97. children: [
  98. SizedBox(height: 7.w),
  99. buildTitle(StringName.homeTalkRecord.tr, () {
  100. controller.goTalkRecordPage();
  101. }),
  102. SizedBox(height: 12.w)
  103. ],
  104. ),
  105. );
  106. }
  107. Row buildOperationBar() {
  108. return Row(children: [buildGoLogin(), const Spacer(), buildGoStore()]);
  109. }
  110. GestureDetector buildGoStore() {
  111. return GestureDetector(
  112. child: DecoratedBox(
  113. decoration: BoxDecoration(
  114. color: Colors.white,
  115. borderRadius: BorderRadius.circular(16),
  116. ),
  117. child: Padding(
  118. padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2).w,
  119. child: Row(
  120. crossAxisAlignment: CrossAxisAlignment.center,
  121. children: [
  122. SizedBox(
  123. width: 28.w,
  124. height: 28.w,
  125. child: Assets.images.iconCharge.image()),
  126. SizedBox(width: 4.w),
  127. SizedBox(
  128. width: 28.w, child: Assets.images.iconChargeTxt.image()),
  129. SizedBox(
  130. width: 12.w,
  131. height: 12.w,
  132. child: Assets.images.iconChargeArrow.image()),
  133. ],
  134. ),
  135. )),
  136. onTap: () {
  137. ToastUtil.showToast('GoStore');
  138. });
  139. }
  140. GestureDetector buildGoLogin() {
  141. return GestureDetector(
  142. onTap: () {
  143. controller.showLoginDrawer();
  144. },
  145. child: Row(
  146. children: [
  147. SizedBox(
  148. width: 0.1.sw,
  149. height: 0.1.sw,
  150. child: Assets.images.iconHomeLogged.image()),
  151. SizedBox(width: 8.w),
  152. Text(StringName.homeGoLogin.tr,
  153. style: TextStyle(
  154. fontWeight: FontWeight.bold,
  155. fontSize: 15.sp,
  156. color: ColorName.primaryTextColor))
  157. ],
  158. ),
  159. );
  160. }
  161. Container buildTopGradient() {
  162. return Container(
  163. width: 1.sw,
  164. height: 112.h,
  165. decoration: BoxDecoration(
  166. gradient: LinearGradient(
  167. colors: ['#E8EBFF'.toColor(), '#00E8EBFF'.toColor()],
  168. begin: Alignment.topCenter,
  169. end: Alignment.bottomCenter,
  170. stops: const [0.3, 1.0],
  171. ),
  172. ) // 其他子小部件
  173. );
  174. }
  175. DecoratedBox buildBgBox() {
  176. return DecoratedBox(
  177. decoration: BoxDecoration(color: '#F6F6F6'.toColor()),
  178. child: Container(
  179. height: double.infinity,
  180. ));
  181. }
  182. Widget buildTalkRecord() {
  183. return SizedBox(
  184. width: 1.sw,
  185. child: CustomScrollView(
  186. scrollDirection: Axis.horizontal,
  187. slivers: [
  188. SliverToBoxAdapter(child: SizedBox(width: 12.w)),
  189. buildGoRecordView(),
  190. SliverAnimatedList(itemBuilder: _buildTalkItem, initialItemCount: 10)
  191. ],
  192. ),
  193. );
  194. }
  195. SliverToBoxAdapter buildGoRecordView() {
  196. return SliverToBoxAdapter(
  197. child: GestureDetector(
  198. onTap: () {
  199. showUnfinishedRecordPopup();
  200. },
  201. child: Container(
  202. margin: EdgeInsets.only(right: 8.w),
  203. decoration: BoxDecoration(
  204. color: Colors.white,
  205. border: Border.all(color: '#EBEBFF'.toColor(), width: 1),
  206. borderRadius: BorderRadius.circular(8.0),
  207. ),
  208. child: SizedBox(
  209. width: 100.w,
  210. height: double.infinity,
  211. child: Stack(
  212. children: [
  213. Positioned(
  214. right: 0,
  215. bottom: 0,
  216. child: SizedBox(
  217. width: 48.w,
  218. child: Assets.images.bgHomeQuickAudio.image(),
  219. ),
  220. ),
  221. Positioned.fill(
  222. child: Align(
  223. alignment: Alignment.center,
  224. child: Column(
  225. children: [
  226. SizedBox(height: 20.h),
  227. SizedBox(
  228. width: 32.w,
  229. height: 32.w,
  230. child: Assets.images.iconAddTalk.image()),
  231. SizedBox(height: 6.h),
  232. Text(StringName.homeTalkAudio.tr,
  233. style: TextStyle(
  234. fontSize: 14.sp,
  235. color: ColorName.colorPrimary,
  236. fontWeight: FontWeight.bold)),
  237. Builder(builder: (context) {
  238. todoTargetContext = context;
  239. return Text(StringName.homeTalkQuickAudio.tr,
  240. style: TextStyle(
  241. fontSize: 10.sp,
  242. color: ColorName.secondaryTextColor));
  243. })
  244. ],
  245. ),
  246. )),
  247. ],
  248. ),
  249. ),
  250. ),
  251. ));
  252. }
  253. Widget _buildTodoItem(
  254. BuildContext context, int index, Animation<double> animation) {
  255. return Container(
  256. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 17).w,
  257. margin: const EdgeInsets.only(left: 12, right: 12, bottom: 8).w,
  258. decoration: BoxDecoration(
  259. color: Colors.white,
  260. borderRadius: BorderRadius.circular(8),
  261. ),
  262. child: Row(
  263. crossAxisAlignment: CrossAxisAlignment.center,
  264. children: [
  265. SizedBox(
  266. width: 20.w,
  267. height: 20.w,
  268. child: Assets.images.iconAgentChecked.image()),
  269. SizedBox(width: 8.w),
  270. Text('今天要完成某项任务',
  271. style: TextStyle(
  272. fontSize: 15.sp,
  273. fontWeight: FontWeight.bold,
  274. color: ColorName.primaryTextColor)),
  275. const Spacer(),
  276. Container(
  277. decoration: BoxDecoration(
  278. gradient: LinearGradient(
  279. colors: ['#9075FF'.toColor(), '#4366FF'.toColor()],
  280. stops: const [0.3, 1.0],
  281. ),
  282. borderRadius: BorderRadius.circular(6),
  283. ),
  284. padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 4).w,
  285. child: Text(
  286. StringName.homeTalkThinking.tr,
  287. style: TextStyle(fontSize: 13.sp, color: ColorName.white),
  288. ),
  289. )
  290. ],
  291. ),
  292. );
  293. }
  294. Widget _buildTalkItem(
  295. BuildContext context, int index, Animation<double> animation) {
  296. return Container(
  297. width: 258.w,
  298. margin: EdgeInsets.only(right: 8.w),
  299. decoration: BoxDecoration(
  300. color: Colors.white,
  301. border: Border.all(color: '#F0F0F0'.toColor(), width: 1),
  302. borderRadius: BorderRadius.circular(8),
  303. ),
  304. height: double.infinity,
  305. padding: EdgeInsets.symmetric(horizontal: 12.w),
  306. child: Column(
  307. mainAxisAlignment: MainAxisAlignment.center,
  308. crossAxisAlignment: CrossAxisAlignment.start,
  309. children: [
  310. Row(
  311. children: [
  312. Container(
  313. padding: const EdgeInsets.symmetric(horizontal: 6).w,
  314. decoration: BoxDecoration(
  315. color: '#DFE4FC'.toColor(),
  316. borderRadius: BorderRadius.circular(4),
  317. ),
  318. child: Text(
  319. StringName.homeTalkExample.tr,
  320. style: TextStyle(
  321. fontSize: 12.sp, color: ColorName.colorPrimary),
  322. )),
  323. SizedBox(width: 6.w),
  324. Text('与吴总张总沟通活动策划',
  325. style: TextStyle(
  326. fontSize: 15.sp,
  327. color: ColorName.colorPrimary,
  328. fontWeight: FontWeight.bold))
  329. ],
  330. ),
  331. SizedBox(height: 5.h),
  332. Text(
  333. style: TextStyle(
  334. fontSize: 12.sp, color: ColorName.secondaryTextColor),
  335. overflow: TextOverflow.ellipsis,
  336. maxLines: 2,
  337. '这个群,现在由我管理。目的是把你们训练成一个个社会高薪人士,从本周起,已经个个社会高薪人士,从本周起,已经个个社会高薪人士,从本周起,已经'),
  338. SizedBox(height: 8.h),
  339. Row(
  340. crossAxisAlignment: CrossAxisAlignment.center,
  341. children: [
  342. Text('1m12s',
  343. style: TextStyle(
  344. fontSize: 12.sp, color: ColorName.tertiaryTextColor)),
  345. SizedBox(width: 6.w),
  346. Container(
  347. width: 1, height: 9, color: ColorName.tertiaryTextColor),
  348. SizedBox(width: 6.w),
  349. Text('2024-04-15 10:04',
  350. style: TextStyle(
  351. fontSize: 12.sp, color: ColorName.tertiaryTextColor))
  352. ],
  353. )
  354. ],
  355. ));
  356. }
  357. Widget buildTitle(String titleName, VoidCallback onTap) {
  358. return Padding(
  359. padding: const EdgeInsets.symmetric(horizontal: 12).w,
  360. child: Row(
  361. crossAxisAlignment: CrossAxisAlignment.center,
  362. children: [
  363. Text(titleName,
  364. style: TextStyle(
  365. fontWeight: FontWeight.bold,
  366. fontSize: 17.sp,
  367. color: ColorName.primaryTextColor)),
  368. const Spacer(),
  369. GestureDetector(
  370. onTap: onTap,
  371. child: Padding(
  372. padding: const EdgeInsets.symmetric(vertical: 6).w,
  373. child: Row(
  374. crossAxisAlignment: CrossAxisAlignment.center,
  375. children: [
  376. Text(
  377. StringName.homeTalkSeeAll.tr,
  378. style: TextStyle(
  379. fontSize: 13.sp, color: ColorName.secondaryTextColor),
  380. ),
  381. SizedBox(
  382. width: 16.w,
  383. height: 16.w,
  384. child: Assets.images.iconHomeTalkArrow.image()),
  385. ],
  386. ),
  387. ),
  388. )
  389. ],
  390. ),
  391. );
  392. }
  393. attachDialog(BuildContext? context, Alignment alignment) {
  394. SmartDialog.showAttach(
  395. targetContext: context,
  396. alignment: alignment,
  397. animationType: SmartAnimationType.fade,
  398. clickMaskDismiss: true,
  399. maskColor: Colors.transparent,
  400. bindPage: true,
  401. builder: (_) => Padding(
  402. padding: const EdgeInsets.only(top: 7).h,
  403. child: Stack(
  404. alignment: Alignment.topCenter,
  405. children: [
  406. SizedBox(
  407. width: 146.w,
  408. height: 66.w,
  409. child: Assets.images.bgAudioTodoPopup.image()),
  410. Container(
  411. alignment: Alignment.center,
  412. padding: const EdgeInsets.only(top: 17).w,
  413. width: 146.w,
  414. child: Text(StringName.homePopupTipsTxt.tr,
  415. style: TextStyle(fontSize: 14.sp, color: Colors.white)))
  416. ],
  417. ),
  418. ),
  419. );
  420. }
  421. void showUnfinishedRecordPopup() {
  422. attachDialog(todoTargetContext, Alignment.bottomRight);
  423. }
  424. }