import 'package:chat/data/UserData.dart'; import 'package:chat/data/WebData.dart'; import 'package:chat/generated/i18n.dart'; import 'package:chat/home/ProfilePage.dart'; import 'package:chat/home/rich_title.dart'; import 'package:chat/models/ref_name_provider.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/conversation_table.dart'; import 'package:chat/utils/friend_list_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:flutter/services.dart'; import 'package:oktoast/oktoast.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:url_launcher/url_launcher.dart'; import '../data/constants.dart' show AppColors, Constants; import '../data/conversation.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'ProgramDetail.dart'; class _ConversationItem extends StatelessWidget { const _ConversationItem( {Key key, this.conversation, this.callback, this.showRight = true, this.rightButton, this.applyInfo, this.bgColor, this.title}) : assert(conversation != null), super(key: key); final Widget rightButton; final Conversation conversation; final callback; final bool showRight; final title; final applyInfo; final bgColor; @override Widget build(BuildContext context) { Widget avatar; double width = 53; if (conversation.isAvatarFromNet()) { avatar = ClipRRect( borderRadius: BorderRadius.circular(10), child: CachedNetworkImage( imageUrl: conversation.avatar, placeholder: (context, url) => Image.asset( Constants.DefaultHeadImgUrl, width: width, height: width, ), fit: BoxFit.cover, width: width, height: width, )); } else { avatar = ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( width: width, height: width, alignment: Alignment.center, decoration: BoxDecoration( gradient: this.bgColor, borderRadius: BorderRadius.all(Radius.circular(50))), child: Image.asset( conversation.avatar, height: 27, ))); } _buildBotton(str, callback) { return InkWell( onTap: callback, child: Container( padding: EdgeInsets.only(top: 5, left: 15, right: 15, bottom: 5), decoration: BoxDecoration( border: Border.all(color: Constants.ConfrimButtonColor, width: 1), color: Constants.ConfrimButtonColor, borderRadius: BorderRadius.all(Radius.circular(5))), child: fixedText( str, fontSize: 12, color: Colors.white, ), )); } void doApply(state, callback) async { Map data = { "id": applyInfo['applyId'], "userId": UserData().basicInfo.userId, "status": state, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('user/handler/apply', data: data); if (res == null) { return; } var resData = res.data; if (resData['code'] == 0) { callback(resData['msg']); } else {} } void doFriendApply(state, callback) async { Map data = { "id": applyInfo['applyId'], "userId": UserData().basicInfo.userId, "status": state, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('friendship/handler/apply', data: data); if (res == null) { return; } var resData = res.data; if (resData['code'] == 0) { callback(resData['msg']); } else {} } var bottomWiget = applyInfo == null ? Container() : Container( padding: EdgeInsets.only(left: 0, top: 10), decoration: BoxDecoration( color: Color(AppColors.ConversationItemBgColor), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: applyInfo['type'] == 0 || applyInfo['type'] == 6 ? [ CustomUI.buildImgCover( applyInfo['imgId'], [ PicSwiperItem(applyInfo['showUrl'], id: applyInfo['imgId'], type: applyInfo['type'] == 0 ? PhotoType.destroy.index : PhotoType.free.index, isWatch: applyInfo['isWatch'], userId: applyInfo['userId']) ], applyInfo['showUrl'], 65, 10, applyInfo['isWatch'], context, applyInfo['type'] == 0 ? PhotoType.destroy.index : PhotoType.free.index), Expanded( child: applyInfo['type'] == 0 ? Container( alignment: Alignment.centerRight, padding: EdgeInsets.only(top: 40), child: applyInfo['state'] == 0 ? Row( mainAxisAlignment: MainAxisAlignment.end, children: [ _buildBotton(I18n.of(context).aging, () { doApply(1, (msg) { showToast(msg); applyInfo['state'] = 1; MessageMgr() .emit('do_info_apply'); }); }), SizedBox( width: 10, ), _buildBotton(I18n.of(context).refuse, () { doApply(2, (msg) { showToast(msg); applyInfo['state'] = 2; MessageMgr() .emit('do_info_apply'); }); }), ], ) : Padding( padding: EdgeInsets.only(right: 0), child: Text( applyInfo['state'] == 1 ? I18n.of(context).passed : I18n.of(context).rejected, style: TextStyle( color: Constants.GreyTextColor, fontSize: 13), textScaleFactor: 1.0, ), ), ) : Container(), ) ] : [ Expanded(child: Container()), Container( alignment: Alignment.centerRight, child: applyInfo['state'] == 0 ? Row( mainAxisAlignment: MainAxisAlignment.end, children: [ _buildBotton(I18n.of(context).agree, () { doFriendApply(1, (msg) { showToast(msg); applyInfo['state'] = 1; var friendModel = FriendModel.fromServerJson({ 'UserId': applyInfo['userId'], 'ImgUrl': applyInfo['imgUrl'], 'UserName': applyInfo['name'] }); FriendListMgr().addFriend(friendModel); MessageMgr().emit('do_info_apply'); MessageMgr().emit('do_friend_apply', { 'userId': applyInfo['userId'], 'state': 1 }); MessageMgr().emit('Add friend'); }); }), SizedBox( width: 10, ), _buildBotton(I18n.of(context).refuse, () { doFriendApply(2, (msg) { showToast(msg); applyInfo['state'] = 2; MessageMgr().emit('do_info_apply'); MessageMgr().emit('do_friend_apply', { 'userId': applyInfo['userId'], 'state': 2 }); }); }), ], ) : Padding( padding: EdgeInsets.only(right: 0), child: Text( applyInfo['state'] == 1 ? I18n.of(context).passed : I18n.of(context).rejected, style: TextStyle( color: Constants.GreyTextColor, fontSize: 13), textScaleFactor: 1.0, ), ), ), ], ), ); return InkWell( child: Container( padding: const EdgeInsets.only(left: 16.5, top: 11, bottom: 11, right: 14.5), decoration: BoxDecoration( color: Color(AppColors.ConversationItemBgColor), border: Border( bottom: BorderSide( color: AppColors.DividerColor, width: Constants.DividerWidth))), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ avatar, Container(width: 19.0), Expanded( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: title == null ? Text(conversation.title, textScaleFactor: 1.0, style: TextStyle( fontSize: 12, color: Constants.LightGreyTextColor)) : title), Container( padding: EdgeInsets.only(top: 5, bottom: 5), child: Row( children: [ Text(conversation.desc, textScaleFactor: 1.0, style: TextStyle( fontSize: 11, color: Constants.LightGreyTextColor)), showRight ? Expanded( child: Container( alignment: Alignment.centerRight, child: rightButton == null ? Text( '${I18n.of(context).go_see}>', textScaleFactor: 1.0, style: TextStyle( fontSize: 11, color: Constants .LightGreyTextColor)) : rightButton, ), ) : Container() ], )), applyInfo != null && applyInfo['content'] != null ? Container( child: Text(applyInfo['content'], textScaleFactor: 1.0, style: TextStyle( fontSize: 14, color: Constants.LightGreyTextColor))) : Container(), ], ), )), ], ), bottomWiget ], ), ), onTap: () { callback(); }, ); } } class InfoListPage extends StatefulWidget { @required final String title; @required final int type; InfoListPage({Key key, this.title = "", this.type = 1}) : super(key: key); _InfoListPageState createState() => _InfoListPageState(); } class _InfoListPageState extends State with SingleTickerProviderStateMixin { List list = new List(); //列表要展示的数据 RefreshController _refreshController = RefreshController(initialRefresh: true); int _page = 1; //加载的页数 int rows = 20; @override void initState() { super.initState(); messageOn(); } void initList(data) { list.clear(); if (data != null) { list.addAll(data); } if (mounted) setState(() {}); } void addList(data) { if (data == null || data.length == 0) { _page--; _refreshController.loadNoData(); } else { list.addAll(data); _refreshController.loadComplete(); } setState(() {}); } messageApply(data) { _onRefresh(); } msgPhoto(id) { for (int i = 0; i < list.length; i++) { if (list[i]['ApplyImg'] == id) { setState(() { list[i]['IsCheck'] = 1; }); break; } } } void messageOn() { MessageMgr().on('do_info_apply', messageApply); MessageMgr().on('refresh_photo', msgPhoto); } void messageOff() { MessageMgr().off('do_info_apply', messageApply); MessageMgr().off('refresh_photo', msgPhoto); } getNewData(callback) { switch (widget.type) { case InfoType.Apply: //获取申请通知 getData('user/check/realecords', callback); break; case InfoType.Evaluation: //获取评价通知 getData('evaluate/user/realecordslist', callback); break; case InfoType.System: //获取系统通知 getData('message/center/list', callback); break; case InfoType.Radio: //获取电台消息 getData('message/center/cast', callback); break; case InfoType.Money: //获取钱包通知 getData('message/wallet/message', callback); break; default: } } Future getData(url, callback) async { Map data = { "userId": UserData().basicInfo.userId, }; if (widget.type == InfoType.System) { data['type'] = UserData().basicInfo.sex; } data['sign'] = TokenMgr().getSign(data); if (widget.type == InfoType.Money) { data['type'] = 1; } data["page"] = _page; data['rows'] = rows; Response res = await HttpUtil() .post(url, data: data, failback: () => Navigator.of(context).pop()); _refreshController.refreshCompleted(); var resData = res.data; print(resData); if (resData['code'] == 0) { callback(resData['data']); } else { showToast(resData['msg']); } } /* * 下拉刷新方法,为list重新赋值 */ Future _onRefresh() async { _page = 1; getNewData(initList); } @override void dispose() { _refreshController.dispose(); messageOff(); super.dispose(); } //钱包通知 Widget _buildMoneyInfo(data) { String imgUrl = data['HeadImg'] == null || data['HeadImg'] == '' ? 'assets/images/chat/icon4.png' : data['HeadImg']; bool showIndex = data['ChangeUserId'] != 0; return _ConversationItem( conversation: Conversation( avatar: imgUrl, title: '', desc: WebData().getLoginTime(context, data['CreateTime']), updateAt: '', ), bgColor: Constants.MoneyGradient, showRight: data['DetailType'] == 10, title: RichTitle.getRichTitleWidget(data, context, InfoType.Money), rightButton: Text(I18n.of(context).alreay_back, style: TextStyle( fontSize: 12, fontWeight: FontWeight.normal, color: Constants.BlackTextColor)), callback: () { if (showIndex) { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProfilePage( userId: data['UserId'] == UserData().basicInfo.userId ? data['ChangeUserId'] : data['UserId'], ); }, ), ); } }, ); } //申请列表 Widget _buildApllayInfo(userInfo) { bool isMyself = userInfo['ApplyUserId'] == UserData().basicInfo.userId; String name = isMyself ? userInfo['UserName'] : userInfo['ApplyName']; String imgUrl = isMyself ? userInfo['UserUrl'] : userInfo['ApplyUrl']; var applyInfo = { 'applyId': userInfo['Id'], 'userId': userInfo['ApplyUserId'], 'name': name, 'type': userInfo['Type'], 'imgUrl': imgUrl, 'showUrl': userInfo['ImgUrl'], 'content': userInfo['Content'], 'imgId': userInfo['ApplyImg'], 'createTime': userInfo['CreatTime'], 'isWatch': userInfo['IsCheck'] == 1, 'state': userInfo['Status'], }; return _ConversationItem( conversation: Conversation( avatar: imgUrl == null || imgUrl == '' ? Constants.DefaultHeadImgUrl : imgUrl, title: '', desc: WebData().getLoginTime(context, userInfo['CreatTime']), updateAt: '17:20', ), title: RichTitle.getRichTitleWidget(userInfo, context, InfoType.Apply), applyInfo: isMyself ? null : applyInfo, callback: () { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProfilePage( userId: isMyself ? userInfo['UserId'] : userInfo['ApplyUserId'], ); }, ), ); }, ); } //评价列表 Widget _buildContentInfo(userInfo) { Widget botton = InkWell( onTap: () async { var data = { "userid": UserData().basicInfo.userId, "evaluateuserid": userInfo['EvaluateUserId'], }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('evaluate/user/appeal', data: data); if (res == null) { return; } Map resData = res.data; if (resData['code'] == 0) { setState(() { userInfo['Status'] = 1; }); } }, child: Container( padding: EdgeInsets.only(top: 2, left: 5, right: 5, bottom: 2), decoration: BoxDecoration( border: Border.all(color: Constants.LightBlueButtonColor, width: 1), color: Constants.LightBlueButtonColor, borderRadius: BorderRadius.all(Radius.circular(5))), child: fixedText( I18n.of(context).appeal, fontSize: 9, color: Colors.white, ), )); return _ConversationItem( conversation: Conversation( avatar: 'assets/images/chat/icon6.png', title: '', desc: WebData().getLoginTime(context, userInfo['CreateTime']), updateAt: '17:20', ), bgColor: Constants.EvaGradient, rightButton: userInfo['Status'] == 0 || userInfo['Status'] == 3 ? botton : Text(userInfo['Status'] == 1 ? I18n.of(context).appealed : "", style: TextStyle(fontSize: 11, color: Constants.LightGreyTextColor)), title: RichTitle.getRichTitleWidget(userInfo, context, InfoType.Evaluation), callback: () {}, ); } String getReportTilte(bool isMyself, data) { String res = ''; switch (data['ReportType']) { //举报用户 case 1: if (isMyself) { res = data['Status'] == 1 ? I18n.of(context) .report_success .replaceFirst('/s1', data['ReportedUserName']) : I18n.of(context) .report_failure .replaceFirst('/s1', data['ReportedUserName']); } else { res = I18n.of(context).coin_returen; } break; //举报节目 case 2: break; //举报动态 case 3: break; //举报评论 case 4: break; default: } return res; } //系统通知 Widget _buildSystemInfo(data) { bool isMyself = data['UserId'] == UserData().basicInfo.userId; String imgUrl = data['Type'] == 3 ? (isMyself ? data['HeadImg'] : 'assets/images/chat/icon5.png') : 'assets/images/chat/icon5.png'; var applyInfo = { 'applyId': data['Id'], 'userId': data['ApplyUserId'], 'name': data['Theme'], 'type': data['Type'], 'imgUrl': imgUrl, 'showUrl': data['HeadImg'], 'content': data['Content'], 'imgId': data['ApplyImg'], 'createTime': data['CreatTime'], 'isWatch': data['IsCheck'] == 1, 'links': data['Links'], 'state': data['Status'], }; return _ConversationItem( conversation: Conversation( avatar: imgUrl, title: '', desc: WebData().getLoginTime(context, data['CreateTime']), updateAt: '17:20', ), showRight: data['Type'] == 6, applyInfo: data['Type'] == 6 ? applyInfo : null, // applyInfo, bgColor: Constants.ParkGradient, title: data['Type'] == 6 ? Text(data['Theme']) : RichTitle.getRichTitleWidget(data, context, InfoType.System), callback: () { if (data['Type'] == 4 && data['Status'] == 1) { ClipboardData clipboardData = new ClipboardData(text: data['Content']); Clipboard.setData(clipboardData); showToast(I18n.of(context).successful_copy); } if (data['Type'] == 3) { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProfilePage( userId: data['ReportedUserId'], ); }, ), ); } if (data['Type'] == 6) { launch(applyInfo['links']); } }, ); } //电台消息 Widget _buildRadioInfo(data) { String imgUrl = data['HeadImg'] == null || data['HeadImg'] == '' ? Constants.DefaultHeadImgUrl : data['HeadImg']; return _ConversationItem( conversation: Conversation( avatar: imgUrl, title: '', desc: WebData().getLoginTime(context, data['CreateTime']), updateAt: '17:20', ), title: RichTitle.getRichTitleWidget(data, context, InfoType.Radio), callback: () { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProgramDetailPage( programId: data['Id'], ); }, ), ); }, ); } Widget _renderRow(BuildContext context, int index) { if (index < list.length) { var userInfo = list[index]; Widget result = Container(); switch (widget.type) { case InfoType.Apply: result = _buildApllayInfo(userInfo); break; case InfoType.Evaluation: result = _buildContentInfo(userInfo); break; case InfoType.System: result = _buildSystemInfo(userInfo); break; case InfoType.Radio: result = _buildRadioInfo(userInfo); break; case InfoType.Money: result = _buildMoneyInfo(userInfo); break; default: } if (index == 0) { result = Padding(padding: EdgeInsets.only(top: 10), child: result); } return result; } return Container(); } void _onLoading() async { _page++; getNewData(addList); } @override Widget build(BuildContext context) { var content = Scaffold( appBar: AppBar( backgroundColor: AppColors.NewAppbarBgColor, title: Text( widget.title, style: TextStyle(color: AppColors.NewAppbarTextColor), ), leading: CustomUI.buildCustomLeading(context), centerTitle: true, ), body: SafeArea( child: SmartRefresher( enablePullDown: true, enablePullUp: true, header: MaterialClassicHeader(), footer: CustomUI.buildLoadingFooter(), controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoading, child: (_refreshController.headerStatus == RefreshStatus.completed && list.length == 0) ? CustomUI.buildNoData(context) : ListView.builder( itemBuilder: _renderRow, itemCount: list.length, ), ))); return content; // CustomUI.buildPageLoading(context, content, !isLoadingFish); } }