view.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/module/agenda/task_item_view.dart';
  3. import 'package:electronic_assistant/resource/colors.gen.dart';
  4. import 'package:electronic_assistant/resource/string.gen.dart';
  5. import 'package:electronic_assistant/router/app_pages.dart';
  6. import 'package:electronic_assistant/utils/expand.dart';
  7. import 'package:flutter/cupertino.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter/services.dart';
  10. import 'package:flutter_screenutil/flutter_screenutil.dart';
  11. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  12. import 'package:get/get.dart';
  13. import 'package:pull_to_refresh/pull_to_refresh.dart';
  14. import '../../data/bean/agenda.dart';
  15. import '../../data/repositories/account_repository.dart';
  16. import '../../popup/common_popup.dart';
  17. import '../../popup/template_utils.dart';
  18. import '../../resource/assets.gen.dart';
  19. import '../chat/view.dart';
  20. import 'controller.dart';
  21. class AgendaPage extends BasePage<AgendaController> {
  22. const AgendaPage({super.key});
  23. @override
  24. Widget buildBody(BuildContext context) {
  25. return Stack(
  26. children: [
  27. buildBgBox(),
  28. buildTopGradient(),
  29. Column(
  30. crossAxisAlignment: CrossAxisAlignment.start,
  31. children: [
  32. AppBar(
  33. systemOverlayStyle: SystemUiOverlayStyle.dark,
  34. backgroundColor: Colors.transparent,
  35. leading: IconButton(
  36. icon: SizedBox(
  37. width: 24.w,
  38. height: 24.w,
  39. child: Assets.images.iconBack.image()),
  40. // Custom icon
  41. onPressed: () {
  42. Get.back();
  43. },
  44. ),
  45. title: Text(StringName.taskTitle.tr,
  46. style: TextStyle(
  47. fontSize: 17.sp,
  48. fontWeight: FontWeight.bold,
  49. color: ColorName.primaryTextColor)),
  50. centerTitle: true,
  51. ),
  52. // Row(
  53. // children: [
  54. // Expanded(
  55. // child: Padding(
  56. // padding: EdgeInsets.only(left: 12.w),
  57. // child: CupertinoSearchTextField(
  58. // enabled: false,
  59. // onTap: () {
  60. // Get.toNamed(RoutePath.taskSearch);
  61. // },
  62. // placeholder: StringName.searchHint.tr,
  63. // prefixIcon: ImageIcon(Assets.images.iconSearch.provider(),
  64. // size: 20.w),
  65. // backgroundColor: Colors.white,
  66. // style: TextStyle(
  67. // fontSize: 14.w, color: ColorName.primaryTextColor),
  68. // placeholderStyle: TextStyle(
  69. // fontSize: 14.w, color: const Color(0xFFAFAFAF)),
  70. // ),
  71. // )),
  72. // GestureDetector(
  73. // onTap: () {},
  74. // child: Column(
  75. // mainAxisAlignment: MainAxisAlignment.center,
  76. // children: [
  77. // Container(
  78. // margin: EdgeInsets.symmetric(horizontal: 16.w),
  79. // width: 20.w,
  80. // height: 20.w,
  81. // child: Assets.images.iconSift.image()),
  82. // // Replace with your image asset
  83. // SizedBox(height: 2.h),
  84. // // Add some space between the image and text
  85. // Text(
  86. // StringName.agendaSift.tr,
  87. // style: TextStyle(
  88. // fontSize: 10.sp, color: ColorName.primaryTextColor),
  89. // ),
  90. // ],
  91. // ),
  92. // )
  93. // ],
  94. // ),
  95. // SizedBox(height: 12.h),
  96. // Container(
  97. // margin: EdgeInsets.only(left: 12.w),
  98. // padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
  99. // decoration: BoxDecoration(
  100. // color: const Color(0xFFE9E9E9),
  101. // borderRadius: BorderRadius.circular(8.w)),
  102. // child: IntrinsicWidth(
  103. // child: Row(
  104. // children: [
  105. // Text(controller.filterTxt,
  106. // style: TextStyle(
  107. // fontSize: 13.sp,
  108. // color: ColorName.secondaryTextColor)),
  109. // SizedBox(width: 6.w),
  110. // Opacity(
  111. // opacity: 0.7,
  112. // child: ImageIcon(
  113. // Assets.images.iconTaskFilterClose.provider(),
  114. // size: 16.w))
  115. // ],
  116. // ),
  117. // ),
  118. // ),
  119. SizedBox(width: 7.h),
  120. Expanded(
  121. child: SmartRefresher(
  122. footer: const ClassicFooter(
  123. noDataText: '',
  124. ),
  125. onLoading: controller.onLoadMoreDoneData,
  126. enablePullDown: false,
  127. enablePullUp: true,
  128. controller: controller.refreshController,
  129. child: CustomScrollView(slivers: [
  130. SliverToBoxAdapter(
  131. child: Obx(() {
  132. return taskGroupItem(
  133. StringName.taskItemTodo.tr,
  134. controller.agendaTodoList.length,
  135. controller.todoIsExpanded.value, itemClick: () {
  136. controller.onClickTodoGroup();
  137. });
  138. }),
  139. ),
  140. Obx(() {
  141. return SliverList.builder(
  142. itemBuilder: _buildTodoItem,
  143. itemCount: controller.todoIsExpanded.value
  144. ? controller.agendaTodoList.length
  145. : 0);
  146. }),
  147. SliverToBoxAdapter(
  148. child: Obx(() {
  149. return taskGroupItem(
  150. StringName.taskItemDone.tr,
  151. controller.doneSize.value,
  152. controller.doneIsExpanded.value, itemClick: () {
  153. controller.onClickDoneGroup();
  154. });
  155. }),
  156. ),
  157. Obx(() {
  158. return SliverList.builder(
  159. itemBuilder: _buildDoneItem,
  160. itemCount: controller.doneIsExpanded.value
  161. ? controller.agendaDoneList.length
  162. : 0);
  163. })
  164. ]),
  165. ))
  166. ],
  167. )
  168. ],
  169. );
  170. }
  171. Widget _buildTodoItem(BuildContext context, int index) {
  172. Agenda item = controller.agendaTodoList[index];
  173. return Builder(builder: (context) {
  174. return GestureDetector(
  175. onLongPressStart: (details) {
  176. if (!accountRepository.isLogin.value) {
  177. return;
  178. }
  179. showCommonPopup(details.globalPosition, Alignment.bottomRight,
  180. _buildListUpdatePopupView(item, controller.agendaDetailPopupTag),
  181. tag: controller.agendaDetailPopupTag);
  182. },
  183. child: taskItemView(
  184. item,
  185. onCheckClick: () {
  186. controller.agendaComplete(item, true);
  187. },
  188. onThinkingClick: () {
  189. ChatPage.startByTalkId(item.talkId, agenda: item);
  190. },
  191. ),
  192. );
  193. });
  194. }
  195. List<Widget> _buildListUpdatePopupView(Agenda item, String tag) {
  196. return [
  197. createNormalPopupItem(StringName.agendaDetailPopupCancel.tr,
  198. onItemClick: () {
  199. SmartDialog.dismiss(tag: tag);
  200. controller.onAgendaCancel(item);
  201. }),
  202. createPopupDivider(),
  203. createNormalPopupItem(StringName.agendaDetailPopupUpdate.tr,
  204. onItemClick: () {
  205. SmartDialog.dismiss(tag: tag);
  206. controller.onAgendaUpdate(item);
  207. }),
  208. ];
  209. }
  210. Widget _buildDoneItem(BuildContext context, int index) {
  211. Agenda item = controller.agendaDoneList[index];
  212. return taskItemView(item, onCheckClick: () {
  213. controller.agendaComplete(item, false);
  214. }, isShowAnalyse: false);
  215. }
  216. Container buildTopGradient() {
  217. return Container(
  218. width: 1.sw,
  219. height: 112.h,
  220. decoration: BoxDecoration(
  221. gradient: LinearGradient(
  222. colors: ['#E8EBFF'.toColor(), '#00E8EBFF'.toColor()],
  223. begin: Alignment.topCenter,
  224. end: Alignment.bottomCenter,
  225. stops: const [0.3, 1.0],
  226. ),
  227. ) // 其他子小部件
  228. );
  229. }
  230. DecoratedBox buildBgBox() {
  231. return DecoratedBox(
  232. decoration: BoxDecoration(color: '#F6F6F6'.toColor()),
  233. child: Container(
  234. height: double.infinity,
  235. ));
  236. }
  237. @override
  238. bool immersive() {
  239. return true;
  240. }
  241. Widget taskGroupItem(String groupName, int count, bool isExpanded,
  242. {VoidCallback? itemClick}) {
  243. return GestureDetector(
  244. onTap: itemClick,
  245. child: Container(
  246. color: Colors.transparent,
  247. padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 12.w),
  248. child: Row(
  249. crossAxisAlignment: CrossAxisAlignment.center,
  250. children: [
  251. Text(groupName,
  252. style: TextStyle(
  253. fontSize: 14.sp, color: ColorName.secondaryTextColor)),
  254. //占位填充
  255. const Spacer(),
  256. Row(
  257. children: [
  258. Text('$count${StringName.taskItemDesc.tr}',
  259. style: TextStyle(
  260. fontSize: 12.sp, color: ColorName.secondaryTextColor)),
  261. SizedBox(width: 4.w),
  262. SizedBox(
  263. width: 16.w,
  264. height: 16.h,
  265. child: isExpanded
  266. ? Assets.images.iconTalkExpand.image()
  267. : Assets.images.iconTalkCollapse.image())
  268. ],
  269. )
  270. ],
  271. ),
  272. ),
  273. );
  274. }
  275. }