import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/address.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/upload_result.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:image_pickers/image_pickers.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:thumbnails/thumbnails.dart'; class ReleaseDynamic extends StatefulWidget { @override State createState() { return _ReleaseDynamic(); } } class _ReleaseDynamic extends State { int selectCount = 9; List mediaPaths = []; bool isRelease = false; int dynamicType = 0; TextEditingController textController = TextEditingController(); TextEditingController addressController = TextEditingController(); // TextEditingController houseNumberController = TextEditingController(); ApiService apiService; Map addressMap; Address preAddress; @override void initState() { super.initState(); SharedPreferences.getInstance().then((value) { apiService = ApiService( Dio(), context: context, token: value.getString("token"), showLoading: false, ); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppBar( title: "写动态", titleColor: Colors.black, leadingColor: Colors.black, background: Colors.white, action: Container( alignment: Alignment.center, child: Container( width: 46.w, height: 24.h, alignment: Alignment.center, decoration: BoxDecoration( color: isRelease ? Color(0xFF32A060) : Color(0xFFD8D8D8), borderRadius: BorderRadius.circular(4), ), child: Text( S.of(context).fabu, style: TextStyle( color: isRelease ? Colors.white : Color(0xFFA0A0A0), fontSize: 14.sp, fontWeight: MyFontWeight.semi_bold, ), ), ), ), onTap: () { if (!isRelease) { SmartDialog.showToast("请输入您此刻的想法!~"); return; } releaseDynamic(); }, ), body: Container( child: Column( children: [ buildEdit(), Container( width: double.infinity, margin: EdgeInsets.all(16), padding: EdgeInsets.only(left: 16, right: 16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( "!", overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: MyFontWeight.semi_bold, fontSize: 14.sp, color: Colors.red, ), ), SizedBox( width: 10, ), Expanded( child: Text( "用户发布内容需要等待系统审核,审核通过后才会在推荐广场展示", maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: MyFontWeight.medium, fontSize: 12.sp, color: Color(0xFFB3B2B2), ), ), ) ], ), ), Expanded( child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 12.w, mainAxisSpacing: 12.w, childAspectRatio: 1, ), padding: EdgeInsets.all(16), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, position) { if (mediaPaths.length > position) { return imageItem(mediaPaths[position]); } else { return addImageItem(); } }, itemCount: (mediaPaths.length == 0) ? 1 : ((dynamicType == 2) ? 1 : mediaPaths.length >= 9 ? 9 : (mediaPaths.length + 1)), ), ), ], ), ), ); } releaseDynamic() async { String dynamicText = textController.text; if (dynamicText == null || dynamicText == "") { SmartDialog.showToast("请输入您此刻的想法!"); return; } EasyLoading.show(status: "上传中"); fileUpload().then((value) async { String subjectType = "text"; if (dynamicType == 0) { subjectType = "text"; } else if (dynamicType == 1) { subjectType = "image"; } else if (dynamicType == 2) { subjectType = "video"; } List remoteImageUrls = []; String remoteVideoUrl = ""; String remoteVideoCoverImg = ""; if (mediaPaths.length > 0) { if (dynamicType == 1) { remoteImageUrls = mediaPaths.map((e) => e.remotePath).toList(); } else if (dynamicType == 2) { remoteVideoUrl = mediaPaths[0].remotePath; remoteVideoCoverImg = mediaPaths[0].thumbPath; } } BaseData baseData = await apiService.trend({ "images": remoteImageUrls, "subject": dynamicText, "subjectType": subjectType, "video": remoteVideoUrl, "coverImg": remoteVideoCoverImg, "latitude": "", "location": addressController.text == "" ? "" : addressController.text, "longitude": "", }).catchError((onError) { EasyLoading.dismiss(); }); if (baseData.isSuccess) { SmartDialog.showToast("发布成功!"); Future.delayed(Duration(seconds: 1), () { Navigator.of(context).pop(true); }); } EasyLoading.dismiss(); }); } ///文件上传 Future fileUpload() async { if (mediaPaths != null && mediaPaths.length > 0) { await Future.forEach(mediaPaths, (element) async { if ((element.remotePath == null || element.remotePath == "") && (element != null && element.path != null && element.path != "" && await File(element.path).exists())) { File file = File(element.path); if (dynamicType == 2) { String thumbnail; if (element.thumbPath != null && element.thumbPath != "" && await File(element.thumbPath).exists()) { thumbnail = element.thumbPath; } else { thumbnail = await Thumbnails.getThumbnail( videoFile: file.path, imageType: ThumbFormat.JPEG, quality: 10, ); } if (thumbnail != null && thumbnail != "" && await File(thumbnail).exists()) { BaseData baseData = await apiService.upload( File(thumbnail), 123123123, dynamicType == 2); if (baseData != null && baseData.isSuccess) { UploadResult uploadResult = baseData.data; mediaPaths[mediaPaths.indexOf(element)].thumbPath = uploadResult.url; } } } BaseData baseData = await apiService.upload(file, 123123123, dynamicType == 2); if (baseData != null && baseData.isSuccess) { UploadResult uploadResult = baseData.data; mediaPaths[mediaPaths.indexOf(element)].remotePath = uploadResult.url; } } }); } } Widget imageItem(Medias media) { return InkWell( onTap: () { showDeletePicker(media); }, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), ), alignment: Alignment.center, child: ClipRRect( borderRadius: BorderRadius.circular(4), child: Image.file( File(media.galleryMode == GalleryMode.video ? media.thumbPath : media.path), fit: BoxFit.cover, width: double.infinity, height: double.infinity, ), ), ), ); } ///显示图片选择方式 showImagePicker() { FocusScope.of(context).requestFocus(FocusNode()); if (dynamicType == 1) { getImageOrVideo(GalleryMode.image); return; } showCupertinoModalPopup( context: context, builder: (context) { return CupertinoActionSheet( title: Text("选择媒体文件"), actions: [ CupertinoActionSheetAction( child: Text("照片"), onPressed: () { getImageOrVideo(GalleryMode.image); Navigator.of(context).pop(); }, isDefaultAction: true, isDestructiveAction: false, ), CupertinoActionSheetAction( child: Text("视频"), onPressed: () { getImageOrVideo(GalleryMode.video); Navigator.of(context).pop(); }, isDefaultAction: true, isDestructiveAction: false, ), ], cancelButton: CupertinoActionSheetAction( onPressed: () { Navigator.of(context).pop(); }, child: Text(S.of(context).quxiao), isDestructiveAction: true, ), ); }); } ///显示图片选择方式 showDeletePicker(Medias media) { showCupertinoModalPopup( context: context, builder: (context) { return CupertinoActionSheet( title: Text("动态"), actions: [ CupertinoActionSheetAction( child: Text("删除"), onPressed: () { mediaPaths.remove(media); if (mediaPaths.length == 0) { dynamicType = 0; } selectCount = 9 - mediaPaths.length; Navigator.of(context).pop(); setState(() {}); }, isDefaultAction: true, isDestructiveAction: false, ), ], cancelButton: CupertinoActionSheetAction( onPressed: () { Navigator.of(context).pop(); }, child: Text(S.of(context).quxiao), isDestructiveAction: true, ), ); }); } Widget addImageItem() { return InkWell( onTap: () { showImagePicker(); }, child: Container( decoration: BoxDecoration( color: Color(0xFFF2F2F2), borderRadius: BorderRadius.circular(4), ), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SvgPicture.asset( "assets/svg/zhaopianshipin.svg", width: 48, height: 48, fit: BoxFit.contain, ), Text( "照片/视频", style: TextStyle( fontWeight: MyFontWeight.semi_bold, fontSize: 15.sp, color: Color(0xFFCDCCCC), ), ), ], ), ), ); } Future getImageOrVideo(GalleryMode galleryMode) async { if (selectCount == 0) return; List medias = await ImagePickers.pickerPaths( galleryMode: galleryMode, selectCount: (galleryMode == GalleryMode.video) ? 1 : selectCount, showGif: true, showCamera: false, compressSize: 500, uiConfig: UIConfig( uiThemeColor: Color(0xFFFFFFFF), ), cropConfig: CropConfig( enableCrop: false, width: 200, height: 200, ), ); mediaPaths.addAll(medias.map((e) => Medias(e)).toList()); selectCount = 9 - mediaPaths.length; if (mediaPaths.length > 0) { if (galleryMode == GalleryMode.image) { dynamicType = 1; } else { dynamicType = 2; } } setState(() {}); } toMap() async { Navigator.of(context).pushNamed('/router/address_map_page').then( (value) => { setState(() { if (value != null) { addressMap = value; addressController.text = "${(value as Map)['cityInfo']}"; if (preAddress != null) { preAddress.cityInfo = addressMap['cityInfo']; } // houseNumberController.text = "${(value as Map)['address']}"; } }) }, ); } ///动态输入框 Widget buildEdit() { return Container( // height: 174.h, margin: EdgeInsets.symmetric(horizontal: 16.w), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 1.w, color: Color(0xFFD8D8D8), style: BorderStyle.solid, ), ), ), child: Column( children: [ TextField( controller: textController, maxLines: 5, style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.medium, color: Color(0xFF4C4C4C), ), onChanged: (text) { bool release = text != "" && text != null; if (release != isRelease) { isRelease = release; setState(() {}); } }, decoration: InputDecoration( contentPadding: EdgeInsets.symmetric( vertical: 18.h, ), errorBorder: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, hintText: "此时此刻的想法~", hintStyle: TextStyle( fontSize: 14.sp, color: Color(0xFFA29E9E), ), ), ), Container( width: double.infinity, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: GestureDetector( onTap: () { toMap(); }, child:Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Icon( Icons.place, size: 16, color: Color(0xFFB3B2B2), ), SizedBox( width: 2, ), Text( addressController.text == "" ? "你在哪里呢?" : addressController.text , overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 11.sp, fontWeight: MyFontWeight.medium, color: Color(0xFFB3B2B2), ), ), ], ), )), addressController.text == "" ? Container() : GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { addressController.text = ""; }); }, child: Container( // color: Colors.red, height: 21.h, padding: EdgeInsets.only(left: 10, right: 10), alignment: Alignment.centerRight, child: Icon( Icons.close, color: Colors.black, size: 16, ), ), ), ], ), ), SizedBox( height: 5, ) ], )); } } class Medias { // Media media; Medias(Media media) { this.thumbPath = media.thumbPath; this.path = media.path; this.galleryMode = media.galleryMode; } String thumbPath; String path; GalleryMode galleryMode; String remotePath; }