Browse Source

消息ui更改

复制粘贴(更改中...)
dart3_last
wurong 2 years ago
parent
commit
3a0ea1fd2d
  1. BIN
      assets/image/2x/c_z.webp
  2. BIN
      assets/image/2x/icon_chat.webp
  3. BIN
      assets/image/2x/icon_chat_camera.webp
  4. BIN
      assets/image/2x/icon_chat_copy.webp
  5. BIN
      assets/image/2x/icon_chat_delete.webp
  6. BIN
      assets/image/2x/icon_chat_emo.webp
  7. BIN
      assets/image/2x/icon_chat_photo.webp
  8. BIN
      assets/image/2x/icon_copy _link.webp
  9. BIN
      assets/image/2x/icon_cz.webp
  10. BIN
      assets/image/2x/icon_gz.webp
  11. BIN
      assets/image/2x/icon_order.webp
  12. BIN
      assets/image/2x/icon_pl.webp
  13. BIN
      assets/image/2x/icon_scan_qr_code.webp
  14. BIN
      assets/image/2x/icon_search.webp
  15. BIN
      assets/image/2x/icon_share_chat.webp
  16. BIN
      assets/image/2x/icon_share_hx.webp
  17. BIN
      assets/image/2x/icon_system_message.webp
  18. BIN
      assets/image/2x/icon_z.webp
  19. BIN
      assets/image/3x/c_z.webp
  20. BIN
      assets/image/3x/icon_chat.webp
  21. BIN
      assets/image/3x/icon_chat_camera.webp
  22. BIN
      assets/image/3x/icon_chat_copy.webp
  23. BIN
      assets/image/3x/icon_chat_delete.webp
  24. BIN
      assets/image/3x/icon_chat_emo.webp
  25. BIN
      assets/image/3x/icon_chat_photo.webp
  26. BIN
      assets/image/3x/icon_copy _link.webp
  27. BIN
      assets/image/3x/icon_cz.webp
  28. BIN
      assets/image/3x/icon_gz.webp
  29. BIN
      assets/image/3x/icon_order.webp
  30. BIN
      assets/image/3x/icon_pl.webp
  31. BIN
      assets/image/3x/icon_scan_qr_code.webp
  32. BIN
      assets/image/3x/icon_search.webp
  33. BIN
      assets/image/3x/icon_share_chat.webp
  34. BIN
      assets/image/3x/icon_share_hx.webp
  35. BIN
      assets/image/3x/icon_system_message.webp
  36. BIN
      assets/image/3x/icon_z.webp
  37. BIN
      assets/image/c_z.webp
  38. BIN
      assets/image/icon_chat.webp
  39. BIN
      assets/image/icon_chat_camera.webp
  40. BIN
      assets/image/icon_chat_copy.webp
  41. BIN
      assets/image/icon_chat_delete.webp
  42. BIN
      assets/image/icon_chat_emo.webp
  43. BIN
      assets/image/icon_chat_photo.webp
  44. BIN
      assets/image/icon_copy _link.webp
  45. BIN
      assets/image/icon_cz.webp
  46. BIN
      assets/image/icon_gz.webp
  47. BIN
      assets/image/icon_order.webp
  48. BIN
      assets/image/icon_pl.webp
  49. BIN
      assets/image/icon_scan_qr_code.webp
  50. BIN
      assets/image/icon_search.webp
  51. BIN
      assets/image/icon_share_chat.webp
  52. BIN
      assets/image/icon_share_hx.webp
  53. BIN
      assets/image/icon_system_message.webp
  54. BIN
      assets/image/icon_z.webp
  55. 20
      lib/community/community_view/community_dynamic.dart
  56. 2
      lib/l10n/intl_en.arb
  57. 2
      lib/l10n/intl_en_US.arb
  58. 2
      lib/l10n/intl_zh_CN.arb
  59. 2
      lib/l10n/intl_zh_Hans_CN.arb
  60. 2
      lib/l10n/intl_zh_Hant_CN.arb
  61. 2
      lib/l10n/intl_zh_TW.arb
  62. 15
      lib/main.dart
  63. 8
      lib/main_page.dart
  64. 690
      lib/message/im/chat_details_page.dart
  65. 107
      lib/message/im/chat_setting.dart
  66. 245
      lib/message/im/contact_share.dart
  67. 53
      lib/message/im/im_view/emoji_text.dart
  68. 466
      lib/message/im/im_view/magic_pop.dart
  69. 3
      lib/message/im/im_view/on_chat_message.dart
  70. 20
      lib/message/im/im_view/on_chat_msg_instance.dart
  71. 55
      lib/message/im/im_view/text_item_container.dart
  72. 33
      lib/message/im/im_view/text_span_builder.dart
  73. 45
      lib/message/im/im_view/triangle_painter.dart
  74. 14
      lib/message/system_details.dart
  75. 362
      lib/message/system_message.dart
  76. 323
      lib/message/system_notice.dart
  77. 15
      lib/mine/mine_view/mine_view.dart
  78. 115
      lib/mine/personal_page.dart
  79. 2
      lib/retrofit/min_api.dart
  80. 2
      lib/retrofit/retrofit_api.dart
  81. 51
      lib/setting/help_feedback_page.dart
  82. 357
      lib/setting/notice_setting.dart
  83. 9
      lib/setting/setting_page.dart
  84. 4
      lib/settlement/settlement_view/settlement_order_commodity.dart
  85. 10
      lib/utils/flutter_utils.dart
  86. 41
      lib/view_widget/share_dialog.dart
  87. 1
      lib/web/web_view/input_comment.dart
  88. 14
      pubspec.lock
  89. 2
      pubspec.yaml

BIN
assets/image/2x/c_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

BIN
assets/image/2x/icon_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/image/2x/icon_chat_camera.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/image/2x/icon_chat_copy.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

BIN
assets/image/2x/icon_chat_delete.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

BIN
assets/image/2x/icon_chat_emo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/image/2x/icon_chat_photo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

BIN
assets/image/2x/icon_copy _link.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
assets/image/2x/icon_cz.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/image/2x/icon_gz.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
assets/image/2x/icon_order.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
assets/image/2x/icon_pl.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/image/2x/icon_scan_qr_code.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 666 B

BIN
assets/image/2x/icon_search.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/image/2x/icon_share_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
assets/image/2x/icon_share_hx.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
assets/image/2x/icon_system_message.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/image/2x/icon_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/image/3x/c_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
assets/image/3x/icon_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
assets/image/3x/icon_chat_camera.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
assets/image/3x/icon_chat_copy.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

BIN
assets/image/3x/icon_chat_delete.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

BIN
assets/image/3x/icon_chat_emo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/image/3x/icon_chat_photo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/image/3x/icon_copy _link.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
assets/image/3x/icon_cz.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
assets/image/3x/icon_gz.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
assets/image/3x/icon_order.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/image/3x/icon_pl.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
assets/image/3x/icon_scan_qr_code.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 766 B

BIN
assets/image/3x/icon_search.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
assets/image/3x/icon_share_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
assets/image/3x/icon_share_hx.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
assets/image/3x/icon_system_message.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
assets/image/3x/icon_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/image/c_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

BIN
assets/image/icon_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

BIN
assets/image/icon_chat_camera.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

BIN
assets/image/icon_chat_copy.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

BIN
assets/image/icon_chat_delete.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

BIN
assets/image/icon_chat_emo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

BIN
assets/image/icon_chat_photo.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

BIN
assets/image/icon_copy _link.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

BIN
assets/image/icon_cz.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

BIN
assets/image/icon_gz.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 822 B

BIN
assets/image/icon_order.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

BIN
assets/image/icon_pl.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 762 B

BIN
assets/image/icon_scan_qr_code.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

After

Width:  |  Height:  |  Size: 600 B

BIN
assets/image/icon_search.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

BIN
assets/image/icon_share_chat.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

BIN
assets/image/icon_share_hx.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/image/icon_system_message.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 890 B

BIN
assets/image/icon_z.webp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 806 B

20
lib/community/community_view/community_dynamic.dart

@ -225,8 +225,7 @@ class _CommunityDynamic extends State<CommunityDynamic> {
goPersonalPage();
},
child: MImage(
(widget?.article?.authorHeadImg ??
""),
(widget?.article?.authorHeadImg ?? ""),
width: 44,
height: 44,
isCircle: true,
@ -269,7 +268,7 @@ class _CommunityDynamic extends State<CommunityDynamic> {
],
),
),
if (widget?.article?.author != widget.userId ?? "")
if ((widget?.article?.author != widget.userId ?? ""))
GestureDetector(
onTap: () {
setState(() {
@ -283,17 +282,21 @@ class _CommunityDynamic extends State<CommunityDynamic> {
}
});
},
child: (widget.commentType == 0)
child: (widget.commentType == 3
? Container()
: ((widget.commentType == 0)
? Container(
width: 56.w,
height: 25.h,
alignment: Alignment.center,
child: RoundButton(
height: 25.h,
backgroup: (widget?.article?.followed ?? false)
backgroup:
(widget?.article?.followed ?? false)
? Color(0xFFE6E6E6)
: Color(0xFF32A060),
textColor: (widget?.article?.followed ?? false)
textColor:
(widget?.article?.followed ?? false)
? Color(0xFF808080)
: Colors.white,
text: (widget?.article?.followed ?? false)
@ -304,7 +307,8 @@ class _CommunityDynamic extends State<CommunityDynamic> {
(widget?.article?.followed ?? false)
? Icons.check
: Icons.add,
color: (widget?.article?.followed ?? false)
color:
(widget?.article?.followed ?? false)
? Color(0xFF808080)
: Colors.white,
size: 15,
@ -317,7 +321,7 @@ class _CommunityDynamic extends State<CommunityDynamic> {
color: Colors.black,
size: 16,
),
),
))),
),
],
),

2
lib/l10n/intl_en.arb

@ -479,7 +479,7 @@
"ruhelingquyouhuiquan": "如何领取优惠券?",
"ruhelingquyouhuiquan1": "点击我的,进入我页面后,点击下方的领劵中心,进入后即可领取优惠券哦~",
"ruhedihuanjifen": "如何兑换积分",
"ruhedihuanjifen1": "点击净弼,进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruhedihuanjifen1": "进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruheqiandao": "如何签到?",
"ruheqiandao1": "1.点击净弼,进入首页,点击上方的去签到。\n2.点击我的,进入我的页面,点击上方的积分详情,进入后即可签到。",
"youxiaoqixian": "有效期限:",

2
lib/l10n/intl_en_US.arb

@ -481,7 +481,7 @@
"ruhelingquyouhuiquan": "How do I get coupons?",
"ruhelingquyouhuiquan1": "Click My, enter my page, click the coupon collection center below, and then you can get the coupon~",
"ruhedihuanjifen":"How to redeem points",
"ruhedihuanjifen1": "Click Jingbi to enter the points store, click the goods you want to exchange, enter the details of the goods and click below to exchange~",
"ruhedihuanjifen1": "click the goods you want to exchange, enter the details of the goods and click below to exchange~",
"ruheqiandao": "How to sign in?",
"ruheqiandao1": "1.Click Jingbi to enter the home page, and click on the top to sign in。\n2.Click on My to enter my page, and click on the point details above to sign in。",
"youxiaoqixian": "Valid Period:",

2
lib/l10n/intl_zh_CN.arb

@ -481,7 +481,7 @@
"ruhelingquyouhuiquan": "如何领取优惠券?",
"ruhelingquyouhuiquan1": "点击我的,进入我页面后,点击下方的领劵中心,进入后即可领取优惠券哦~",
"ruhedihuanjifen":"如何兑换积分",
"ruhedihuanjifen1": "点击净弼,进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruhedihuanjifen1": "进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruheqiandao": "如何签到?",
"ruheqiandao1": "1.点击净弼,进入首页,点击上方的去签到。\n2.点击我的,进入我的页面,点击上方的积分详情,进入后即可签到。",

2
lib/l10n/intl_zh_Hans_CN.arb

@ -481,7 +481,7 @@
"ruhelingquyouhuiquan": "如何领取优惠券?",
"ruhelingquyouhuiquan1": "点击我的,进入我页面后,点击下方的领劵中心,进入后即可领取优惠券哦~",
"ruhedihuanjifen":"如何兑换积分",
"ruhedihuanjifen1": "点击净弼,进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruhedihuanjifen1": "进入积分商城,点击你想兑换的领商品,进入商品详情后点击下方兑换,即可兑换哦~",
"ruheqiandao": "如何签到?",
"ruheqiandao1": "1.点击净弼,进入首页,点击上方的去签到。\n2.点击我的,进入我的页面,点击上方的积分详情,进入后即可签到。",

2
lib/l10n/intl_zh_Hant_CN.arb

@ -475,7 +475,7 @@
"ruhelingquyouhuiquan": "如何領取優惠券?",
"ruhelingquyouhuiquan1": "點擊我的,進入我的頁面後,點擊下方的領取中心,進入后即可領取優惠券哦~",
"ruhedihuanjifen":"如何兌換積分",
"ruhedihuanjifen1": "點擊淨弼,進入積分商城,點擊你想兌換的領商品,進入商品詳情後點擊下方兌換,即可兌換哦~",
"ruhedihuanjifen1": "進入積分商城,點擊你想兌換的領商品,進入商品詳情後點擊下方兌換,即可兌換哦~",
"ruheqiandao": "如何簽到?",
"ruheqiandao1": "1.點擊淨弼,進入首頁,點擊上方的去簽到。\n2.點擊我的,進入我的頁面,點擊上方的積分詳情,進入後即可簽到。",
"youxiaoqixian": "有效期限:",

2
lib/l10n/intl_zh_TW.arb

@ -473,7 +473,7 @@
"ruhelingquyouhuiquan": "如何領取優惠券?",
"ruhelingquyouhuiquan1": "點擊我的,進入我的頁面後,點擊下方的領取中心,進入后即可領取優惠券哦~",
"ruhedihuanjifen":"如何兌換積分",
"ruhedihuanjifen1": "點擊淨弼,進入積分商城,點擊你想兌換的領商品,進入商品詳情後點擊下方兌換,即可兌換哦~",
"ruhedihuanjifen1": "進入積分商城,點擊你想兌換的領商品,進入商品詳情後點擊下方兌換,即可兌換哦~",
"ruheqiandao": "如何簽到?",
"ruheqiandao1": "1.點擊淨弼,進入首頁,點擊上方的去簽到。\n2.點擊我的,進入我的頁面,點擊上方的積分詳情,進入後即可簽到。",

15
lib/main.dart

@ -50,6 +50,7 @@ import 'package:huixiang/setting/account_security_page.dart';
import 'package:huixiang/setting/help_feedback_page.dart';
import 'package:huixiang/setting/logout_ing.dart';
import 'package:huixiang/setting/logout_page.dart';
import 'package:huixiang/setting/notice_setting.dart';
import 'package:huixiang/setting/permission_setting_page.dart';
import 'package:huixiang/setting/platform_code_page.dart';
import 'package:huixiang/setting/platform_pay_code.dart';
@ -97,7 +98,11 @@ import 'home/welfare_page.dart';
import 'login/new_login_page.dart';
import 'login/phone_address_page.dart';
import 'main_page.dart';
import 'message/im/chat_details_page.dart';
import 'message/im/chat_setting.dart';
import 'message/im/contact_share.dart';
import 'message/system_details.dart';
import 'message/system_notice.dart';
import 'mine/coupon_page.dart';
import 'mine/edit_signature.dart';
import 'mine/invitation_record.dart';
@ -423,4 +428,14 @@ Map<String, WidgetBuilder> routers = <String, WidgetBuilder>{
ScanWeb(arguments:arguments),
'/router/vip_pay_code': (context, {arguments}) =>
VipPayCode(),
'/router/system_notice': (context, {arguments}) =>
SystemNotice(),
'/router/contacts_share': (context, {arguments}) =>
ContactsShare(arguments:arguments),
'/router/chat_details_page': (context, {arguments}) =>
ChatDetailsPage(),
'/router/chat_setting': (context, {arguments}) =>
ChatSetting(),
'/router/notice_setting': (context, {arguments}) =>
NoticeSetting(),
};

8
lib/main_page.dart

@ -35,6 +35,7 @@ import 'package:tpns_flutter_plugin/android/xg_android_api.dart';
import 'package:tpns_flutter_plugin/tpns_flutter_plugin.dart';
import 'community/order_page.dart';
import 'message/im/im_view/on_chat_msg_instance.dart';
class MainPage extends StatefulWidget {
final Map<String, dynamic> arguments;
@ -223,6 +224,13 @@ class _MainPage extends State<MainPage> with WidgetsBindingObserver {
);
}
// Future.delayed(Duration(seconds: 15), () {
// if(OnChatMsgInstance.instance.onChatMessage != null){
// OnChatMsgInstance.instance.onChatMessage.onMessage("你好");
// }else
// SmartDialog.showToast("当前不在聊天页面", alignment: Alignment.center);
// });
/// @typed: 1 2 3 4 5 6 7 8/ 9
xgFlutterPlugin.addEventHandler(xgPushClickAction: (event) async {
print("xgPushClickAction1: $event");

690
lib/message/im/chat_details_page.dart

@ -0,0 +1,690 @@
import 'dart:io';
import 'dart:ui';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart';
import 'package:image_pickers/image_pickers.dart';
import '../../community/release_dynamic.dart';
import '../../generated/l10n.dart';
import '../../utils/font_weight.dart';
import 'im_view/on_chat_message.dart';
import 'im_view/on_chat_msg_instance.dart';
import 'im_view/text_item_container.dart';
class ChatDetailsPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _ChatDetailsPage();
}
}
class _ChatDetailsPage extends State<ChatDetailsPage>
with WidgetsBindingObserver
implements OnChatMessage {
ApiService apiService;
List<Medias> mediaPaths = [];
int selectCount = 9;
int dynamicType = 0;
final TextEditingController chatController = TextEditingController();
bool emojiShowing = false;
double keyboard = -1;
bool needShowSmiley = false;
bool needHideSmiley = false;
bool isKeyBoardShow = false;
bool moreShow = false;
bool needShowMore = false;
bool needHideMore = false;
var commentFocus = FocusNode();
String hintText = "请输入消息内容...";
final OnChatMessage _tempOnChatMessage =
OnChatMsgInstance.instance.onChatMessage;
final ScrollController scrollController = ScrollController();
String tex = "";
@override
void onMessage(txt) {
// SmartDialog.showToast("聊天 $txt", alignment: Alignment.center);
}
@override
void initState() {
super.initState();
OnChatMsgInstance.instance.onChatMessage = this;
WidgetsBinding.instance.addObserver(this);
commentFocus.addListener(_focusNodeListener);
Future.delayed(Duration.zero, () {
jumpToBottom();
});
}
void jumpToBottom(){
scrollController.position
.jumpTo(scrollController.position.maxScrollExtent);
}
void didChangeMetrics() {
WidgetsBinding.instance.addPostFrameCallback((_) {
isKeyBoardShow = MediaQuery.of(context).viewInsets.bottom > 0;
if (!mounted) return;
if (MediaQuery.of(context).viewInsets.bottom == 0) {
if (isKeyBoardShow) {
FocusScope.of(context).requestFocus(FocusNode());
if (mounted) if (!emojiShowing) if (!moreShow)
setState(() {
hintText = "请输入消息内容...";
isKeyBoardShow = false;
});
}
} else {
if (mounted)
setState(() {
isKeyBoardShow = true;
});
}
});
if (needShowSmiley && window.viewInsets.bottom <= 0.1) {
needShowSmiley = false;
setState(() {
emojiShowing = true;
});
}
if (needHideSmiley && window.viewInsets.bottom > 0.1) {
needHideSmiley = false;
setState(() {
emojiShowing = false;
});
}
if (needShowMore && window.viewInsets.bottom <= 0.1) {
needShowMore = false;
setState(() {
moreShow = true;
});
}
if (needHideMore && window.viewInsets.bottom > 0.1) {
needHideMore = false;
setState(() {
moreShow = false;
});
}
}
@override
void dispose() {
super.dispose();
OnChatMsgInstance.instance.onChatMessage = _tempOnChatMessage;
WidgetsBinding.instance.removeObserver(this);
commentFocus.removeListener(_focusNodeListener);
}
void _focusNodeListener() {
/*if (_focusNode.hasFocus || _focusNode.consumeKeyboardToken()){
setState(() {
smileyPadGone = true;
});
}*/
}
_onTextFieldTap() {
if (emojiShowing) {
needHideSmiley = true;
}
if (moreShow) {
needHideMore = true;
}
}
_onSmileyTap() {
if (!emojiShowing && commentFocus.hasFocus && isKeyBoardShow) {
needShowSmiley = true;
commentFocus.unfocus();
} else {
setState(() {
emojiShowing = !emojiShowing;
isKeyBoardShow = emojiShowing;
moreShow = false;
});
}
}
_onMoreTap() {
if (!moreShow && commentFocus.hasFocus && isKeyBoardShow) {
needShowMore = true;
commentFocus.unfocus();
} else {
setState(() {
moreShow = !moreShow;
isKeyBoardShow = moreShow;
emojiShowing = false;
});
}
}
////
Future getImageOrVideo(GalleryMode galleryMode) async {
if (selectCount == 0) return;
List<Media> medias = await ImagePickers.pickerPaths(
galleryMode: galleryMode,
selectCount: (galleryMode == GalleryMode.video) ? 1 : selectCount,
showGif: true,
showCamera: false,
compressSize: 500,
uiConfig: UIConfig(
uiThemeColor: Color(0xFFFFFFFF),
),
cropConfig: CropConfig(
enableCrop: false,
width: 200,
height: 200,
),
);
mediaPaths.addAll(medias.map((e) => Medias(e)).toList());
selectCount = 9 - mediaPaths.length;
if (mediaPaths.length > 0) {
if (galleryMode == GalleryMode.image) {
dynamicType = 1;
} else {
dynamicType = 2;
}
}
setState(() {});
}
@override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).viewInsets.bottom;
if (h > 0) {
jumpToBottom();
if(keyboard < h){
keyboard = h;
// setState(() {});
}
}
return Scaffold(
// resizeToAvoidBottomInset: false,
backgroundColor: Color(0xFFF9FAF7),
appBar: MyAppBar(
title: "哈哈哈哈",
titleColor: Colors.black,
titleSize: 18.sp,
background: Colors.white,
leading: true,
leadingColor: Colors.black,
action: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
Navigator.of(context).pushNamed('/router/chat_setting');
});
},
child: Container(
padding: EdgeInsets.only(top: 3.h, bottom: 16.h),
alignment: Alignment.center,
// color: Colors.red,
child: Icon(
Icons.more_horiz,
color: Colors.black,
size: 30,
),
)),
),
body: Container(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: scrollController,
child: Column(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
setState(() {
emojiShowing = false;
isKeyBoardShow = emojiShowing;
moreShow = false;
isKeyBoardShow = moreShow;
FocusScope.of(context).requestFocus(FocusNode());
});
},
child: chatDetailsList()),
],
),
),
flex: 1,
),
input()
],
),
),
);
}
///
Widget chatDetailsList() {
return Container(
margin: EdgeInsets.only(bottom: 48.h),
child: ListView.builder(
itemCount: 10,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
onTap: () {
},
onLongPress: (){
showCustomDialog(context,position);
},
child: chatDetailsItem(),
);
}),
);
}
Widget chatDetailsItem() {
return Container(
padding: EdgeInsets.only(top: 32.h,),
child: Column(
children: [
Text(
"3月08日 上午 12:10",
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFFA29E9E),
fontSize: 10.sp,
fontWeight: MyFontWeight.regular,
),
),
Padding(
padding: EdgeInsets.only(top: 10.h, bottom: 24.h),
child: Text(
"在对方未回复或关注你之前,你只能发送一条信息",
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFFA29E9E),
fontSize: 10.sp,
fontWeight: MyFontWeight.regular,
),
),
),
SizedBox(
height: 16.h,
),
Padding(padding:EdgeInsets.only(left: 17.w,right: 39.w),
child: Row(
children: [
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height: 44,
width: 44,
),
SizedBox(
width: 12.w,
),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Color(0xFFF0FAF4),
),
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 12.w),
child:GestureDetector(
onTap:this.copy(tex),
child: SelectableText(
tex = "凭本事买的为啥要给你钱啊伙计",
textAlign: TextAlign.left,
style: TextStyle(
height: 1.2.h,
color: Colors.black,
fontSize: 17.sp,
fontWeight: MyFontWeight.regular,
),
),
)
)),
],
),),
SizedBox(height: 40.h,),
Padding(padding:EdgeInsets.only(left:36.w,right: 16.w),
child: Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFFF441A),
),
width: 20,
height: 20,
alignment: Alignment.center,
child: Text(
"!",
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 17.sp,
fontWeight: MyFontWeight.regular,
),
),
),
SizedBox(
width: 12.w,
),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Color(0xFF32A060),
),
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 12.w),
child: TextItemContainer(
text: "上次你在我这里买的水果钱是不是忘记付了?一共18块钱做点生意也是真的不容易啊。",
action: '',
isMyself: true,),
)),
SizedBox(
width: 12.w,
),
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height: 44,
width: 44,
),
],
)),
Padding(
padding: EdgeInsets.only(left: 17.w, right: 17.w, top: 24.h),
child: Text(
"由于对方没有回复你,你只能发送一条消息,需要对方关注或回复后才能恢复正常聊天",
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFFA29E9E),
fontSize: 10.sp,
fontWeight: MyFontWeight.regular,
),
),
),
],
),
);
}
///
Widget input() {
return Container(
color: Colors.white,
padding: EdgeInsets.only(top: 16.h, bottom: 15.h),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(
left: 20.w,
),
decoration: BoxDecoration(
color: Color(0xFFF0FAF4),
borderRadius: BorderRadius.circular(6),
),
child: Container(
margin: EdgeInsets.symmetric(horizontal: 12.w),
alignment: Alignment.topLeft,
child: TextField(
textInputAction: TextInputAction.send,
onTap: () {
moreShow = false;
_onTextFieldTap();
},
onEditingComplete: () {
var commentText = chatController.text;
if (commentText.trim() == "") {
return;
}
// widget.queryMemberComment(commentText);
},
maxLines: 8,
minLines: 1,
focusNode: commentFocus,
controller: chatController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: hintText,
hintStyle: TextStyle(
fontSize: 14.sp,
color: Color(0xFF868686),
),
),
),
),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_onSmileyTap();
Future.delayed(Duration(milliseconds: 500), () {
jumpToBottom();
});
},
child: Container(
padding: EdgeInsets.only(left: 15.w, right: 8.w),
child: Image.asset(
"assets/image/icon_chat_emo.webp",
height: 24,
width: 24,
)),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_onMoreTap();
Future.delayed(Duration(milliseconds: 500), () {
jumpToBottom();
});
},
child: Container(
padding: EdgeInsets.only(left: 8.w, right: 19.w),
child: Image.asset(
"assets/image/fa_bu.webp",
height: 24,
width: 24,
),
),
),
],
),
SizedBox(
height: 16.h,
),
///
Offstage(
offstage: !emojiShowing,
child: SizedBox(
height: keyboard == -1 ? 270 : keyboard,
width: MediaQuery.of(context).size.width,
child: EmojiPicker(
textEditingController: chatController,
config: Config(
columns: 7,
emojiSizeMax: 32 * (Platform.isIOS ? 1.10 : 1.0),
verticalSpacing: 0,
horizontalSpacing: 0,
gridPadding: EdgeInsets.zero,
initCategory: Category.RECENT,
bgColor: const Color(0xFFF2F2F2),
// indicatorColor: Colors.blue,
iconColor: Colors.grey,
iconColorSelected: Colors.blue,
backspaceColor: Colors.blue,
skinToneDialogBgColor: Colors.white,
skinToneIndicatorColor: Colors.grey,
enableSkinTones: true,
showRecentsTab: true,
recentsLimit: 28,
replaceEmojiOnLimitExceed: false,
noRecents: Text(
"最近使用",
style: TextStyle(fontSize: 20, color: Colors.black26),
textAlign: TextAlign.center,
),
loadingIndicator: const SizedBox.shrink(),
tabIndicatorAnimDuration: Duration(milliseconds: 0),
categoryIcons: const CategoryIcons(),
buttonMode: ButtonMode.MATERIAL,
checkPlatformCompatibility: true,
),
)),
),
///
Offstage(
offstage: !moreShow,
child: Container(
height: keyboard == -1 ? 270 : keyboard,
child: Column(
children: [
Container(
width: double.infinity,
height: 1.h,
color: Color(0xFFF7F7F7),
),
Row(
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
getImageOrVideo(GalleryMode.video);
},
child: Container(
padding: EdgeInsets.only(
left: 19.w, right: 16.w, top: 11.h, bottom: 5.h),
child: Image.asset(
"assets/image/icon_chat_camera.webp",
height: 26,
width: 24,
),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
getImageOrVideo(GalleryMode.image);
},
child: Container(
// color: Colors.yellow,
padding: EdgeInsets.only(
left: 16.w, right: 16.w, top: 13.h, bottom: 5.h),
child: Image.asset(
"assets/image/icon_chat_photo.webp",
height: 24,
width: 24,
),
),
),
],
)
],
),
),
)
],
),
);
}
showCustomDialog(BuildContext context,int position ){
showDialog(
context: context,
builder: (BuildContext context) {
return new AlertDialog(
backgroundColor: Color(0xFF2A2A2A),
elevation: 0,
contentPadding:EdgeInsets.only(top: 8.h,bottom: 5.h,),
content: Container(
height: 40.h,
// width:20.w,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
Image.asset(
"assets/image/icon_chat_copy.webp",
height:16,
width: 16,
),
Text(
"复制",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: MyFontWeight.regular,
),
),
],
),
Column(
children: [
Image.asset(
"assets/image/icon_chat_delete.webp",
height:16,
width: 16,
),
Text(
S.of(context).shanchu,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: MyFontWeight.regular,
),
),
],
)
],
),
),
);
});
}
///
copy(String tex) {
print(tex);
Clipboard.setData(ClipboardData(text: tex));
}
}

107
lib/message/im/chat_setting.dart

@ -0,0 +1,107 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart';
import '../../generated/l10n.dart';
import '../../utils/font_weight.dart';
class ChatSetting extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _ChatSetting();
}
}
class _ChatSetting extends State<ChatSetting>{
ApiService apiService;
bool topSetting = false;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF9FAF7),
appBar: MyAppBar(
title:"聊天设置",
titleColor: Colors.black,
titleSize: 18.sp,
background: Colors.white,
leading: true,
leadingColor: Colors.black,
),
body: Container(
child: Column(
children: [
Container(
color: Colors.white,
margin: EdgeInsets.symmetric(vertical: 14.h),
padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 14.h),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"置顶聊天",
style: TextStyle(
color: Color(0xFF353535),
fontSize:15.sp,
fontWeight: MyFontWeight.semi_bold,
),
),
CupertinoSwitch(
value: (topSetting),
activeColor: Color(0xFF32A060),
onChanged: (bool value) {
setState((){
topSetting = !topSetting;
});
},
),
],
),
SizedBox(height:31.h,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"清空聊天记录",
style: TextStyle(
color: Color(0xFF353535),
fontSize:15.sp,
fontWeight: MyFontWeight.semi_bold,
),
),
Image.asset(
"assets/image/icon_right_z.webp",
height:16,
width:16,
color: Colors.black,
),
],
)
],
),
),
Expanded(child:
Container(
color: Colors.white,
))
],
),
),
);
}
}

245
lib/message/im/contact_share.dart

@ -0,0 +1,245 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart';
import '../../generated/l10n.dart';
import '../../retrofit/data/base_data.dart';
import '../../utils/font_weight.dart';
class ContactsShare extends StatefulWidget {
final Map<String, dynamic> arguments;
ContactsShare({this.arguments});
@override
State<StatefulWidget> createState() {
return _ContactsShare();
}
}
class _ContactsShare extends State<ContactsShare> {
ApiService apiService;
final TextEditingController searchController = TextEditingController();
int searchIndex = 0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF9FAF7),
appBar: MyAppBar(
background: Color(0xFFFFFFFFF),
leadingColor: Colors.white,
title: "私信给",
titleSize: 18,
titleColor: Colors.black,
),
body: Container(
margin: EdgeInsets.only(top:14.h),
color: Colors.white,
child:SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child:Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
contactSearch(),
Padding(
padding: EdgeInsets.only(left: 17.w,bottom:24.h),
child: Text("最近联系(0)",
style: TextStyle(
fontSize: 17.sp,
color: Color(0xFF0D0D0D),
fontWeight: MyFontWeight.regular,
)),
),
recentList(),
Padding(
padding: EdgeInsets.only(left: 17.w,bottom:24.h),
child: Text("我的关注(0)",
style: TextStyle(
fontSize: 17.sp,
color: Color(0xFF0D0D0D),
fontWeight: MyFontWeight.regular,
)),
),
mineFollowList(),
],
)),)
),
);
}
Widget contactSearch() {
return Container(
width: double.infinity,
margin: EdgeInsets.only(left: 16.w, right: 16.w, top: 4.h, bottom: 16.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.w),
color: Color(0xFFF9FAF7),
),
child: Stack(
alignment: Alignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
"assets/image/icon_search.webp",
fit: BoxFit.fill,
),
SizedBox(
width: 4.w,
),
Text("搜索",
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFFB3B3B3),
fontWeight: MyFontWeight.regular,
)),
],
),
TextField(
textInputAction: TextInputAction.search,
enableInteractiveSelection: true,
onEditingComplete: () {
},
controller: searchController,
cursorHeight: 25.h,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 7.h, bottom: 9.h,left:5.w),
border: InputBorder.none,
),
)
],
)
);
}
Widget recentList() {
return ListView.builder(
itemCount: 6,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
onTap: () {},
child: recentItem(),
);
});
}
Widget recentItem() {
return Container(
margin: EdgeInsets.only(bottom: 14.h),
padding: EdgeInsets.only(left: 16.w,right: 14.w),
child:Column(
children: [
Row(
children: [
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height:44,
width:44,
),
SizedBox(width: 10.w,),
Text("张五",
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF1A1A1A),
fontWeight: MyFontWeight.bold,
)),
],
),
Container(
height: 1.h,
width: double.infinity,
color: Color(0xFFF7F7F7),
margin: EdgeInsets.only(left:54.w,top: 10.h),
)
],
)
);
}
Widget mineFollowList() {
return ListView.builder(
itemCount: 3,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
onTap: () {},
child: recentItem(),
);
});
}
Widget mineFollowItem() {
return Container(
margin: EdgeInsets.only(bottom: 14.h),
padding: EdgeInsets.only(left: 16.w,right: 14.w),
child:Column(
children: [
Row(
children: [
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height:44,
width:44,
),
SizedBox(width: 10.w,),
Text("小王",
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF1A1A1A),
fontWeight: MyFontWeight.bold,
)),
],
),
Container(
height: 1.h,
width: double.infinity,
color: Color(0xFFF7F7F7),
margin: EdgeInsets.only(left:54.w,top: 10.h),
)
],
)
);
}
}

53
lib/message/im/im_view/emoji_text.dart

@ -0,0 +1,53 @@
import 'package:extended_text/extended_text.dart';
import 'package:flutter/material.dart';
///emoji/image text
class EmojiText extends SpecialText {
static const String flag = "[";
final int start;
EmojiText(TextStyle textStyle, {this.start})
: super(EmojiText.flag, "]", textStyle);
@override
InlineSpan finishText() {
var key = toString();
if (EmojiUitl.instance.emojiMap.containsKey(key)) {
//fontsize id define image height
//size = 30.0/26.0 * fontSize
final double size = 20.0;
///fontSize 26 and text height =30.0
//final double fontSize = 26.0;
return ImageSpan(AssetImage(EmojiUitl.instance.emojiMap[key]),
actualText: key,
imageWidth: size,
imageHeight: size,
start: start,
fit: BoxFit.fill,
margin: EdgeInsets.only(left: 2.0, right: 2.0));
}
return TextSpan(text: toString(), style: textStyle);
}
}
class EmojiUitl {
final Map<String, String> _emojiMap = new Map<String, String>();
Map<String, String> get emojiMap => _emojiMap;
final String _emojiFilePath = "assets/images/emoji";
static EmojiUitl _instance;
static EmojiUitl get instance {
if (_instance == null) _instance = new EmojiUitl._();
return _instance;
}
EmojiUitl._() {
for (int i = 1; i < 100; i++) {
_emojiMap["[$i]"] = "$_emojiFilePath/sg$i.png";
}
}
}

466
lib/message/im/im_view/magic_pop.dart

@ -0,0 +1,466 @@
import 'package:flutter/material.dart';
import 'package:huixiang/message/im/im_view/triangle_painter.dart';
const double _kMenuScreenPadding = 8.0;
class MagicPop extends StatefulWidget {
MagicPop({
@required this.onValueChanged,
@required this.actions,
@required this.child,
this.pressType = PressType.longPress,
this.pageMaxChildCount = 5,
this.backgroundColor = Colors.black,
this.menuWidth = 250,
this.menuHeight = 42,
}) : assert(onValueChanged != null),
assert(actions != null && actions.length > 0),
assert(child != null);
final ValueChanged<int> onValueChanged;
final List<String> actions;
final Widget child;
final PressType pressType; //
final int pageMaxChildCount;
final Color backgroundColor;
final double menuWidth;
final double menuHeight;
@override
_WPopupMenuState createState() => _WPopupMenuState();
}
class _WPopupMenuState extends State<MagicPop> {
@override
Widget build(BuildContext context) {
return GestureDetector(
child: widget.child,
onTap: () {
if (widget.pressType == PressType.singleClick) {
onTap();
}
},
onLongPress: () {
if (widget.pressType == PressType.longPress) {
onTap();
}
},
);
}
void onTap() {
Navigator.push(
context,
_PopupMenuRoute(context, widget.actions, widget.pageMaxChildCount,
widget.backgroundColor, widget.menuWidth, widget.menuHeight))
.then((index) {
widget.onValueChanged(index);
});
}
}
enum PressType {
//
longPress,
//
singleClick,
}
class _PopupMenuRoute extends PopupRoute {
final BuildContext btnContext;
double _height;
double _width;
final List<String> actions;
final int _pageMaxChildCount;
final Color backgroundColor;
final double menuWidth;
final double menuHeight;
_PopupMenuRoute(this.btnContext, this.actions, this._pageMaxChildCount,
this.backgroundColor, this.menuWidth, this.menuHeight) {
_height = btnContext.size.height;
_width = btnContext.size.width;
}
@override
Animation<double> createAnimation() {
return CurvedAnimation(
parent: super.createAnimation(),
curve: Curves.linear,
reverseCurve: const Interval(0.0, 2.0 / 3.0),
);
}
@override
Color get barrierColor => null;
@override
bool get barrierDismissible => true;
@override
String get barrierLabel => null;
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return _MenuPopWidget(this.btnContext, _height, _width, actions,
_pageMaxChildCount, backgroundColor, menuWidth, menuHeight);
}
@override
Duration get transitionDuration => Duration(milliseconds: 300);
}
class _MenuPopWidget extends StatefulWidget {
final BuildContext btnContext;
final double _height;
final double _width;
final List<String> actions;
final int _pageMaxChildCount;
final Color backgroundColor;
final double menuWidth;
final double menuHeight;
_MenuPopWidget(
this.btnContext,
this._height,
this._width,
this.actions,
this._pageMaxChildCount,
this.backgroundColor,
this.menuWidth,
this.menuHeight);
@override
__MenuPopWidgetState createState() => __MenuPopWidgetState();
}
class __MenuPopWidgetState extends State<_MenuPopWidget> {
int _curPage = 0;
final double _arrowWidth = 40;
final double _separatorWidth = 1;
final double _triangleHeight = 10;
RenderBox button;
RenderBox overlay;
RelativeRect position;
@override
void initState() {
super.initState();
button = widget.btnContext.findRenderObject();
overlay = Overlay.of(widget.btnContext).context.findRenderObject();
position = RelativeRect.fromRect(
Rect.fromPoints(
button.localToGlobal(Offset.zero, ancestor: overlay),
button.localToGlobal(Offset.zero, ancestor: overlay),
),
Offset.zero & overlay.size,
);
}
@override
Widget build(BuildContext context) {
// child
int _curPageChildCount =
(_curPage + 1) * widget._pageMaxChildCount > widget.actions.length
? widget.actions.length % widget._pageMaxChildCount
: widget._pageMaxChildCount;
double _curArrowWidth = 0;
int _curArrowCount = 0; //
if (widget.actions.length > widget._pageMaxChildCount) {
// widget._pageMaxChildCount
if (_curPage == 0) {
//
_curArrowWidth = _arrowWidth;
_curArrowCount = 1;
} else {
//
_curArrowWidth = _arrowWidth * 2;
_curArrowCount = 2;
}
}
double _curPageWidth = widget.menuWidth +
(_curPageChildCount - 1 + _curArrowCount) * _separatorWidth +
_curArrowWidth;
// ignore: unused_element
Widget view() {
var isInverted = (position.top +
(MediaQuery.of(context).size.height -
position.top -
position.bottom) /
2.0 -
(widget.menuHeight + _triangleHeight)) <
(widget.menuHeight + _triangleHeight) * 2;
var pain = CustomPaint(
size: Size(_curPageWidth, _triangleHeight),
painter: TrianglePainter(
color: widget.backgroundColor,
position: position,
isInverted: true,
size: button.size),
);
var row = Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
//
_curPage == 0
? Container(
height: widget.menuHeight,
)
: InkWell(
onTap: () {
setState(() {
_curPage--;
});
},
child: Container(
width: _arrowWidth,
height: widget.menuHeight,
child: Image.asset(
'images/left_white.png',
fit: BoxFit.none,
),
),
),
//
_curPage == 0
? Container(
height: widget.menuHeight,
)
: Container(
width: 1,
height: widget.menuHeight,
color: Colors.grey,
),
// ListView
_buildList(_curPageChildCount, _curPageWidth, _curArrowWidth,
_curArrowCount),
//
_curArrowCount > 0
? Container(
width: 1,
color: Colors.grey,
height: widget.menuHeight,
)
: Container(
height: widget.menuHeight,
),
_curArrowCount > 0
? InkWell(
onTap: () {
if ((_curPage + 1) * widget._pageMaxChildCount <
widget.actions.length)
setState(() {
_curPage++;
});
},
child: Container(
width: _arrowWidth,
height: widget.menuHeight,
child: Image.asset(
(_curPage + 1) * widget._pageMaxChildCount >=
widget.actions.length
? 'images/right_gray.png'
: 'images/right_white.png',
fit: BoxFit.none,
),
),
)
: Container(
height: widget.menuHeight,
),
],
);
return Material(
color: Colors.transparent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
isInverted ? pain : Container(),
Expanded(
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5)),
child: Container(
color: widget.backgroundColor,
height: widget.menuHeight,
),
),
row,
],
),
),
isInverted
? Container()
: CustomPaint(
size: Size(_curPageWidth, _triangleHeight),
painter: TrianglePainter(
color: widget.backgroundColor,
position: position,
size: button.size),
),
],
),
);
}
return MediaQuery.removePadding(
context: context,
removeTop: true,
removeBottom: true,
removeLeft: true,
removeRight: true,
child: Builder(
builder: (BuildContext context) {
return CustomSingleChildLayout(
//
delegate: _PopupMenuRouteLayout(
position,
widget.menuHeight + _triangleHeight,
Directionality.of(widget.btnContext),
widget._width,
widget.menuWidth),
child: SizedBox(
height: widget.menuHeight + _triangleHeight,
width: _curPageWidth,
child: view()),
);
},
),
);
}
Widget _buildList(int _curPageChildCount, double _curPageWidth,
double _curArrowWidth, int _curArrowCount) {
return ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: _curPageChildCount,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
Navigator.pop(
context, _curPage * widget._pageMaxChildCount + index);
},
child: SizedBox(
width: (_curPageWidth -
_curArrowWidth -
(_curPageChildCount - 1 + _curArrowCount) *
_separatorWidth) /
_curPageChildCount,
height: widget.menuHeight,
child: Center(
child: Text(
widget.actions[_curPage * widget._pageMaxChildCount + index],
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
),
);
},
separatorBuilder: (BuildContext context, int index) {
return Container(
width: 1,
height: widget.menuHeight,
color: Colors.grey,
);
},
);
}
}
// Positioning of the menu on the screen.
class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
_PopupMenuRouteLayout(this.position, this.selectedItemOffset,
this.textDirection, this.width, this.menuWidth);
// Rectangle of underlying button, relative to the overlay's dimensions.
final RelativeRect position;
// The distance from the top of the menu to the middle of selected item.
//
// This will be null if there's no item to position in this way.
final double selectedItemOffset;
// Whether to prefer going to the left or to the right.
final TextDirection textDirection;
final double width;
final double menuWidth;
// We put the child wherever position specifies, so long as it will fit within
// the specified parent size padded (inset) by 8. If necessary, we adjust the
// child's position so that it fits.
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
// The menu can be at most the size of the overlay minus 8.0 pixels in each
// direction.
return BoxConstraints.loose(constraints.biggest -
const Offset(_kMenuScreenPadding * 2.0, _kMenuScreenPadding * 2.0));
}
@override
Offset getPositionForChild(Size size, Size childSize) {
// size: The size of the overlay.
// childSize: The size of the menu, when fully open, as determined by
// getConstraintsForChild.
// Find the ideal vertical position.
double y;
if (selectedItemOffset == null) {
y = position.top;
} else {
y = position.top +
(size.height - position.top - position.bottom) / 2.0 -
selectedItemOffset;
}
// Find the ideal horizontal position.
double x;
if (position.left > position.right) {
// Menu button is closer to the right edge, so grow to the left, aligned to the right edge.
// x = childSize.width - (size.width - position.right);
x = position.left + width - childSize.width;
} else if (position.left < position.right) {
// Menu button is closer to the left edge, so grow to the right, aligned to the left edge.
if (width > childSize.width) {
x = position.left + (childSize.width - menuWidth) / 2;
} else
x = position.left;
} else {
x = position.right - width / 2 - childSize.width / 2;
}
// Avoid going outside an area defined as the rectangle 8.0 pixels from the
// edge of the screen in every direction.
if (x < _kMenuScreenPadding)
x = _kMenuScreenPadding;
else if (x + childSize.width > size.width - _kMenuScreenPadding)
x = size.width - childSize.width - _kMenuScreenPadding;
if (y < _kMenuScreenPadding)
y = _kMenuScreenPadding;
else if (y + childSize.height > size.height - _kMenuScreenPadding)
y = size.height - childSize.height;
else if (y < childSize.height * 2) {
y = position.top + childSize.height;
}
return Offset(x, y);
}
@override
bool shouldRelayout(_PopupMenuRouteLayout oldDelegate) {
return position != oldDelegate.position;
}
}

3
lib/message/im/im_view/on_chat_message.dart

@ -0,0 +1,3 @@
abstract class OnChatMessage{
void onMessage(txt);
}

20
lib/message/im/im_view/on_chat_msg_instance.dart

@ -0,0 +1,20 @@
import 'on_chat_message.dart';
class OnChatMsgInstance{
factory OnChatMsgInstance() => _getInstance();
static OnChatMsgInstance get instance => _getInstance();
static OnChatMsgInstance _instance;
OnChatMessage onChatMessage;
OnChatMsgInstance._internal();
static OnChatMsgInstance _getInstance(){
if(_instance == null){
_instance = OnChatMsgInstance._internal();
}
return _instance;
}
}

55
lib/message/im/im_view/text_item_container.dart

@ -0,0 +1,55 @@
import 'package:extended_text/extended_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';import 'package:huixiang/message/im/im_view/text_span_builder.dart';
import 'magic_pop.dart';
class TextItemContainer extends StatefulWidget {
final String text;
final String action;
final bool isMyself;
TextItemContainer({this.text, this.action, this.isMyself = true});
@override
_TextItemContainerState createState() => _TextItemContainerState();
}
class _TextItemContainerState extends State<TextItemContainer> {
TextSpanBuilder _spanBuilder = TextSpanBuilder();
@override
Widget build(BuildContext context) {
return MagicPop(
onValueChanged: (int value) {
switch (value) {
case 0:
Clipboard.setData(new ClipboardData(text: widget.text));
break;
case 3:
break;
}
},
pressType: PressType.longPress,
actions: ['复制', '转发', '收藏', '撤回', '删除'],
child: new Container(
// width: widget.text.length > 24 ? (MediaQuery.of(context).size.width - 66) - 100 : null,
// padding: EdgeInsets.all(5.0),
// decoration: BoxDecoration(
// color: widget.isMyself ? Color(0xff98E165) : Colors.white,
// borderRadius: BorderRadius.all(Radius.circular(5.0)),
// ),
// margin: EdgeInsets.only(right: 7.0),
child: ExtendedText(
widget.text ?? '文字为空',
maxLines: 99,
overflow: TextOverflow.ellipsis,
specialTextSpanBuilder: _spanBuilder,
style: TextStyle(fontSize: 17,color: Colors.white),
),
),
);
}
}

33
lib/message/im/im_view/text_span_builder.dart

@ -0,0 +1,33 @@
import 'package:extended_text_library/extended_text_library.dart';
import 'package:flutter/material.dart';
import 'emoji_text.dart';
class TextSpanBuilder extends SpecialTextSpanBuilder {
final bool showAtBackground;
TextSpanBuilder({
this.showAtBackground: false,
});
@override
TextSpan build(String data, {TextStyle textStyle, onTap}) {
TextSpan result = super.build(data, textStyle: textStyle, onTap: onTap);
return result;
}
@override
SpecialText createSpecialText(String flag,
{TextStyle textStyle, SpecialTextGestureTapCallback onTap, int index}) {
if (flag == null || flag == "") return null;
if (isStart(flag, EmojiText.flag)) {
return EmojiText(textStyle, start: index - (EmojiText.flag.length - 1));
}
return null;
}
}
class SpecialTextStyle {
TextRange textRange;
}

45
lib/message/im/im_view/triangle_painter.dart

@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
class TrianglePainter extends CustomPainter {
Paint _paint;
final Color color;
final RelativeRect position;
final Size size;
final double radius;
final bool isInverted;
final double screenWidth;
TrianglePainter(
{@required this.color,
@required this.position,
@required this.size,
this.radius = 20,
this.isInverted = false,
this.screenWidth}) {
_paint = Paint()
..style = PaintingStyle.fill
..color = color
..strokeWidth = 10
..isAntiAlias = true;
}
@override
void paint(Canvas canvas, Size size) {
var path = Path();
path.moveTo(size.width - this.size.width + this.size.width / 1.5,
isInverted ? 0 : size.height);
path.lineTo(
size.width - this.size.width + this.size.width / 1.5 - radius / 3,
isInverted ? size.height : 0);
path.lineTo(
size.width - this.size.width + this.size.width / 1.5 + radius / 3,
isInverted ? size.height : 0);
path.close();
canvas.drawPath(path, _paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

14
lib/message/system_details.dart

@ -244,7 +244,7 @@ class _SystemDetails extends State<SystemDetails> {
? "assets/image/icon_system_message.webp"
: (message.typed == 2)
? "assets/image/icon_system_message.webp"
: "assets/image/c_z.webp",
: "assets/image/icon_cz.webp",
width: 24.w,
height: 24.h,
),
@ -294,10 +294,6 @@ class _SystemDetails extends State<SystemDetails> {
),
),
),
Icon(
Icons.keyboard_arrow_right,
color: Colors.black,
)
],
),
Container(
@ -371,7 +367,7 @@ class _SystemDetails extends State<SystemDetails> {
? "assets/image/icon_system_message.webp"
: (message.typed == 2)
? "assets/image/icon_system_message.webp"
: "assets/image/c_z.webp",
: "assets/image/icon_cz.webp",
width: 24.w,
height: 24.h,
),
@ -411,7 +407,7 @@ class _SystemDetails extends State<SystemDetails> {
Text(
S.of(context).chongzhichenggong,
style: TextStyle(
fontSize: 20.sp,
fontSize: 12.sp,
fontWeight: MyFontWeight.semi_bold,
color: Color(0xFF353535),
),
@ -434,10 +430,6 @@ class _SystemDetails extends State<SystemDetails> {
),
),
),
Icon(
Icons.keyboard_arrow_right,
color: Colors.black,
)
],
),
Container(

362
lib/message/system_message.dart

@ -1,6 +1,7 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/data/message.dart';
@ -17,6 +18,10 @@ import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../view_widget/custom_image.dart';
import 'im/im_view/on_chat_message.dart';
import 'im/im_view/on_chat_msg_instance.dart';
class SystemMessagePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
@ -24,7 +29,7 @@ class SystemMessagePage extends StatefulWidget {
}
}
class _SystemMessagePage extends State<SystemMessagePage> {
class _SystemMessagePage extends State<SystemMessagePage> implements OnChatMessage {
ApiService apiService;
int pageNum = 1;
List<Message> messages = [];
@ -38,9 +43,21 @@ class _SystemMessagePage extends State<SystemMessagePage> {
};
int state = 0;
@override
void onMessage(txt){
// SmartDialog.showToast("列表 $txt", alignment: Alignment.center);
}
@override
void dispose() {
super.dispose();
OnChatMsgInstance.instance.onChatMessage = null;
}
@override
void initState() {
super.initState();
OnChatMsgInstance.instance.onChatMessage = this;
SharedPreferences.getInstance().then((value) {
apiService =
@ -126,37 +143,37 @@ class _SystemMessagePage extends State<SystemMessagePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: MyAppBar(
// background: Colors.white,
// leadingColor: Colors.black,
// title: S.of(context).xiaoxi,
// titleSize: 18.sp,
// titleColor: Colors.black,
// actions: [
// Container(
// margin: EdgeInsets.only(right: 16.w),
// alignment: Alignment.centerRight,
// child: GestureDetector(
// onTap: () {
// setState(() {
// queryMsgStats();
// });
// },
// child: Text(
// S.of(context).biaoweiyidu,
// style: TextStyle(
// fontSize: 16.sp,
// fontWeight:MyFontWeight.semi_bold,
// color: Color(0xFF353535),
// ),
// ),
// ),
// ),
// ],
// ),
appBar: MyAppBar(
background: Colors.white,
leadingColor: Colors.black,
title: S.of(context).xiaoxi,
titleSize: 18.sp,
titleColor: Colors.black,
actions: [
Container(
margin: EdgeInsets.only(right: 16.w),
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: () {
setState(() {
queryMsgStats();
});
},
child: Text(
S.of(context).biaoweiyidu,
style: TextStyle(
fontSize: 16.sp,
fontWeight:MyFontWeight.semi_bold,
color: Color(0xFF353535),
),
),
),
),
],
),
body: SmartRefresher(
enablePullDown: true,
enablePullUp: true,
enablePullUp: false,
header: MyHeader(),
physics: BouncingScrollPhysics(),
footer: CustomFooter(
@ -173,84 +190,151 @@ class _SystemMessagePage extends State<SystemMessagePage> {
});
},
child: Container(
color: Colors.white,
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Container(
padding: EdgeInsets.only(bottom: 30.h),
child: Column(
children: [
Container(
color: Colors.white,
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 10.h,
bottom: 15.h,right: 16.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pop();
onTap: (){
Navigator.of(context).pushNamed('/router/system_details',
arguments: {"msgType": 6}).then((value) {
setState(() {
msgNumber["6"] = 0;
});
});
},
child: Container(
alignment: Alignment.centerRight,
margin: EdgeInsets.only(left: 12,),
padding: EdgeInsets.all(6),
child: Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: 24,
),
child:messageItem("assets/image/icon_pl.webp", S.of(context).pinglun, msgNumber["6"].toString()),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
Navigator.of(context).pushNamed('/router/system_details',
arguments: {"msgType": 5}).then((value) {
setState(() {
msgNumber["5"] = 0;
});
});
},
child: messageItem("assets/image/icon_z.webp", S.of(context).dianzan, msgNumber["5"].toString()),
),
Spacer(),
Expanded(
child: Text(
S.of(context).xiaoxi,
style: TextStyle(
color: Colors.black,
fontSize: 16.sp,
fontWeight: MyFontWeight.regular,
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
Navigator.of(context).pushNamed('/router/system_details',
arguments: {"msgType": 4}).then((value) {
setState(() {
msgNumber["4"] = 0;
});
});
},
child:messageItem("assets/image/icon_gz.webp", S.of(context).guanzhu,msgNumber["4"].toString()),
),
)),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
onTap: (){
Navigator.of(context).pushNamed('/router/system_notice').then((value) {
setState(() {
queryMsgStats();
msgNumber["2"] = 0;
msgNumber["3"] = 0;
});
});
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.w),
child: Text(
S.of(context).biaoweiyidu,
style: TextStyle(
color: Colors.black,
fontSize: 16.sp,
fontWeight: FontWeight.bold,
child:messageItem("assets/image/icon_system_message.webp", S.of(context).xitongxiaoxi, (msgNumber["2"]+msgNumber["3"]).toString()),
),
// newSurvey(),
chatList(),
// buildMessage(),fgg
],
),
),
),
),
],
),
);
}
Widget messageItem(img, title, messageNum) {
return Container(
padding: EdgeInsets.only(top:14.h, left:14.w, bottom:10.h, right:14.w),
decoration: BoxDecoration(
color: Colors.white,
),
child: Column(
children: [
Row(
children: [
Image.asset(
img,
fit: BoxFit.fill,
),
newsSurvey(),
SizedBox(
height: 16.h,
width: 12.w,
),
buildMessage(),
],
Text(
title,
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF060606),
fontWeight: MyFontWeight.semi_bold,
),
),
SizedBox(
width: 9.w,
),
if(messageNum != "0")
((double.tryParse(messageNum) < 100)?
Container(
width: 16,
height: 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFFF441A),
),
child: RoundButton(
text:messageNum,
textColor: Colors.white,
fontWeight: MyFontWeight.regular,
backgroup: Color(0xFFFF441A),
fontSize: 10.sp,
radius: 100,
)):
Container(
padding: EdgeInsets.symmetric(horizontal:4.w,vertical:2.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFFF441A),
),
child: RoundButton(
text:"99+",
textColor: Colors.white,
fontWeight: MyFontWeight.regular,
backgroup: Color(0xFFFF441A),
fontSize: 10.sp,
radius: 100,
))),
Spacer(),
Icon(
Icons.keyboard_arrow_right,
size: 24,
),
],
),
Container(
margin: EdgeInsets.only(top: 12.h),
width: double.infinity,
height: 1.h,
color: Color(0xFFF7F7F7),
)
],
),
);
}
Widget newsSurvey() {
Widget newSurvey() {
return Container(
color: Colors.white,
padding: EdgeInsets.only(top: 16.h, bottom: 16.h),
@ -432,6 +516,7 @@ class _SystemMessagePage extends State<SystemMessagePage> {
);
}
///
Widget buildMessage() {
return Container(
color: Colors.white,
@ -492,20 +577,6 @@ class _SystemMessagePage extends State<SystemMessagePage> {
Widget buildMessageItem(Message message) {
return Container(
margin: EdgeInsets.only(top: 8.h, bottom: 8.h),
// margin: EdgeInsets.only(left: 16.w, right: 16.w, top: 8.h, bottom: 8.h),
// padding: EdgeInsets.all(20.w),
// decoration: BoxDecoration(
// color: Colors.white,
// boxShadow: [
// BoxShadow(
// color: Colors.black.withAlpha(12),
// offset: Offset(0, 3),
// blurRadius: 14,
// spreadRadius: 0,
// )
// ],
// borderRadius: BorderRadius.circular(8),
// ),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
@ -519,7 +590,7 @@ class _SystemMessagePage extends State<SystemMessagePage> {
? "assets/image/icon_system_message.webp"
: (message.typed == 2)
? "assets/image/icon_system_message.webp"
: "assets/image/c_z.webp",
: "assets/image/icon_cz.webp",
width: 40.w,
height: 40.h,
),
@ -727,4 +798,115 @@ class _SystemMessagePage extends State<SystemMessagePage> {
// ),
);
}
Widget chatList(){
return Container(
child: ListView.builder(
// padding: EdgeInsets.only(top: 16),
itemCount: 6,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
behavior:HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pushNamed('/router/chat_details_page');
},
child: chatItem(),
);
}),
);
}
Widget chatItem(){
return Container(
padding: EdgeInsets.only(left: 16.w,right: 17.w,bottom:27.h),
child: Column(
children: [
Row(
children: [
// MImage(
// "",
// isCircle: true,
// width: 40,
// height: 40,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height:40,
width:40,
),
SizedBox(width: 12.w,),
Expanded(child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: Text(
"好大一只鞋子",
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF060606),
fontWeight: MyFontWeight.semi_bold,
)),),
Text(
"2021.03.08 13:22",
style: TextStyle(
fontSize: 10.sp,
color: Color(0xFFA29E9E),
fontWeight: MyFontWeight.regular,
),
),
],
),
SizedBox(height: 7.h,),
Row(
children: [
Expanded(child:Text(
"新开的火锅店好吃得很",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 10.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.regular,
),
)),
Container(
width: 16,
height: 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFFF441A),
),
child: RoundButton(
text:"99",
textColor: Colors.white,
fontWeight: MyFontWeight.regular,
backgroup: Color(0xFFFF441A),
fontSize: 10.sp,
radius: 100,
))
],
)
],
)),
],
),
Container(
margin: EdgeInsets.only(top: 12.h),
width: double.infinity,
height: 1.h,
color: Color(0xFFF7F7F7),
)
],
),
);
}
}

323
lib/message/system_notice.dart

@ -0,0 +1,323 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/data/message.dart';
import 'package:huixiang/retrofit/data/page.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/utils/font_weight.dart';
import 'package:huixiang/view_widget/classic_header.dart';
import 'package:huixiang/view_widget/custom_image.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:huixiang/view_widget/my_footer.dart';
import 'package:huixiang/view_widget/no_data_view.dart';
import 'package:huixiang/view_widget/round_button.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class SystemNotice extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _SystemNotice();
}
}
class _SystemNotice extends State<SystemNotice> {
ApiService apiService;
int pageNum = 1;
List<Message> messages = [];
int msgType = 0;
// String parenId = "0";
var commentFocus = FocusNode();
String hintText = S.current.liuxianinjingcaidepinglunba;
bool isKeyBoardShow = false;
final GlobalKey commentKey = GlobalKey();
final GlobalKey inputKey = GlobalKey();
final TextEditingController commentTextController = TextEditingController();
int indexMsg = 0;
@override
void initState() {
super.initState();
// msgType = widget.arguments["msgType"];
SharedPreferences.getInstance().then((value) {
apiService =
ApiService(Dio(), token: value.getString("token"), context: context);
queryMessage();
});
}
_refresh() {
pageNum = 1;
queryMessage();
}
queryMessage() async {
BaseData<PageInfo<Message>> baseData = await apiService.msgList({
"pageNum": pageNum,
"pageSize": 10,
"searchKey": "",
"state": "",
"typed": ""
}).catchError((onError) {
_refreshController.loadFailed();
_refreshController.refreshFailed();
});
if (baseData != null && baseData.isSuccess) {
if (pageNum == 1) {
messages.clear();
}
List<Message> message = [];
message.addAll(baseData.data.list);
message.forEach((element) {
if (element.typed == 2 || element.typed == 3) {
messages.add(element);
}
});
_refreshController.loadComplete();
_refreshController.refreshCompleted();
if (mounted) setState(() {});
if (pageNum * 10 > int.tryParse(baseData.data.total)) {
_refreshController.loadNoData();
} else {
pageNum += 1;
}
} else {
_refreshController.loadFailed();
_refreshController.refreshFailed();
}
}
RefreshController _refreshController = RefreshController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SmartRefresher(
enablePullDown: true,
enablePullUp: true,
header: MyHeader(),
physics: BouncingScrollPhysics(),
footer: CustomFooter(
loadStyle: LoadStyle.ShowWhenLoading,
builder: (BuildContext context, LoadStatus mode) {
return (messages.length == 0) ? Container() : MyFooter(mode);
},
),
controller: _refreshController,
onRefresh: _refresh,
onLoading: () {
queryMessage();
},
child: Container(
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Container(
child: Column(
children: [
Container(
color: Colors.white,
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 10.h,
bottom: 10.h,
right: 16.w),
child: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pop();
},
child: Container(
alignment: Alignment.centerRight,
margin: EdgeInsets.only(
left: 12,
),
padding: EdgeInsets.all(6),
child: Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: 24,
),
),
),
Text(
"消息通知",
style: TextStyle(
color: Colors.black,
fontSize: 18.sp,
fontWeight: MyFontWeight.bold,
),
),
],
),
),
buildMessage()
],
),
),
),
),
),
);
}
Widget buildMessage() {
return Container(
color: Colors.white,
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(messages == null || messages.length == 0)
? NoDataView(
src: "assets/image/icon_empty.webp",
isShowBtn: false,
text: S.of(context).haimeiyouxiaoxi,
fontSize: 16.sp,
margin: EdgeInsets.only(top: 120.h),
)
: ListView.builder(
padding: EdgeInsets.only(top: 16),
itemCount: messages.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (messages[position].typed == 2)
Navigator.of(context).pushNamed(
'/router/system_details',
arguments: {"msgType": 2});
else if (messages[position].typed == 3)
Navigator.of(context).pushNamed(
'/router/system_details',
arguments: {"msgType": 3});
},
child: buildMessageItem(messages[position]),
);
}),
],
));
}
Widget buildMessageItem(Message message) {
return Container(
margin: EdgeInsets.only(top: 8.h, bottom: 8.h,left: 16.w,right: 17.w),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
(message.typed == 1)
? "assets/image/icon_order.webp"
: (message.typed == 2)
? "assets/image/icon_order.webp"
: "assets/image/icon_cz.webp",
width: 24.w,
height: 24.h,
),
SizedBox(
width: 8.w,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
(message.typed == 1)
? S.of(context).xitongtongzhi
: (message.typed == 2)
? S.of(context).dingdanxiaoxi
: S.of(context).chongzhixiaoxi,
style: TextStyle(
fontSize: 14.sp,
fontWeight: MyFontWeight.semi_bold,
color: Color(0xFF060606),
),
)),
Text(
message.updateTime,
style: TextStyle(
fontSize: 10.sp,
color: Color(0xFFA29E9E),
),
),
],
),
SizedBox(
height: 24.h,
),
(message.typed != 3)
? Row(
mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
S.of(context).ninyouyigexindedingdan,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF353535),
),
),
),
Icon(
Icons.keyboard_arrow_right,
size: 24,
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
message.content,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF353535),
),
)),
Icon(
Icons.keyboard_arrow_right,
size: 24,
),
],
),
Container(
margin: EdgeInsets.only(top: 16.h, bottom: 8.h),
height: 1.h,
width: double.infinity,
color: Color(0xFFF7F7F7),
),
],
),
),
],
),
],
),
);
}
}

15
lib/mine/mine_view/mine_view.dart

@ -76,6 +76,7 @@ class _MineView extends State<MineView> {
Container(
height: 24.h,
alignment: Alignment.center,
margin: EdgeInsets.only(right: 12.w),
child: GestureDetector(
onTap: () {
Navigator.of(context)
@ -90,10 +91,9 @@ class _MineView extends State<MineView> {
child: Stack(
children: [
Image.asset(
"assets/image/icon_notices.webp",
width: 32,
height: 32,
color: Colors.white,
"assets/image/icon_chat.webp",
width:24,
height: 24,
),
if (widget.totalMsg != 0)
Container(
@ -128,12 +128,11 @@ class _MineView extends State<MineView> {
toScan();
},
child: Container(
padding: EdgeInsets.all(8.h),
padding: EdgeInsets.only(left: 12.w,right:16.w,top:8.h,bottom:8.h),
child: Image.asset(
"assets/image/icon_scan_qr_code.webp",
width: 32,
height: 32,
color: Colors.white,
width: 24,
height: 24,
),
),
),

115
lib/mine/personal_page.dart

@ -96,6 +96,27 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
}
}
////
vipFollow(followId, isFollow) async {
if (apiService == null) {
SharedPreferences value = await SharedPreferences.getInstance();
apiService = ApiService(
Dio(),
context: context,
token: value.getString("token"),
);
}
BaseData baseData = await apiService.follow(followId ?? "");
if (baseData != null && baseData.isSuccess) {
queryCommunity(null);
SmartDialog.showToast(isFollow ? "关注成功" : "取关成功",
alignment: Alignment.center);
setState(() {});
} else {
SmartDialog.showToast(baseData.msg, alignment: Alignment.center);
}
}
///
queryCommunity(String searchKey) async {
if (!isRefresh) {
@ -322,7 +343,7 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body:SmartRefresher(
body: SmartRefresher(
controller: refreshController,
enablePullDown: true,
enablePullUp: true,
@ -382,7 +403,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
color: Colors.transparent,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
@ -407,7 +429,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
showImagePicker();
},
child: Container(
padding: EdgeInsets.only(left: 2, right: 2),
padding:
EdgeInsets.only(left: 2, right: 2),
width: 59.w,
height: 23.h,
alignment: Alignment.center,
@ -442,8 +465,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin:
EdgeInsets.only(left: 86.w, top: 12.h, right: 16.w),
margin: EdgeInsets.only(
left: 86.w, top: 12.h, right: 16.w),
child: GestureDetector(
onTap: () {
setState(() {
@ -474,7 +497,7 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
)),
Icon(
(isShrink != null && !isShrink)
? Icons.chevron_right
? Icons.keyboard_arrow_down
: Icons.keyboard_arrow_up,
color: Colors.black,
size: 18,
@ -504,7 +527,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
style: TextStyle(
color: Color(0xFF353535),
fontSize: 16.sp,
fontWeight: MyFontWeight.semi_bold,
fontWeight:
MyFontWeight.semi_bold,
),
),
SizedBox(
@ -538,7 +562,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
style: TextStyle(
color: Color(0xFF353535),
fontSize: 16.sp,
fontWeight: MyFontWeight.semi_bold,
fontWeight:
MyFontWeight.semi_bold,
),
),
SizedBox(
@ -571,7 +596,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
style: TextStyle(
color: Color(0xFF353535),
fontSize: 16.sp,
fontWeight: MyFontWeight.semi_bold,
fontWeight:
MyFontWeight.semi_bold,
),
),
SizedBox(
@ -604,7 +630,8 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
style: TextStyle(
color: Color(0xFF353535),
fontSize: 16.sp,
fontWeight: MyFontWeight.semi_bold,
fontWeight:
MyFontWeight.semi_bold,
),
),
SizedBox(
@ -646,8 +673,7 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
),
],
)),
)
);
));
}
Widget homeInfo() {
@ -738,7 +764,66 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
),
),
),
)
),
if (memberId != "0")
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context)
.pushNamed('/router/chat_details_page');
},
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 16.w, vertical: 3.h),
margin: EdgeInsets.only(right: 8.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
border: Border.all(
width: 1,
color: Color(0xFF32A060),
style: BorderStyle.solid,
),
color: Colors.white,
),
child: Text("私信",
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF32A060),
fontWeight: MyFontWeight.regular,
)),
),
),
if (memberId != "0")
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
if (articles.isNotEmpty)
vipFollow(memberId, articles.first.followed ?? false);
});
},
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 16.w, vertical: 3.5.h),
margin: EdgeInsets.only(right: 8.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: (articles.isNotEmpty && articles.first.followed ?? false)
? Color(0xFFE6E6E6)
: Color(0xFF32A060),),
child: Text(
(articles.isNotEmpty && articles.first.followed ?? false)
? S.of(context).yiguanzhu
: S.of(context).guanzhu,
style: TextStyle(
fontSize: 12.sp,
color: (articles.isNotEmpty && articles.first.followed ?? false)
? Color(0xFF808080)
: Colors.white,
fontWeight: MyFontWeight.regular,
)),
),
),
],
),
));
@ -752,7 +837,7 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
isShowBtn: false,
text: "目前暂无发布动态,要把开心的事讲出来哦~",
fontSize: 16.sp,
margin: EdgeInsets.only(left: 60.w, right: 60.w, bottom:80.h),
margin: EdgeInsets.only(left: 60.w, right: 60.w, bottom: 80.h),
)
: ListView.builder(
physics: NeverScrollableScrollPhysics(),
@ -761,7 +846,7 @@ class _PersonalPage extends State<PersonalPage> with WidgetsBindingObserver {
return InkWell(
child: CommunityDynamic(
articles[position],
memberId == "0" ? 1 : 0,
memberId == "0" ? 1 : 3,
exitFull: () {
setState(() {
_onRefresh();

2
lib/retrofit/min_api.dart

@ -26,7 +26,7 @@ import 'data/shopping_home_config.dart';
part 'min_api.g.dart';
const localBaseUrl = "http://192.168.10.129:8765/app/";///
const localBaseUrl = "https://pos.api.lotus-wallet.com/app/";///
// const localBaseUrl = "https://2946-27-19-77-115.jp.ngrok.io/app/";///
const serviceBaseUrl = "https://pos.api.lotus-wallet.com/app/";///线

2
lib/retrofit/retrofit_api.dart

@ -64,7 +64,7 @@ import 'data/wx_pay.dart';
part 'retrofit_api.g.dart';
const localBaseUrl = "http://192.168.10.129:8766/app/";///
const localBaseUrl = "https://pos.platform.lotus-wallet.com/app/";///
// const localBaseUrl = "https://2946-27-19-77-115.jp.ngrok.io/app/";///
const serviceBaseUrl = "https://pos.platform.lotus-wallet.com/app/";///线

51
lib/setting/help_feedback_page.dart

@ -21,7 +21,9 @@ class HelpFeedbackPage extends StatefulWidget {
class _HelpFeedbackPage extends State<HelpFeedbackPage> {
var _isExpanded = [false, false, false];
final TextEditingController editingController = TextEditingController();
final TextEditingController phoneController = TextEditingController();
int textLength = 0;
ApiService apiService;
@override
@ -34,6 +36,28 @@ class _HelpFeedbackPage extends State<HelpFeedbackPage> {
}
///
report() async {
if (apiService == null) {
SharedPreferences value = await SharedPreferences.getInstance();
apiService = ApiService(
Dio(),
context: context,
token: value.getString("token"),
);
}
BaseData baseData = await apiService.complaint({
"content": phoneController.text,
"informationId":0,
}).catchError((onError) {});
if (baseData != null && baseData.isSuccess) {
SmartDialog.showToast("反馈成功");
Navigator.of(context).pop();
} else {
SmartDialog.showToast(baseData.msg,alignment: Alignment.center);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -174,31 +198,6 @@ class _HelpFeedbackPage extends State<HelpFeedbackPage> {
);
}
report() async {
if (apiService == null) {
SharedPreferences value = await SharedPreferences.getInstance();
apiService = ApiService(
Dio(),
context: context,
token: value.getString("token"),
);
}
BaseData baseData = await apiService.complaint({
"content": phoneController.text,
"informationId":0,
}).catchError((onError) {});
if (baseData != null && baseData.isSuccess) {
SmartDialog.showToast("反馈成功");
Navigator.of(context).pop();
} else {
SmartDialog.showToast(baseData.msg,alignment: Alignment.center);
}
}
final TextEditingController editingController = TextEditingController();
final TextEditingController phoneController = TextEditingController();
int textLength = 0;
///
_feedback() {
return Container(

357
lib/setting/notice_setting.dart

@ -0,0 +1,357 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart';
import '../../generated/l10n.dart';
import '../../retrofit/data/base_data.dart';
import '../../utils/font_weight.dart';
class NoticeSetting extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _NoticeSetting();
}
}
class _NoticeSetting extends State<NoticeSetting> {
ApiService apiService;
bool commentSetting = true;
bool followSetting = true;
bool likesSetting = false;
int index = 0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF9FAF7),
appBar: MyAppBar(
title: "通知设置",
titleColor: Colors.black,
titleSize: 18.sp,
background: Colors.white,
leading: true,
leadingColor: Colors.black,
),
body: Container(
color: Color(0xFFF9FAF7),
child: Column(
children: [
SizedBox(
height: 12,
),
// Container(
// decoration: BoxDecoration(
// color: Colors.white,
// ),
// padding: EdgeInsets.only(
// left: 16.w, right: 16.w, top: 14.h, bottom: 16.h),
// child: Row(
// children: [
// Expanded(
// child: Text(
// S.of(context).pinglun,
// style: TextStyle(
// fontSize: 15.sp,
// color: Color(0xFF353535),
// fontWeight: MyFontWeight.semi_bold,
// ),
// )),
// CupertinoSwitch(
// value: (commentSetting),
// activeColor: Color(0xFF32A060),
// onChanged: (bool value) {
// setState(() {
// commentSetting = !commentSetting;
// });
// },
// ),
// ],
// ),
// ),
// Container(
// decoration: BoxDecoration(
// color: Colors.white,
// ),
// padding: EdgeInsets.only(
// left: 16.w, right: 16.w, top: 14.h, bottom: 16.h),
// child: Row(
// children: [
// Expanded(
// child: Text(
// S.of(context).guanzhu,
// style: TextStyle(
// fontSize: 15.sp,
// color: Color(0xFF353535),
// fontWeight: MyFontWeight.semi_bold,
// ),
// )),
// CupertinoSwitch(
// value: (followSetting),
// activeColor: Color(0xFF32A060),
// onChanged: (bool value) {
// setState(() {
// followSetting = !followSetting;
// });
// },
// ),
// ],
// ),
// ),
// Container(
// decoration: BoxDecoration(
// color: Colors.white,
// ),
// padding: EdgeInsets.only(
// left: 16.w, right: 16.w, top: 14.h, bottom: 16.h),
// child: Row(
// children: [
// Expanded(
// child: Text(
// S.of(context).dianzan,
// style: TextStyle(
// fontSize: 15.sp,
// color: Color(0xFF353535),
// fontWeight: MyFontWeight.semi_bold,
// ),
// )),
// CupertinoSwitch(
// value: (likesSetting),
// activeColor: Color(0xFF32A060),
// onChanged: (bool value) {
// setState(() {
// likesSetting = !likesSetting;
// });
// },
// ),
// ],
// ),
// ),
settingItem(S.of(context).pinglun,commentSetting,(){
setState(() {
commentSetting = !commentSetting;
});
}),
settingItem(S.of(context).guanzhu,followSetting,(){
setState(() {
followSetting = !followSetting;
});
}),
settingItem(S.of(context).dianzan,likesSetting,(){
setState(() {
likesSetting = !likesSetting;
});
}),
SizedBox(
height: 12,
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
),
padding: EdgeInsets.only(
left: 16.w, right: 16.w, top: 14.h, bottom: 16.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: Text(
"谁可以私信我",
style: TextStyle(
fontSize: 15.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.semi_bold,
),
)),
GestureDetector(
onTap: (){
showAlertDialog();
},
child: Text(
index == 0?"默认接收":(index == 1 ? "互关好友": "不接收"),
style: TextStyle(
fontSize: 14.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.regular,
),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
showAlertDialog();
},
child: Image.asset(
"assets/image/icon_right_z.webp",
height:16,
width:16,
color: Colors.black,
),
),
],
),
),
)
],
),
),
);
}
Widget settingItem(text, buttonSet,fun) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
),
padding:
EdgeInsets.only(left: 16.w, right: 16.w, top: 14.h, bottom: 16.h),
child: Row(
children: [
Expanded(
child: Text(
text,
style: TextStyle(
fontSize: 15.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.semi_bold,
),
)),
CupertinoSwitch(
value: (buttonSet),
activeColor: Color(0xFF32A060),
onChanged: (bool value) {
fun();
},
),
],
),
);
}
///
showAlertDialog() {
showModalBottomSheet(
builder: (BuildContext context) {
return StatefulBuilder(builder: (
context,
state,
) {
return WillPopScope(
///
// onWillPop: () async => false,
child: Container(
width: double.infinity,
height: 225.h,
padding:
EdgeInsets.only(left: 16.w, top:21.h),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
),
),
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Container(
padding: EdgeInsets.only(right: 18.w),
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
setState((){
index = 0;
Navigator.of(context).pop();
});
},
child:Container(
width: double.infinity,
padding: EdgeInsets.only(bottom: 23.h),
child: Text(
"默认接收",
style: TextStyle(
fontWeight: MyFontWeight.medium,
fontSize: 16.sp,
color: Color(0xFF353535),
),
),
),
),
Container(
color: Color(0xFFF7F7F7),
width: double.infinity,
height: 1.h,
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
setState((){
index = 1;
Navigator.of(context).pop();
});
},
child:Container(
width: double.infinity,
padding: EdgeInsets.only(top: 20.h,bottom: 23.h),
child: Text(
"互关好友",
style: TextStyle(
fontWeight: MyFontWeight.medium,
fontSize: 16.sp,
color: Color(0xFF353535),
),
),
),
),
Container(
color: Color(0xFFF7F7F7),
width: double.infinity,
height: 1.h,
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
setState((){
index = 2;
Navigator.of(context).pop();
});
},
child:Container(
width: double.infinity,
padding: EdgeInsets.only(top: 20.h),
child: Text(
"不接收",
style: TextStyle(
fontWeight: MyFontWeight.medium,
fontSize: 16.sp,
color: Color(0xFF353535),
),
),
),
),
],
),
),
),
));
});
},
backgroundColor: Colors.transparent,
context: context);
}
}

9
lib/setting/setting_page.dart

@ -157,6 +157,15 @@ class _SettingPage extends State<SettingPage> {
SizedBox(
height: 16.h,
),
GestureDetector(
child: settingSingleItem("通知设置"),
onTap: () {
Navigator.of(context).pushNamed('/router/notice_setting');
},
),
SizedBox(
height: 16.h,
),
GestureDetector(
child: settingItem(S.of(context).qinglihuancun, cacheTotal),
onTap: () {

4
lib/settlement/settlement_view/settlement_order_commodity.dart

@ -218,7 +218,9 @@ class _SettlementOrderCommodity extends State<SettlementOrderCommodity> {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
S.of(context).yuan_(AppUtils.calculateDouble(double.tryParse(productList.sellPrice ?? "0") - double.tryParse(productList.discountAmount ?? "0"))),
productList.buyNum > 1 ?
S.of(context).yuan_(AppUtils.calculateDouble(double.tryParse(productList.sellPrice ?? "0") - AppUtils.stringAsFixedDouble2((double.tryParse(productList.discountAmount ?? "0")/productList.buyNum))))
:S.of(context).yuan_(AppUtils.calculateDouble(double.tryParse(productList.sellPrice ?? "0") - double.tryParse(productList.discountAmount ?? "0"))),
style: TextStyle(
fontWeight: MyFontWeight.medium,
fontSize: 14.sp,

10
lib/utils/flutter_utils.dart

@ -17,6 +17,16 @@ class AppUtils {
return "${numberFormat.format(mi / 1000)}";
}
///
static double stringAsFixedDouble2(double value) {
String valueStr = value.toString();
if (!valueStr.contains(".")) return value;
if (valueStr.indexOf(".") + 3 >= valueStr.length)
return value;
else
return double.tryParse(valueStr.substring(0, valueStr.indexOf(".") + 3))??0;
}
///
static bool versionCompare(String localVersion, String serverVersion) {
try {

41
lib/view_widget/share_dialog.dart

@ -15,18 +15,23 @@ class ShareDialog extends StatefulWidget {
}
class _ShareDialog extends State<ShareDialog> {
List<String> platformNames = ["line", "微信好友", "朋友圈", "facebook"];
// List<String> platformNames = ["line", "微信好友", "朋友圈", "facebook"];
List<String> platformNames = ["转至回乡", "转至微信", "转发到朋友圈", "转至私信","复制链接"];
List<String> platformIcons = [
"assets/image/icon_line.webp",
// "assets/image/icon_line.webp",
"assets/image/icon_share_hx.webp",
"assets/image/icon_weixin.webp",
"assets/image/icon_pengyouquan.webp",
"assets/image/icon_facebook.webp"
"assets/image/icon_share_chat.webp",
"assets/image/icon_copy _link.webp"
// "assets/image/icon_facebook.webp"
];
List<ShareSDKPlatform> platforms = [
ShareSDKPlatforms.line,
ShareSDKPlatforms.wechatSession,
ShareSDKPlatforms.wechatTimeline,
ShareSDKPlatforms.facebook
ShareSDKPlatforms.facebook,
ShareSDKPlatforms.copy
];
@override
@ -42,7 +47,7 @@ class _ShareDialog extends State<ShareDialog> {
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(8),),
),
padding: EdgeInsets.only(top: 16.h, bottom: 66.h,),
padding: EdgeInsets.only(top: 16.h,),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
@ -72,14 +77,14 @@ class _ShareDialog extends State<ShareDialog> {
children: [
Image.asset(
platformIcons[platforms.indexOf(e)],
width: 40.w,
height: 40.h,
width: 40,
height: 40,
),
SizedBox(
height: 4.h,
),
Container(
height: 18.h,
width: 40.w,
child: Text(
platformNames[platforms.indexOf(e)],
style: TextStyle(
@ -96,6 +101,26 @@ class _ShareDialog extends State<ShareDialog> {
))
.toList(),
),
Spacer(),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
Navigator.of(context).pop();
},
child: Container(
width: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.only(top: 14.h,bottom:17.h),
color: Color(0xFF32A060),
child: Text(
S.of(context).quxiao,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.sp,
color: Colors.white),
),
),
)
],
),
);

1
lib/web/web_view/input_comment.dart

@ -55,7 +55,6 @@ class InputComment extends StatefulWidget {
}
class _InputComment extends State<InputComment> {
bool emojiShowing = false;
@override
Widget build(BuildContext context) {

14
pubspec.lock

@ -134,6 +134,20 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
extended_text:
dependency: "direct main"
description:
name: extended_text
url: "https://pub.flutter-io.cn"
source: hosted
version: "9.1.2"
extended_text_library:
dependency: transitive
description:
name: extended_text_library
url: "https://pub.flutter-io.cn"
source: hosted
version: "9.1.1"
fake_async:
dependency: transitive
description:

2
pubspec.yaml

@ -105,6 +105,8 @@ dependencies:
mqtt_client: ^9.6.8
extended_text: ^9.0.0
dev_dependencies:
flutter_test:
sdk: flutter

Loading…
Cancel
Save