@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填写自我简介获得更多关注,在此处填写", | |||||
"new_msg": "/s1条新消息", | |||||
"upload1": "上传", | |||||
"his_profile": "他的资料", | |||||
"her_profile": "她的资料" | |||||
} | } |
@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填写自我简介获得更多关注,在此处填写", | |||||
"new_msg": "/s1条新消息", | |||||
"upload1": "上传", | |||||
"his_profile": "他的资料", | |||||
"her_profile": "她的资料" | |||||
} | } |
@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填写自我简介获得更多关注,在此处填写", | |||||
"new_msg": "/s1条新消息", | |||||
"upload1": "上传", | |||||
"his_profile": "他的资料", | |||||
"her_profile": "她的资料" | |||||
} | } |
@@ -1159,7 +1159,7 @@ | |||||
"not_have_user": " Người dùng không tồn tại ", | "not_have_user": " Người dùng không tồn tại ", | ||||
"not_add_Myself": "Bạn không thể thêm chính mình", | "not_add_Myself": "Bạn không thể thêm chính mình", | ||||
"you_are_blaklisted": " Đối phương đã đưa bạn vào danh sách đen", | "you_are_blaklisted": " Đối phương đã đưa bạn vào danh sách đen", | ||||
"confrim_recovery": " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa", | |||||
"confrim_recovery": " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa)", | |||||
"send_to": " Gửi tới ", | "send_to": " Gửi tới ", | ||||
"search_plach": "Rà soát địa điểm", | "search_plach": "Rà soát địa điểm", | ||||
"finding_place": " Tìm địa điểm", | "finding_place": " Tìm địa điểm", | ||||
@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填写自我简介获得更多关注,在此处填写", | |||||
"new_msg": "/s1条新消息", | |||||
"upload1": "上传", | |||||
"his_profile": "他的资料", | |||||
"her_profile": "她的资料" | |||||
} | } |
@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填写自我简介获得更多关注,在此处填写", | |||||
"new_msg": "/s1条新消息", | |||||
"upload1": "上传", | |||||
"his_profile": "他的资料", | |||||
"her_profile": "她的资料" | |||||
} | } |
@@ -1251,5 +1251,10 @@ | |||||
"shock_notice": "震动通知", | "shock_notice": "震动通知", | ||||
"max_upload_size": "最多上传/s1张", | "max_upload_size": "最多上传/s1张", | ||||
"travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | "travel_tips2": "您的贴身出行管家,解决语言不通打车走错路的问题", | ||||
"new_friends_tips": "现在我们可以开始聊天了。" | |||||
"new_friends_tips": "现在我们可以开始聊天了。", | |||||
"msg_tips": "填寫自我簡介獲得更多關注,在此處填寫", | |||||
"new_msg": "/s1條新消息", | |||||
"upload1": "上傳", | |||||
"his_profile": "他的資料", | |||||
"her_profile": "她的資料" | |||||
} | } |
@@ -18,6 +18,7 @@ import 'package:chat/utils/MessageMgr.dart'; | |||||
import 'package:chat/utils/analyze_utils.dart'; | import 'package:chat/utils/analyze_utils.dart'; | ||||
import 'package:chat/utils/msgHandler.dart'; | import 'package:chat/utils/msgHandler.dart'; | ||||
import 'package:chat/utils/net_state_widget.dart'; | import 'package:chat/utils/net_state_widget.dart'; | ||||
import 'package:chat/utils/screen.dart'; | |||||
import 'package:chat/utils/sound_util.dart'; | import 'package:chat/utils/sound_util.dart'; | ||||
import 'package:chat/utils/sp_utils.dart'; | import 'package:chat/utils/sp_utils.dart'; | ||||
import 'package:chat/utils/sql_util.dart'; | import 'package:chat/utils/sql_util.dart'; | ||||
@@ -160,6 +161,17 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||||
sendMsg(msg); | sendMsg(msg); | ||||
} | } | ||||
}); | }); | ||||
controller.addListener(() { | |||||
if (alterTime != null || unreadTime != null) { | |||||
for (int i = 0; i < msgList.length; i++) { | |||||
if ((msgList[i].time == alterTime || msgList[i].time == unreadTime) && | |||||
controller.isIndexStateInLayoutRange(i)) { | |||||
clearUnreadNews(); | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
} | } | ||||
jumpToMsg(time) async { | jumpToMsg(time) async { | ||||
@@ -236,6 +248,11 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||||
} | } | ||||
} | } | ||||
clearUnreadNews() { | |||||
unreadTime = null; | |||||
setState(() {}); | |||||
} | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
List<Widget> actions = []; | List<Widget> actions = []; | ||||
@@ -289,111 +306,126 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||||
Provider<bool>.value(value: true), | Provider<bool>.value(value: true), | ||||
Provider<GroupInfoModel>.value(value: widget.groupInfoModel), | Provider<GroupInfoModel>.value(value: widget.groupInfoModel), | ||||
], | ], | ||||
child: GestureDetector( | |||||
onTapDown: (args){hideKeyBoard();}, | |||||
child: ExtendedTextSelectionPointerHandler( | |||||
///选择文字,消除弹窗 | |||||
builder: (states) { | |||||
return Listener( | |||||
child: Scaffold( | |||||
resizeToAvoidBottomInset: false, | |||||
backgroundColor: const Color(0xFFE2E9F1), | |||||
appBar: AppBar( | |||||
backgroundColor: AppColors.NewAppbarBgColor, | |||||
title: Text( | |||||
widget.groupInfoModel.getGroupName(refMap), | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle( | |||||
color: Constants.BlackTextColor, | |||||
fontSize: 16.47), | |||||
), | |||||
leading: CustomUI.buildCustomLeading(context), | |||||
titleSpacing: -10, | |||||
elevation: 1, | |||||
centerTitle: false, | |||||
actions: actions), | |||||
body: SafeArea( | |||||
child: Stack( | |||||
child: GestureDetector(onTapDown: (args) { | |||||
hideKeyBoard(); | |||||
}, child: ExtendedTextSelectionPointerHandler( | |||||
///选择文字,消除弹窗 | |||||
builder: (states) { | |||||
return Listener( | |||||
child: Scaffold( | |||||
resizeToAvoidBottomInset: false, | |||||
backgroundColor: const Color(0xFFE2E9F1), | |||||
appBar: AppBar( | |||||
backgroundColor: AppColors.NewAppbarBgColor, | |||||
title: Text( | |||||
widget.groupInfoModel.getGroupName(refMap), | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle( | |||||
color: Constants.BlackTextColor, fontSize: 16.47), | |||||
), | |||||
leading: CustomUI.buildCustomLeading(context), | |||||
titleSpacing: -10, | |||||
elevation: 1, | |||||
centerTitle: false, | |||||
actions: actions), | |||||
body: SafeArea( | |||||
child: Stack( | |||||
children: <Widget>[ | |||||
Column( | |||||
children: <Widget>[ | children: <Widget>[ | ||||
Column( | |||||
children: <Widget>[ | |||||
NetStateWidget(), | |||||
Expanded(child: _buildMessageList()), | |||||
InputBar(sendMsg: sendMsg), | |||||
], | |||||
), | |||||
isHaveUnreadNews | |||||
? Positioned( | |||||
top: 32.5, | |||||
right: 0, | |||||
child: InkWell( | |||||
onTap: () { | |||||
jumpToMsg(isAlterYou | |||||
? alterTime | |||||
: unreadTime); | |||||
unreadTime = null; | |||||
setState(() {}); | |||||
}, | |||||
child: Container( | |||||
alignment: Alignment.center, | |||||
decoration: BoxDecoration( | |||||
boxShadow: [ | |||||
BoxShadow( | |||||
color: Color(0x33000000), //阴影颜色 | |||||
blurRadius: 10.0, //阴影大小 | |||||
) | |||||
], | |||||
borderRadius: BorderRadius.only( | |||||
topLeft: Radius.circular(80), | |||||
bottomLeft: Radius.circular(80)), | |||||
color: Colors.white, | |||||
NetStateWidget(), | |||||
Expanded(child: _buildMessageList()), | |||||
InputBar(sendMsg: sendMsg), | |||||
], | |||||
), | |||||
isHaveUnreadNews | |||||
? Positioned( | |||||
top: 32.5, | |||||
right: 0, | |||||
child: InkWell( | |||||
onTap: () { | |||||
jumpToMsg( | |||||
isAlterYou ? alterTime : unreadTime); | |||||
clearUnreadNews(); | |||||
}, | |||||
child: Container( | |||||
alignment: Alignment.center, | |||||
decoration: BoxDecoration( | |||||
boxShadow: [ | |||||
BoxShadow( | |||||
color: Color(0x33000000), //阴影颜色 | |||||
blurRadius: 7, //阴影大小 | |||||
) | |||||
], | |||||
borderRadius: BorderRadius.only( | |||||
topLeft: Radius.circular(80), | |||||
bottomLeft: Radius.circular(80)), | |||||
color: Colors.white, | |||||
), | |||||
constraints: BoxConstraints(minWidth: 120), | |||||
height: 39, | |||||
child: Row( | |||||
children: <Widget>[ | |||||
SizedBox(width: 16.5), | |||||
Image.asset( | |||||
'assets/images/up.png', | |||||
width: 12, | |||||
), | ), | ||||
constraints: | |||||
BoxConstraints(minWidth: 120), | |||||
height: 39, | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Icon( | |||||
Icons.arrow_upward, | |||||
color: Color(0xFF3875E9), | |||||
size: 20, | |||||
), | |||||
Text( | |||||
SizedBox(width: 10), | |||||
Container( | |||||
child: Text( | |||||
isAlterYou | isAlterYou | ||||
? '$alterUserName @你' | |||||
: '$unreadNums条新消息', | |||||
? '$alterUserName' | |||||
: I18n.of(context) | |||||
.new_msg | |||||
.replaceFirst( | |||||
'/s1', | |||||
unreadNums | |||||
.toString()), | |||||
style: TextStyle( | style: TextStyle( | ||||
color: Color(0xFF3875E9)), | color: Color(0xFF3875E9)), | ||||
) | |||||
], | |||||
overflow: TextOverflow.ellipsis, | |||||
), | |||||
constraints: BoxConstraints( | |||||
maxWidth: isAlterYou | |||||
? 60 | |||||
: Screen.width)), | |||||
Text( | |||||
isAlterYou | |||||
? '@${I18n.of(context).you}' | |||||
: '', | |||||
style: TextStyle( | |||||
color: Color(0xFF3875E9)), | |||||
), | ), | ||||
))) | |||||
: Container() | |||||
], | |||||
))), | |||||
onPointerDown: (value) { | |||||
for (var state in states) { | |||||
if (!state.containsPosition(value.position)) { | |||||
//clear other selection | |||||
state.clearSelection(); | |||||
} | |||||
} | |||||
}, | |||||
onPointerMove: (value) { | |||||
SizedBox(width: 14), | |||||
], | |||||
), | |||||
))) | |||||
: Container() | |||||
], | |||||
))), | |||||
onPointerDown: (value) { | |||||
for (var state in states) { | |||||
if (!state.containsPosition(value.position)) { | |||||
//clear other selection | //clear other selection | ||||
for (var state in states) { | |||||
if (!state.containsPosition(value.position)) { | |||||
//clear other selection | |||||
state.clearSelection(); | |||||
} | |||||
} | |||||
}, | |||||
); | |||||
state.clearSelection(); | |||||
} | |||||
} | |||||
}, | |||||
onPointerMove: (value) { | |||||
//clear other selection | |||||
for (var state in states) { | |||||
if (!state.containsPosition(value.position)) { | |||||
//clear other selection | |||||
state.clearSelection(); | |||||
} | |||||
} | |||||
}, | }, | ||||
))); | |||||
); | |||||
}, | |||||
))); | |||||
} | } | ||||
Widget _buildMessageList() { | Widget _buildMessageList() { | ||||
return Container( | return Container( | ||||
alignment: Alignment.topCenter, | alignment: Alignment.topCenter, | ||||
@@ -59,7 +59,6 @@ class ChatDataMgr { | |||||
getLastRecord(); | getLastRecord(); | ||||
} | } | ||||
//初始化私聊未读消息 | //初始化私聊未读消息 | ||||
initUnreadCount() async { | initUnreadCount() async { | ||||
@@ -77,6 +76,7 @@ class ChatDataMgr { | |||||
unreadCountMap.forEach((k, v) { | unreadCountMap.forEach((k, v) { | ||||
groupUnreadProvider.updateUnreadCount(k, v); | groupUnreadProvider.updateUnreadCount(k, v); | ||||
}); | }); | ||||
groupUnreadProvider.initUnreadAlter(); | |||||
} | } | ||||
logout() { | logout() { | ||||
@@ -92,7 +92,8 @@ class ChatDataMgr { | |||||
//获取私聊记录 | //获取私聊记录 | ||||
List<MsgModel> getRecord({int sessionId}) { | List<MsgModel> getRecord({int sessionId}) { | ||||
var record = msgRecordMap[sessionId==null?MsgHandler.curActiveSession:sessionId]; | |||||
var record = msgRecordMap[ | |||||
sessionId == null ? MsgHandler.curActiveSession : sessionId]; | |||||
if (record == null) { | if (record == null) { | ||||
record = []; | record = []; | ||||
msgRecordMap[MsgHandler.curActiveSession] = record; | msgRecordMap[MsgHandler.curActiveSession] = record; | ||||
@@ -102,7 +103,8 @@ class ChatDataMgr { | |||||
//获取群聊记录 | //获取群聊记录 | ||||
List<MsgModel> getGroupRecord({int sessionId}) { | List<MsgModel> getGroupRecord({int sessionId}) { | ||||
var record = groupRecordMap[sessionId==null?MsgHandler.curActiveSession:sessionId]; | |||||
var record = groupRecordMap[ | |||||
sessionId == null ? MsgHandler.curActiveSession : sessionId]; | |||||
if (record == null) { | if (record == null) { | ||||
record = []; | record = []; | ||||
groupRecordMap[MsgHandler.curActiveSession] = record; | groupRecordMap[MsgHandler.curActiveSession] = record; | ||||
@@ -118,7 +120,6 @@ class ChatDataMgr { | |||||
msgRecordMap[MsgHandler.curActiveSession] = record; | msgRecordMap[MsgHandler.curActiveSession] = record; | ||||
} | } | ||||
return record; | return record; | ||||
} | } | ||||
updateLastMsgWithTranslateMsg(PushChat chat) async { | updateLastMsgWithTranslateMsg(PushChat chat) async { | ||||
@@ -281,7 +282,7 @@ class ChatDataMgr { | |||||
} | } | ||||
var result = getMsgBy(msg.sessionId, msg.time, true); | var result = getMsgBy(msg.sessionId, msg.time, true); | ||||
if (result != null) { | if (result != null) { | ||||
print('消息存在!!!!'); | |||||
print('消息存在!!!!'); | |||||
} else { | } else { | ||||
print('插入消息!!!!'); | print('插入消息!!!!'); | ||||
insertToDB(msg, record); | insertToDB(msg, record); | ||||
@@ -315,10 +316,10 @@ class ChatDataMgr { | |||||
print('数据为空,无法插入'); | print('数据为空,无法插入'); | ||||
} else { | } else { | ||||
record.insert(0, msg); | record.insert(0, msg); | ||||
// print(MsgHandler.time); | |||||
// print(MsgHandler.time); | |||||
//int after = DateTime.now().millisecondsSinceEpoch-MsgHandler.time; | //int after = DateTime.now().millisecondsSinceEpoch-MsgHandler.time; | ||||
// print('******插入数据 use $after'); | |||||
// print('******record length ${record.length} ${msg.sessionId}'); | |||||
// print('******插入数据 use $after'); | |||||
// print('******record length ${record.length} ${msg.sessionId}'); | |||||
SqlUtil.insert(msg); | SqlUtil.insert(msg); | ||||
@@ -92,8 +92,8 @@ class GroupOperatingPageType { | |||||
//消息发送界面类别 | //消息发送界面类别 | ||||
class SendMessagePageType { | class SendMessagePageType { | ||||
static const int AddFriends = 0; //添加朋友 | |||||
static const int ChangeGroupName = 1; //修改群名字 | |||||
static const int AddFriends = 0; //添加朋友 | |||||
static const int ChangeGroupName = 1; //修改群名字 | |||||
static const int ChangeGroupNickName = 2; //修改群昵称 | static const int ChangeGroupNickName = 2; //修改群昵称 | ||||
static const int Remark = 3; //修改备注 | static const int Remark = 3; //修改备注 | ||||
} | } | ||||
@@ -285,6 +285,8 @@ class Constants { | |||||
static const Latitude = 'Latitude'; | static const Latitude = 'Latitude'; | ||||
static const Longitude = 'Longitude'; | static const Longitude = 'Longitude'; | ||||
static const GroupAlterKey = 'GroupAlterKey'; //群@ | |||||
/// currentGoodsId+'@'+receipt+'@'+purchaseToken | /// currentGoodsId+'@'+receipt+'@'+purchaseToken | ||||
static final vipIcon = Image.asset( | static final vipIcon = Image.asset( | ||||
@@ -2539,6 +2539,16 @@ class I18n implements WidgetsLocalizations { | |||||
String get travel_tips2 => "您的贴身出行管家,解决语言不通打车走错路的问题"; | String get travel_tips2 => "您的贴身出行管家,解决语言不通打车走错路的问题"; | ||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填写自我简介获得更多关注,在此处填写" | |||||
String get msg_tips => "填写自我简介获得更多关注,在此处填写"; | |||||
/// "/s1条新消息" | |||||
String get new_msg => "/s1条新消息"; | |||||
/// "上传" | |||||
String get upload1 => "上传"; | |||||
/// "他的资料" | |||||
String get his_profile => "他的资料"; | |||||
/// "她的资料" | |||||
String get her_profile => "她的资料"; | |||||
} | } | ||||
class _I18n_en_US extends I18n { | class _I18n_en_US extends I18n { | ||||
@@ -5680,9 +5690,9 @@ class _I18n_vi_VN extends I18n { | |||||
/// "Đơn xin xác thực của bạn đã gửi và chờ đối phương thông qua" | /// "Đơn xin xác thực của bạn đã gửi và chờ đối phương thông qua" | ||||
@override | @override | ||||
String get add_friends_tips => "Đơn xin xác thực của bạn đã gửi và chờ đối phương thông qua"; | String get add_friends_tips => "Đơn xin xác thực của bạn đã gửi và chờ đối phương thông qua"; | ||||
/// "Tôi là/s1" | |||||
/// "Tôi là /s1" | |||||
@override | @override | ||||
String get i_am => "Tôi là/s1"; | |||||
String get i_am => "Tôi là /s1"; | |||||
/// "Cho phép" | /// "Cho phép" | ||||
@override | @override | ||||
String get agree => "Cho phép"; | String get agree => "Cho phép"; | ||||
@@ -6031,9 +6041,9 @@ class _I18n_vi_VN extends I18n { | |||||
/// " Đối phương đã đưa bạn vào danh sách đen" | /// " Đối phương đã đưa bạn vào danh sách đen" | ||||
@override | @override | ||||
String get you_are_blaklisted => " Đối phương đã đưa bạn vào danh sách đen"; | String get you_are_blaklisted => " Đối phương đã đưa bạn vào danh sách đen"; | ||||
/// " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa" | |||||
/// " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa)" | |||||
@override | @override | ||||
String get confrim_recovery => " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa"; | |||||
String get confrim_recovery => " Có chắc là bạn muốn phục hồi ảnh đã tiêu hủy không?\n (người dùng đã xem có thể xem lại lần nữa)"; | |||||
/// " Gửi tới " | /// " Gửi tới " | ||||
@override | @override | ||||
String get send_to => " Gửi tới "; | String get send_to => " Gửi tới "; | ||||
@@ -6310,6 +6320,21 @@ class _I18n_vi_VN extends I18n { | |||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
@override | @override | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填写自我简介获得更多关注,在此处填写" | |||||
@override | |||||
String get msg_tips => "填写自我简介获得更多关注,在此处填写"; | |||||
/// "/s1条新消息" | |||||
@override | |||||
String get new_msg => "/s1条新消息"; | |||||
/// "上传" | |||||
@override | |||||
String get upload1 => "上传"; | |||||
/// "他的资料" | |||||
@override | |||||
String get his_profile => "他的资料"; | |||||
/// "她的资料" | |||||
@override | |||||
String get her_profile => "她的资料"; | |||||
@override | @override | ||||
TextDirection get textDirection => TextDirection.ltr; | TextDirection get textDirection => TextDirection.ltr; | ||||
@@ -10077,6 +10102,21 @@ class _I18n_zh_HK extends I18n { | |||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
@override | @override | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填寫自我簡介獲得更多關注,在此處填寫" | |||||
@override | |||||
String get msg_tips => "填寫自我簡介獲得更多關注,在此處填寫"; | |||||
/// "/s1條新消息" | |||||
@override | |||||
String get new_msg => "/s1條新消息"; | |||||
/// "上傳" | |||||
@override | |||||
String get upload1 => "上傳"; | |||||
/// "他的資料" | |||||
@override | |||||
String get his_profile => "他的資料"; | |||||
/// "她的資料" | |||||
@override | |||||
String get her_profile => "她的資料"; | |||||
@override | @override | ||||
TextDirection get textDirection => TextDirection.ltr; | TextDirection get textDirection => TextDirection.ltr; | ||||
@@ -13844,6 +13884,21 @@ class _I18n_zh_CN extends _I18n_zh_HK { | |||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
@override | @override | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填写自我简介获得更多关注,在此处填写" | |||||
@override | |||||
String get msg_tips => "填写自我简介获得更多关注,在此处填写"; | |||||
/// "/s1条新消息" | |||||
@override | |||||
String get new_msg => "/s1条新消息"; | |||||
/// "上传" | |||||
@override | |||||
String get upload1 => "上传"; | |||||
/// "他的资料" | |||||
@override | |||||
String get his_profile => "他的资料"; | |||||
/// "她的资料" | |||||
@override | |||||
String get her_profile => "她的资料"; | |||||
@override | @override | ||||
TextDirection get textDirection => TextDirection.ltr; | TextDirection get textDirection => TextDirection.ltr; | ||||
@@ -17611,6 +17666,21 @@ class _I18n_ko_KR extends I18n { | |||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
@override | @override | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填写自我简介获得更多关注,在此处填写" | |||||
@override | |||||
String get msg_tips => "填写自我简介获得更多关注,在此处填写"; | |||||
/// "/s1条新消息" | |||||
@override | |||||
String get new_msg => "/s1条新消息"; | |||||
/// "上传" | |||||
@override | |||||
String get upload1 => "上传"; | |||||
/// "他的资料" | |||||
@override | |||||
String get his_profile => "他的资料"; | |||||
/// "她的资料" | |||||
@override | |||||
String get her_profile => "她的资料"; | |||||
@override | @override | ||||
TextDirection get textDirection => TextDirection.ltr; | TextDirection get textDirection => TextDirection.ltr; | ||||
@@ -21378,6 +21448,21 @@ class _I18n_ja_JP extends I18n { | |||||
/// "现在我们可以开始聊天了。" | /// "现在我们可以开始聊天了。" | ||||
@override | @override | ||||
String get new_friends_tips => "现在我们可以开始聊天了。"; | String get new_friends_tips => "现在我们可以开始聊天了。"; | ||||
/// "填写自我简介获得更多关注,在此处填写" | |||||
@override | |||||
String get msg_tips => "填写自我简介获得更多关注,在此处填写"; | |||||
/// "/s1条新消息" | |||||
@override | |||||
String get new_msg => "/s1条新消息"; | |||||
/// "上传" | |||||
@override | |||||
String get upload1 => "上传"; | |||||
/// "他的资料" | |||||
@override | |||||
String get his_profile => "他的资料"; | |||||
/// "她的资料" | |||||
@override | |||||
String get her_profile => "她的资料"; | |||||
@override | @override | ||||
TextDirection get textDirection => TextDirection.ltr; | TextDirection get textDirection => TextDirection.ltr; | ||||
@@ -78,6 +78,7 @@ class SystemEditPageState extends State<SystemEditPage> { | |||||
textScaleFactor: 1.0, | textScaleFactor: 1.0, | ||||
), | ), | ||||
centerTitle: true, | centerTitle: true, | ||||
elevation: 1, | |||||
leading: CustomUI.buildCustomLeading(context), | leading: CustomUI.buildCustomLeading(context), | ||||
), | ), | ||||
body: SafeArea( | body: SafeArea( | ||||
@@ -107,6 +108,8 @@ class SystemEditPageState extends State<SystemEditPage> { | |||||
_buildMyEvaluation(), | _buildMyEvaluation(), | ||||
_buildVersion(), | _buildVersion(), | ||||
_buildHelp(), | _buildHelp(), | ||||
_buildHistory(), | |||||
_buildRset(), | |||||
SizedBox(height: Separate_Size), | SizedBox(height: Separate_Size), | ||||
_buildLogout(), | _buildLogout(), | ||||
SizedBox(height: Separate_Size), | SizedBox(height: Separate_Size), | ||||
@@ -114,6 +117,56 @@ class SystemEditPageState extends State<SystemEditPage> { | |||||
); | ); | ||||
} | } | ||||
//恢复焚阅照片 | |||||
Widget _buildRset() { | |||||
//历史访客 | |||||
return Container( | |||||
margin: EdgeInsets.only(top: Separate_Size), | |||||
padding: EdgeInsets.symmetric(horizontal: 10), | |||||
child: FullWidthButton( | |||||
title: I18n.of(context) | |||||
.visit_photo | |||||
.replaceFirst('/s1', UserData().basicInfo.burnNum.toString()), | |||||
description: I18n.of(context).recovery_photo, | |||||
showDivider: false, | |||||
showRightIcon: false, | |||||
onPressed: () async { | |||||
CustomUI.buildOneConfirm(context, I18n.of(context).confrim_recovery, | |||||
I18n.of(context).determine, () async { | |||||
HttpUtil().resetPhoto(() { | |||||
Navigator.of(context).pop(); | |||||
UserData().basicInfo.burnNum = 0; | |||||
setState(() {}); | |||||
}); | |||||
}); | |||||
}, | |||||
), | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, border: Border(top: Constants.GreyBorderSide)), | |||||
); | |||||
} | |||||
Widget _buildHistory() { | |||||
//历史访客 | |||||
return Container( | |||||
margin: EdgeInsets.only(top: Separate_Size), | |||||
padding: EdgeInsets.symmetric(horizontal: 10), | |||||
child: FullWidthButton( | |||||
title: I18n.of(context).historical_visitor, | |||||
description: I18n.of(context) | |||||
.visit_you | |||||
.replaceFirst('/s1', UserData().basicInfo.accessNum.toString()), | |||||
showDivider: false, | |||||
showRightIcon: false, | |||||
onPressed: () {}, | |||||
), | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, | |||||
border: Border( | |||||
top: Constants.GreyBorderSide, bottom: Constants.GreyBorderSide)), | |||||
); | |||||
} | |||||
//有问题需要帮助 | //有问题需要帮助 | ||||
Widget _buildHelp() { | Widget _buildHelp() { | ||||
return Container( | return Container( | ||||
@@ -398,7 +451,6 @@ class SystemEditPageState extends State<SystemEditPage> { | |||||
}, true); | }, true); | ||||
setStatusBar(); | setStatusBar(); | ||||
} | } | ||||
//清楚图片缓存 | //清楚图片缓存 | ||||
@@ -512,17 +564,14 @@ class SystemEditPageState extends State<SystemEditPage> { | |||||
context, I18n.of(context).exit, I18n.of(context).determine, () { | context, I18n.of(context).exit, I18n.of(context).determine, () { | ||||
userLogout(); | userLogout(); | ||||
HttpUtil().postLoginOut(context); | HttpUtil().postLoginOut(context); | ||||
}); | }); | ||||
} | } | ||||
static userLogout(){ | |||||
static userLogout() { | |||||
LocalNotificationUtil().removeAlias(); | LocalNotificationUtil().removeAlias(); | ||||
ReceiveShareFile.dispose(); | ReceiveShareFile.dispose(); | ||||
} | } | ||||
//退出登陆 | //退出登陆 | ||||
Widget _buildLogout() { | Widget _buildLogout() { | ||||
return Container( | return Container( | ||||
@@ -17,10 +17,8 @@ import 'package:chat/utils/friend_list_mgr.dart'; | |||||
import 'package:chat/utils/screen.dart'; | import 'package:chat/utils/screen.dart'; | ||||
import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||
import 'package:oktoast/oktoast.dart'; | import 'package:oktoast/oktoast.dart'; | ||||
import 'package:permission_handler/permission_handler.dart'; | |||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:shared_preferences/shared_preferences.dart'; | import 'package:shared_preferences/shared_preferences.dart'; | ||||
import 'address_book.dart'; | |||||
List showUserList = []; | List showUserList = []; | ||||
@@ -34,7 +34,6 @@ import 'package:shared_preferences/shared_preferences.dart'; | |||||
import 'package:chat/utils/my_bottom_navigation_bar.dart' as myBottm; | import 'package:chat/utils/my_bottom_navigation_bar.dart' as myBottm; | ||||
import 'friend_page.dart'; | import 'friend_page.dart'; | ||||
import 'group_chat_page.dart'; | |||||
class NavigationIconView { | class NavigationIconView { | ||||
final BottomNavigationBarItem item; | final BottomNavigationBarItem item; | ||||
@@ -110,7 +110,7 @@ class _LastChatPageState extends State<LastChatPage> { | |||||
: Container(), | : Container(), | ||||
NetStateWidget(), | NetStateWidget(), | ||||
widget.needRobot ? _translateRobot() : Container(), | widget.needRobot ? _translateRobot() : Container(), | ||||
_CompanyServer(), | |||||
_companyServer(), | |||||
lastMsgList.length == 0 | lastMsgList.length == 0 | ||||
? _emptyContent() | ? _emptyContent() | ||||
: _chatRecordsList(lastMsgList) | : _chatRecordsList(lastMsgList) | ||||
@@ -155,7 +155,7 @@ class _LastChatPageState extends State<LastChatPage> { | |||||
)); | )); | ||||
} | } | ||||
Widget _CompanyServer() { | |||||
Widget _companyServer() { | |||||
return InkWell( | return InkWell( | ||||
onTap: () { | onTap: () { | ||||
AppNavigator.pushCompanyServerPage(context); | AppNavigator.pushCompanyServerPage(context); | ||||
@@ -0,0 +1,179 @@ | |||||
import 'dart:io'; | |||||
import 'package:chat/generated/i18n.dart'; | |||||
import 'package:chat/utils/CustomUI.dart'; | |||||
import 'package:chat/utils/LoadingDialog.dart'; | |||||
import 'package:chat/utils/MessageMgr.dart'; | |||||
import 'package:chat/utils/screen.dart'; | |||||
import 'package:extended_image/extended_image.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:image_cropper/image_cropper.dart'; | |||||
import 'package:image_picker/image_picker.dart'; | |||||
import '../utils/HttpUtil.dart'; | |||||
import 'package:dio/dio.dart'; | |||||
import "../data/UserData.dart"; | |||||
import '../utils/TokenMgr.dart'; | |||||
class MyHeadViewPage extends StatefulWidget { | |||||
MyHeadViewPage({Key key}) : super(key: key); | |||||
@override | |||||
_MyHeadViewPageState createState() => new _MyHeadViewPageState(); | |||||
} | |||||
class _MyHeadViewPageState extends State<MyHeadViewPage> | |||||
with SingleTickerProviderStateMixin { | |||||
AnimationController _animationController; | |||||
Animation<double> _animation; | |||||
Function animationListener; | |||||
List<double> doubleTapScales = <double>[1.0, 2.0]; | |||||
@override | |||||
void initState() { | |||||
super.initState(); | |||||
_animationController = AnimationController( | |||||
duration: const Duration(milliseconds: 150), vsync: this); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Scaffold( | |||||
body: SafeArea(child: _buildBody()), | |||||
backgroundColor: Colors.black, | |||||
); | |||||
} | |||||
Widget _buildHeadView() { | |||||
return ExtendedImageGesturePageView( | |||||
children: <Widget>[ | |||||
InkWell( | |||||
onTap: () { | |||||
Navigator.pop(context); | |||||
}, | |||||
child: ExtendedImage.network( | |||||
UserData().basicInfo.headimgurl, | |||||
fit: BoxFit.contain, | |||||
mode: ExtendedImageMode.gesture, | |||||
initGestureConfigHandler: (state) { | |||||
return GestureConfig( | |||||
inPageView: true, | |||||
maxScale: 5, | |||||
initialAlignment: InitialAlignment.topCenter, | |||||
animationMaxScale: 5, | |||||
cacheGesture: false); | |||||
}, | |||||
onDoubleTap: (ExtendedImageGestureState state) { | |||||
var pointerDownPosition = state.pointerDownPosition; | |||||
double begin = state.gestureDetails.totalScale; | |||||
double end; | |||||
//remove old | |||||
_animation?.removeListener(animationListener); | |||||
//stop pre | |||||
_animationController.stop(); | |||||
//reset to use | |||||
_animationController.reset(); | |||||
if (begin == doubleTapScales[0]) { | |||||
end = doubleTapScales[1]; | |||||
} else { | |||||
end = doubleTapScales[0]; | |||||
} | |||||
animationListener = () { | |||||
//print(_animation.value); | |||||
state.handleDoubleTap( | |||||
scale: _animation.value, | |||||
doubleTapPosition: pointerDownPosition); | |||||
}; | |||||
_animation = _animationController | |||||
.drive(Tween<double>(begin: begin, end: end)); | |||||
_animation.addListener(animationListener); | |||||
_animationController.forward(); | |||||
}, | |||||
)) | |||||
], | |||||
); | |||||
} | |||||
Widget _buildBody() { | |||||
return Stack( | |||||
children: <Widget>[ | |||||
_buildHeadView(), | |||||
Positioned( | |||||
child: _buildChangeButton(), | |||||
bottom: 40, | |||||
) | |||||
], | |||||
); | |||||
} | |||||
Widget _buildChangeButton() { | |||||
return InkWell( | |||||
onTap: _sendPicture, | |||||
child: Container( | |||||
alignment: Alignment.center, | |||||
width: Screen.width, | |||||
child: Container( | |||||
height: 47.5, | |||||
alignment: Alignment.center, | |||||
width: 230, | |||||
child: Text( | |||||
I18n.of(context).upload_avatar, | |||||
style: TextStyle(color: Colors.white, fontSize: 17.5), | |||||
), | |||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(24), | |||||
color: Color(0xFF181818)), | |||||
))); | |||||
} | |||||
void _sendPicture() async { | |||||
if (await CustomUI.showPhotoPermissionSetting(context)) { | |||||
showDialog( | |||||
context: context, | |||||
barrierDismissible: false, | |||||
builder: (BuildContext context) { | |||||
return LoadingDialog( | |||||
text: "", | |||||
); | |||||
}); | |||||
var tempFile = await ImagePicker.pickImage(source: ImageSource.gallery); | |||||
Navigator.of(context).pop(); | |||||
if (tempFile != null) { | |||||
_cropPicture(tempFile); | |||||
} | |||||
} | |||||
} | |||||
void _cropPicture(tempFile) async { | |||||
File croppedFile = await ImageCropper.cropImage( | |||||
sourcePath: tempFile.path, | |||||
aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1), | |||||
); | |||||
if (croppedFile != null) { | |||||
Map data = {"type": 1, "userId": UserData().basicInfo.userId}; | |||||
data['sign'] = TokenMgr().getSign(data); | |||||
Response res = await HttpUtil() | |||||
.uploadFile(croppedFile, data, 'upload/file/postflie', 'image'); | |||||
var resData = res.data; | |||||
if (resData['code'] == 0) { | |||||
UserData().basicInfo.headimgurl = resData['msg']; | |||||
MessageMgr().emit('change_my_headview'); | |||||
if (mounted) { | |||||
setState(() {}); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@override | |||||
void dispose() { | |||||
super.dispose(); | |||||
} | |||||
} |
@@ -1,8 +1,6 @@ | |||||
import 'dart:io'; | import 'dart:io'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:chat/home/global_search.dart'; | import 'package:chat/home/global_search.dart'; | ||||
import 'package:chat/home/new_friends.dart'; | |||||
import 'package:chat/models/friends_info.dart'; | import 'package:chat/models/friends_info.dart'; | ||||
import 'package:chat/utils/TutorialOverlay.dart'; | import 'package:chat/utils/TutorialOverlay.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
@@ -10,16 +8,9 @@ import 'package:chat/data/UserData.dart'; | |||||
import 'package:chat/data/constants.dart'; | import 'package:chat/data/constants.dart'; | ||||
import 'package:chat/generated/i18n.dart'; | import 'package:chat/generated/i18n.dart'; | ||||
import 'package:chat/utils/CustomUI.dart'; | import 'package:chat/utils/CustomUI.dart'; | ||||
import 'package:chat/utils/HttpUtil.dart'; | |||||
import 'package:chat/utils/MessageMgr.dart'; | import 'package:chat/utils/MessageMgr.dart'; | ||||
import 'package:chat/utils/TokenMgr.dart'; | |||||
import 'package:chat/utils/conversation_table.dart'; | |||||
import 'package:chat/utils/friend_list_mgr.dart'; | |||||
import 'package:chat/utils/screen.dart'; | import 'package:chat/utils/screen.dart'; | ||||
import 'package:dio/dio.dart'; | |||||
import 'package:oktoast/oktoast.dart'; | |||||
import 'package:permission_handler/permission_handler.dart'; | import 'package:permission_handler/permission_handler.dart'; | ||||
import 'package:shared_preferences/shared_preferences.dart'; | |||||
import 'address_book.dart'; | import 'address_book.dart'; | ||||
import 'my_qr.dart'; | import 'my_qr.dart'; | ||||
@@ -8,7 +8,6 @@ import 'package:chat/utils/HttpUtil.dart'; | |||||
import 'package:chat/utils/MessageMgr.dart'; | import 'package:chat/utils/MessageMgr.dart'; | ||||
import 'package:chat/utils/TokenMgr.dart'; | import 'package:chat/utils/TokenMgr.dart'; | ||||
import 'package:chat/utils/conversation_table.dart'; | import 'package:chat/utils/conversation_table.dart'; | ||||
import 'package:chat/utils/screen.dart'; | |||||
import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
@@ -0,0 +1,516 @@ | |||||
import 'dart:io'; | |||||
import 'dart:typed_data'; | |||||
import 'package:chat/data/UserData.dart'; | |||||
import 'package:chat/data/constants.dart'; | |||||
import 'package:chat/generated/i18n.dart'; | |||||
import 'package:chat/home/rich_title.dart'; | |||||
import 'package:chat/models/UserInfo.dart'; | |||||
import 'package:chat/models/money_change.dart'; | |||||
import 'package:chat/models/ref_name_provider.dart'; | |||||
import 'package:chat/utils/ChargeMoney.dart'; | |||||
import 'package:chat/utils/CustomUI.dart'; | |||||
import 'package:chat/utils/HttpUtil.dart'; | |||||
import 'package:chat/utils/MessageMgr.dart'; | |||||
import 'package:chat/utils/PicSwiper.dart'; | |||||
import 'package:chat/utils/TokenMgr.dart'; | |||||
import 'package:chat/utils/file_cache_mgr.dart'; | |||||
import 'package:chat/utils/screen.dart'; | |||||
import 'package:dio/dio.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:multi_image_picker/multi_image_picker.dart'; | |||||
import 'package:oktoast/oktoast.dart'; | |||||
import 'package:provider/provider.dart'; | |||||
import 'VipPage.dart'; | |||||
const double LeftSize = 80; | |||||
const MaxImgSize = 20; | |||||
class PhotoPage extends StatefulWidget { | |||||
@required | |||||
final UserInfo userInfo; | |||||
PhotoPage({Key key, this.userInfo}) : super(key: key); | |||||
@override | |||||
_PhotoPageState createState() => new _PhotoPageState(); | |||||
} | |||||
class _PhotoPageState extends State<PhotoPage> { | |||||
bool isMyself = false; | |||||
bool isMan = false; | |||||
Map imgList = {}; | |||||
bool isLoadingFinish = false; | |||||
double imgWidth = (Screen.width - LeftSize - 60) / 3; | |||||
var resultList = []; | |||||
bool isBuyPicture = false; | |||||
@override | |||||
void initState() { | |||||
super.initState(); | |||||
isMyself = widget.userInfo.userId == UserData().basicInfo.userId; | |||||
isMan = widget.userInfo.sex == 1; | |||||
isBuyPicture = (isMyself || | |||||
widget.userInfo.photoAut == 0 || | |||||
widget.userInfo.payStatus == 1); | |||||
getImg(); | |||||
MessageMgr().on('refresh_photo', msgRefreshPhoto); | |||||
} | |||||
msgRefreshPhoto(data) { | |||||
getImg(); | |||||
} | |||||
void getImg() async { | |||||
Map data = { | |||||
"visitUserId": UserData().basicInfo.userId, | |||||
"userId": widget.userInfo.userId, | |||||
}; | |||||
data['sign'] = TokenMgr().getSign(data); | |||||
Response res = await HttpUtil().post('user/personal/album', data: data); | |||||
if (res == null) { | |||||
return; | |||||
} | |||||
isLoadingFinish = true; | |||||
Map resData = res.data; | |||||
if (resData['code'] == 0) { | |||||
imgList = {}; | |||||
resultList = resData['data'] ?? []; | |||||
for (int i = 0; i < resultList.length; i++) { | |||||
var temp = DateTime.parse(resultList[i]['CreatTime']); | |||||
if (imgList[temp.year] == null) { | |||||
imgList[temp.year] = { | |||||
1: [], | |||||
2: [], | |||||
3: [], | |||||
4: [], | |||||
5: [], | |||||
6: [], | |||||
7: [], | |||||
8: [], | |||||
9: [], | |||||
10: [], | |||||
11: [], | |||||
12: [], | |||||
}; | |||||
} | |||||
imgList[temp.year][temp.month].add(resultList[i]); | |||||
} | |||||
if (isMyself) { | |||||
UserData().picNum = 0; | |||||
for (int i = 0; i < resultList.length; i++) { | |||||
if (resultList[i]['Status'] == 1) { | |||||
UserData().picNum++; | |||||
} | |||||
if (resultList[i]['Status'] == 0 || resultList[i]['Status'] == 2) { | |||||
UserData().haveReview = true; | |||||
} | |||||
} | |||||
} | |||||
if (mounted) { | |||||
setState(() {}); | |||||
} | |||||
} | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
var content = Scaffold( | |||||
appBar: AppBar( | |||||
title: !isMyself | |||||
? Text( | |||||
(isMyself | |||||
? I18n.of(context).my_album | |||||
: (isMan | |||||
? I18n.of(context).his_photo | |||||
: I18n.of(context).her_photo)), | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle( | |||||
color: AppColors.NewAppbarTextColor, fontSize: 20), | |||||
) | |||||
: Column(children: <Widget>[ | |||||
Text( | |||||
(isMyself | |||||
? I18n.of(context).my_album | |||||
: (isMan | |||||
? I18n.of(context).his_photo | |||||
: I18n.of(context).her_photo)), | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle( | |||||
color: AppColors.NewAppbarTextColor, fontSize: 20), | |||||
), | |||||
Text( | |||||
'${resultList.length}/$MaxImgSize', | |||||
style: TextStyle(fontSize: 11), | |||||
) | |||||
]), | |||||
leading: CustomUI.buildCustomLeading(context), | |||||
titleSpacing: -10, | |||||
centerTitle: true, | |||||
elevation: 1), | |||||
backgroundColor: Colors.white, | |||||
body: SafeArea( | |||||
child: SingleChildScrollView( | |||||
child: Column(children: _buildBody()), | |||||
)), | |||||
); | |||||
return CustomUI.buildPageLoading(context, content, !isLoadingFinish); | |||||
} | |||||
buyPhoto() { | |||||
//女性用户付费,男性用户会员的话免费解锁,非会员付费解锁 | |||||
becomeVip() { | |||||
Navigator.of(context).push( | |||||
new MaterialPageRoute( | |||||
builder: (context) { | |||||
return VipPage(); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
payCallback() { | |||||
if (Provider.of<MoneyChangeProvider>(context).money < | |||||
widget.userInfo.price) { | |||||
Navigator.of(context).pop(); | |||||
CustomUI.buildOneConfirm(context, I18n.of(context).balance_insufficien, | |||||
I18n.of(context).recharge, () { | |||||
Navigator.of(context).pop(); | |||||
ChargeMoney.showChargeSheet(context, () { | |||||
setState(() {}); | |||||
}); | |||||
}); | |||||
return; | |||||
} | |||||
Navigator.of(context).pop(); | |||||
HttpUtil().buyPictures( | |||||
widget.userInfo.price, widget.userInfo.userId, context, () { | |||||
setState(() { | |||||
isBuyPicture = true; | |||||
widget.userInfo.payStatus = 1; | |||||
}); | |||||
}); | |||||
} | |||||
freeTime() { | |||||
HttpUtil().userFreeTime(context, widget.userInfo.userId, 1, () { | |||||
UserData().basicInfo.usedNum++; | |||||
Navigator.of(context).pop(); | |||||
setState(() { | |||||
isBuyPicture = true; | |||||
widget.userInfo.payStatus = 1; | |||||
}); | |||||
}); | |||||
} | |||||
String title = I18n.of(context).unlock_user.replaceFirst( | |||||
'/s1', | |||||
Provider.of<RefNameProvider>(context) | |||||
.getRefName(widget.userInfo.userId, widget.userInfo.nickName), | |||||
); | |||||
if (!UserData().isMan()) { | |||||
CustomUI.buildOneConfirm( | |||||
context, | |||||
title, | |||||
I18n.of(context) | |||||
.pay_unlock | |||||
.replaceFirst('/s1', widget.userInfo.price.toString()), | |||||
payCallback); | |||||
} else if (UserData().isVip) { | |||||
if (UserData().basicInfo.freeNum < UserData().basicInfo.usedNum) { | |||||
CustomUI.buildOneConfirm( | |||||
context, | |||||
title, | |||||
I18n.of(context) | |||||
.pay_unlock | |||||
.replaceFirst('/s1', widget.userInfo.price.toString()), | |||||
payCallback); | |||||
} else { | |||||
CustomUI.buildOneConfirm( | |||||
context, title, I18n.of(context).unlock_choose, freeTime); | |||||
} | |||||
} else { | |||||
CustomUI.buildTowConfirm( | |||||
context, | |||||
title, | |||||
I18n.of(context).become_member, | |||||
becomeVip, | |||||
I18n.of(context) | |||||
.pay_unlock | |||||
.replaceFirst('/s1', widget.userInfo.price.toString()), | |||||
payCallback); | |||||
} | |||||
} | |||||
Widget _buildLockWidget() { | |||||
TitleItem title; | |||||
if (!isMan) { | |||||
title = UserData().isVip | |||||
? TitleItem( | |||||
title: I18n.of(context).unlock_user, | |||||
name: Provider.of<RefNameProvider>(context) | |||||
.getRefName(widget.userInfo.userId, widget.userInfo.nickName), | |||||
) | |||||
: TitleItem( | |||||
title: I18n.of(context).free_unlock, | |||||
name: widget.userInfo.price.toString() + | |||||
I18n.of(context).mask_coin); | |||||
} else { | |||||
title = TitleItem( | |||||
title: I18n.of(context).pay_unlock, | |||||
name: widget.userInfo.price.toString()); | |||||
} | |||||
return Container( | |||||
height: Screen.height * 0.7, | |||||
alignment: Alignment.center, | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Image.asset( | |||||
'assets/images/lock_photo.png', | |||||
width: 160, | |||||
//color: Colors.grey[700], | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 20), | |||||
alignment: Alignment.center, | |||||
child: Text( | |||||
isMan ? I18n.of(context).set_lock : I18n.of(context).set_lock2, | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle( | |||||
color: Colors.grey[700], | |||||
fontSize: 15, | |||||
fontWeight: FontWeight.bold), | |||||
), | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 8), | |||||
alignment: Alignment.center, | |||||
child: RichText( | |||||
text: TextSpan( | |||||
children: RichTitle.getRichText(title, | |||||
titleStyle: | |||||
TextStyle(color: Colors.grey[700], fontSize: 13), | |||||
nameStyle: TextStyle(color: Colors.red, fontSize: 13))), | |||||
), | |||||
), | |||||
InkWell( | |||||
onTap: buyPhoto, | |||||
child: Container( | |||||
margin: EdgeInsets.only(top: 30), | |||||
padding: EdgeInsets.only(top: 6, bottom: 6), | |||||
width: 100, | |||||
alignment: Alignment.center, | |||||
decoration: Constants.ConfirmBUttonBoxDecoration, | |||||
child: Text( | |||||
I18n.of(context).unlock, | |||||
textScaleFactor: 1.0, | |||||
style: TextStyle(color: Colors.white, fontSize: 18), | |||||
), | |||||
)), | |||||
], | |||||
)); | |||||
} | |||||
List<Widget> _buildBody() { | |||||
List<Widget> list = [_buildUpload()]; | |||||
if (imgList.length == 0 && isLoadingFinish && !isMyself) { | |||||
list.add(CustomUI.buildNoData(context)); | |||||
return list; | |||||
} | |||||
if (!isBuyPicture) { | |||||
list.add(_buildLockWidget()); | |||||
return list; | |||||
} | |||||
imgList.keys.forEach((k) { | |||||
list.add(_buildYear(k)); | |||||
}); | |||||
return list; | |||||
} | |||||
//上传相册 | |||||
void _uploadPhoto() async { | |||||
int leftLength = MaxImgSize - imgList.length; | |||||
if (leftLength <= 0) { | |||||
showToast(I18n.of(context) | |||||
.max_upload_size | |||||
.replaceFirst('/s1', MaxImgSize.toString())); | |||||
return; | |||||
} | |||||
List<Asset> resultList = List<Asset>(); | |||||
resultList = await MultiImagePicker.pickImages( | |||||
maxImages: leftLength > 9 ? 9 : leftLength, | |||||
enableCamera: false, | |||||
selectedAssets: [], | |||||
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"), | |||||
materialOptions: MaterialOptions( | |||||
actionBarColor: "#50A7F9", | |||||
actionBarTitle: "Hibok", | |||||
allViewTitle: "", | |||||
useDetailsView: true, | |||||
selectCircleStrokeColor: "#000000", | |||||
), | |||||
); | |||||
if (resultList != null && resultList.length > 0) { | |||||
List<File> fileList = []; | |||||
for (var i = 0; i < resultList.length; i++) { | |||||
Asset photoEntity = resultList[i]; | |||||
print('名字:${photoEntity.name}'); | |||||
ByteData byteData = await photoEntity.getByteData(); | |||||
File file = await FileCacheMgr().writeFile( | |||||
'temp-photo-${DateTime.now().millisecondsSinceEpoch}.png', | |||||
byteData.buffer.asInt8List(0)); | |||||
fileList.add(file); | |||||
} | |||||
print('文件列表${fileList.length}'); | |||||
Map data = {"type": 2, "userId": UserData().basicInfo.userId}; | |||||
data['sign'] = TokenMgr().getSign(data); | |||||
data['sex'] = UserData().basicInfo.sex; | |||||
data['isBurn'] = 0; | |||||
Response res = await HttpUtil().uploadFiles( | |||||
fileList, data, 'upload/post/postfiles', 'image', | |||||
isShowLoading: true); | |||||
var resData = res.data; | |||||
if (resData['code'] == 0) { | |||||
if (resData['data']['msg'] != '' && resData['data']['msg'] != null) { | |||||
showToast(resData['data']['msg']); | |||||
} | |||||
if (resData['msg'].split('|').length != fileList.length) { | |||||
showToast(I18n.of(context).hava_error_photo); | |||||
} | |||||
//MessageMgr().emit('refresh_photo'); | |||||
getImg(); | |||||
} else { | |||||
showToast(resData['msg']); | |||||
} | |||||
} | |||||
} | |||||
Widget _buildUpload() { | |||||
return isMyself | |||||
? Container( | |||||
margin: EdgeInsets.only(top: 20), | |||||
child: Row( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Container( | |||||
alignment: Alignment.centerRight, | |||||
margin: EdgeInsets.only(right: 15), | |||||
width: LeftSize, | |||||
child: Text( | |||||
I18n.of(context).upload1, | |||||
style: | |||||
TextStyle(fontSize: 15, fontWeight: FontWeight.w600), | |||||
)), | |||||
InkWell( | |||||
onTap: _uploadPhoto, | |||||
child: Container( | |||||
width: imgWidth, | |||||
height: imgWidth, | |||||
margin: EdgeInsets.all(5), | |||||
decoration: BoxDecoration( | |||||
color: Color(0xFFEDEDED), | |||||
borderRadius: BorderRadius.circular(10)), | |||||
child: Icon( | |||||
IconData(0xe686, fontFamily: Constants.IconFontFamily), | |||||
size: 35, | |||||
color: Colors.white, | |||||
), | |||||
)) | |||||
], | |||||
), | |||||
) | |||||
: Container(); | |||||
} | |||||
Widget _buildYear(int year) { | |||||
var list = [_buildYearTips(year)]; | |||||
imgList[year].keys.forEach((k) { | |||||
if (imgList[year][k].length > 0) { | |||||
list.add(_buildMonth(year, k)); | |||||
} | |||||
}); | |||||
return Container( | |||||
width: Screen.width, | |||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: list, | |||||
)); | |||||
} | |||||
Widget _buildYearTips(int year) { | |||||
return Container( | |||||
alignment: Alignment.centerRight, | |||||
margin: EdgeInsets.only(right: 15, top: 20, bottom: 18), | |||||
width: LeftSize, | |||||
child: Text( | |||||
'$year${I18n.of(context).year}', | |||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600), | |||||
)); | |||||
} | |||||
Widget _buildMonth(int year, int month) { | |||||
if (imgList[year] == null || imgList[year][month] == null) { | |||||
return Container(); | |||||
} | |||||
List<PicSwiperItem> pisc = []; | |||||
imgList[year][month].forEach((f) { | |||||
pisc.add(PicSwiperItem( | |||||
f['ImgUrl'], | |||||
id: f['Id'], | |||||
type: f['Type'], | |||||
isWatch: f['IsCheck'] == 1, | |||||
userId: widget.userInfo.userId, | |||||
isBuy: f['PayStatus'] == 1, | |||||
isCheck: f['Status'] == 0, | |||||
)); | |||||
}); | |||||
List<Widget> list = []; | |||||
imgList[year][month].forEach((data) { | |||||
bool isWatch = data['IsCheck'] == 1; | |||||
double raduis = 10; | |||||
list.add(CustomUI.buildImgCover(data['Id'], pisc, data['ImgUrl'], | |||||
imgWidth, raduis, isWatch, context, data['Type'], | |||||
isMyself: isMyself, | |||||
payStatus: data['PayStatus'], | |||||
state: isMan ? 1 : data['Status'])); | |||||
}); | |||||
return Row( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Container( | |||||
alignment: Alignment.centerRight, | |||||
margin: EdgeInsets.only(right: 15, top: 1), | |||||
width: LeftSize, | |||||
child: Text( | |||||
'$month${I18n.of(context).month}', | |||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600), | |||||
)), | |||||
Container( | |||||
width: Screen.width - LeftSize - 15, | |||||
child: Wrap( | |||||
crossAxisAlignment: WrapCrossAlignment.start, | |||||
children: list, | |||||
)) | |||||
], | |||||
); | |||||
} | |||||
@override | |||||
void dispose() { | |||||
super.dispose(); | |||||
MessageMgr().off('refresh_photo', msgRefreshPhoto); | |||||
} | |||||
} |
@@ -1,4 +1,6 @@ | |||||
import 'package:chat/data/constants.dart'; | |||||
import 'package:chat/utils/MessageMgr.dart'; | import 'package:chat/utils/MessageMgr.dart'; | ||||
import 'package:chat/utils/sp_utils.dart'; | |||||
class UnreadCountProvider { | class UnreadCountProvider { | ||||
//未读消息条数管理 | //未读消息条数管理 | ||||
@@ -16,12 +18,41 @@ class UnreadCountProvider { | |||||
MessageMgr().emit('Update UnreadCount', sessionId); | MessageMgr().emit('Update UnreadCount', sessionId); | ||||
} | } | ||||
initUnreadAlter() async { | |||||
//初始化@消息 | |||||
List<String> alterList = await SPUtils.getStringList(Constants.GroupAlterKey) ?? []; | |||||
for (int i = 0; i < alterList.length; i++) { | |||||
var list = alterList[i].split('-'); | |||||
if (list.length == 2) { | |||||
isHaveAlterme[int.parse(list[0])] = int.parse(list[1]); | |||||
} | |||||
} | |||||
} | |||||
getHavaAltertime(int sessionId) { | getHavaAltertime(int sessionId) { | ||||
return isHaveAlterme[sessionId] ?? null; | return isHaveAlterme[sessionId] ?? null; | ||||
} | } | ||||
setAlterMe(int sessionId, int time) { | setAlterMe(int sessionId, int time) { | ||||
if (isHaveAlterme[sessionId] == null) isHaveAlterme[sessionId] = time; | |||||
if (isHaveAlterme[sessionId] == null) { | |||||
isHaveAlterme[sessionId] = time; | |||||
saveGroupAlterToLocal(); | |||||
} | |||||
} | |||||
saveGroupAlterToLocal() { | |||||
List<String> alterList = []; | |||||
isHaveAlterme.forEach((k, v) { | |||||
if (v != null) { | |||||
alterList.add('$k-$v'); | |||||
} | |||||
}); | |||||
SPUtils.saveList(Constants.GroupAlterKey, alterList); | |||||
} | |||||
signUnreadAlter(int sessionId) { | |||||
isHaveAlterme[sessionId] = null; | |||||
saveGroupAlterToLocal(); | |||||
} | } | ||||
clear() { | clear() { | ||||
@@ -45,7 +76,7 @@ class UnreadCountProvider { | |||||
print('消除未读标记:$sessionId'); | print('消除未读标记:$sessionId'); | ||||
int count = getUnreadCount(sessionId); | int count = getUnreadCount(sessionId); | ||||
isHaveAlterme[sessionId] = null; | |||||
signUnreadAlter(sessionId); | |||||
if (count > 0) { | if (count > 0) { | ||||
unreadCountMap[sessionId] = 0; | unreadCountMap[sessionId] = 0; | ||||
@@ -382,7 +382,7 @@ class CustomUI { | |||||
static Widget buildImgCover( | static Widget buildImgCover( | ||||
int imgId, | int imgId, | ||||
List<PicSwiperItem> pics, | |||||
List pics, | |||||
String imgUrl, | String imgUrl, | ||||
double width, | double width, | ||||
double raduis, | double raduis, | ||||
@@ -11,6 +11,8 @@ class FullWidthButton extends StatelessWidget { | |||||
final String description; | final String description; | ||||
final Color descriptionColor; | final Color descriptionColor; | ||||
final bool showRightIcon; | final bool showRightIcon; | ||||
final int iconCode; | |||||
final iconColor; | |||||
final Widget extendWidget; | final Widget extendWidget; | ||||
@@ -21,8 +23,9 @@ class FullWidthButton extends StatelessWidget { | |||||
this.descriptionColor, | this.descriptionColor, | ||||
this.showRightIcon: true, | this.showRightIcon: true, | ||||
this.showDivider: false, | this.showDivider: false, | ||||
this.extendWidget | |||||
}) | |||||
this.iconCode, | |||||
this.iconColor, | |||||
this.extendWidget}) | |||||
: assert(title != null), | : assert(title != null), | ||||
assert(onPressed != null); | assert(onPressed != null); | ||||
@@ -32,28 +35,39 @@ class FullWidthButton extends StatelessWidget { | |||||
mainAxisAlignment: MainAxisAlignment.start, | mainAxisAlignment: MainAxisAlignment.start, | ||||
crossAxisAlignment: CrossAxisAlignment.center, | crossAxisAlignment: CrossAxisAlignment.center, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
iconCode == null | |||||
? Container() | |||||
: Container( | |||||
margin: EdgeInsets.only(right: 5,bottom: 3), | |||||
child: Icon( | |||||
IconData( | |||||
iconCode, | |||||
fontFamily: 'iconfont', | |||||
), | |||||
color: Color(iconColor), | |||||
size: 20, | |||||
)), | |||||
SizedBox(width: Hor_Padding), | SizedBox(width: Hor_Padding), | ||||
Expanded( | Expanded( | ||||
child: Text( | child: Text( | ||||
title, | title, | ||||
textScaleFactor: 1.0, | textScaleFactor: 1.0, | ||||
style: TextStyle( | |||||
fontSize: 14, | |||||
fontWeight: FontWeight.normal | |||||
), | |||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal), | |||||
), | ), | ||||
), | ), | ||||
extendWidget!=null?extendWidget: Text( | |||||
description, | |||||
textScaleFactor: 1.0, | |||||
textAlign: TextAlign.end, | |||||
style: TextStyle( | |||||
fontSize: 12, | |||||
fontWeight: FontWeight.normal, | |||||
color: descriptionColor == null | |||||
? const Color(0xFF818181) | |||||
: descriptionColor), | |||||
), | |||||
extendWidget != null | |||||
? extendWidget | |||||
: Text( | |||||
description, | |||||
textScaleFactor: 1.0, | |||||
textAlign: TextAlign.end, | |||||
style: TextStyle( | |||||
fontSize: 12, | |||||
fontWeight: FontWeight.normal, | |||||
color: descriptionColor == null | |||||
? const Color(0xFF818181) | |||||
: descriptionColor), | |||||
), | |||||
showRightIcon | showRightIcon | ||||
? Padding( | ? Padding( | ||||
padding: EdgeInsets.only(bottom: 1.5), | padding: EdgeInsets.only(bottom: 1.5), | ||||
@@ -282,7 +282,7 @@ class HttpUtil { | |||||
} | } | ||||
Map resData = res.data; | Map resData = res.data; | ||||
print('用户信息resData $resData'); | print('用户信息resData $resData'); | ||||
if (resData['code'] == 0) { | |||||
if (resData['code'] == 0 && resData != null) { | |||||
var info = UserInfo.fromJson(resData['data']); | var info = UserInfo.fromJson(resData['data']); | ||||
info.isBlackened | info.isBlackened | ||||
? BlacklistMgr.addBlackListMe(info.userId) | ? BlacklistMgr.addBlackListMe(info.userId) | ||||
@@ -1,10 +1,6 @@ | |||||
import 'package:shared_preferences/shared_preferences.dart'; | import 'package:shared_preferences/shared_preferences.dart'; | ||||
class SPUtils { | class SPUtils { | ||||
static saveString(String key, value) async { | static saveString(String key, value) async { | ||||
SharedPreferences spf = await SharedPreferences.getInstance(); | SharedPreferences spf = await SharedPreferences.getInstance(); | ||||
spf.setString(key, value); | spf.setString(key, value); | ||||
@@ -15,7 +11,6 @@ class SPUtils { | |||||
spf.setStringList(key, value); | spf.setStringList(key, value); | ||||
} | } | ||||
static saveBool(String key, value) async { | static saveBool(String key, value) async { | ||||
SharedPreferences prefs = await SharedPreferences.getInstance(); | SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||
prefs.setBool(key, value); | prefs.setBool(key, value); | ||||
@@ -36,6 +31,11 @@ class SPUtils { | |||||
return prefs.get(key); | return prefs.get(key); | ||||
} | } | ||||
static getStringList(String key) async { | |||||
SharedPreferences prefs = await SharedPreferences.getInstance(); | |||||
return prefs.getStringList(key); | |||||
} | |||||
static remove(String key) async { | static remove(String key) async { | ||||
SharedPreferences prefs = await SharedPreferences.getInstance(); | SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||
prefs.remove(key); | prefs.remove(key); | ||||
@@ -311,6 +311,8 @@ flutter: | |||||
- assets/images/gift_2.png | - assets/images/gift_2.png | ||||
- assets/images/ext_txt.png | - assets/images/ext_txt.png | ||||
- assets/images/gift_show_2_1.png | - assets/images/gift_show_2_1.png | ||||
- assets/images/up.png | |||||
- assets/images/lock_photo.png | |||||
# assets/images/chat/* | # assets/images/chat/* | ||||
- assets/images/chat/emoji.png | - assets/images/chat/emoji.png | ||||
- assets/images/chat/onion.png | - assets/images/chat/onion.png | ||||