contacts.dart 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import 'package:e2ee_chat/azlistview/azlistview.dart';
  2. import 'package:e2ee_chat/common/global.dart';
  3. import 'package:e2ee_chat/model/message.dart';
  4. import 'package:e2ee_chat/presenter/contact_list.dart';
  5. import 'package:e2ee_chat/presenter/session.dart';
  6. import 'package:e2ee_chat/widgets/utils.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:provider/provider.dart';
  9. class ContactListPage extends StatefulWidget {
  10. @override
  11. _ContactListPageState createState() => _ContactListPageState();
  12. }
  13. class _ContactListPageState extends State<ContactListPage> {
  14. @override
  15. void initState() {
  16. super.initState();
  17. ContactListPresenter().freshContacts().then((_) => setState(() {}));
  18. }
  19. @override
  20. Widget build(BuildContext context) {
  21. return ChangeNotifierProvider<ContactListPresenter>(
  22. create: (context) => ContactListPresenter(),
  23. child: Builder(
  24. builder: (context) {
  25. var provider = Provider.of<ContactListPresenter>(context);
  26. var contacts = provider.contacts;
  27. return AzListView(
  28. data: contacts,
  29. itemCount: contacts.length,
  30. itemBuilder: (context, index) {
  31. var info = contacts[index];
  32. return Utils.getWeChatListItem(
  33. context,
  34. info,
  35. defHeaderBgColor: Color(0xFFE5E5E5),
  36. );
  37. },
  38. physics: BouncingScrollPhysics(),
  39. susItemBuilder: (BuildContext context, int index) {
  40. ContactInfo model = contacts[index];
  41. if ('↑' == model.getSuspensionTag()) {
  42. return Container();
  43. }
  44. return Utils.getSusItem(context, model.getSuspensionTag());
  45. },
  46. indexBarData: ['↑', '☆', ...kIndexBarData],
  47. indexBarOptions: IndexBarOptions(
  48. needRebuild: true,
  49. ignoreDragCancel: true,
  50. downTextStyle: TextStyle(fontSize: 12, color: Colors.white),
  51. downItemDecoration:
  52. BoxDecoration(shape: BoxShape.circle, color: Colors.green),
  53. indexHintWidth: 120 / 2,
  54. indexHintHeight: 100 / 2,
  55. indexHintDecoration: BoxDecoration(
  56. image: DecorationImage(
  57. image: AssetImage(Utils.getImgPath('ic_index_bar_bubble_gray')),
  58. fit: BoxFit.contain,
  59. ),
  60. ),
  61. indexHintAlignment: Alignment.centerRight,
  62. indexHintChildAlignment: Alignment(-0.25, 0.0),
  63. indexHintOffset: Offset(-20, 0),
  64. ),
  65. );
  66. },
  67. ),
  68. );
  69. }
  70. }
  71. class ContactItem extends StatelessWidget {
  72. final SessionModel model;
  73. ContactItem(this.model);
  74. @override
  75. Widget build(BuildContext context) {
  76. return Row(
  77. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  78. children: <Widget>[
  79. model.avatar ?? Global.defaultAvatar,
  80. Expanded(
  81. child: Column(
  82. children: <Widget>[
  83. Padding(
  84. padding: EdgeInsets.symmetric(vertical: 8),
  85. child: Row(
  86. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  87. children: <Widget>[
  88. Expanded(
  89. child: Text(
  90. model.chatName,
  91. style: TextStyle(fontSize: 34),
  92. overflow: TextOverflow.ellipsis,
  93. ),
  94. ),
  95. Text(
  96. _formatDate(),
  97. style: TextStyle(fontSize: 26),
  98. overflow: TextOverflow.ellipsis,
  99. ),
  100. ],
  101. ),
  102. ),
  103. Row(
  104. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  105. children: <Widget>[
  106. Expanded(
  107. child: RichText(
  108. text: TextSpan(children: [
  109. TextSpan(
  110. text: model.isAtYou ? "[@你]" : "",
  111. style: TextStyle(fontSize: 28),
  112. ),
  113. TextSpan(
  114. text: model.isSpecialAttention ? "[特别关注]" : "",
  115. style: TextStyle(fontSize: 28),
  116. ),
  117. TextSpan(
  118. text: model.isAtAll ? "[@所有人]" : "",
  119. style: TextStyle(fontSize: 28),
  120. ),
  121. TextSpan(
  122. text: model.lastMessage?.content.target?.plaintext ?? "",
  123. style: TextStyle(fontSize: 28),
  124. )
  125. ]),
  126. overflow: TextOverflow.ellipsis,
  127. ),
  128. ),
  129. (model.unReadCount > 0 && !model.isDND)
  130. ? Container(
  131. width: 32,
  132. height: 32,
  133. alignment: Alignment.center,
  134. decoration: BoxDecoration(borderRadius: BorderRadius.circular(20)),
  135. child: Text(
  136. model.unReadCount.toString(),
  137. style: TextStyle(color: Colors.white, fontSize: 26),
  138. ))
  139. : Container(),
  140. model.isDND
  141. ? Row(
  142. children: <Widget>[
  143. Icon(Icons.visibility_off),
  144. model.unReadCount > 0
  145. ? Icon(
  146. Icons.chat_bubble,
  147. color: Colors.red,
  148. ) // TODO: 小红点
  149. : Container()
  150. ],
  151. )
  152. : Container()
  153. ],
  154. )
  155. ],
  156. ),
  157. )
  158. ],
  159. );
  160. }
  161. String _formatDate() {
  162. try {
  163. DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(model.lastMessage!.time);
  164. return "${dateTime.hour}:${dateTime.minute}";
  165. } catch (e) {
  166. return "";
  167. }
  168. }
  169. }