mod: reply api

This commit is contained in:
guozhigq
2024-10-17 23:24:45 +08:00
parent 163b8a3013
commit b60e693e2e
6 changed files with 123 additions and 46 deletions

View File

@ -104,7 +104,7 @@ class Api {
// 评论列表 // 评论列表
// https://api.bilibili.com/x/v2/reply/main?csrf=6e22efc1a47225ea25f901f922b5cfdd&mode=3&oid=254175381&pagination_str=%7B%22offset%22:%22%22%7D&plat=1&seek_rpid=0&type=11 // https://api.bilibili.com/x/v2/reply/main?csrf=6e22efc1a47225ea25f901f922b5cfdd&mode=3&oid=254175381&pagination_str=%7B%22offset%22:%22%22%7D&plat=1&seek_rpid=0&type=11
static const String replyList = '/x/v2/reply'; static const String replyList = '/x/v2/reply/main';
// 楼中楼 // 楼中楼
static const String replyReplyList = '/x/v2/reply/reply'; static const String replyReplyList = '/x/v2/reply/reply';

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import '../models/video/reply/data.dart'; import '../models/video/reply/data.dart';
import '../models/video/reply/emote.dart'; import '../models/video/reply/emote.dart';
import 'api.dart'; import 'api.dart';
@ -6,17 +8,16 @@ import 'init.dart';
class ReplyHttp { class ReplyHttp {
static Future replyList({ static Future replyList({
required int oid, required int oid,
required int pageNum, required String nextOffset,
required int type, required int type,
int? ps, int? ps,
int sort = 1, int sort = 1,
}) async { }) async {
var res = await Request().get(Api.replyList, data: { var res = await Request().get(Api.replyList, data: {
'oid': oid, 'oid': oid,
'pn': pageNum,
'type': type, 'type': type,
'sort': sort, 'pagination_str': jsonEncode({'offset': nextOffset}),
'ps': ps ?? 20 'mode': sort + 2,
}); });
if (res.data['code'] == 0) { if (res.data['code'] == 0) {
return { return {
@ -52,19 +53,13 @@ class ReplyHttp {
if (res.data['code'] == 0) { if (res.data['code'] == 0) {
return { return {
'status': true, 'status': true,
'data': ReplyData.fromJson(res.data['data']), 'data': ReplyReplyData.fromJson(res.data['data']),
}; };
} else { } else {
Map errMap = {
-400: '请求错误',
-404: '无此项',
12002: '评论区已关闭',
12009: '评论主体的type不合法',
};
return { return {
'status': false, 'status': false,
'date': [], 'date': [],
'msg': errMap[res.data['code']] ?? '请求异常', 'msg': res.data['message'],
}; };
} }
} }

View File

@ -6,6 +6,98 @@ import 'upper.dart';
class ReplyData { class ReplyData {
ReplyData({ ReplyData({
this.cursor,
this.config,
this.replies,
this.topReplies,
this.upper,
});
ReplyCursor? cursor;
ReplyConfig? config;
late List<ReplyItemModel>? replies;
late List<ReplyItemModel>? topReplies;
ReplyUpper? upper;
ReplyData.fromJson(Map<String, dynamic> json) {
cursor = ReplyCursor.fromJson(json['cursor']);
config = ReplyConfig.fromJson(json['config']);
replies = json['replies'] != null
? json['replies']
.map<ReplyItemModel>(
(item) => ReplyItemModel.fromJson(item, json['upper']['mid']))
.toList()
: [];
topReplies = json['top_replies'] != null
? json['top_replies']
.map<ReplyItemModel>((item) => ReplyItemModel.fromJson(
item, json['upper']['mid'],
isTopStatus: true))
.toList()
: [];
upper = ReplyUpper.fromJson(json['upper']);
}
}
class ReplyCursor {
ReplyCursor({
this.isBegin,
this.prev,
this.next,
this.isEnd,
this.mode,
this.modeText,
this.allCount,
this.supportMode,
this.name,
this.paginationReply,
this.sessionId,
});
bool? isBegin;
int? prev;
int? next;
bool? isEnd;
int? mode;
String? modeText;
int? allCount;
List<int>? supportMode;
String? name;
PaginationReply? paginationReply;
String? sessionId;
ReplyCursor.fromJson(Map<String, dynamic> json) {
isBegin = json['is_begin'];
prev = json['prev'];
next = json['next'];
isEnd = json['is_end'];
mode = json['mode'];
modeText = json['mode_text'];
allCount = json['all_count'];
supportMode = json['support_mode'].cast<int>();
name = json['name'];
paginationReply = json['pagination_reply'] != null
? PaginationReply.fromJson(json['pagination_reply'])
: null;
sessionId = json['session_id'];
}
}
class PaginationReply {
PaginationReply({
this.nextOffset,
this.prevOffset,
});
String? nextOffset;
String? prevOffset;
PaginationReply.fromJson(Map<String, dynamic> json) {
nextOffset = json['next_offset'];
prevOffset = json['prev_offset'];
}
}
class ReplyReplyData {
ReplyReplyData({
this.page, this.page,
this.config, this.config,
this.replies, this.replies,
@ -19,7 +111,7 @@ class ReplyData {
late List<ReplyItemModel>? topReplies; late List<ReplyItemModel>? topReplies;
ReplyUpper? upper; ReplyUpper? upper;
ReplyData.fromJson(Map<String, dynamic> json) { ReplyReplyData.fromJson(Map<String, dynamic> json) {
page = ReplyPage.fromJson(json['page']); page = ReplyPage.fromJson(json['page']);
config = ReplyConfig.fromJson(json['config']); config = ReplyConfig.fromJson(json['config']);
replies = json['replies'] != null replies = json['replies'] != null

View File

@ -14,7 +14,7 @@ class DynamicDetailController extends GetxController {
int? type; int? type;
dynamic item; dynamic item;
int? floor; int? floor;
int currentPage = 0; String nextOffset = "";
bool isLoadingMore = false; bool isLoadingMore = false;
RxString noMore = ''.obs; RxString noMore = ''.obs;
RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs; RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs;
@ -49,25 +49,25 @@ class DynamicDetailController extends GetxController {
Future queryReplyList({reqType = 'init'}) async { Future queryReplyList({reqType = 'init'}) async {
if (reqType == 'init') { if (reqType == 'init') {
currentPage = 0; nextOffset = "";
} }
var res = await ReplyHttp.replyList( var res = await ReplyHttp.replyList(
oid: oid!, oid: oid!,
pageNum: currentPage + 1, nextOffset: nextOffset,
type: type!, type: type!,
sort: _sortType.index, sort: _sortType.index,
); );
if (res['status']) { if (res['status']) {
List<ReplyItemModel> replies = res['data'].replies; List<ReplyItemModel> replies = res['data'].replies;
acount.value = res['data'].page.acount; acount.value = res['data'].cursor.allCount;
nextOffset = res['data'].cursor.paginationReply.nextOffset ?? "";
if (replies.isNotEmpty) { if (replies.isNotEmpty) {
currentPage++;
noMore.value = '加载中...'; noMore.value = '加载中...';
if (replies.length < 20) { if (res['data'].cursor.isEnd == true) {
noMore.value = '没有更多了'; noMore.value = '没有更多了';
} }
} else { } else {
noMore.value = currentPage == 0 ? '还没有评论' : '没有更多了'; noMore.value = nextOffset == "" ? '还没有评论' : '没有更多了';
} }
if (reqType == 'init') { if (reqType == 'init') {
// 添加置顶回复 // 添加置顶回复

View File

@ -15,7 +15,7 @@ class HtmlRenderController extends GetxController {
RxInt oid = (-1).obs; RxInt oid = (-1).obs;
late Map response; late Map response;
int? floor; int? floor;
int currentPage = 0; String nextOffset = "";
bool isLoadingMore = false; bool isLoadingMore = false;
RxString noMore = ''.obs; RxString noMore = ''.obs;
RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs; RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs;
@ -52,21 +52,21 @@ class HtmlRenderController extends GetxController {
Future queryReplyList({reqType = 'init'}) async { Future queryReplyList({reqType = 'init'}) async {
var res = await ReplyHttp.replyList( var res = await ReplyHttp.replyList(
oid: oid.value, oid: oid.value,
pageNum: currentPage + 1, nextOffset: nextOffset,
type: type, type: type,
sort: _sortType.index, sort: _sortType.index,
); );
if (res['status']) { if (res['status']) {
List<ReplyItemModel> replies = res['data'].replies; List<ReplyItemModel> replies = res['data'].replies;
acount.value = res['data'].page.acount; acount.value = res['data'].cursor.allCount;
nextOffset = res['data'].cursor.paginationReply.nextOffset ?? "";
if (replies.isNotEmpty) { if (replies.isNotEmpty) {
currentPage++;
noMore.value = '加载中...'; noMore.value = '加载中...';
if (replies.length < 20) { if (res['data'].cursor.isEnd == true) {
noMore.value = '没有更多了'; noMore.value = '没有更多了';
} }
} else { } else {
noMore.value = currentPage == 0 ? '还没有评论' : '没有更多了'; noMore.value = nextOffset == "" ? '还没有评论' : '没有更多了';
} }
if (reqType == 'init') { if (reqType == 'init') {
// 添加置顶回复 // 添加置顶回复
@ -102,7 +102,7 @@ class HtmlRenderController extends GetxController {
} }
sortTypeTitle.value = _sortType.titles; sortTypeTitle.value = _sortType.titles;
sortTypeLabel.value = _sortType.labels; sortTypeLabel.value = _sortType.labels;
currentPage = 0; nextOffset = "";
replyList.clear(); replyList.clear();
queryReplyList(reqType: 'init'); queryReplyList(reqType: 'init');
} }

View File

@ -21,11 +21,9 @@ class VideoReplyController extends GetxController {
// rpid 请求楼中楼回复 // rpid 请求楼中楼回复
String? rpid; String? rpid;
RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs; RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs;
// 当前页 String nextOffset = "";
int currentPage = 0;
bool isLoadingMore = false; bool isLoadingMore = false;
RxString noMore = ''.obs; RxString noMore = ''.obs;
int ps = 20;
RxInt count = 0.obs; RxInt count = 0.obs;
// 当前回复的回复 // 当前回复的回复
ReplyItemModel? currentReplyItem; ReplyItemModel? currentReplyItem;
@ -57,7 +55,7 @@ class VideoReplyController extends GetxController {
} }
isLoadingMore = true; isLoadingMore = true;
if (type == 'init') { if (type == 'init') {
currentPage = 0; nextOffset = '';
noMore.value = ''; noMore.value = '';
} }
if (noMore.value == '没有更多了') { if (noMore.value == '没有更多了') {
@ -66,28 +64,20 @@ class VideoReplyController extends GetxController {
} }
final res = await ReplyHttp.replyList( final res = await ReplyHttp.replyList(
oid: aid!, oid: aid!,
pageNum: currentPage + 1, nextOffset: nextOffset,
ps: ps,
type: ReplyType.video.index, type: ReplyType.video.index,
sort: _sortType.index, sort: _sortType.index,
); );
if (res['status']) { if (res['status']) {
final List<ReplyItemModel> replies = res['data'].replies; final List<ReplyItemModel> replies = res['data'].replies;
nextOffset = res['data'].cursor.paginationReply.nextOffset ?? "";
if (replies.isNotEmpty) { if (replies.isNotEmpty) {
noMore.value = '加载中...'; noMore.value = '加载中...';
if (res['data'].cursor.isEnd == true) {
/// 第一页回复数小于20
if (currentPage == 0 && replies.length < 18) {
noMore.value = '没有更多了';
}
currentPage++;
if (replyList.length == res['data'].page.acount) {
noMore.value = '没有更多了'; noMore.value = '没有更多了';
} }
} else { } else {
// 未登录状态replies可能返回null noMore.value = nextOffset == "" ? '还没有评论' : '没有更多了';
noMore.value = currentPage == 0 ? '还没有评论' : '没有更多了';
} }
if (type == 'init') { if (type == 'init') {
// 添加置顶回复 // 添加置顶回复
@ -99,7 +89,7 @@ class VideoReplyController extends GetxController {
} }
} }
replies.insertAll(0, res['data'].topReplies); replies.insertAll(0, res['data'].topReplies);
count.value = res['data'].page.count; count.value = res['data'].cursor.allCount;
replyList.value = replies; replyList.value = replies;
} else { } else {
replyList.addAll(replies); replyList.addAll(replies);
@ -130,7 +120,7 @@ class VideoReplyController extends GetxController {
} }
sortTypeTitle.value = _sortType.titles; sortTypeTitle.value = _sortType.titles;
sortTypeLabel.value = _sortType.labels; sortTypeLabel.value = _sortType.labels;
currentPage = 0; nextOffset = "";
noMore.value = ''; noMore.value = '';
replyList.clear(); replyList.clear();
queryReplyList(type: 'init'); queryReplyList(type: 'init');