view.dart 10 KB

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