import 'package:chat/data/UserData.dart'; import 'package:chat/data/WebData.dart'; import 'package:chat/data/constants.dart'; import 'package:chat/generated/i18n.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/TokenMgr.dart'; import 'package:chat/utils/conversation_table.dart'; import 'package:chat/utils/screen.dart'; import 'package:dio/dio.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:chat/models/friends_info.dart'; import 'ProfilePage.dart'; import 'package:permission_handler/permission_handler.dart'; import 'dart:io'; import 'address_book.dart'; import 'new_addfriends.dart'; class _ContactItem extends StatelessWidget { _ContactItem( {@required this.avatar, @required this.title, @required this.userId, this.groupTitle, this.onPressed, this.gradient, this.iconCode, this.applyId, this.isShowDivder: true, this.state}); final int userId; final int iconCode; final String avatar; final String title; final String groupTitle; final VoidCallback onPressed; final Gradient gradient; final bool isShowDivder; final int state; final int applyId; static const double MARGIN_VERTICAL = 10.0; static const double GROUP_TITLE_HEIGHT = 24.0; @override Widget build(BuildContext context) { Widget _avatarIcon; if (iconCode == null) { _avatarIcon = ClipRRect( borderRadius: BorderRadius.circular(6), child: CachedNetworkImage( imageUrl: this.avatar, placeholder: (context, url) => Image.asset( Constants.DefaultHeadImgUrl, width: Constants.ContactAvatarSize, height: Constants.ContactAvatarSize, ), width: Constants.ContactAvatarSize, height: Constants.ContactAvatarSize, )); } else { _avatarIcon = Container( width: Constants.ContactAvatarSize, height: Constants.ContactAvatarSize, decoration: BoxDecoration( gradient: gradient, borderRadius: BorderRadius.circular(6)), child: Icon( IconData(this.iconCode, fontFamily: Constants.IconFontFamily), color: Colors.white, ), ); } Widget _button = Container( padding: const EdgeInsets.symmetric( vertical: MARGIN_VERTICAL, horizontal: 16.0), decoration: BoxDecoration(color: Colors.white), child: Row( children: [ _avatarIcon, SizedBox(width: 10.0), Expanded( child: Text( title, textScaleFactor: 1.0, )), state == 1 ? Container( padding: EdgeInsets.symmetric(horizontal: 21, vertical: 7), child: Text( I18n.of(context).added, textScaleFactor: 1.0, style: TextStyle(color: const Color(0xFF8A8B8B)), ), ) : (state == 0 ? Container( padding: EdgeInsets.symmetric(horizontal: 21, vertical: 7), child: Text( I18n.of(context).check, textScaleFactor: 1.0, style: TextStyle(color: Constants.BlueTextColor), ), ) : Container( padding: EdgeInsets.symmetric(horizontal: 21, vertical: 7), child: Text( I18n.of(context).rejected, textScaleFactor: 1.0, style: TextStyle(color: const Color(0xFF8A8B8B)), ), )), ], ), ); _button = Dismissible( key: Key(userId.toString()), child: _button, direction: DismissDirection.endToStart, background: Container( color: Colors.red, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ fixedText(I18n.of(context).delete, color: Colors.white), Icon( Icons.delete, color: Colors.white, ), SizedBox(width: 20), ], ), ), confirmDismiss: (direction) async { var _confirmContent = I18n.of(context).confirm_delete; bool isDismiss = await CustomUI.showIosDialog(context, _confirmContent, () async { Map data = { "userId": UserData().basicInfo.userId, "aUserId": userId, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post( 'friendship/delete/applicationRecord', data: data, isShowLoading: true); Map resData = res.data; //showToast(resData['msg']); if (resData['code'] == 0) { MessageMgr().emit('delete_friend_record', userId); } Navigator.of(context).pop(true); }, () { Navigator.of(context).pop(false); }); return isDismiss; }); //分组标签 Widget _itemBody; if (this.groupTitle != null) { _itemBody = Column( children: [ Container( height: GROUP_TITLE_HEIGHT, padding: EdgeInsets.only(left: 16.0, right: 16.0), color: const Color(AppColors.ContactGroupTitleBgColor), alignment: Alignment.centerLeft, child: Text( this.groupTitle, style: AppStyles.GroupTitleItemTextStyle, textScaleFactor: 1.0, ), ), _button, ], ); } else { _itemBody = _button; } return InkWell( onTap: () { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProfilePage( userId: userId, addMode: state == 0 ? 2 : 0, applyId: applyId, ); }, ), ); }, child: Container( color: Colors.white, child: Column( children: [ _itemBody, isShowDivder ? Container( height: 1, color: const Color(0xFFF3F3F3), margin: EdgeInsets.only( left: 26 + Constants.ContactAvatarSize), ) : Container() ], ))); } } class NewFriendsPage extends StatefulWidget { @override _NewFriendsPageState createState() => _NewFriendsPageState(); } class _NewFriendsPageState extends State { String _currentLetter = ''; ScrollController _scrollController; TextEditingController _txtCtrl = new TextEditingController(); bool _hasdeleteIcon = false; List searchList = []; List friendList = []; List _functionButtons = []; @override void initState() { super.initState(); print('NewFriendsPage initState'); getNewFriendList(); _scrollController = new ScrollController(); MessageMgr().on('do_friend_apply', messageApply); MessageMgr().on('delete_friend_record', deleteFriendRecord); _functionButtons = [ FriendsInfo( avatar: '', userId: 0, iconCode: 0xe67a, title: I18n.of(Constants.getCurrentContext()).contact_add, gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ const Color(0xFF1AC59E), const Color(0xFF088E76), ]), onPressed: () async { final PermissionStatus addStatus = await PermissionHandler() .checkPermissionStatus(PermissionGroup.contacts); if ((addStatus == PermissionStatus.unknown || addStatus == PermissionStatus.denied) && Platform.isIOS) { CustomUI.buildContacts(context, I18n.of(context).privacyAgreement, I18n.of(context).determine, () { Navigator.of(context).pop(); showPermission(); }, title: I18n.of(context).tip); } else { showPermission(); } }), ]; } showPermission() async { if (await CustomUI.showPermissionSetting( Constants.getCurrentContext(), PermissionGroup.contacts, I18n.of(Constants.getCurrentContext()).contact_permission)) { MessageMgr().emit('PostContact'); Navigator.push(Constants.getCurrentContext(), MaterialPageRoute(builder: (BuildContext context) { return ContactsPage(); })); } } messageApply(data) { for (int i = 0; i < friendList.length; i++) { if (friendList[i].friendId == data['userId']) { setState(() { friendList[i].state = data['state']; }); break; } } } deleteFriendRecord(userId) { for (int i = 0; i < friendList.length; i++) { if (friendList[i].friendId == userId) { setState(() { friendList.removeAt(i); }); break; } } } getNewFriendList() async { Map data = { "userId": UserData().basicInfo.userId, "type": 2, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('friendship/newFriends/record', data: data); Map resData = res.data; print(resData['data']); if (resData['code'] == 0 && resData['data'] != null) { resData['data'].forEach((f) { var friend = FriendModel.fromApplyServerJson(f); if (friend.friendId != UserData().basicInfo.userId) friendList.add(friend); }); setState(() {}); } } @override void dispose() { _scrollController.dispose(); MessageMgr().off('do_friend_apply', messageApply); MessageMgr().off('delete_friend_record', deleteFriendRecord); super.dispose(); } @override Widget build(BuildContext context) { final List _body = []; if (!_hasdeleteIcon) { _body.add(ListView.builder( controller: _scrollController, itemBuilder: (BuildContext context, int index) { if (index < _functionButtons.length) { if (index == 0) { return Padding( padding: EdgeInsets.only(top: 7), child: _functionButtons[index], ); } else { return _functionButtons[index]; } } int _contactIndex = index - _functionButtons.length; bool _isGroupTitle = true; FriendModel _contact = friendList[_contactIndex]; bool isThreeDay = WebData().isThreeDayAgo(_contact.creatTime); if (_contactIndex >= 1 && WebData().isThreeDayAgo(_contact.creatTime) == WebData() .isThreeDayAgo(friendList[_contactIndex - 1].creatTime)) { _isGroupTitle = false; } return _ContactItem( userId: _contact.friendId, avatar: _contact.avatar, title: Provider.of(context) .getRefName(_contact.friendId, _contact.name), state: _contact.state, isShowDivder: true, applyId: _contact.applyId, groupTitle: _isGroupTitle ? (isThreeDay ? I18n.of(context).before_three_day : I18n.of(context).after_three_day) : null); }, itemCount: friendList.length + _functionButtons.length, )); } else { _body.add(ListView.builder( controller: _scrollController, itemBuilder: (BuildContext context, int index) { FriendModel _contact = searchList[index]; return _ContactItem( userId: _contact.friendId, avatar: _contact.avatar, title: _contact.name, state: _contact.state, isShowDivder: true, applyId: _contact.applyId, groupTitle: null); }, itemCount: searchList.length, )); } if (_currentLetter != null && _currentLetter.isNotEmpty && !_hasdeleteIcon) { _body.add(Center( child: Container( width: Constants.IndexLetterBoxSize, height: Constants.IndexLetterBoxSize, decoration: BoxDecoration( color: AppColors.IndexLetterBoxBgColor, borderRadius: BorderRadius.all( Radius.circular(Constants.IndexLetterBoxRadius)), ), child: Center( child: Text( _currentLetter, style: AppStyles.IndexLetterBoxTextStyle, textScaleFactor: 1.0, ), ), ), )); } return Scaffold( resizeToAvoidBottomPadding: false, appBar: AppBar( backgroundColor: AppColors.NewAppbarBgColor, title: Text( I18n.of(context).new_friends, textScaleFactor: 1.0, style: TextStyle(color: AppColors.NewAppbarTextColor), ), centerTitle: true, leading: CustomUI.buildCustomLeading(context), elevation: 1, actions: [ Container( child: IconButton( icon: CircleAvatar( backgroundColor: Constants.GreyBackgroundColor, radius: 13.75, child: Padding( padding: EdgeInsets.only(bottom: 1.5), child: Icon( IconData(0xe662, fontFamily: Constants.IconFontFamily), color: Constants.BlackTextColor, size: 21, ))), onPressed: () { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return NewAddFriendsPage(); }, ), ); }, ), ), ], bottom: PreferredSize( preferredSize: Size.fromHeight(49), child: Container( alignment: Alignment.center, margin: EdgeInsets.only(bottom: 14, left: 12.5, right: 12.5), height: 35, decoration: BoxDecoration( color: const Color(0xFFEEEEEE), borderRadius: BorderRadius.all(Radius.circular(8))), child: TextField( keyboardAppearance: Brightness.light, keyboardType: TextInputType.text, textInputAction: TextInputAction.search, controller: _txtCtrl, maxLines: 1, style: TextStyle( textBaseline: TextBaseline.alphabetic, fontSize: 14.5), autofocus: false, inputFormatters: [ LengthLimitingTextInputFormatter(50), ], decoration: InputDecoration( hintText: I18n.of(context).search, hintStyle: TextStyle(fontSize: 14.5), contentPadding: EdgeInsets.only( left: 20, top: (UserData().language == LanguageType.English || UserData().language == LanguageType.Vietnamese) ? 3 : 10.5, bottom: 10.5), prefixIcon: Icon( IconData( 0xe664, fontFamily: Constants.IconFontFamily, ), color: const Color(0xFFA0A0A0), size: 18, ), suffixIcon: Padding( padding: EdgeInsetsDirectional.only( start: 2.0, end: _hasdeleteIcon ? 20.0 : 0), child: _hasdeleteIcon ? new InkWell( onTap: (() { setState(() { WidgetsBinding.instance .addPostFrameCallback( (_) => _txtCtrl.clear()); _hasdeleteIcon = false; }); }), child: Icon( Icons.clear, size: 18.0, color: Constants.BlackTextColor, )) : new Text('')), filled: true, fillColor: Colors.transparent, border: InputBorder.none, ), onChanged: (str) async { setState(() { if (str.isEmpty) { _hasdeleteIcon = false; } else { _hasdeleteIcon = true; searchList = CustomUI().getSearchResult( str, friendList == null ? [] : friendList); } }); }, onEditingComplete: () {}), )), ), body: Stack( children: _body, )); } }