mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-24 20:35:50 +08:00
refa query follow up
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -5,7 +5,7 @@ import 'package:PiliPlus/http/follow.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
|
||||
import 'package:PiliPlus/models/dynamics/up.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/pages/common/common_controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_tab/controller.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
@@ -13,25 +13,30 @@ import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class DynamicsController extends GetxController
|
||||
with GetSingleTickerProviderStateMixin, ScrollOrRefreshMixin {
|
||||
@override
|
||||
final ScrollController scrollController = ScrollController();
|
||||
String? offset = '';
|
||||
Rx<FollowUpModel> upData = FollowUpModel().obs;
|
||||
// 默认获取全部动态
|
||||
RxInt mid = (-1).obs;
|
||||
late TabController tabController;
|
||||
Set<int> tempBannedList = <int>{};
|
||||
List<UpItem> hasUpdatedUps = <UpItem>[];
|
||||
int allFollowedUpsPage = 1;
|
||||
int allFollowedUpsTotal = 0;
|
||||
late final TabController tabController = TabController(
|
||||
length: DynamicsTabType.values.length,
|
||||
vsync: this,
|
||||
initialIndex: Pref.defaultDynamicType,
|
||||
);
|
||||
|
||||
late final RxInt mid = (-1).obs;
|
||||
late int currentMid = -1;
|
||||
late bool showLiveItems = Pref.expandDynLivePanel;
|
||||
|
||||
Set<int> tempBannedList = <int>{};
|
||||
|
||||
final Rx<LoadingState<FollowUpModel>> upState =
|
||||
LoadingState<FollowUpModel>.loading().obs;
|
||||
late int _upPage = 1;
|
||||
late bool _upEnd = false;
|
||||
List<UpItem>? _cacheUpList;
|
||||
late final showAllUp = Pref.dynamicsShowAllFollowedUp;
|
||||
late bool showLiveUp = Pref.expandDynLivePanel;
|
||||
|
||||
final upPanelPosition = Pref.upPanelPosition;
|
||||
|
||||
@@ -50,114 +55,98 @@ class DynamicsController extends GetxController
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
tabController = TabController(
|
||||
length: DynamicsTabType.values.length,
|
||||
vsync: this,
|
||||
initialIndex: Pref.defaultDynamicType,
|
||||
);
|
||||
|
||||
if (showAllUp) {
|
||||
scrollController.addListener(listener);
|
||||
}
|
||||
queryFollowUp();
|
||||
}
|
||||
|
||||
void listener() {
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 300) {
|
||||
EasyThrottle.throttle(
|
||||
'following',
|
||||
const Duration(seconds: 1),
|
||||
queryFollowing2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> queryFollowing2() async {
|
||||
if (upData.value.upList != null &&
|
||||
upData.value.upList!.length >= allFollowedUpsTotal) {
|
||||
if (isQuerying) return;
|
||||
isQuerying = true;
|
||||
if (_upEnd) {
|
||||
isQuerying = false;
|
||||
return;
|
||||
}
|
||||
var res = await FollowHttp.followings(
|
||||
|
||||
final res = await FollowHttp.followings(
|
||||
vmid: accountService.mid,
|
||||
pn: allFollowedUpsPage,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
);
|
||||
|
||||
if (res.isSuccess) {
|
||||
upData.value.upList ??= <UpItem>[];
|
||||
upData.value.upList!.addAll(
|
||||
res.data.list!
|
||||
.where((e) => hasUpdatedUps.every((e1) => e.mid != e1.mid))
|
||||
.map(
|
||||
(FollowItemModel e) => UpItem(
|
||||
face: e.face,
|
||||
mid: e.mid,
|
||||
uname: e.uname,
|
||||
hasUpdate: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
allFollowedUpsPage += 1;
|
||||
allFollowedUpsTotal = res.data.total!;
|
||||
upData.refresh();
|
||||
} else {
|
||||
res.toast();
|
||||
_upPage++;
|
||||
final list = res.data.list;
|
||||
if (list.isEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
upState
|
||||
..value.data.upList.addAll(
|
||||
list..removeWhere((e) => _cacheUpList?.contains(e) == true),
|
||||
)
|
||||
..refresh();
|
||||
}
|
||||
|
||||
isQuerying = false;
|
||||
}
|
||||
|
||||
late bool isQuerying = false;
|
||||
Future<void> queryFollowUp() async {
|
||||
if (isQuerying) return;
|
||||
isQuerying = true;
|
||||
|
||||
if (!accountService.isLogin.value) {
|
||||
upData
|
||||
..value.errMsg = '账号未登录'
|
||||
..refresh();
|
||||
upState.value = const Error(null);
|
||||
isQuerying = false;
|
||||
return;
|
||||
}
|
||||
upData.value.errMsg = null;
|
||||
if (Pref.dynamicsShowAllFollowedUp) {
|
||||
allFollowedUpsPage = 1;
|
||||
final f1 = DynamicsHttp.followUp();
|
||||
final f2 = FollowHttp.followings(
|
||||
vmid: accountService.mid,
|
||||
pn: allFollowedUpsPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
);
|
||||
final res0 = await f1;
|
||||
if (!res0.isSuccess) {
|
||||
SmartDialog.showToast("获取关注动态失败:$res0");
|
||||
upData
|
||||
..value.errMsg = (res0 as Error).errMsg
|
||||
..refresh();
|
||||
} else {
|
||||
upData
|
||||
..value.liveUsers = res0.data.liveUsers
|
||||
..refresh();
|
||||
hasUpdatedUps = res0.data.upList!;
|
||||
}
|
||||
List<UpItem> allFollowedUps = <UpItem>[];
|
||||
final res1 = await f2;
|
||||
if (!res1.isSuccess) {
|
||||
SmartDialog.showToast("获取关注列表失败:$res1");
|
||||
} else {
|
||||
allFollowedUps = res1.data.list!
|
||||
.where((e) => hasUpdatedUps.every((e1) => e.mid != e1.mid))
|
||||
.map(
|
||||
(e) => UpItem(
|
||||
face: e.face,
|
||||
mid: e.mid,
|
||||
uname: e.uname,
|
||||
hasUpdate: false,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
allFollowedUpsPage += 1;
|
||||
allFollowedUpsTotal = res1.data.total!;
|
||||
}
|
||||
upData
|
||||
..value.upList = hasUpdatedUps + allFollowedUps
|
||||
..refresh();
|
||||
} else {
|
||||
var res = await DynamicsHttp.followUp();
|
||||
if (res.isSuccess) {
|
||||
upData.value = res.data;
|
||||
if (upData.value.upList.isNullOrEmpty) {
|
||||
mid.value = -1;
|
||||
|
||||
final res = await Future.wait([
|
||||
DynamicsHttp.followUp(),
|
||||
if (showAllUp)
|
||||
FollowHttp.followings(
|
||||
vmid: accountService.mid,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
),
|
||||
]);
|
||||
|
||||
final first = res.first;
|
||||
final second = res.getOrNull(1);
|
||||
if (first.isSuccess) {
|
||||
FollowUpModel data = first.data as FollowUpModel;
|
||||
if (second != null && second.isSuccess) {
|
||||
_cacheUpList = List<UpItem>.from(data.upList);
|
||||
FollowData data1 = second.data as FollowData;
|
||||
final list1 = data1.list;
|
||||
|
||||
_upPage++;
|
||||
if (list1.isEmpty || list1.length >= (data1.total ?? 0)) {
|
||||
_upEnd = true;
|
||||
}
|
||||
} else {
|
||||
upData
|
||||
..value.errMsg = (res as Error).errMsg
|
||||
..refresh();
|
||||
|
||||
final list = data.upList;
|
||||
list.addAll(list1..removeWhere((e) => list.contains(e)));
|
||||
}
|
||||
upState.value = Success(data);
|
||||
} else {
|
||||
upState.value = const Error(null);
|
||||
}
|
||||
|
||||
isQuerying = false;
|
||||
}
|
||||
|
||||
@@ -177,6 +166,10 @@ class DynamicsController extends GetxController
|
||||
|
||||
@override
|
||||
Future<void> onRefresh() async {
|
||||
if (showAllUp) {
|
||||
_upPage = 1;
|
||||
_cacheUpList = null;
|
||||
}
|
||||
queryFollowUp();
|
||||
await controller?.onRefresh();
|
||||
}
|
||||
@@ -212,7 +205,9 @@ class DynamicsController extends GetxController
|
||||
@override
|
||||
void onClose() {
|
||||
tabController.dispose();
|
||||
scrollController.dispose();
|
||||
scrollController
|
||||
..removeListener(listener)
|
||||
..dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
|
||||
import 'package:PiliPlus/models/dynamics/up.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/up_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_create/view.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_tab/view.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart' hide DraggableScrollableSheet;
|
||||
import 'package:get/get.dart';
|
||||
|
||||
@@ -52,29 +52,6 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (Pref.dynamicsShowAllFollowedUp) {
|
||||
_dynamicsController.scrollController.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void listener() {
|
||||
if (_dynamicsController.scrollController.position.pixels >=
|
||||
_dynamicsController.scrollController.position.maxScrollExtent - 300) {
|
||||
EasyThrottle.throttle('following', const Duration(seconds: 1), () {
|
||||
_dynamicsController.queryFollowing2();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_dynamicsController.scrollController.removeListener(listener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget upPanelPart(ThemeData theme) {
|
||||
bool isTop = upPanelPosition == UpPanelPosition.top;
|
||||
bool needBg = upPanelPosition.index > 1;
|
||||
@@ -84,25 +61,28 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
child: SizedBox(
|
||||
width: isTop ? null : 64,
|
||||
height: isTop ? 76 : null,
|
||||
child: Obx(
|
||||
() {
|
||||
final upData = _dynamicsController.upData.value;
|
||||
if (upData.upList == null && upData.liveUsers == null) {
|
||||
return const SizedBox.shrink();
|
||||
} else if (upData.errMsg != null) {
|
||||
return Center(
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.refresh),
|
||||
onPressed: _dynamicsController.queryFollowUp,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return UpPanel(dynamicsController: _dynamicsController);
|
||||
}
|
||||
child: Obx(() => _buildUpPanel(_dynamicsController.upState.value)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildUpPanel(LoadingState<FollowUpModel> upState) {
|
||||
return switch (upState) {
|
||||
Loading() => const SizedBox.shrink(),
|
||||
Success<FollowUpModel>() => UpPanel(
|
||||
dynamicsController: _dynamicsController,
|
||||
),
|
||||
Error() => Center(
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.refresh),
|
||||
onPressed: () {
|
||||
_dynamicsController
|
||||
..upState.value = LoadingState<FollowUpModel>.loading()
|
||||
..queryFollowUp();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -30,8 +30,8 @@ class _UpPanelState extends State<UpPanel> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final theme = Theme.of(context);
|
||||
final upData = controller.upData.value;
|
||||
final List<UpItem>? upList = upData.upList;
|
||||
final upData = controller.upState.value.data;
|
||||
final List<UpItem> upList = upData.upList;
|
||||
final List<LiveUserItem>? liveList = upData.liveUsers?.items;
|
||||
return CustomScrollView(
|
||||
scrollDirection: isTop ? Axis.horizontal : Axis.vertical,
|
||||
@@ -41,7 +41,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
SliverToBoxAdapter(
|
||||
child: InkWell(
|
||||
onTap: () => setState(() {
|
||||
controller.showLiveItems = !controller.showLiveItems;
|
||||
controller.showLiveUp = !controller.showLiveUp;
|
||||
}),
|
||||
onLongPress: () => Get.to(const LiveFollowPage()),
|
||||
child: Container(
|
||||
@@ -64,7 +64,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
controller.showLiveItems
|
||||
controller.showLiveUp
|
||||
? Icons.expand_less
|
||||
: Icons.expand_more,
|
||||
size: 12,
|
||||
@@ -75,7 +75,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
controller.showLiveItems
|
||||
controller.showLiveUp
|
||||
? Icons.keyboard_arrow_right
|
||||
: Icons.keyboard_arrow_left,
|
||||
color: theme.colorScheme.primary,
|
||||
@@ -88,7 +88,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.showLiveItems && liveList?.isNotEmpty == true)
|
||||
if (controller.showLiveUp && liveList?.isNotEmpty == true)
|
||||
SliverList.builder(
|
||||
itemCount: liveList!.length,
|
||||
itemBuilder: (context, index) {
|
||||
@@ -110,9 +110,9 @@ class _UpPanelState extends State<UpPanel> {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (upList?.isNotEmpty == true)
|
||||
if (upList.isNotEmpty == true)
|
||||
SliverList.builder(
|
||||
itemCount: upList!.length,
|
||||
itemCount: upList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return upItemBuild(theme, upList[index]);
|
||||
},
|
||||
@@ -122,7 +122,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
void _onSelect(UserItem data) {
|
||||
void _onSelect(UpItem data) {
|
||||
controller
|
||||
..currentMid = data.mid
|
||||
..onSelectUp(data.mid);
|
||||
@@ -132,7 +132,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Widget upItemBuild(ThemeData theme, UserItem data) {
|
||||
Widget upItemBuild(ThemeData theme, UpItem data) {
|
||||
final currentMid = controller.currentMid;
|
||||
final isLive = data is LiveUserItem;
|
||||
bool isCurrent = isLive || currentMid == data.mid || currentMid == -1;
|
||||
@@ -143,14 +143,14 @@ class _UpPanelState extends State<UpPanel> {
|
||||
onTap: () {
|
||||
feedBack();
|
||||
switch (data) {
|
||||
case LiveUserItem():
|
||||
Get.toNamed('/liveRoom?roomid=${data.roomId}');
|
||||
case UpItem():
|
||||
_onSelect(data);
|
||||
break;
|
||||
case LiveUserItem():
|
||||
Get.toNamed('/liveRoom?roomid=${data.roomId}');
|
||||
}
|
||||
},
|
||||
onDoubleTap: isLive ? () => _onSelect(data) : null,
|
||||
// onDoubleTap: isLive ? () => _onSelect(data) : null,
|
||||
onLongPress: data.mid == -1
|
||||
? null
|
||||
: () => Get.toNamed('/member?mid=${data.mid}'),
|
||||
|
||||
Reference in New Issue
Block a user