view.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/data/bean/talks.dart';
  3. import 'package:electronic_assistant/data/consts/constants.dart';
  4. import 'package:electronic_assistant/module/files/controller.dart';
  5. import 'package:electronic_assistant/module/talk/view.dart';
  6. import 'package:electronic_assistant/resource/colors.gen.dart';
  7. import 'package:electronic_assistant/resource/string.gen.dart';
  8. import 'package:electronic_assistant/utils/expand.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:flutter_screenutil/flutter_screenutil.dart';
  11. import 'package:get/get.dart';
  12. import 'package:pull_to_refresh/pull_to_refresh.dart';
  13. import '../../data/repositories/account_repository.dart';
  14. import '../../dialog/rename_dialog.dart';
  15. import '../../dialog/talk_delete_dialog.dart';
  16. import '../../popup/talk_popup.dart';
  17. import '../../resource/assets.gen.dart';
  18. class FilesPage extends BasePage<FilesController> {
  19. const FilesPage({super.key});
  20. @override
  21. bool immersive() {
  22. return true;
  23. }
  24. @override
  25. Widget buildBody(BuildContext context) {
  26. return Scaffold(
  27. backgroundColor: const Color.fromRGBO(246, 245, 248, 1),
  28. appBar: AppBar(
  29. title: Text(StringName.talkAll.tr),
  30. backgroundColor: const Color.fromRGBO(246, 245, 248, 1),
  31. scrolledUnderElevation: 0,
  32. // actions: [
  33. // IconButton(
  34. // onPressed: () {},
  35. // icon: ImageIcon(Assets.images.iconFilesNewDir.provider()),
  36. // ),
  37. // IconButton(
  38. // onPressed: () {},
  39. // icon: ImageIcon(Assets.images.iconMore.provider()),
  40. // ),
  41. // ],
  42. ),
  43. body: Column(
  44. children: [
  45. // Column(
  46. // children: [
  47. // GestureDetector(
  48. // onTap: () {
  49. // Get.toNamed(RoutePath.fileSearch);
  50. // },
  51. // child: Container(
  52. // margin: EdgeInsets.symmetric(horizontal: 12.w),
  53. // padding:
  54. // EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.w),
  55. // height: 36.w,
  56. // decoration: BoxDecoration(
  57. // color: Colors.white,
  58. // borderRadius: BorderRadius.circular(8.w),
  59. // ),
  60. // child: TextField(
  61. // maxLines: 1,
  62. // textAlignVertical: TextAlignVertical.center,
  63. // textInputAction: TextInputAction.search,
  64. // decoration: InputDecoration(
  65. // hintText: '搜索所有文件标题 / 内容',
  66. // border: InputBorder.none,
  67. // icon: ImageIcon(Assets.images.iconSearch.provider()),
  68. // iconColor: const Color.fromRGBO(95, 95, 97, 1),
  69. // enabled: false),
  70. // style: TextStyle(fontSize: 14.sp),
  71. // ),
  72. // ),
  73. // ),
  74. // ],
  75. // ),
  76. Expanded(
  77. child: Padding(
  78. // padding: EdgeInsets.only(top: 16.w, left: 12.w, right: 12.w),
  79. padding: EdgeInsets.only(left: 12.w, right: 12.w),
  80. child: SmartRefresher(
  81. enablePullUp: true,
  82. enablePullDown: true,
  83. controller: controller.refreshController,
  84. onRefresh: controller.onRefreshData,
  85. onLoading: controller.onLoadMoreTalkData,
  86. footer: ClassicFooter(
  87. height: Constants.bottomBarHeight + 80,
  88. outerBuilder: (child) {
  89. return Padding(
  90. padding: EdgeInsets.only(bottom: Constants.bottomBarHeight),
  91. child: child,
  92. );
  93. },
  94. canLoadingText: StringName.loadingMore.tr,
  95. idleText: StringName.loadPullUp.tr,
  96. loadingText: StringName.loadingTxt.tr,
  97. noDataText: StringName.loadNoData.tr,
  98. failedText: StringName.loadFailed.tr,
  99. ),
  100. child: CustomScrollView(
  101. slivers: [
  102. // SliverAnimatedGrid(
  103. // itemBuilder: _buildDirItem,
  104. // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  105. // crossAxisCount: 2,
  106. // crossAxisSpacing: 8.w,
  107. // mainAxisSpacing: 8.w,
  108. // childAspectRatio: 164 / 65,
  109. // ),
  110. // initialItemCount: 10,
  111. // ),
  112. // SliverToBoxAdapter(
  113. // child: Padding(
  114. // padding: EdgeInsets.only(top: 20.w, bottom: 12.w),
  115. // child: Text(StringName.talkAll.tr,
  116. // style: TextStyle(
  117. // fontSize: 14.sp,
  118. // color: ColorName.secondaryTextColor,
  119. // fontWeight: FontWeight.bold))),
  120. // ),
  121. Obx(() {
  122. return SliverList.builder(
  123. itemBuilder: _buildFileItem,
  124. itemCount: controller.talkList.length);
  125. }),
  126. ],
  127. ),
  128. ),
  129. ))
  130. ],
  131. ),
  132. );
  133. }
  134. Widget _buildDirItem(
  135. BuildContext context, int index, Animation<double> animation) {
  136. return Container(
  137. decoration: BoxDecoration(
  138. color: Colors.white,
  139. borderRadius: BorderRadius.circular(8.w),
  140. ),
  141. padding: EdgeInsets.only(left: 8.w),
  142. child: Row(
  143. crossAxisAlignment: CrossAxisAlignment.center,
  144. children: [
  145. Image(
  146. image: Assets.images.iconFilesDir.provider(),
  147. width: 32.w,
  148. height: 32.w),
  149. Expanded(
  150. child: Padding(
  151. padding: EdgeInsets.symmetric(horizontal: 8.w),
  152. child: Column(
  153. mainAxisAlignment: MainAxisAlignment.center,
  154. crossAxisAlignment: CrossAxisAlignment.start,
  155. children: [
  156. Text('文件夹',
  157. maxLines: 1,
  158. overflow: TextOverflow.ellipsis,
  159. style: TextStyle(
  160. fontSize: 14.sp,
  161. color: ColorName.primaryTextColor,
  162. fontWeight: FontWeight.bold)),
  163. Text('2021-09-09 12:00:00',
  164. maxLines: 1,
  165. overflow: TextOverflow.ellipsis,
  166. style: TextStyle(
  167. fontSize: 12.sp, color: ColorName.secondaryTextColor)),
  168. ],
  169. ),
  170. ))
  171. ],
  172. ),
  173. );
  174. }
  175. Widget _buildFileItem(BuildContext context, int index) {
  176. TalkBean talkBean = controller.talkList[index];
  177. return Obx(() {
  178. return buildFileTalkItem(talkBean, onTap: () {
  179. TalkPage.start(talkBean);
  180. }, onLongPressStart: (details) {
  181. if (!accountRepository.isLogin.value) {
  182. return;
  183. }
  184. showTalkPopup(details.globalPosition, Alignment.bottomRight,
  185. onRename: () {
  186. showRenameTalkDialog(talkBean);
  187. }, onDelete: () {
  188. showDeleteTalkDialog(talkBean);
  189. });
  190. });
  191. });
  192. }
  193. void showRenameTalkDialog(TalkBean item) {
  194. reNameDialog(StringName.talkRenameTitle.tr, item.title.value,
  195. hintTxt: StringName.talkRenameTitleHint.tr,
  196. maxLength: 15, returnBuilder: (newName) {
  197. controller.requestName(newName, item);
  198. });
  199. }
  200. void showDeleteTalkDialog(TalkBean item) {
  201. talkDeleteDialog(item.id, item.title.value, returnBuilder: () {
  202. controller.requestDelete(item);
  203. });
  204. }
  205. }
  206. Widget buildFileTalkItem(TalkBean talkBean,
  207. {GestureTapCallback? onTap,
  208. GestureLongPressStartCallback? onLongPressStart}) {
  209. return Padding(
  210. padding: EdgeInsets.only(bottom: 8.w),
  211. child: GestureDetector(
  212. onLongPressStart: onLongPressStart,
  213. onTap: onTap,
  214. child: Container(
  215. decoration: BoxDecoration(
  216. color: Colors.white,
  217. borderRadius: BorderRadius.circular(8.w),
  218. ),
  219. padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 14.w),
  220. child: Row(
  221. crossAxisAlignment: CrossAxisAlignment.start,
  222. children: [
  223. Image(
  224. image: (talkBean.status.value == TalkStatus.analysing ||
  225. talkBean.status.value == TalkStatus.waitAnalysis)
  226. ? Assets.images.iconTalkAnalysis.provider()
  227. : Assets.images.iconFilesFile.provider(),
  228. width: 28.w,
  229. height: 32.w),
  230. Expanded(
  231. child: Padding(
  232. padding: EdgeInsets.symmetric(horizontal: 8.w),
  233. child: Column(
  234. crossAxisAlignment: CrossAxisAlignment.start,
  235. children: [
  236. Text(talkBean.title.value.orEmpty,
  237. maxLines: 1,
  238. overflow: TextOverflow.ellipsis,
  239. style: TextStyle(
  240. fontSize: 14.sp,
  241. color: ColorName.primaryTextColor,
  242. fontWeight: FontWeight.bold)),
  243. Text(talkBean.summary.value.orEmpty,
  244. maxLines: 2,
  245. overflow: TextOverflow.ellipsis,
  246. style: TextStyle(
  247. fontSize: 12.sp,
  248. color:
  249. talkBean.status.value == TalkStatus.analysisFail
  250. ? "#F5574E".toColor()
  251. : ColorName.secondaryTextColor)),
  252. Container(
  253. margin: EdgeInsets.only(top: 6.w),
  254. child: Row(
  255. crossAxisAlignment: CrossAxisAlignment.center,
  256. children: [
  257. Text(talkBean.duration.toFormattedDuration(),
  258. style: TextStyle(
  259. fontSize: 12.sp,
  260. color: ColorName.tertiaryTextColor)),
  261. Text(" | ",
  262. style: TextStyle(
  263. fontSize: 12.sp,
  264. color: ColorName.tertiaryTextColor,
  265. fontWeight: FontWeight.bold)),
  266. Text(talkBean.createTime.orEmpty,
  267. style: TextStyle(
  268. fontSize: 12.sp,
  269. color: ColorName.tertiaryTextColor)),
  270. ],
  271. ),
  272. )
  273. ],
  274. ),
  275. )),
  276. ],
  277. ),
  278. ),
  279. ));
  280. }