mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-01 00:28:18 +08:00
feat: create dynamic with pics
This commit is contained in:
@@ -625,4 +625,6 @@ class Api {
|
|||||||
static const String createTextDynamic = '/dynamic_svr/v1/dynamic_svr/create';
|
static const String createTextDynamic = '/dynamic_svr/v1/dynamic_svr/create';
|
||||||
|
|
||||||
static const String removeDynamic = '/dynamic_svr/v1/dynamic_svr/rm_dynamic';
|
static const String removeDynamic = '/dynamic_svr/v1/dynamic_svr/rm_dynamic';
|
||||||
|
|
||||||
|
static const String uploadBfs = '/x/dynamic/feed/draw/upload_bfs';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:PiliPalaX/http/constants.dart';
|
import 'package:PiliPalaX/http/constants.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
@@ -145,8 +146,9 @@ class MsgHttp {
|
|||||||
|
|
||||||
static Future createDynamic({
|
static Future createDynamic({
|
||||||
dynamic mid,
|
dynamic mid,
|
||||||
dynamic dynIdStr,
|
dynamic dynIdStr, // repost
|
||||||
dynamic rawText,
|
dynamic rawText,
|
||||||
|
List? pics,
|
||||||
}) async {
|
}) async {
|
||||||
String csrf = await Request.getCsrf();
|
String csrf = await Request.getCsrf();
|
||||||
var res = await Request().post(
|
var res = await Request().post(
|
||||||
@@ -165,7 +167,12 @@ class MsgHttp {
|
|||||||
{"raw_text": rawText, "type": 1, "biz_id": ""}
|
{"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,
|
"attach_card": null,
|
||||||
"upload_id":
|
"upload_id":
|
||||||
"${mid}_${DateTime.now().millisecondsSinceEpoch ~/ 1000}_${Random().nextInt(9000) + 1000}",
|
"${mid}_${DateTime.now().millisecondsSinceEpoch ~/ 1000}_${Random().nextInt(9000) + 1000}",
|
||||||
@@ -173,7 +180,7 @@ class MsgHttp {
|
|||||||
"app_meta": {"from": "create.dynamic.web", "mobi_app": "web"}
|
"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) {
|
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(
|
static Future createTextDynamic(
|
||||||
dynamic content,
|
dynamic content,
|
||||||
) async {
|
) async {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:PiliPalaX/http/msg.dart';
|
import 'package:PiliPalaX/http/msg.dart';
|
||||||
import 'package:PiliPalaX/models/common/dynamics_type.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:hive/hive.dart';
|
||||||
import 'package:PiliPalaX/utils/feed_back.dart';
|
import 'package:PiliPalaX/utils/feed_back.dart';
|
||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
import 'widgets/up_panel.dart';
|
import 'widgets/up_panel.dart';
|
||||||
@@ -219,14 +221,21 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
final _ctr = TextEditingController();
|
final _ctr = TextEditingController();
|
||||||
bool _isEnable = false;
|
bool _isEnable = false;
|
||||||
final _isEnableStream = StreamController<bool>();
|
final _isEnableStream = StreamController<bool>();
|
||||||
|
late final _imagePicker = ImagePicker();
|
||||||
|
late final _pics = [];
|
||||||
|
late final _pathList = <String>[];
|
||||||
|
late final _pathStream = StreamController<List<String>>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_isEnableStream.close();
|
||||||
|
_pathStream.close();
|
||||||
_ctr.dispose();
|
_ctr.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _onCreate() async {
|
Future _onCreate() async {
|
||||||
|
if (_pathList.isEmpty) {
|
||||||
dynamic result = await MsgHttp.createTextDynamic(_ctr.text);
|
dynamic result = await MsgHttp.createTextDynamic(_ctr.text);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
Get.back();
|
Get.back();
|
||||||
@@ -234,6 +243,39 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
96
pubspec.lock
96
pubspec.lock
@@ -559,6 +559,38 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
file_selector_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_linux
|
||||||
|
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.2+1"
|
||||||
|
file_selector_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_macos
|
||||||
|
sha256: cb284e267f8e2a45a904b5c094d2ba51d0aabfc20b1538ab786d9ef7dc2bf75c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.4+1"
|
||||||
|
file_selector_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_platform_interface
|
||||||
|
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.6.2"
|
||||||
|
file_selector_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_windows
|
||||||
|
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.3+2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -890,6 +922,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.0"
|
version: "4.2.0"
|
||||||
|
image_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_picker
|
||||||
|
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
image_picker_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_android
|
||||||
|
sha256: c0a6763d50b354793d0192afd0a12560b823147d3ded7c6b77daf658fa05cc85
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.12+13"
|
||||||
|
image_picker_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_for_web
|
||||||
|
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.5"
|
||||||
|
image_picker_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_ios
|
||||||
|
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.12"
|
||||||
|
image_picker_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_linux
|
||||||
|
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1+1"
|
||||||
|
image_picker_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_macos
|
||||||
|
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1+1"
|
||||||
|
image_picker_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_platform_interface
|
||||||
|
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.10.0"
|
||||||
|
image_picker_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_windows
|
||||||
|
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1+1"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ dependencies:
|
|||||||
#富文本
|
#富文本
|
||||||
extended_text: ^14.0.1
|
extended_text: ^14.0.1
|
||||||
chat_bottom_container: ^0.2.0
|
chat_bottom_container: ^0.2.0
|
||||||
|
image_picker: ^1.1.2
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
mime:
|
mime:
|
||||||
git: https://github.com/orz12/mime.git
|
git: https://github.com/orz12/mime.git
|
||||||
|
|||||||
Reference in New Issue
Block a user