mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 16:18:22 +08:00
@@ -214,6 +214,8 @@ class Api {
|
|||||||
// https://api.bilibili.com/x/polymer/web-dynamic/v1/portal
|
// https://api.bilibili.com/x/polymer/web-dynamic/v1/portal
|
||||||
static const String followUp = '/x/polymer/web-dynamic/v1/portal';
|
static const String followUp = '/x/polymer/web-dynamic/v1/portal';
|
||||||
|
|
||||||
|
static const String dynUplist = '/x/polymer/web-dynamic/v1/uplist';
|
||||||
|
|
||||||
// 关注的up动态
|
// 关注的up动态
|
||||||
// https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all
|
// https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all
|
||||||
// https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&page=1&features=itemOpusStyle
|
// https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?timezone_offset=-480&type=video&page=1&features=itemOpusStyle
|
||||||
|
|||||||
@@ -68,7 +68,13 @@ class DynamicsHttp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<LoadingState<FollowUpModel>> followUp() async {
|
static Future<LoadingState<FollowUpModel>> followUp() async {
|
||||||
var res = await Request().get(Api.followUp);
|
var res = await Request().get(
|
||||||
|
Api.followUp,
|
||||||
|
queryParameters: {
|
||||||
|
'up_list_more': 1,
|
||||||
|
'web_location': 333.1365,
|
||||||
|
},
|
||||||
|
);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return Success(FollowUpModel.fromJson(res.data['data']));
|
return Success(FollowUpModel.fromJson(res.data['data']));
|
||||||
} else {
|
} else {
|
||||||
@@ -76,6 +82,22 @@ class DynamicsHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<LoadingState<DynUpList>> dynUpList(String? offset) async {
|
||||||
|
var res = await Request().get(
|
||||||
|
Api.dynUplist,
|
||||||
|
queryParameters: {
|
||||||
|
'offset': offset,
|
||||||
|
'platform': 'web',
|
||||||
|
'web_location': 333.1365,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return Success(DynUpList.fromJson(res.data['data']));
|
||||||
|
} else {
|
||||||
|
return Error(res.data['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 动态点赞
|
// 动态点赞
|
||||||
// static Future likeDynamic({
|
// static Future likeDynamic({
|
||||||
// required String? dynamicId,
|
// required String? dynamicId,
|
||||||
|
|||||||
@@ -6,16 +6,34 @@ class FollowUpModel {
|
|||||||
|
|
||||||
LiveUsers? liveUsers;
|
LiveUsers? liveUsers;
|
||||||
late List<UpItem> upList;
|
late List<UpItem> upList;
|
||||||
|
bool? hasMore;
|
||||||
|
String? offset;
|
||||||
|
|
||||||
FollowUpModel.fromJson(Map<String, dynamic> json) {
|
FollowUpModel.fromJson(Map<String, dynamic> json) {
|
||||||
liveUsers = json['live_users'] != null
|
liveUsers = json['live_users'] != null
|
||||||
? LiveUsers.fromJson(json['live_users'])
|
? LiveUsers.fromJson(json['live_users'])
|
||||||
: null;
|
: null;
|
||||||
upList =
|
upList =
|
||||||
(json['up_list'] as List?)
|
(json['up_list']?['items'] as List?)
|
||||||
?.map<UpItem>((e) => UpItem.fromJson(e))
|
?.map<UpItem>((e) => UpItem.fromJson(e))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
<UpItem>[];
|
<UpItem>[];
|
||||||
|
hasMore = json['up_list']?['has_more'];
|
||||||
|
offset = json['up_list']?['offset'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DynUpList {
|
||||||
|
List<UpItem>? upList;
|
||||||
|
bool? hasMore;
|
||||||
|
String? offset;
|
||||||
|
|
||||||
|
DynUpList.fromJson(Map<String, dynamic> json) {
|
||||||
|
upList = (json['items'] as List?)
|
||||||
|
?.map<UpItem>((e) => UpItem.fromJson(e))
|
||||||
|
.toList();
|
||||||
|
hasMore = json['has_more'];
|
||||||
|
offset = json['offset'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,27 +55,45 @@ class DynamicsController extends GetxController
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
if (_showAllUp) {
|
|
||||||
scrollController.addListener(listener);
|
|
||||||
}
|
|
||||||
queryFollowUp();
|
queryFollowUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void listener() {
|
void onLoadMoreUp() {
|
||||||
if (scrollController.position.pixels >=
|
if (_showAllUp) {
|
||||||
scrollController.position.maxScrollExtent - 300) {
|
|
||||||
queryAllUp();
|
queryAllUp();
|
||||||
|
} else {
|
||||||
|
queryUpList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> queryAllUp() async {
|
Future<void> queryUpList() async {
|
||||||
if (isQuerying) return;
|
if (isQuerying || _upEnd) return;
|
||||||
isQuerying = true;
|
isQuerying = true;
|
||||||
if (_upEnd) {
|
|
||||||
isQuerying = false;
|
final res = await DynamicsHttp.dynUpList(upState.value.data.offset);
|
||||||
return;
|
|
||||||
|
if (res.isSuccess) {
|
||||||
|
final data = res.data;
|
||||||
|
if (data.hasMore == false || data.offset.isNullOrEmpty) {
|
||||||
|
_upEnd = true;
|
||||||
|
}
|
||||||
|
final upData = upState.value.data
|
||||||
|
..hasMore = data.hasMore
|
||||||
|
..offset = data.offset;
|
||||||
|
final list = data.upList;
|
||||||
|
if (list != null && list.isNotEmpty) {
|
||||||
|
upData.upList.addAll(list);
|
||||||
|
upState.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isQuerying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> queryAllUp() async {
|
||||||
|
if (isQuerying || _upEnd) return;
|
||||||
|
isQuerying = true;
|
||||||
|
|
||||||
final res = await FollowHttp.followings(
|
final res = await FollowHttp.followings(
|
||||||
vmid: accountService.mid,
|
vmid: accountService.mid,
|
||||||
pn: _upPage,
|
pn: _upPage,
|
||||||
@@ -110,6 +128,10 @@ class DynamicsController extends GetxController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset
|
||||||
|
_upEnd = false;
|
||||||
|
if (_showAllUp) _upPage = 1;
|
||||||
|
|
||||||
final res = await Future.wait([
|
final res = await Future.wait([
|
||||||
DynamicsHttp.followUp(),
|
DynamicsHttp.followUp(),
|
||||||
if (_showAllUp)
|
if (_showAllUp)
|
||||||
@@ -138,6 +160,11 @@ class DynamicsController extends GetxController
|
|||||||
_cacheUpList = List<UpItem>.from(list);
|
_cacheUpList = List<UpItem>.from(list);
|
||||||
list.addAll(list1..removeWhere(list.contains));
|
list.addAll(list1..removeWhere(list.contains));
|
||||||
}
|
}
|
||||||
|
if (!_showAllUp) {
|
||||||
|
if (data.hasMore == false || data.offset.isNullOrEmpty) {
|
||||||
|
_upEnd = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
upState.value = Success(data);
|
upState.value = Success(data);
|
||||||
} else {
|
} else {
|
||||||
upState.value = const Error(null);
|
upState.value = const Error(null);
|
||||||
@@ -201,9 +228,7 @@ class DynamicsController extends GetxController
|
|||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
tabController.dispose();
|
tabController.dispose();
|
||||||
scrollController
|
scrollController.dispose();
|
||||||
..removeListener(listener)
|
|
||||||
..dispose();
|
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,16 @@ class _DynamicsPageState extends State<DynamicsPage>
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: isTop ? null : 64,
|
width: isTop ? null : 64,
|
||||||
height: isTop ? 76 : null,
|
height: isTop ? 76 : null,
|
||||||
child: Obx(() => _buildUpPanel(_dynamicsController.upState.value)),
|
child: NotificationListener<ScrollEndNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final metrics = notification.metrics;
|
||||||
|
if (metrics.pixels >= metrics.maxScrollExtent - 300) {
|
||||||
|
_dynamicsController.onLoadMoreUp();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: Obx(() => _buildUpPanel(_dynamicsController.upState.value)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,43 +26,22 @@ class _FavSortPageState extends State<FavSortPage> {
|
|||||||
);
|
);
|
||||||
List<String> sort = <String>[];
|
List<String> sort = <String>[];
|
||||||
|
|
||||||
final ScrollController _scrollController = ScrollController();
|
void onLoadMore() {
|
||||||
|
|
||||||
void listener() {
|
|
||||||
if (_favDetailController.isEnd) {
|
if (_favDetailController.isEnd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_scrollController.position.pixels >=
|
_favDetailController.onLoadMore().whenComplete(() {
|
||||||
_scrollController.position.maxScrollExtent - 200) {
|
try {
|
||||||
_favDetailController.onLoadMore().whenComplete(() {
|
if (_favDetailController.loadingState.value.isSuccess) {
|
||||||
try {
|
List<FavDetailItemModel> list =
|
||||||
if (_favDetailController.loadingState.value.isSuccess) {
|
_favDetailController.loadingState.value.data!;
|
||||||
List<FavDetailItemModel> list =
|
sortList.addAll(list.sublist(sortList.length));
|
||||||
_favDetailController.loadingState.value.data!;
|
if (mounted) {
|
||||||
sortList.addAll(list.sublist(sortList.length));
|
setState(() {});
|
||||||
if (mounted) {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
}
|
||||||
});
|
} catch (_) {}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
if (!_favDetailController.isEnd) {
|
|
||||||
_scrollController.addListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_scrollController
|
|
||||||
..removeListener(listener)
|
|
||||||
..dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -119,9 +98,8 @@ class _FavSortPageState extends State<FavSortPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget get _buildBody {
|
Widget get _buildBody {
|
||||||
return ReorderableListView.builder(
|
final child = ReorderableListView.builder(
|
||||||
key: _key,
|
key: _key,
|
||||||
scrollController: _scrollController,
|
|
||||||
onReorder: onReorder,
|
onReorder: onReorder,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
padding:
|
padding:
|
||||||
@@ -137,5 +115,18 @@ class _FavSortPageState extends State<FavSortPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
if (!_favDetailController.isEnd) {
|
||||||
|
return NotificationListener<ScrollEndNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
final metrics = notification.metrics;
|
||||||
|
if (metrics.pixels >= metrics.maxScrollExtent - 300) {
|
||||||
|
onLoadMore();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,11 +278,10 @@ class LiveRoomController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void listener() {
|
void listener() {
|
||||||
if (scrollController.position.userScrollDirection ==
|
final userScrollDirection = scrollController.position.userScrollDirection;
|
||||||
ScrollDirection.forward) {
|
if (userScrollDirection == ScrollDirection.forward) {
|
||||||
disableAutoScroll.value = true;
|
disableAutoScroll.value = true;
|
||||||
} else if (scrollController.position.userScrollDirection ==
|
} else if (userScrollDirection == ScrollDirection.reverse) {
|
||||||
ScrollDirection.reverse) {
|
|
||||||
final pos = scrollController.position;
|
final pos = scrollController.position;
|
||||||
if (pos.maxScrollExtent - pos.pixels <= 100) {
|
if (pos.maxScrollExtent - pos.pixels <= 100) {
|
||||||
disableAutoScroll.value = false;
|
disableAutoScroll.value = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user