Files
PiliPlus/lib/http/msg.dart
bggRGjQaUbCoE 261922d73a refa: whisper detail page
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-04-18 09:49:57 +08:00

592 lines
15 KiB
Dart

import 'dart:math';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/msg/msgfeed_at_me.dart';
import 'package:PiliPlus/models/msg/msgfeed_like_me.dart';
import 'package:PiliPlus/models/msg/msgfeed_reply_me.dart';
import 'package:PiliPlus/models/msg/msgfeed_sys_msg.dart';
import 'package:PiliPlus/pages/dynamics/view.dart' show ReplyOption;
import 'package:PiliPlus/utils/storage.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../models/msg/account.dart';
import '../models/msg/session.dart';
import '../utils/wbi_sign.dart';
import 'api.dart';
import 'init.dart';
class MsgHttp {
static Future<LoadingState<MsgFeedReplyMe>> msgFeedReplyMe(
{int cursor = -1, int cursorTime = -1}) async {
var res = await Request().get(Api.msgFeedReply, queryParameters: {
'id': cursor == -1 ? null : cursor,
'reply_time': cursorTime == -1 ? null : cursorTime,
'platform': 'android',
'mobi_app': 'android',
'build': '8350200',
});
if (res.data['code'] == 0) {
MsgFeedReplyMe data = MsgFeedReplyMe.fromJson(res.data['data']);
return LoadingState.success(data);
} else {
return LoadingState.error(res.data['message']);
}
}
static Future<LoadingState<MsgFeedAtMe>> msgFeedAtMe(
{int cursor = -1, int cursorTime = -1}) async {
var res = await Request().get(Api.msgFeedAt, queryParameters: {
'id': cursor == -1 ? null : cursor,
'at_time': cursorTime == -1 ? null : cursorTime,
'platform': 'android',
'mobi_app': 'android',
'build': '8350200',
});
if (res.data['code'] == 0) {
MsgFeedAtMe data = MsgFeedAtMe.fromJson(res.data['data']);
return LoadingState.success(data);
} else {
return LoadingState.error(res.data['message']);
}
}
static Future<LoadingState<MsgFeedLikeMe>> msgFeedLikeMe(
{int cursor = -1, int cursorTime = -1}) async {
var res = await Request().get(Api.msgFeedLike, queryParameters: {
'id': cursor == -1 ? null : cursor,
'like_time': cursorTime == -1 ? null : cursorTime,
'platform': 'android',
'mobi_app': 'android',
'build': '8350200',
});
if (res.data['code'] == 0) {
MsgFeedLikeMe data = MsgFeedLikeMe.fromJson(res.data['data']);
return LoadingState.success(data);
} else {
return LoadingState.error(res.data['message']);
}
}
static Future<LoadingState<List<SystemNotifyList>?>> msgFeedNotify(
{int cursor = -1, int pageSize = 20}) async {
var res = await Request().get(Api.msgSysNotify, queryParameters: {
'cursor': cursor == -1 ? null : cursor,
'page_size': pageSize,
});
if (res.data['code'] == 0) {
List<SystemNotifyList>? list = (res.data['data'] as List?)
?.map((e) => SystemNotifyList.fromJson(e))
.toList();
return LoadingState.success(list);
} else {
return LoadingState.error(res.data['message']);
}
}
static Future msgSysUpdateCursor(int cursor) async {
String csrf = Accounts.main.csrf;
var res = await Request().get(Api.msgSysUpdateCursor, queryParameters: {
'csrf': csrf,
'cursor': cursor,
});
if (res.data['code'] == 0) {
return {
'status': true,
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future msgFeedUnread() async {
var res = await Request().get(Api.msgFeedUnread);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {'status': false, 'msg': res.data['message']};
}
}
static Future createDynamic({
dynamic mid,
dynamic dynIdStr, // repost dyn
dynamic rid, // repost video
dynamic dynType,
dynamic rawText,
List? pics,
int? publishTime,
ReplyOption? replyOption,
int? privatePub,
}) async {
String csrf = Accounts.main.csrf;
var res = await Request().post(
Api.createDynamic,
queryParameters: {
'platform': 'web',
'csrf': csrf,
'x-bili-device-req-json': {"platform": "web", "device": "pc"},
'x-bili-web-req-json': {"spm_id": "333.999"},
},
data: {
"dyn_req": {
"content": {
"contents": [
{
"raw_text": rawText,
"type": 1,
"biz_id": "",
}
]
},
if (privatePub != null || replyOption != null || publishTime != null)
"option": {
if (privatePub != null) 'private_pub': privatePub,
if (publishTime != null) "timer_pub_time": publishTime,
if (replyOption == ReplyOption.close)
"close_comment": 1
else if (replyOption == ReplyOption.choose)
"up_choose_comment": 1,
},
"scene": rid != null
? 5
: dynIdStr != null
? 4
: pics != null
? 2
: 1,
if (pics != null) 'pics': pics,
"attach_card": null,
"upload_id":
"${rid != null ? 0 : mid}_${DateTime.now().millisecondsSinceEpoch ~/ 1000}_${Random().nextInt(9000) + 1000}",
"meta": {
"app_meta": {"from": "create.dynamic.web", "mobi_app": "web"}
}
},
if (dynIdStr != null || rid != null)
"web_repost_src": {
if (dynIdStr != null) "dyn_id_str": dynIdStr,
if (rid != null)
"revs_id": {
"dyn_type": dynType,
"rid": rid,
}
}
},
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future uploadImage({
required dynamic path,
required String bucket,
required String dir,
}) async {
var res = await Request().post(
Api.uploadImage,
data: FormData.fromMap({
'bucket': bucket,
'file': await MultipartFile.fromFile(path),
'dir': dir,
'csrf': Accounts.main.csrf,
}),
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future uploadBfs({
dynamic path,
String? category,
String? biz,
CancelToken? cancelToken,
}) async {
final file = await MultipartFile.fromFile(path);
Map<String, dynamic> data = {
'file_up': file,
if (category != null) 'category': category,
if (biz != null) 'biz': biz,
'csrf': Accounts.main.csrf,
};
var res = await Request().post(
Api.uploadBfs,
data: FormData.fromMap(data),
cancelToken: cancelToken,
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data']..['img_size'] = file.length,
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future createTextDynamic(
dynamic content,
) async {
String csrf = Accounts.main.csrf;
Map<String, dynamic> data = await WbiSign.makSign({
'dynamic_id': 0,
'type': 4,
'rid': 0,
'content': content,
'csrf_token': csrf,
'csrf': csrf,
});
var res = await Request().post(
HttpString.tUrl + Api.createTextDynamic,
data: FormData.fromMap(data),
);
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future removeDynamic(
dynamic dynamicId,
) async {
String csrf = Accounts.main.csrf;
Map<String, dynamic> data = await WbiSign.makSign({
'dynamic_id': dynamicId,
'csrf_token': csrf,
'csrf': csrf,
});
var res = await Request().post(
HttpString.tUrl + Api.removeDynamic,
data: FormData.fromMap(data),
);
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future removeMsg(
dynamic talkerId,
) async {
String csrf = Accounts.main.csrf;
Map<String, dynamic> data = await WbiSign.makSign({
'talker_id': talkerId,
'session_type': 1,
'build': 0,
'mobi_app': 'web',
'csrf_token': csrf,
'csrf': csrf
});
var res = await Request().post(
HttpString.tUrl + Api.removeMsg,
data: FormData.fromMap(data),
);
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {'status': false, 'msg': res.data['message']};
}
}
static Future delMsgfeed(
int tp,
dynamic id,
) async {
String csrf = Accounts.main.csrf;
var res = await Request().post(
Api.delMsgfeed,
data: {
'tp': tp,
'id': id,
'build': 0,
'mobi_app': 'web',
'csrf_token': csrf,
'csrf': csrf,
},
options: Options(
contentType: Headers.formUrlEncodedContentType,
),
);
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future delSysMsg(
dynamic id,
) async {
String csrf = Accounts.main.csrf;
var res = await Request().post(
HttpString.messageBaseUrl + Api.delSysMsg,
queryParameters: {
'mobi_app': 'android',
'csrf': csrf,
},
data: {
'csrf': csrf,
'ids': [id],
'station_ids': [],
'type': 4,
'mobi_app': 'android',
},
);
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future setTop({
required dynamic talkerId,
required int opType,
}) async {
String csrf = Accounts.main.csrf;
Map<String, dynamic> data = await WbiSign.makSign({
'talker_id': talkerId,
'session_type': 1,
'op_type': opType,
'build': 0,
'mobi_app': 'web',
'csrf_token': csrf,
'csrf': csrf
});
var res = await Request()
.post(HttpString.tUrl + Api.setTop, data: FormData.fromMap(data));
if (res.data['code'] == 0) {
return {'status': true};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
// 会话列表
static Future<LoadingState<List<SessionList>?>> sessionList(
{int? endTs}) async {
final params = await WbiSign.makSign({
'session_type': 1,
'group_fold': 1,
'unfollow_fold': 0,
'sort_rule': 2,
'build': 0,
'mobi_app': 'web',
if (endTs != null) 'end_ts': endTs,
});
var res = await Request().get(Api.sessionList, queryParameters: params);
if (res.data['code'] == 0) {
try {
return LoadingState.success(
SessionDataModel.fromJson(res.data['data']).sessionList,
);
} catch (err) {
return LoadingState.error(err.toString());
}
} else {
return LoadingState.error(res.data['message']);
}
}
static Future accountList(uids) async {
var res = await Request().get(Api.sessionAccountList, queryParameters: {
'uids': uids,
'build': 0,
'mobi_app': 'web',
});
if (res.data['code'] == 0) {
try {
return {
'status': true,
'data': res.data['data']
.map<AccountListModel>((e) => AccountListModel.fromJson(e))
.toList(),
};
} catch (err) {
debugPrint('err🔟: $err');
}
} else {
return {'status': false, 'msg': res.data['message']};
}
}
static Future<LoadingState<SessionMsgDataModel>> sessionMsg(
{int? talkerId}) async {
Map params = await WbiSign.makSign({
'talker_id': talkerId,
'session_type': 1,
'size': 20,
'sender_device_id': 1,
'build': 0,
'mobi_app': 'web',
});
var res = await Request().get(Api.sessionMsg, queryParameters: params);
if (res.data['code'] == 0) {
try {
return LoadingState.success(
SessionMsgDataModel.fromJson(res.data['data']));
} catch (err) {
return LoadingState.error(err.toString());
}
} else {
return LoadingState.error(res.data['message']);
}
}
// 消息标记已读
static Future ackSessionMsg({
int? talkerId,
int? ackSeqno,
}) async {
String csrf = Accounts.main.csrf;
Map params = await WbiSign.makSign({
'talker_id': talkerId,
'session_type': 1,
'ack_seqno': ackSeqno,
'build': 0,
'mobi_app': 'web',
'csrf_token': csrf,
'csrf': csrf
});
var res = await Request().get(Api.ackSessionMsg, queryParameters: params);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'msg': "message: ${res.data['message']},"
" msg: ${res.data['msg']},"
" code: ${res.data['code']}",
};
}
}
// 发送私信
static Future sendMsg({
int? senderUid,
int? receiverId,
int? receiverType,
int? msgType,
dynamic content,
}) async {
String csrf = Accounts.main.csrf;
Map<String, dynamic> base = {
'msg[sender_uid]': senderUid,
'msg[receiver_id]': receiverId,
'msg[receiver_type]': receiverType ?? 1,
'msg[msg_type]': msgType ?? 1,
'msg[msg_status]': 0,
'msg[dev_id]': getDevId(),
'msg[timestamp]': DateTime.now().millisecondsSinceEpoch ~/ 1000,
'msg[new_face_version]': 1,
'msg[content]': content,
'from_firework': 0,
'build': 0,
'mobi_app': 'web',
'csrf_token': csrf,
'csrf': csrf,
};
Map<String, dynamic> params = await WbiSign.makSign(base);
var res = await Request().post(Api.sendMsg,
queryParameters: <String, dynamic>{
'w_sender_uid': params['msg[sender_uid]'],
'w_receiver_id': params['msg[receiver_id]'],
'w_dev_id': params['msg[dev_id]'],
'w_rid': params['w_rid'],
'wts': params['wts'],
},
data: FormData.fromMap(base));
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {'status': false, 'msg': res.data['message']};
}
}
static String getDevId() {
return Uuid().v4();
// final List<String> b = [
// '0',
// '1',
// '2',
// '3',
// '4',
// '5',
// '6',
// '7',
// '8',
// '9',
// 'A',
// 'B',
// 'C',
// 'D',
// 'E',
// 'F'
// ];
// final List<String> s = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".split('');
// for (int i = 0; i < s.length; i++) {
// if ('-' == s[i] || '4' == s[i]) {
// continue;
// }
// final int randomInt = Random().nextInt(16);
// if ('x' == s[i]) {
// s[i] = b[randomInt];
// } else {
// s[i] = b[3 & randomInt | 8];
// }
// }
// return s.join();
}
}