import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:huixiang/community/community_view/community_dynamic.dart'; import 'package:huixiang/community/photo_view_gallery_screen.dart'; import 'package:huixiang/data/im_user.dart'; import 'package:huixiang/data/member_infor.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/data/article.dart'; import 'package:huixiang/data/base_data.dart'; import 'package:huixiang/data/comunity_comment.dart'; import 'package:huixiang/data/page.dart'; import 'package:huixiang/data/upload_result.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/utils/shared_preference.dart'; import 'package:huixiang/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/my_footer.dart'; import 'package:huixiang/view_widget/no_data_view.dart'; import 'package:huixiang/view_widget/settlement_tips_dialog.dart'; import 'package:image_pickers/image_pickers.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; class PersonalPage extends StatefulWidget { final Map? arguments; PersonalPage({this.arguments}); @override State createState() { return _PersonalPage(); } } class _PersonalPage extends State with WidgetsBindingObserver { ApiService? apiService; final RefreshController refreshController = RefreshController(); final ScrollController scrollController = ScrollController(); var isShrink = false; int pageNum = 1; String? userId; List
articles = []; MemberInfor? memberInfor; String? filePath; bool isLoadMore = false; bool isRefresh = true; bool isLoadingData = false; String? memberId; Map modifyInfo = {"background": ""}; String? selfUserId; @override void initState() { super.initState(); memberId = widget.arguments?["memberId"]; WidgetsBinding.instance.addObserver(this); selfUserId = SharedInstance.instance.userId; apiService = ApiService(Dio(), context: context, token: SharedInstance.instance.token, showLoading: true, ); _onRefresh(); } _onRefresh() async { queryCommunity(null); queryMember(memberId); } ///查询会员信息 queryMember(id) async { apiService ??= ApiService( Dio(), context: context, token: SharedInstance.instance.token, ); BaseData? baseData = await apiService?.memberDetail(id).catchError((error) { refreshController.refreshFailed(); debugPrint(error); return BaseData()..isSuccess = false; }); if (baseData?.isSuccess ?? false) { setState(() { memberInfor = baseData!.data; }); refreshController.refreshCompleted(); } else { refreshController.refreshFailed(); } } ///关注/取关会员 vipFollow(followId, isFollow) async { apiService ??= ApiService( Dio(), context: context, token: SharedInstance.instance.token, ); BaseData? baseData = await apiService?.follow(followId ?? ""); if (baseData?.isSuccess ?? false) { queryCommunity(null); SmartDialog.show(builder: (BuildContext context) { return SettlementTips(() {}, text: isFollow ? "取关成功" : "关注成功"); }); setState(() {}); } } ///动态列表 queryCommunity(String? searchKey) async { if (!isRefresh) { isRefresh = true; return; } if (isLoadingData) { return; } isLoadingData = true; userId = SharedInstance.instance.userId; apiService ??= ApiService(Dio(), context: context, token: SharedInstance.instance.token, showLoading: false); if (isLoadMore) { pageNum += 1; isLoadMore = false; } else if (searchKey == null) pageNum = 1; BaseData>? baseData = await apiService?.trendList({ "mid": memberId == "0" ? userId : memberId, "onlyFollow": false, "onlyMe": true, "pageNum": searchKey == null ? pageNum : 1, "pageSize": 10, "searchKey": searchKey ?? "" }).catchError((error) { debugPrint(error); if (searchKey == null) { refreshController.refreshFailed(); refreshController.loadFailed(); } return BaseData>()..isSuccess = false; }); if (baseData?.isSuccess ?? false) { if (baseData!.data?.list?.isNotEmpty ?? false) { if (searchKey != null) { articles.forEach((element) { if (element.id == searchKey) { element.content = jsonEncode(baseData.data!.list![0].subjectInfo); element.mainTitle = baseData.data!.list![0].subject; element.followed = baseData.data!.list![0].selfFollow; element.liked = baseData.data!.list![0].selfLike; element.authorHeadImg = baseData.data!.list![0].memberInfo?.avatar; element.authorName = baseData.data!.list![0].memberInfo?.nickname; element.location = baseData.data!.list![0].location; element.createTime = baseData.data!.list![0].createTime; element.author = baseData.data!.list![0].memberInfo?.mid; element.viewers = baseData.data!.list![0].viewers; element.likes = baseData.data!.list![0].likes; element.comments = baseData.data!.list![0].comments; this.isRefresh = false; setState(() {}); } }); } else { if (pageNum == 1) { articles.clear(); } baseData.data?.list?.forEach((element) { var article = Article(); article.id = element.id; article.content = jsonEncode(element.subjectInfo); article.mainTitle = element.subject; article.followed = element.selfFollow; article.liked = element.selfLike; article.authorHeadImg = element.memberInfo?.avatar; article.authorName = element.memberInfo?.nickname; article.location = element.location; article.createTime = element.createTime; article.author = element.memberInfo?.mid; article.viewers = element.viewers; article.likes = element.likes; article.comments = element.comments; articles.add(article); }); setState(() {}); // comments.sort((a,b)=>b.createTime.compareTo(a.createTime)); // print("comments: ${comments.length}"); if ((int.tryParse(baseData.data?.total ?? "0") ?? 0) < (pageNum * 10)) { refreshController.loadNoData(); } } } } isLoadingData = false; } ///去编辑个人资料 _toUserInfo() async { if (SharedInstance.instance.token.isEmpty) { Navigator.of(context).pushNamed( '/router/new_login_page', arguments: {"login": "login"}, ); return; } await Navigator.of(context) .pushNamed('/router/user_info_page') .then((value) { _onRefresh(); setState(() {}); }); setState(() {}); } ///显示图片选择方式 showImagePicker() { showCupertinoModalPopup( context: context, builder: (context) { return CupertinoActionSheet( title: Text(S.of(context).genghuantouxiang), actions: [ CupertinoActionSheetAction( child: Text(S.of(context).paizhao), onPressed: () { openCamera(); Navigator.of(context).pop(); }, isDefaultAction: true, isDestructiveAction: false, ), CupertinoActionSheetAction( child: Text(S.of(context).xiangce), onPressed: () { openStorage(); Navigator.of(context).pop(); }, isDefaultAction: true, isDestructiveAction: false, ), ], cancelButton: CupertinoActionSheetAction( onPressed: () { Navigator.of(context).pop(); }, child: Text(S.of(context).quxiao), isDestructiveAction: true, ), ); }, ); } ///拍照 openCamera() async { if (await Permission.camera.isGranted) { Media? medias = await ImagePickers.openCamera( cameraMimeType: CameraMimeType.photo, cropConfig: CropConfig( enableCrop: true, width: 200, height: 200, ), compressSize: 500, ); filePath = medias?.path; fileUpload(); } else { await Permission.camera.request(); openCamera(); } } ///打开相册 openStorage() async { if (await Permission.storage.isGranted) { List medias = await ImagePickers.pickerPaths( galleryMode: GalleryMode.image, selectCount: 1, showGif: true, showCamera: false, compressSize: 500, uiConfig: UIConfig( uiThemeColor: Color(0xFFFFFFFF), ), cropConfig: CropConfig( enableCrop: true, width: 200, height: 200, ), ); if (medias.length == 0) return; filePath = medias[0].path; setState(() {}); fileUpload(); } else { await Permission.storage.request(); openStorage(); } } ///调用修改用户信息接口 modifyInfos() async { var info = await apiService?.editInfo(modifyInfo).catchError((onError) { return BaseData()..isSuccess = false; }); if (info?.isSuccess ?? false) { setState(() { SmartDialog.showToast("用户信息修改成功", alignment: Alignment.center); }); _onRefresh(); } } ///文件上传 fileUpload() async { if ((filePath?.isNotEmpty ?? false) && await File(filePath!).exists()) { BaseData? baseData = await apiService ?.upload(File(filePath!), 123123123, false) .catchError((onError) { return BaseData()..isSuccess = false; }); if (baseData?.isSuccess ?? false) { UploadResult? uploadResult = baseData!.data; modifyInfo["background"] = uploadResult?.url; modifyInfos(); } } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SmartRefresher( controller: refreshController, enablePullDown: true, enablePullUp: (articles.length == 0) ? false : true, header: MyHeader(), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), onRefresh: _onRefresh, onLoading: () { isLoadMore = true; setState(() { _onRefresh(); }); }, physics: BouncingScrollPhysics(), scrollController: scrollController, child: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ Container( color: Colors.black, child: Opacity( opacity: 0.9, child: MImage( memberInfor?.background ?? "", width: double.infinity, height: 210.h, fit: BoxFit.cover, errorSrc: "assets/image/default_1.webp", fadeSrc: "assets/image/default_1.webp", ), ), ), Positioned( top: MediaQuery.of(context).padding.top + 20.h, left: 17.w, child: GestureDetector( child: Image.asset( "assets/image/integral_return.webp", width: 24, height: 24, ), onTap: () { Navigator.of(context).pop(); }, ), ), if (memberId == "0") Positioned( bottom: 9.h, right: 16.w, child: GestureDetector( onTap: () { showImagePicker(); }, child: Container( padding: EdgeInsets.only(left: 2, right: 2), width: 59.w, height: 23.h, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), color: Color(0x80000000), ), child: Text( S.of(context).genghuanbeijing, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFFFFFFFF), ), ), ), ), ), ], ), Container( // margin: EdgeInsets.only(bottom: 30.h), decoration: BoxDecoration( color: Color(0xFFFFFFFF), borderRadius: BorderRadius.only( topRight: Radius.circular(12), topLeft: Radius.circular(12), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ trendsInfo(), Padding( padding: EdgeInsets.only( left: 16, top: 16, bottom: 16, ), child: Text( memberId != selfUserId ? "TA的动态" : "我的动态", style: TextStyle( color: Color(0xFF353535), fontSize: 15.sp, fontWeight: MyFontWeight.semi_bold, ), ), ), dynamicList(), ], ), ), ], ), ), ), ); } ///个人信息 Widget homeInfo() { return Positioned( top: 0, bottom: 0, left: 0, right: 0, child: Container( padding: EdgeInsets.only( left: 16.w, right: 16.w, ), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => PhotoViewGalleryScreen( images: [ (memberInfor?.headimg ?? "").isEmpty ? "https://i.postimg.cc/Pq6vjfnw/default-1.webp" : memberInfor?.headimg ], //传入图片list index: 0, //传入当前点击的图片的index ), ), ); }, child: MImage( memberInfor?.headimg ?? "", isCircle: true, width: 66.h, height: 66.h, fit: BoxFit.cover, errorSrc: "assets/image/default_user.webp", fadeSrc: "assets/image/default_user.webp", ), ), SizedBox(width: 10.w), Text( memberInfor?.nickname ?? "回乡", overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 16.sp, fontWeight: MyFontWeight.medium, color: Color(0xFF353535), ), ), SizedBox(width: 4.w), Image.asset( "assets/image/vip_yk.webp", width: 20, height: 20, ), Spacer(), if (memberId == "0") GestureDetector( onTap: () { setState(() { _toUserInfo(); }); }, child: Container( height: 23.h, padding: EdgeInsets.only( left: 6.w, right: 6.w, bottom: 2.h, top: 2.h, ), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(100), border: Border.all( width: 1.w, color: Color(0xFF353535), style: BorderStyle.solid, ), ), child: Text( S.of(context).bianjigerenziliao, style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF353535), ), ), ), ), if (memberId != selfUserId) GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (memberInfor?.id == selfUserId) { SmartDialog.showToast( "不能跟自己聊天", alignment: Alignment.center, ); return; } Navigator.of(context).pushNamed( '/router/chat_details_page', arguments: { "toUser": ImUser( avatar: memberInfor?.headimg, mid: memberInfor?.id, nickname: memberInfor?.nickname, ), }, ); }, 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 != selfUserId) GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { vipFollow( memberId, (articles.isNotEmpty && (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, ), ), ), ), ], ), ), ); } ///个人信息 Widget trendsInfo() { return Container( color: Colors.white, margin: EdgeInsets.only( top: 16, left: 16, right: 16, ), child: Column( children: [ ///个人信息 Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => PhotoViewGalleryScreen( images: [ (memberInfor?.headimg ?? "").isEmpty ? "https://i.postimg.cc/Pq6vjfnw/default-1.webp" : memberInfor?.headimg ], //传入图片list index: 0, //传入当前点击的图片的index ), ), ); }, child: MImage( memberInfor?.headimg ?? "", isCircle: true, width: 69, height: 69, fit: BoxFit.cover, errorSrc: "assets/image/default_user.webp", fadeSrc: "assets/image/default_user.webp", ), ), Expanded( child: Container( padding: EdgeInsets.only(left: 10), height: 69, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( children: [ Text( memberInfor?.nickname ?? "回乡", overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 16.sp, fontWeight: MyFontWeight.medium, color: Color(0xFF353535), ), ), SizedBox(width: 4.w), Image.asset( "assets/image/vip_yk.webp", width: 20, height: 20, ), Spacer(), if (memberId == "0") GestureDetector( onTap: () { setState(() { _toUserInfo(); }); }, child: Container( height: 23.h, padding: EdgeInsets.only( left: 6.w, right: 6.w, bottom: 2.h, top: 2.h, ), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(100), border: Border.all( width: 1.w, color: Color(0xFF353535), style: BorderStyle.solid, ), ), child: Text( S.of(context).bianjigerenziliao, style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF353535), ), ), ), ), ], ), Container( child: GestureDetector( onTap: () { setState(() { isShrink = !isShrink; }); }, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( flex: 1, child: Text( memberId == "0" ? ((memberInfor?.signature == "") ? "还未编辑个性签名~" : memberInfor?.signature ?? "") : "个性签名: ${(memberInfor?.signature == "") ? "还未编辑个性签名~" : memberInfor?.signature ?? ""}", overflow: isShrink ? TextOverflow.visible : TextOverflow.ellipsis, maxLines: isShrink ? 10 : 2, style: TextStyle( fontSize: 12.sp, color: Color(0xFF868686), fontWeight: MyFontWeight.regular, height: 1.5.h, ), ), ), Icon( (!isShrink) ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_up, color: Colors.black, size: 18, ), ], ), ), ), ], ), ), ), ], ), ///关注,粉丝,动态,获赞,好友数量 Container( margin: EdgeInsets.only( top: 16, bottom: 16, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () {}, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "${memberInfor?.follow ?? 0}", style: TextStyle( color: Color(0xFF353535), fontSize: 16.sp, fontWeight: MyFontWeight.semi_bold, ), ), SizedBox( height: 4.h, ), Text( S.of(context).guanzhu, style: TextStyle( color: Color(0xFF353535), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ], ), ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "${memberInfor?.fans ?? 0}", style: TextStyle( color: Color(0xFF353535), fontSize: 16.sp, fontWeight: MyFontWeight.semi_bold, ), ), SizedBox( height: 4.h, ), Text( S.of(context).fensi, style: TextStyle( color: Color(0xFF353535), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( (memberInfor?.trendTotal ?? 0).toString(), style: TextStyle( color: Color(0xFF353535), fontSize: 16.sp, fontWeight: MyFontWeight.semi_bold, ), ), SizedBox( height: 4.h, ), Text( S.of(context).dongtai, style: TextStyle( color: Color(0xFF353535), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( (memberInfor?.gainLikeTotal ?? 0).toString(), style: TextStyle( color: Color(0xFF353535), fontSize: 16.sp, fontWeight: MyFontWeight.semi_bold, ), ), SizedBox( height: 4.h, ), Text( S.of(context).huozan, style: TextStyle( color: Color(0xFF353535), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( (memberInfor?.gainLikeTotal ?? 0).toString(), style: TextStyle( color: Color(0xFF353535), fontSize: 16.sp, fontWeight: MyFontWeight.semi_bold, ), ), SizedBox( height: 4.h, ), Text( S.of(context).haoyou, style: TextStyle( color: Color(0xFF353535), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ], ), ), ], ), ), Container( height: 1.h, color: Color(0xFFF7F7F7), margin: EdgeInsets.only(bottom: (memberId != selfUserId) ? 24: 0), ), ///关注,聊天按钮 if (memberId != selfUserId) Row( children: [ Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { vipFollow( memberId, (articles.isNotEmpty && (articles.first.followed ?? false))); }, child: Container( height: 41, margin: EdgeInsets.only(right: 8.w, left: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.5), color: (articles.isNotEmpty && (articles.first.followed ?? false)) ? Color(0xFFE6E6E6) : Color(0xFF32A060), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( (articles.isNotEmpty && (articles.first.followed ?? false)) ? Icons.check : Icons.add, color: (articles.isNotEmpty && (articles.first.followed ?? false)) ? Color(0xFF808080) : Colors.white, size: 18.sp, ), SizedBox( width: 5, ), 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, ), ), ], ), ), ), ), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (memberInfor?.id == selfUserId) { SmartDialog.showToast( "不能跟自己聊天", alignment: Alignment.center, ); return; } if (widget.arguments?["inletType"] == 1) { //聊天框跳转到该页面inletType = 1,别的页面都是0,为了避免打开多个聊天框bug; Navigator.of(context).pop(); } else { Navigator.of(context).pushNamed( '/router/chat_details_page', arguments: { "toUser": ImUser( avatar: memberInfor?.headimg, mid: memberInfor?.id, nickname: memberInfor?.nickname, ), }, ); } }, child: Container( width: 110.w, height: 41, margin: EdgeInsets.only(right: 1.w), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.5), color: Color(0xFFFF9640), ), child: Text( "聊一聊", style: TextStyle( fontSize: 13.sp, color: Colors.white, fontWeight: MyFontWeight.regular, ), ), ), ), ], ), ], ), ); } ///动态 Widget dynamicList() { return Container( child: (articles.length == 0) ? NoDataView( src: "assets/image/dong_tai.webp", isShowBtn: false, text: "目前暂无发布动态,要把开心的事讲出来哦~", fontSize: 16.sp, margin: EdgeInsets.only( left: 60.w, right: 60.w, bottom: 80.h, ), ) : ListView.builder( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, padding: EdgeInsets.zero, itemBuilder: (context, position) { return InkWell( child: CommunityDynamic( articles[position], memberId == "0" ? 1 : 0, exitFull: () { setState(() { _onRefresh(); }); }, isList: true, removalDynamic: () { setState(() { _onRefresh(); }); }, ), onTap: () { Navigator.of(context).pushNamed( '/router/community_details', arguments: { "businessId": articles[position].id, "userId": userId, }, ).then((value) { queryCommunity(articles[position].id); }); }, ); }, itemCount: articles.length, ), ); } }