473 lines
14 KiB
Dart
473 lines
14 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
import 'dart:typed_data';
|
||
|
||
import 'package:circle_app/util/util.dart';
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:image_picker/image_picker.dart';
|
||
import 'package:video_player/video_player.dart';
|
||
import 'package:video_thumbnail/video_thumbnail.dart';
|
||
|
||
import '../../common/Widgets/base_tip_widget.dart';
|
||
import '../../common/Widgets/open_vip_tip/view.dart';
|
||
import '../../network/api.dart';
|
||
import '../../network/dio_manager.dart';
|
||
import '../../router/app_routers.dart';
|
||
import '../../util/SharedPreferencesHelper.dart';
|
||
import '../../util/eventBus.dart';
|
||
import '../../util/qiniu.dart';
|
||
import '../circle/logic.dart';
|
||
import '../dialog/UnlockCallDialog.dart';
|
||
import '../select_circle/logic.dart';
|
||
import 'state.dart';
|
||
import '../../common/config.dart';
|
||
import 'package:image/image.dart' as img;
|
||
|
||
class Call_outLogic extends GetxController {
|
||
final Call_outState state = Call_outState();
|
||
TextEditingController textEditingController = TextEditingController();
|
||
bool isCheck = false;
|
||
late ConfigBean configBean;
|
||
String circleName = "";
|
||
final ImagePicker _picker = ImagePicker();
|
||
var quToken = '';
|
||
VideoPlayerController? videoPlayerController;
|
||
List<MyConfigData> numbers = [];
|
||
List<MyConfigData>? myConfigData;
|
||
int vip = 0;
|
||
|
||
bool isZfbPrice = true;
|
||
|
||
@override
|
||
void onClose() {
|
||
super.onClose();
|
||
videoPlayerController?.dispose();
|
||
}
|
||
|
||
@override
|
||
void onInit() async {
|
||
super.onInit();
|
||
|
||
|
||
var data =
|
||
await DioManager.instance.get(url: Api.getCircleList, params: {});
|
||
var bean = BaseResponse<ConfigBean>.fromJson(
|
||
data, (data) => ConfigBean.fromJson(data));
|
||
if (bean.isSuccess()) {
|
||
configBean = bean.data!;
|
||
} else {
|
||
showOKToast(bean.msg);
|
||
}
|
||
|
||
Map arg = Get.arguments;
|
||
|
||
if (arg != null) {
|
||
// print(myConfigData.name);
|
||
List<MyConfigData> myConfigData = Get.arguments['numbers'];
|
||
numbers.addAll(myConfigData);
|
||
if(numbers.length>0) {
|
||
circleName = numbers[0].name;
|
||
}
|
||
update();
|
||
} else {
|
||
var data = await DioManager.instance
|
||
.get(url: Api.getMyCircleInterests, params: {"page": 1,'page_size':20});
|
||
|
||
var bean = BaseResponse<InterestsBean>.fromJson(
|
||
data, (data) => InterestsBean.fromJson(data));
|
||
|
||
InterestsBean info = bean.data;
|
||
|
||
if (info.lists.isNotEmpty) {
|
||
Circle circle = info.lists.first;
|
||
MyConfigData configData = MyConfigData(circle.id.toString(),circle.title,true);
|
||
numbers.add(configData);
|
||
if(numbers.length>0){
|
||
circleName = numbers[0].name;
|
||
}
|
||
|
||
|
||
update();
|
||
}
|
||
|
||
|
||
}
|
||
|
||
SharedPreferencesHelper.getInstance().then((sharedPreferences) {
|
||
vip = sharedPreferences.getInt(SharedPreferencesHelper.VIP);
|
||
print(vip);
|
||
if (vip == 2) {
|
||
isCheck = true;
|
||
}
|
||
update();
|
||
});
|
||
|
||
|
||
loadQiniuToken();
|
||
|
||
StreamSubscription subscription =
|
||
EventBusManager.on<CommentVipEvent>().listen((event) {
|
||
vip = event.vip;
|
||
});
|
||
}
|
||
|
||
Future<void> loadQiniuToken() async {
|
||
var quniuData =
|
||
await DioManager.instance.get(url: Api.getqiniuToken, params: {});
|
||
var qiniuBean = BaseResponse<QnTokenData>.fromJson(
|
||
quniuData, (quniuData) => QnTokenData.fromJson(quniuData));
|
||
quToken = qiniuBean.data!.token.toString();
|
||
}
|
||
|
||
showRechargeDialog() {
|
||
Get.bottomSheet(
|
||
Scaffold(
|
||
backgroundColor: Colors.transparent,
|
||
body: Open_vip_tipPage(true),
|
||
),
|
||
isScrollControlled: true,
|
||
enableDrag: false);
|
||
}
|
||
|
||
sendShout() async {
|
||
if (numbers.isEmpty) {
|
||
showOKToast("请选择要喊话的圈子。");
|
||
return;
|
||
}
|
||
if (textEditingController.text.isEmpty) {
|
||
showOKToast("请输入喊话内容");
|
||
return;
|
||
}
|
||
if (state.imaglist.isEmpty && state.videolist.isEmpty) {
|
||
if (textEditingController.text.length < 10) {
|
||
showOKToast("您当前未添加图片或视频,请至少输入10字喊话内容。");
|
||
return;
|
||
}
|
||
} else {
|
||
if (!state.imaglist.isEmpty) {
|
||
if (textEditingController.text.length < 5) {
|
||
showOKToast("请至少输入5个字内容");
|
||
return;
|
||
}
|
||
}
|
||
if (!state.videolist.isEmpty) {
|
||
if (textEditingController.text.length < 5) {
|
||
showOKToast("请至少输入5个字内容");
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
List myBean = [];
|
||
if (!state.imaglist.isEmpty) {
|
||
state.imaglist.forEach((element) {
|
||
myBean.add(MyBean(type: 1, url: element).toJson());
|
||
});
|
||
}
|
||
if (!state.videolist.isEmpty) {
|
||
myBean.add(MyBean(type: 2, url: state.videolist[0]).toJson());
|
||
}
|
||
print(myBean.toString());
|
||
SmartDialog.showLoading();
|
||
var data = await DioManager.instance.post(url: Api.SendShout, params: {
|
||
'album': myBean,
|
||
'content': textEditingController.text.trim(),
|
||
'interest_id': numbers[0].id,
|
||
'use_queen': isCheck ? 1 : 0,
|
||
});
|
||
|
||
var beandata = BaseResponse<dynamic>.fromJson(
|
||
data,
|
||
(jsonData) => jsonData,
|
||
);
|
||
SmartDialog.dismiss();
|
||
if (beandata.isSuccess()) {
|
||
showOKToast(beandata.msg);
|
||
final logic = Get.put(CircleLogic());
|
||
logic.setCircle(numbers[0].id);
|
||
logic.refresh();
|
||
|
||
EventBusManager.fire(CallRefreshCircle(numbers[0].id));
|
||
// logic.update();
|
||
// Navigator.pop(Get.context!, numbers);
|
||
Get.back();
|
||
} else if (beandata.code == 30503) {
|
||
// if (beandata.data == null) {
|
||
// return;
|
||
// }
|
||
showOKToast(beandata.msg);
|
||
var callOutBean = BaseResponse<List<String>>.fromJson(
|
||
data,
|
||
(jsonData) => List<String>.from(jsonData),
|
||
);
|
||
|
||
textEditingController.text =
|
||
filterSensitiveWords(textEditingController.text, callOutBean.data!);
|
||
print(
|
||
filterSensitiveWords(textEditingController.text, callOutBean.data!));
|
||
update();
|
||
} else if (beandata.code == 30505) {
|
||
var callOutBean = BaseResponse<CirclePaymentBean>.fromJson(
|
||
data,
|
||
(jsonData) => CirclePaymentBean.fromJson(jsonData),
|
||
);
|
||
// showDialog();
|
||
print(numbers[0].id);
|
||
|
||
// showJoinCiclePiker(numbers[0].id.toString(),callOutBean.data.amount.toString(),callOutBean.data.oldAmount.toString(),0,(payResult){
|
||
// final logic = Get.put(CircleLogic());
|
||
// logic.circle.lists.forEach((element) {
|
||
// if(element.id == numbers[0].id){
|
||
// element.is_limit = false;
|
||
// }
|
||
// });
|
||
// // widget.bean.is_limit = false;
|
||
// });
|
||
|
||
UnlockCallDialog().showUnlockBottomSheet(numbers[0].id,callOutBean.data.amount.toString(),callOutBean.data.oldAmount.toString(),iositem: callOutBean.data.ios_item);
|
||
// tipWdiget()
|
||
} else {
|
||
showOKToast(beandata.msg);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
startSelectCircleActivity() async {
|
||
var data = await Get.toNamed(AppRoutes.SelectCircleActivity, arguments: {
|
||
"interestMap": configBean.interestMap,
|
||
'selectCircle': numbers,
|
||
"isRodio": true
|
||
});
|
||
if (null != data) {
|
||
numbers = data;
|
||
circleName = numbers[0].name;
|
||
|
||
print(circleName);
|
||
update();
|
||
}
|
||
}
|
||
|
||
showImg() async {
|
||
try {
|
||
if (state.videolist.length != 0) {
|
||
showOKToast("已添加视频,无法添加图片。");
|
||
return;
|
||
}
|
||
if (state.imaglist.length == 6) {
|
||
showOKToast("最多上传6张图片哦~");
|
||
return;
|
||
}
|
||
final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery,);
|
||
if (null == pickedFile) {
|
||
return;
|
||
}
|
||
// final image = img.decodeImage(File(pickedFile.path).readAsBytesSync())!;
|
||
// img.Image watermarkedImage = img.Image(image.width, image.height);
|
||
// watermarkedImage = img.copyResize(image, width: image.width, height: image.height);
|
||
//
|
||
// // 添加文字水印
|
||
// img.drawString(watermarkedImage, img.arial_48, 10, 1000, 'Watermark Text', color: img.getColor(255, 0, 0));
|
||
//
|
||
// var path = await getApplicationSupportDirectoryPath();
|
||
// String outputPath = path+"ceshishuiyin";
|
||
// File(outputPath).writeAsBytesSync(img.encodeJpg(watermarkedImage));
|
||
|
||
SmartDialog.showLoading();
|
||
uploadImage(quToken, pickedFile!, CONFIG.CALL_OUT_IMAGE, (result) {
|
||
SmartDialog.dismiss();
|
||
state.imaglist.add(result);
|
||
update();
|
||
});
|
||
} catch (e) {
|
||
print(e);
|
||
}
|
||
}
|
||
|
||
Future<ThumbnailResult> getFirstPic(url) async {
|
||
Uint8List? bytes = await VideoThumbnail.thumbnailData(video: url);
|
||
final Completer<ThumbnailResult> completer = Completer();
|
||
if (bytes != null) {
|
||
int _imageDataSize = bytes.length;
|
||
print("image size: $_imageDataSize");
|
||
|
||
final _image = Image.memory(bytes);
|
||
_image.image
|
||
.resolve(ImageConfiguration())
|
||
.addListener(ImageStreamListener((ImageInfo info, bool _) {
|
||
completer.complete(ThumbnailResult(
|
||
image: _image,
|
||
dataSize: _imageDataSize,
|
||
height: info.image.height,
|
||
width: info.image.width,
|
||
));
|
||
}));
|
||
}
|
||
|
||
return completer.future;
|
||
}
|
||
|
||
showVideo() async {
|
||
if (state.imaglist.length != 0) {
|
||
showOKToast("已添加图片,无法添加视频。");
|
||
return;
|
||
}
|
||
if (state.videolist.length != 0) {
|
||
showOKToast("最多上传1个视频哦~");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
final XFile? pickedFile = await _picker.pickVideo(
|
||
source: ImageSource.gallery,
|
||
);
|
||
if (null == pickedFile) {
|
||
return;
|
||
}
|
||
SmartDialog.showLoading();
|
||
// var path = await getApplicationSupportDirectoryPath();
|
||
videoPlayerController = VideoPlayerController.file(
|
||
File(pickedFile.path),
|
||
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
|
||
);
|
||
await videoPlayerController?.initialize();
|
||
final Duration videoDuration = videoPlayerController!.value.duration;
|
||
final double durationInSeconds = videoDuration.inSeconds.toDouble();
|
||
if (durationInSeconds >= 5 && durationInSeconds <= 30) {
|
||
videoPlayerController?.setLooping(true);
|
||
videoPlayerController?.addListener(() {
|
||
if (!videoPlayerController!.value.isPlaying) {
|
||
// Navigator.pop(context);
|
||
}
|
||
});
|
||
|
||
uploadQiniu(
|
||
pickedFile.path, pickedFile.name, CONFIG.CALL_OUT_VIDEO, quToken,
|
||
(result) {
|
||
SmartDialog.dismiss();
|
||
state.videolist.add(result);
|
||
update();
|
||
});
|
||
} else {
|
||
SmartDialog.dismiss();
|
||
showOKToast("请上传5-30秒的视频,当前视频长度为:$durationInSeconds" "秒");
|
||
}
|
||
} catch (e) {}
|
||
|
||
//压缩 感觉越压越大
|
||
// try {
|
||
// final XFile? pickedFile = await _picker.pickVideo(
|
||
// source: ImageSource.gallery,
|
||
// );
|
||
// if(null==pickedFile){
|
||
// return;
|
||
// }
|
||
// SmartDialog.showLoading();
|
||
// var path = await getApplicationSupportDirectoryPath();
|
||
//
|
||
//
|
||
// compressVideo(pickedFile.path, path, (result) async {
|
||
// print(result);
|
||
// videoPlayerController = VideoPlayerController.file(
|
||
// File(result),
|
||
// videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
|
||
// );
|
||
// await videoPlayerController?.initialize();
|
||
// final Duration videoDuration = videoPlayerController!.value.duration;
|
||
// final double durationInSeconds = videoDuration.inSeconds.toDouble();
|
||
// print("////////////");
|
||
// print(durationInSeconds.toString());
|
||
// if (durationInSeconds >= 5 && durationInSeconds <= 30) {
|
||
// videoPlayerController?.setLooping(true);
|
||
// videoPlayerController?.addListener(() {
|
||
// if (!videoPlayerController!.value.isPlaying) {
|
||
// // Navigator.pop(context);
|
||
// }
|
||
// });
|
||
//
|
||
// updataQiniu(result, pickedFile.name, CONFIG.CALL_OUT_VIDEO, quToken,
|
||
// (result) {
|
||
// SmartDialog.dismiss();
|
||
// state.videolist.add(result);
|
||
// update();
|
||
// });
|
||
// } else {
|
||
// SmartDialog.dismiss();
|
||
// showToast("请上传5-30秒的视频");
|
||
// }
|
||
// });
|
||
// } catch (e) {}
|
||
}
|
||
|
||
Future<ClosedCaptionFile> _loadCaptions(BuildContext context) async {
|
||
final String fileContents = await DefaultAssetBundle.of(context)
|
||
.loadString('assets/bumble_bee_captions.vtt');
|
||
return WebVTTCaptionFile(
|
||
fileContents); // For vtt files, use WebVTTCaptionFile
|
||
}
|
||
}
|
||
|
||
class MyBean {
|
||
int type;
|
||
String url;
|
||
|
||
MyBean({required this.type, required this.url});
|
||
|
||
factory MyBean.fromJson(Map<String, dynamic> json) {
|
||
return MyBean(
|
||
type: json['type'],
|
||
url: json['url'],
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'type': type,
|
||
'url': url,
|
||
};
|
||
}
|
||
}
|
||
|
||
class ThumbnailResult {
|
||
final Image image;
|
||
final int dataSize;
|
||
final int height;
|
||
final int width;
|
||
|
||
const ThumbnailResult(
|
||
{required this.image,
|
||
required this.dataSize,
|
||
required this.height,
|
||
required this.width});
|
||
}
|
||
|
||
class CirclePaymentBean {
|
||
final int id;
|
||
final String title;
|
||
final String ios_item;
|
||
final double amount;
|
||
final double oldAmount;
|
||
|
||
CirclePaymentBean({
|
||
required this.id,
|
||
required this.title,
|
||
required this.ios_item,
|
||
required this.amount,
|
||
required this.oldAmount,
|
||
});
|
||
|
||
factory CirclePaymentBean.fromJson(Map<String, dynamic> json) {
|
||
return CirclePaymentBean(
|
||
id: json['id'] as int,
|
||
ios_item: json['ios_item'] ?? '',
|
||
title: json['title'] as String,
|
||
amount: json['amount'] as double,
|
||
oldAmount: json['old_amount'] as double,
|
||
);
|
||
}
|
||
}
|