feat: create dynamic with pics

This commit is contained in:
bggRGjQaUbCoE
2024-09-30 16:50:47 +08:00
parent 8f246148be
commit 8d34b7ee81
5 changed files with 261 additions and 8 deletions

View File

@@ -625,4 +625,6 @@ class Api {
static const String createTextDynamic = '/dynamic_svr/v1/dynamic_svr/create';
static const String removeDynamic = '/dynamic_svr/v1/dynamic_svr/rm_dynamic';
static const String uploadBfs = '/x/dynamic/feed/draw/upload_bfs';
}

View File

@@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:math';
import 'package:PiliPalaX/http/constants.dart';
import 'package:dio/dio.dart';
@@ -145,8 +146,9 @@ class MsgHttp {
static Future createDynamic({
dynamic mid,
dynamic dynIdStr,
dynamic dynIdStr, // repost
dynamic rawText,
List? pics,
}) async {
String csrf = await Request.getCsrf();
var res = await Request().post(
@@ -165,7 +167,12 @@ class MsgHttp {
{"raw_text": rawText, "type": 1, "biz_id": ""}
]
},
"scene": 4,
"scene": dynIdStr != null
? 4
: pics != null
? 2
: 1,
if (pics != null) 'pics': pics,
"attach_card": null,
"upload_id":
"${mid}_${DateTime.now().millisecondsSinceEpoch ~/ 1000}_${Random().nextInt(9000) + 1000}",
@@ -173,7 +180,7 @@ class MsgHttp {
"app_meta": {"from": "create.dynamic.web", "mobi_app": "web"}
}
},
"web_repost_src": {"dyn_id_str": dynIdStr}
if (dynIdStr != null) "web_repost_src": {"dyn_id_str": dynIdStr}
},
);
if (res.data['code'] == 0) {
@@ -186,6 +193,32 @@ class MsgHttp {
}
}
static Future uploadBfs(
dynamic path,
) async {
String csrf = await Request.getCsrf();
Map<String, dynamic> data = await WbiSign().makSign({
'file_up': await MultipartFile.fromFile(path),
'category': 'daily',
'csrf': csrf,
});
var res = await Request().post(
Api.uploadBfs,
data: FormData.fromMap(data),
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future createTextDynamic(
dynamic content,
) async {

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:PiliPalaX/http/msg.dart';
import 'package:PiliPalaX/models/common/dynamics_type.dart';
@@ -12,6 +13,7 @@ import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:PiliPalaX/utils/feed_back.dart';
import 'package:PiliPalaX/utils/storage.dart';
import 'package:image_picker/image_picker.dart';
import 'controller.dart';
import 'widgets/up_panel.dart';
@@ -219,20 +221,60 @@ class _CreatePanelState extends State<CreatePanel> {
final _ctr = TextEditingController();
bool _isEnable = false;
final _isEnableStream = StreamController<bool>();
late final _imagePicker = ImagePicker();
late final _pics = [];
late final _pathList = <String>[];
late final _pathStream = StreamController<List<String>>();
@override
void dispose() {
_isEnableStream.close();
_pathStream.close();
_ctr.dispose();
super.dispose();
}
Future _onCreate() async {
dynamic result = await MsgHttp.createTextDynamic(_ctr.text);
if (result['status']) {
Get.back();
SmartDialog.showToast('发布成功');
if (_pathList.isEmpty) {
dynamic result = await MsgHttp.createTextDynamic(_ctr.text);
if (result['status']) {
Get.back();
SmartDialog.showToast('发布成功');
} else {
SmartDialog.showToast(result['msg']);
}
} else {
SmartDialog.showToast(result['msg']);
for (int i = 0; i < _pathList.length; i++) {
SmartDialog.showLoading(msg: '正在上传图片: ${i + 1}/${_pathList.length}');
dynamic result = await MsgHttp.uploadBfs(_pathList[i]);
if (result['status']) {
int imageSize = await File(_pathList[i]).length();
_pics.add({
'img_width': result['data']['image_width'],
'img_height': result['data']['image_height'],
'img_size': imageSize / 1024,
'img_src': result['data']['image_url'],
});
} else {
SmartDialog.dismiss();
SmartDialog.showToast(result['msg']);
return;
}
if (i == _pathList.length - 1) {
SmartDialog.dismiss();
}
}
dynamic result = await MsgHttp.createDynamic(
mid: GStorage.userInfo.get('userInfoCache').mid,
rawText: _ctr.text,
pics: _pics,
);
if (result['status']) {
Get.back();
SmartDialog.showToast('发布成功');
} else {
SmartDialog.showToast(result['msg']);
}
}
}
@@ -320,6 +362,84 @@ class _CreatePanelState extends State<CreatePanel> {
),
),
),
StreamBuilder(
initialData: const [],
stream: _pathStream.stream,
builder: (_, snapshot) => SizedBox(
height: 75,
child: ListView.separated(
scrollDirection: Axis.horizontal,
physics: const AlwaysScrollableScrollPhysics(
parent: BouncingScrollPhysics(),
),
padding: const EdgeInsets.symmetric(horizontal: 15),
itemCount: _pathList.length == 9 ? 9 : _pathList.length + 1,
itemBuilder: (context, index) {
if (_pathList.length != 9 && index == _pathList.length) {
return Ink(
width: 75,
height: 75,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).colorScheme.secondaryContainer,
),
child: InkWell(
onTap: () async {
List<XFile> pickedFiles =
await _imagePicker.pickMultiImage(
limit: 9,
imageQuality: 100,
);
if (pickedFiles.isNotEmpty) {
for (int i = 0; i < pickedFiles.length; i++) {
if (_pathList.length == 9) {
SmartDialog.showToast('最多选择9张图片');
if (i != 0) {
_pathStream.add(_pathList);
}
break;
} else {
_pathList.add(pickedFiles[i].path);
if (i == pickedFiles.length - 1) {
_pathStream.add(_pathList);
}
}
}
if (_pathList.isNotEmpty && !_isEnable) {
_isEnable = true;
_isEnableStream.add(true);
}
}
},
borderRadius: BorderRadius.circular(12),
child: const Center(child: Icon(Icons.add)),
),
);
} else {
return GestureDetector(
onTap: () {
_pics.clear();
_pathList.removeAt(index);
_pathStream.add(_pathList);
if (_pathList.isEmpty &&
_ctr.text.replaceAll('\n', '').isEmpty) {
_isEnable = false;
_isEnableStream.add(false);
}
},
child: Image(
height: 75,
fit: BoxFit.fitHeight,
filterQuality: FilterQuality.low,
image: FileImage(File(_pathList[index])),
),
);
}
},
separatorBuilder: (_, index) => const SizedBox(width: 10),
),
),
),
],
);
}