view.dart 14 KB

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