message_list.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import 'package:easy_localization/easy_localization.dart';
  2. import 'package:easy_refresh/easy_refresh.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:provider/provider.dart';
  5. import 'package:telnow_mobile_new/src/layouts/functions/message.dart';
  6. import 'package:telnow_mobile_new/src/layouts/mobile/message_chat.dart';
  7. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  8. import 'package:telnow_mobile_new/src/utils/C.dart';
  9. import 'package:telnow_mobile_new/src/utils/U.dart';
  10. import 'package:telnow_mobile_new/src/utils/provider.dart';
  11. import 'history_forum.dart';
  12. class MobMessageListPage extends StatefulWidget {
  13. Map<String, dynamic>? user;
  14. MobMessageListPage(this.user, {super.key});
  15. @override
  16. State<MobMessageListPage> createState() => _MobMessageListPageState();
  17. }
  18. class _MobMessageListPageState extends State<MobMessageListPage> {
  19. final MessageFunction messageFunc = MessageFunction();
  20. @override
  21. void initState() {
  22. Provider.of<MessageModule>(context, listen: false).reset();
  23. if(widget.user == null){
  24. messageFunc.getUser(context);
  25. } else {
  26. WidgetsBinding.instance.addPostFrameCallback((_) {
  27. Provider.of<MessageModule>(context, listen: false).setUser(widget.user!);
  28. });
  29. messageFunc.getDataMessages(context);
  30. }
  31. // TODO: implement initState
  32. super.initState();
  33. }
  34. @override
  35. Widget build(BuildContext context) {
  36. Widget chat(){
  37. return Column(
  38. children: [
  39. divider(),
  40. Expanded(
  41. child: Container(
  42. alignment: Alignment.topCenter,
  43. width: U.bodyWidth(context),
  44. child: EasyRefresh(
  45. header: MaterialHeader(clamping: true, color: primaryColor),
  46. onRefresh: () => messageFunc.onRefresh(context),
  47. child: Provider.of<MessageModule>(context).data().isEmpty && !Provider.of<MessageModule>(context).firstLoad()? loadingTemplateNoVoid() : Provider.of<MessageModule>(context).data().isEmpty ? Center(
  48. child: Text('noMessageText').tr(),
  49. ) : ListView(
  50. padding: EdgeInsets.only(top: 12.0),
  51. children: List.generate(Provider.of<MessageModule>(context).data().length, (i) {
  52. bool isMe = Provider.of<MessageModule>(context, listen: false).data()[i]['userId'] == Provider.of<MessageModule>(context, listen: false).user()['userId'] ? true : false;
  53. return GestureDetector(
  54. child: Container(
  55. child: ListTile(
  56. leading: Provider.of<MessageModule>(context).data()[i]['senderAvatar'] != null && Provider.of<MessageModule>(context).data()[i]['senderAvatar'] != '' ? CircleAvatar(
  57. backgroundImage: NetworkImage(Provider.of<MessageModule>(context).data()[i]['senderAvatar']),
  58. radius: 24,
  59. ) : Container(
  60. height: 48,
  61. width: 48,
  62. child: Center(child: Text(isMe ? Provider.of<MessageModule>(context).data()[i]['recipientName'] == "all_informants" ? "allInformants".tr()[0] : Provider.of<MessageModule>(context).data()[i]['recipientName'][0] : Provider.of<MessageModule>(context).data()[i]['senderName'][0], style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18))),
  63. decoration: BoxDecoration(shape: BoxShape.circle, color: Color(U.getColor(isMe ? Provider.of<MessageModule>(context).data()[i]['recipient'] : Provider.of<MessageModule>(context).data()[i]['recipientId']))),
  64. ),
  65. title: Text(isMe ? Provider.of<MessageModule>(context).data()[i]['recipientName'] == "all_informants" ? "allInformants".tr() : Provider.of<MessageModule>(context).data()[i]['recipientName'] : Provider.of<MessageModule>(context).data()[i]['senderName']),
  66. subtitle: Row(
  67. children: [
  68. isMe ? Padding(
  69. padding: EdgeInsets.only(right: 4),
  70. child: Icon(Icons.done_all, size: 18, color: Colors.blueGrey),
  71. ) : Container(),
  72. Provider.of<MessageModule>(context).data()[i]['isImage'] ? Align(
  73. alignment: Alignment.centerLeft,
  74. child: Row(
  75. children: [
  76. Icon(Provider.of<MessageModule>(context).data()[i]['fileType'] == 'pdf' ? Icons.picture_as_pdf : Icons.image, color: Colors.black45, size: 16),
  77. SizedBox(width: 6),
  78. Provider.of<MessageModule>(context).data()[i]['lastText'] == '' ? Provider.of<MessageModule>(context).data()[i]['fileType'] == 'pdf' ? Text('pdfFile'.tr()) : Text('photo'.tr()) : Container()
  79. ],
  80. ),
  81. ) : Container(),
  82. Expanded(
  83. child: Text(Provider.of<MessageModule>(context).data()[i]['lastText'], style: TextStyle(fontSize: 13), maxLines: 1, overflow: TextOverflow.ellipsis),
  84. )
  85. ],
  86. ),
  87. trailing: Column(
  88. mainAxisAlignment: MainAxisAlignment.center,
  89. crossAxisAlignment: CrossAxisAlignment.end,
  90. children: [
  91. Text(messageFunc.timeSet(Provider.of<MessageModule>(context).data()[i]['lastDateTimeSend']), style: TextStyle(fontSize: 11, color: Provider.of<MessageModule>(context).data()[i]['lastReadStatus'] == 'UNREAD' && !isMe ? Colors.green : Colors.black45)),
  92. SizedBox(height: 4),
  93. Icon(Icons.circle, color: Colors.green.withValues(alpha: Provider.of<MessageModule>(context).data()[i]['lastReadStatus'] == 'UNREAD' && !isMe ? 1 : 0))
  94. ],
  95. ),
  96. ),
  97. ),
  98. onTap: () async {
  99. navigateTo(context, MobMessageChatPage(Provider.of<MessageModule>(context, listen: false).user(), Provider.of<MessageModule>(context, listen: false).data()[i]['chatId'], isMe ? Provider.of<MessageModule>(context, listen: false).data()[i]['recipientName'] : Provider.of<MessageModule>(context, listen: false).data()[i]['senderName'], Provider.of<MessageModule>(context, listen: false).data()[i]['id'].toString(), isMe, Provider.of<MessageModule>(context, listen: false).data()[i]['recipient']));
  100. messageFunc.onRefresh(context);
  101. });
  102. })
  103. ),
  104. ),
  105. ),
  106. )
  107. ],
  108. );
  109. }
  110. Widget forum(){
  111. return Column(
  112. children: [
  113. Expanded(
  114. child: Container(
  115. alignment: Alignment.topCenter,
  116. width: U.bodyWidth(context),
  117. child: EasyRefresh(
  118. header: MaterialHeader(clamping: true, color: primaryColor),
  119. onRefresh: () => messageFunc.onRefresh(context),
  120. child: Provider.of<MessageModule>(context).forum().isEmpty && !Provider.of<MessageModule>(context).firstLoad()? loadingTemplateNoVoid() : Provider.of<MessageModule>(context).forum().isEmpty ? Center(
  121. child: Text('noMessageText').tr(),
  122. ) : ListView(
  123. padding: EdgeInsets.only(top: 16.0),
  124. children: List.generate(Provider.of<MessageModule>(context).forum().length, (i){
  125. return GestureDetector(
  126. onTap: (){
  127. navigateTo(context, MobHistoryForumPage(data: Provider.of<MessageModule>(context, listen: false).forum()[i]['ticket'])).then((_){
  128. messageFunc.getDataForum(context);
  129. });
  130. },
  131. child: Container(
  132. decoration: BoxDecoration(
  133. color: Colors.white,
  134. ),
  135. width: double.infinity,
  136. child: Column(
  137. children: [
  138. Padding(
  139. padding: const EdgeInsets.all(12.0),
  140. child: Row(
  141. children: [
  142. Container(
  143. height: 50,
  144. width: 50,
  145. decoration: BoxDecoration(
  146. image: Provider.of<MessageModule>(context).forum()[i]['ticket']['_requestImage'] != null && Provider.of<MessageModule>(context).forum()[i]['ticket']['_requestImage'].isNotEmpty
  147. ? DecorationImage(image: NetworkImage(Provider.of<MessageModule>(context).forum()[i]['ticket']['_requestImage']))
  148. : null,
  149. border: Border.all(color: Colors.black12),
  150. borderRadius: BorderRadius.circular(50),
  151. ),
  152. ),
  153. SizedBox(width: 12,),
  154. ConstrainedBox(
  155. constraints: BoxConstraints(
  156. maxWidth: MediaQuery.of(context).size.width - (16*2+12+50),
  157. ),
  158. child: Column(
  159. crossAxisAlignment: CrossAxisAlignment.start,
  160. children: [
  161. Row(
  162. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  163. crossAxisAlignment: CrossAxisAlignment.start,
  164. children: [
  165. Flexible(
  166. child: Text(
  167. Provider.of<MessageModule>(context).forum()[i]['ticket'][U.langColumn(context, 'requestSubject')] ?? "",
  168. maxLines: 1,
  169. overflow: TextOverflow.ellipsis,
  170. softWrap: false,
  171. style: TextStyle(
  172. fontWeight: FontWeight.w600,
  173. ),
  174. ),
  175. ),
  176. SizedBox(width: 8),
  177. Text(
  178. convertDate(Provider.of<MessageModule>(context).forum()[i]['datetime'], context.locale.toString()),
  179. style: TextStyle(
  180. fontSize: 12,
  181. fontWeight: Provider.of<MessageModule>(context).forum()[i]['readStatus']=='UNREAD' ? FontWeight.w600 : FontWeight.w300,
  182. color: Provider.of<MessageModule>(context).forum()[i]['readStatus']=='UNREAD' ? primaryColor : Colors.black,
  183. ),
  184. ),
  185. ],
  186. ),
  187. SizedBox(height: 8,),
  188. Row(
  189. crossAxisAlignment: CrossAxisAlignment.start,
  190. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  191. children: [
  192. Flexible(
  193. child: Text(
  194. Provider.of<MessageModule>(context).forum()[i]['msg'],
  195. overflow: TextOverflow.ellipsis,
  196. maxLines: 2,
  197. ),
  198. ),
  199. SizedBox(width: 12,),
  200. Provider.of<MessageModule>(context).forum()[i]['readStatus']=='UNREAD' ? Container(
  201. width: 12,
  202. height: 12,
  203. decoration: BoxDecoration(
  204. borderRadius: BorderRadius.all(Radius.circular(12)),
  205. color: primaryColor
  206. ),
  207. ):SizedBox()
  208. ],
  209. ),
  210. ],
  211. ),
  212. ),
  213. ],
  214. ),
  215. ),
  216. Container(
  217. padding: EdgeInsets.only(top: 16),
  218. height: 8,
  219. decoration: BoxDecoration(
  220. color: Color(0xFFF3F3F3)
  221. ),
  222. )
  223. ],
  224. )
  225. ),
  226. );
  227. }),
  228. )
  229. ),
  230. ),
  231. ),
  232. ],
  233. );
  234. }
  235. Widget tabForum(){
  236. return Row(
  237. mainAxisAlignment: MainAxisAlignment.start,
  238. children: [
  239. GestureDetector(
  240. onTap: () {
  241. Provider.of<MessageModule>(context, listen: false).setActiveTab(0);
  242. },
  243. child: Container(
  244. margin: EdgeInsets.only(left: 16),
  245. padding: EdgeInsets.symmetric(vertical: 5, horizontal: 16),
  246. decoration: BoxDecoration(
  247. color: Colors.white,
  248. border: Border(bottom: BorderSide(color: Provider.of<MessageModule>(context).activeTab() == 0 ? primaryColor : primaryColor.withValues(alpha: 0.3), width: Provider.of<MessageModule>(context).activeTab() == 0 ? 2 : 1))),
  249. child: Text('chat'.tr(), style: TextStyle(color: Provider.of<MessageModule>(context).activeTab() == 0 ? textColor : textColor.withValues(alpha: 0.65), fontSize: 16)),
  250. ),
  251. ),
  252. GestureDetector(
  253. onTap: () {
  254. Provider.of<MessageModule>(context, listen: false).setActiveTab(1);
  255. },
  256. child: Container(
  257. padding: EdgeInsets.symmetric(vertical: 5, horizontal: 16),
  258. decoration: BoxDecoration(
  259. color: Colors.white,
  260. border: Border(bottom: BorderSide(color: Provider.of<MessageModule>(context).activeTab() == 1 ? primaryColor : primaryColor.withValues(alpha: 0.3), width: Provider.of<MessageModule>(context).activeTab() == 1 ? 2 : 1))),
  261. child: Text('forum'.tr(), style: TextStyle(color: Provider.of<MessageModule>(context).activeTab() == 1 ? textColor : textColor.withValues(alpha: 0.65), fontSize: 16)),
  262. ),
  263. ),
  264. ],
  265. );
  266. }
  267. Widget bodyForum(){
  268. return Column(
  269. children: [
  270. divider(padding: EdgeInsets.only(bottom: 12)),
  271. tabForum(),
  272. SizedBox(height: 12,),
  273. Expanded(
  274. child: Provider.of<MessageModule>(context).activeTab() == 0 ? chat() : forum(),
  275. )
  276. ]
  277. );
  278. }
  279. return Scaffold(
  280. backgroundColor: Colors.white,
  281. appBar: appBarTemplate(context: context, title: 'message'.tr()),
  282. body: FutureBuilder(future: U.isCompatibleWith(VersionKey.multiBahasa), builder: (context, snapshot){
  283. if (!snapshot.hasData) {
  284. return chat(); // or a loading spinner
  285. } else {
  286. return bodyForum();
  287. }
  288. }),
  289. // U.isCompatibleWith(VersionKey.multiBahasa) ? bodyForum() : chat(),
  290. floatingActionButton: Provider.of<MessageModule>(context).user().isNotEmpty &&
  291. Provider.of<MessageModule>(context).user()['canSendMessage'] &&
  292. Provider.of<MessageModule>(context).activeTab() == 0 ? FloatingActionButton(
  293. backgroundColor: primaryColor,
  294. onPressed: () => messageFunc.createMessage(context),
  295. child: U.iconsax('message', color: Colors.white),
  296. ):null,
  297. );
  298. }
  299. }