mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-27 21:00:17 +08:00
@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/http/error_msg.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/reply.dart';
|
||||
@@ -33,19 +34,14 @@ import 'package:dio/dio.dart';
|
||||
abstract final class DynamicsHttp {
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
static Future<LoadingState<DynamicsDataModel>> followDynamic({
|
||||
DynamicsTabType type = DynamicsTabType.all,
|
||||
int? hostMid,
|
||||
String? offset,
|
||||
int? mid,
|
||||
Set<int>? tempBannedList,
|
||||
DynamicsTabType type = .all,
|
||||
}) async {
|
||||
Map<String, dynamic> data = {
|
||||
if (type == DynamicsTabType.up)
|
||||
'host_mid': mid
|
||||
else ...{
|
||||
'type': type.name,
|
||||
'timezone_offset': '-480',
|
||||
},
|
||||
'offset': offset,
|
||||
if (type == .up) 'host_mid': hostMid else 'type': type.name,
|
||||
'offset': ?offset,
|
||||
'features': Constants.dynFeatures,
|
||||
};
|
||||
final res = await Request().get(Api.followDynamic, queryParameters: data);
|
||||
@@ -61,7 +57,7 @@ abstract final class DynamicsHttp {
|
||||
return await followDynamic(
|
||||
type: type,
|
||||
offset: data.offset,
|
||||
mid: mid,
|
||||
hostMid: hostMid,
|
||||
tempBannedList: tempBannedList,
|
||||
);
|
||||
}
|
||||
@@ -89,22 +85,45 @@ abstract final class DynamicsHttp {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState<DynUpList>> dynUpList(String? offset) async {
|
||||
static Future<LoadingState<FollowUpModel>> dynUpList(String? offset) async {
|
||||
final res = await Request().get(
|
||||
Api.dynUplist,
|
||||
queryParameters: {
|
||||
'offset': offset,
|
||||
'offset': ?offset,
|
||||
'platform': 'web',
|
||||
'web_location': 333.1365,
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return Success(DynUpList.fromJson(res.data['data']));
|
||||
return Success(FollowUpModel.fromUpList(res.data['data']));
|
||||
} else {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState<FollowUpModel>> followings({
|
||||
int? vmid,
|
||||
int? pn,
|
||||
int ps = 20,
|
||||
String orderType = '', // ''=>最近关注,'attention'=>最常访问
|
||||
}) async {
|
||||
final res = await Request().get(
|
||||
Api.followings,
|
||||
queryParameters: {
|
||||
'vmid': vmid,
|
||||
'pn': pn,
|
||||
'ps': ps,
|
||||
'order': 'desc',
|
||||
'order_type': orderType,
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return Success(FollowUpModel.fromFollowList(res.data['data']));
|
||||
} else {
|
||||
return Error(errorMsg[res.data['code']] ?? res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
// 动态点赞
|
||||
// static Future likeDynamic({
|
||||
// required String? dynamicId,
|
||||
@@ -817,7 +836,7 @@ abstract final class DynamicsHttp {
|
||||
Api.dynReaction,
|
||||
queryParameters: {
|
||||
'id': id,
|
||||
'offset': offset,
|
||||
'offset': ?offset,
|
||||
'web_location': 333.1369,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -132,7 +132,7 @@ class Word {
|
||||
style = json['style'] == null ? null : Style.fromJson(json['style']);
|
||||
if (json['color'] case final String rawColor
|
||||
when rawColor.startsWith('#')) {
|
||||
color = ColourUtils.parse2Int(json['color']);
|
||||
color = ColourUtils.parse2Int(rawColor);
|
||||
}
|
||||
fontLevel = json['font_level'];
|
||||
}
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:PiliPlus/utils/parse_int.dart';
|
||||
|
||||
class FollowUpModel {
|
||||
FollowUpModel({
|
||||
this.liveUsers,
|
||||
required this.upList,
|
||||
});
|
||||
|
||||
LiveUsers? liveUsers;
|
||||
late List<UpItem> upList;
|
||||
bool? hasMore;
|
||||
String? offset;
|
||||
|
||||
FollowUpModel.fromJson(Map<String, dynamic> json) {
|
||||
liveUsers = json['live_users'] != null
|
||||
? LiveUsers.fromJson(json['live_users'])
|
||||
: null;
|
||||
upList =
|
||||
(json['up_list']?['items'] as List?)
|
||||
?.map<UpItem>((e) => UpItem.fromJson(e))
|
||||
.toList() ??
|
||||
<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))
|
||||
void addAllUpList(List<UpItem> newList) {
|
||||
if (upList != null) {
|
||||
upList!.addAll(newList);
|
||||
} else {
|
||||
upList = newList;
|
||||
}
|
||||
}
|
||||
|
||||
factory FollowUpModel.fromJson(Map<String, dynamic> json) {
|
||||
final model = FollowUpModel.fromUpList(json['up_list']);
|
||||
final liveUsers = json['live_users'];
|
||||
if (liveUsers != null) {
|
||||
model.liveUsers = LiveUsers.fromJson(liveUsers);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
FollowUpModel.fromUpList(Map<String, dynamic>? json) {
|
||||
if (json != null) {
|
||||
upList = (json['items'] as List?)
|
||||
?.map((e) => UpItem.fromJson(e))
|
||||
.toList();
|
||||
hasMore = json['has_more'];
|
||||
offset = json['offset'];
|
||||
}
|
||||
}
|
||||
|
||||
FollowUpModel.fromFollowList(Map<String, dynamic> json) {
|
||||
upList = (json['list'] as List?)
|
||||
?.map((e) => FollowItemModel.fromJson(e))
|
||||
.toList();
|
||||
hasMore = json['has_more'];
|
||||
offset = json['offset'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
|
||||
class FollowData {
|
||||
late List<FollowItemModel> list;
|
||||
List<FollowItemModel>? list;
|
||||
int? total;
|
||||
|
||||
FollowData({required this.list, this.total});
|
||||
|
||||
factory FollowData.fromJson(Map<String, dynamic> json) => FollowData(
|
||||
list:
|
||||
(json['list'] as List<dynamic>?)
|
||||
?.map((e) => FollowItemModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
<FollowItemModel>[],
|
||||
list: (json['list'] as List<dynamic>?)
|
||||
?.map((e) => FollowItemModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
total: json['total'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPlus/http/dynamics.dart';
|
||||
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/data.dart';
|
||||
import 'package:PiliPlus/pages/common/common_controller.dart';
|
||||
import 'package:PiliPlus/pages/common/common_data_controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_tab/controller.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
@@ -17,24 +15,20 @@ import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class DynamicsController extends GetxController
|
||||
with GetSingleTickerProviderStateMixin, ScrollOrRefreshMixin, AccountMixin {
|
||||
@override
|
||||
final ScrollController scrollController = ScrollController();
|
||||
class DynamicsController
|
||||
extends CommonDataController<FollowUpModel, FollowUpModel>
|
||||
with GetSingleTickerProviderStateMixin, AccountMixin {
|
||||
late final TabController tabController;
|
||||
|
||||
late final RxInt mid = (-1).obs;
|
||||
late int currentMid = -1;
|
||||
final Set<int> tempBannedList = <int>{};
|
||||
|
||||
Set<int> tempBannedList = <int>{};
|
||||
|
||||
final Rx<LoadingState<FollowUpModel>> upState =
|
||||
LoadingState<FollowUpModel>.loading().obs;
|
||||
late int _upPage = 1;
|
||||
late bool _upEnd = false;
|
||||
String? _offset;
|
||||
late int _page = 1;
|
||||
late bool _isEnd = false;
|
||||
Set<UpItem>? _cacheUpList;
|
||||
late final _showAllUp = Pref.dynamicsShowAllFollowedUp;
|
||||
late int hostMid = -1, currentMid = -1;
|
||||
late bool showLiveUp = Pref.expandDynLivePanel;
|
||||
late final _showAllUp = Pref.dynamicsShowAllFollowedUp;
|
||||
|
||||
final upPanelPosition = Pref.upPanelPosition;
|
||||
|
||||
@@ -55,154 +49,56 @@ class DynamicsController extends GetxController
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
tabController = TabController(
|
||||
length: DynamicsTabType.values.length,
|
||||
vsync: this,
|
||||
length: DynamicsTabType.values.length,
|
||||
initialIndex: Pref.defaultDynamicTypeIndex,
|
||||
);
|
||||
queryFollowUp();
|
||||
queryData();
|
||||
}
|
||||
|
||||
void onLoadMoreUp() {
|
||||
if (_showAllUp) {
|
||||
queryAllUp();
|
||||
} else {
|
||||
queryUpList();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> queryUpList() async {
|
||||
if (isQuerying || _upEnd) return;
|
||||
isQuerying = true;
|
||||
|
||||
final res = await DynamicsHttp.dynUpList(upState.value.data.offset);
|
||||
|
||||
if (res case Success(:final response)) {
|
||||
if (response.hasMore == false || response.offset.isNullOrEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
final upData = upState.value.data
|
||||
..hasMore = response.hasMore
|
||||
..offset = response.offset;
|
||||
final list = response.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(
|
||||
vmid: Accounts.main.mid,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
);
|
||||
|
||||
if (res case Success(:final response)) {
|
||||
_upPage++;
|
||||
final list = response.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) {
|
||||
upState.value = const Error(null);
|
||||
isQuerying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// reset
|
||||
_upEnd = false;
|
||||
if (_showAllUp) _upPage = 1;
|
||||
|
||||
final res = await Future.wait([
|
||||
DynamicsHttp.followUp(),
|
||||
if (_showAllUp)
|
||||
FollowHttp.followings(
|
||||
vmid: Accounts.main.mid,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
),
|
||||
]);
|
||||
|
||||
final first = res.first;
|
||||
if (first case final Success<FollowUpModel> i) {
|
||||
final data = i.response;
|
||||
final second = res.elementAtOrNull(1);
|
||||
if (second case final Success<FollowData> j) {
|
||||
final data1 = j.response;
|
||||
final list1 = data1.list;
|
||||
|
||||
_upPage++;
|
||||
if (list1.isEmpty || list1.length >= (data1.total ?? 0)) {
|
||||
_upEnd = true;
|
||||
}
|
||||
|
||||
final list = data.upList;
|
||||
list.addAll(list1..removeWhere((_cacheUpList = list.toSet()).contains));
|
||||
}
|
||||
if (!_showAllUp) {
|
||||
if (data.hasMore == false || data.offset.isNullOrEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
}
|
||||
upState.value = Success(data);
|
||||
} else {
|
||||
upState.value = const Error(null);
|
||||
}
|
||||
|
||||
isQuerying = false;
|
||||
void _jumpToTab(int mid) {
|
||||
tabController.index = mid == -1 ? 0 : 4;
|
||||
}
|
||||
|
||||
void onSelectUp(int mid) {
|
||||
if (this.mid.value == mid) {
|
||||
tabController.index = (mid == -1 ? 0 : 4);
|
||||
if (currentMid == mid) {
|
||||
_jumpToTab(mid);
|
||||
if (mid == -1) {
|
||||
queryFollowUp();
|
||||
singleRefresh();
|
||||
}
|
||||
controller?.onReload();
|
||||
return;
|
||||
}
|
||||
|
||||
this.mid.value = mid;
|
||||
tabController.index = (mid == -1 ? 0 : 4);
|
||||
if (mid != -1) {
|
||||
hostMid = mid;
|
||||
try {
|
||||
Get.find<DynamicsTabController>(
|
||||
tag: DynamicsTabType.up.name,
|
||||
).onReload();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
currentMid = mid;
|
||||
_jumpToTab(mid);
|
||||
}
|
||||
|
||||
Future<void> singleRefresh() {
|
||||
if (_showAllUp) {
|
||||
_page = 1;
|
||||
_cacheUpList = null;
|
||||
}
|
||||
_offset = null;
|
||||
_isEnd = false;
|
||||
return super.onRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onRefresh() {
|
||||
_refreshFollowUp();
|
||||
singleRefresh();
|
||||
return controller!.onRefresh();
|
||||
}
|
||||
|
||||
void _refreshFollowUp() {
|
||||
if (_showAllUp) {
|
||||
_upPage = 1;
|
||||
_cacheUpList = null;
|
||||
}
|
||||
queryFollowUp();
|
||||
}
|
||||
|
||||
@override
|
||||
void animateToTop() {
|
||||
controller?.animateToTop();
|
||||
@@ -234,10 +130,71 @@ class DynamicsController extends GetxController
|
||||
@override
|
||||
void onClose() {
|
||||
tabController.dispose();
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
@override
|
||||
void onChangeAccount(bool isLogin) => _refreshFollowUp();
|
||||
void onChangeAccount(bool isLogin) => onReload();
|
||||
|
||||
@override
|
||||
Future<LoadingState<FollowUpModel>> customGetData() {
|
||||
if (_offset == null) {
|
||||
return DynamicsHttp.followUp();
|
||||
}
|
||||
if (_showAllUp) {
|
||||
return DynamicsHttp.followings(
|
||||
vmid: Accounts.main.mid,
|
||||
pn: _page,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
);
|
||||
} else {
|
||||
return DynamicsHttp.dynUpList(_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> queryData([bool isRefresh = true]) {
|
||||
if (!isRefresh && _isEnd) return Future.value();
|
||||
return super.queryData(isRefresh);
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(bool isRefresh, Success<FollowUpModel> response) {
|
||||
final res = response.response;
|
||||
|
||||
if (_showAllUp) {
|
||||
if (res.upList?.isNotEmpty != true) {
|
||||
_isEnd = true;
|
||||
}
|
||||
} else {
|
||||
_offset = res.offset;
|
||||
if (res.hasMore != true || _offset.isNullOrEmpty) {
|
||||
_isEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRefresh) {
|
||||
if (_showAllUp) {
|
||||
_offset = '';
|
||||
_cacheUpList = res.upList?.toSet();
|
||||
}
|
||||
loadingState.value = response;
|
||||
} else {
|
||||
if (_showAllUp) {
|
||||
_page++;
|
||||
}
|
||||
|
||||
if (res.upList case final upList? when upList.isNotEmpty) {
|
||||
if (_showAllUp && _cacheUpList != null) {
|
||||
upList.removeWhere(_cacheUpList!.contains);
|
||||
}
|
||||
loadingState
|
||||
..value.data.addAllUpList(upList)
|
||||
..refresh();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,11 +65,13 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
onNotification: (notification) {
|
||||
final metrics = notification.metrics;
|
||||
if (metrics.pixels >= metrics.maxScrollExtent - 300) {
|
||||
_dynamicsController.onLoadMoreUp();
|
||||
_dynamicsController.onLoadMore();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: Obx(() => _buildUpPanel(_dynamicsController.upState.value)),
|
||||
child: Obx(
|
||||
() => _buildUpPanel(_dynamicsController.loadingState.value),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -78,15 +80,14 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
Widget _buildUpPanel(LoadingState<FollowUpModel> upState) {
|
||||
return switch (upState) {
|
||||
Loading() => const SizedBox.shrink(),
|
||||
Success<FollowUpModel>() => UpPanel(
|
||||
Success(:final response) => UpPanel(
|
||||
upData: response,
|
||||
dynamicsController: _dynamicsController,
|
||||
),
|
||||
Error() => Center(
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.refresh),
|
||||
onPressed: () => _dynamicsController
|
||||
..upState.value = LoadingState<FollowUpModel>.loading()
|
||||
..queryFollowUp(),
|
||||
onPressed: _dynamicsController.onReload,
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:PiliPlus/common/assets.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models/dynamics/up.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/controller.dart';
|
||||
import 'package:PiliPlus/pages/live_follow/view.dart';
|
||||
@@ -15,10 +14,12 @@ import 'package:get/get.dart';
|
||||
|
||||
class UpPanel extends StatefulWidget {
|
||||
const UpPanel({
|
||||
required this.dynamicsController,
|
||||
super.key,
|
||||
required this.upData,
|
||||
required this.dynamicsController,
|
||||
});
|
||||
|
||||
final FollowUpModel upData;
|
||||
final DynamicsController dynamicsController;
|
||||
|
||||
@override
|
||||
@@ -33,16 +34,12 @@ class _UpPanelState extends State<UpPanel> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final accountService = controller.accountService;
|
||||
if (!accountService.isLogin.value) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final theme = Theme.of(context);
|
||||
final upData = controller.upState.value.data;
|
||||
final List<UpItem> upList = upData.upList;
|
||||
final List<LiveUserItem>? liveList = upData.liveUsers?.items;
|
||||
final upData = widget.upData;
|
||||
final upList = upData.upList;
|
||||
final liveList = upData.liveUsers?.items;
|
||||
return CustomScrollView(
|
||||
scrollDirection: isTop ? Axis.horizontal : Axis.vertical,
|
||||
scrollDirection: isTop ? .horizontal : .vertical,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: controller.scrollController,
|
||||
slivers: [
|
||||
@@ -54,11 +51,11 @@ class _UpPanelState extends State<UpPanel> {
|
||||
onLongPress: toFollowPage,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : toFollowPage,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
alignment: .center,
|
||||
height: isTop ? 76 : 60,
|
||||
padding: isTop ? const EdgeInsets.only(left: 12, right: 6) : null,
|
||||
padding: isTop ? const .only(left: 12, right: 6) : null,
|
||||
child: Text.rich(
|
||||
textAlign: TextAlign.center,
|
||||
textAlign: .center,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.primary,
|
||||
@@ -71,7 +68,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
if (!isTop) ...[
|
||||
const TextSpan(text: '\n'),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
alignment: .middle,
|
||||
child: Icon(
|
||||
controller.showLiveUp
|
||||
? Icons.expand_less
|
||||
@@ -82,7 +79,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
),
|
||||
] else
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
alignment: .middle,
|
||||
child: Icon(
|
||||
controller.showLiveUp
|
||||
? Icons.keyboard_arrow_right
|
||||
@@ -113,13 +110,13 @@ class _UpPanelState extends State<UpPanel> {
|
||||
theme,
|
||||
UpItem(
|
||||
uname: '我',
|
||||
face: accountService.face.value,
|
||||
face: controller.accountService.face.value,
|
||||
mid: Accounts.main.mid,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (upList.isNotEmpty)
|
||||
if (upList != null && upList.isNotEmpty)
|
||||
SliverList.builder(
|
||||
itemCount: upList.length,
|
||||
itemBuilder: (context, index) {
|
||||
@@ -131,23 +128,19 @@ class _UpPanelState extends State<UpPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
void _onSelect(UpItem data) {
|
||||
controller
|
||||
..currentMid = data.mid
|
||||
..onSelectUp(data.mid);
|
||||
|
||||
data.hasUpdate = false;
|
||||
|
||||
void _onSelect(UpItem item) {
|
||||
item.hasUpdate = false;
|
||||
controller.onSelectUp(item.mid);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Widget upItemBuild(ThemeData theme, UpItem data) {
|
||||
Widget upItemBuild(ThemeData theme, UpItem item) {
|
||||
final currentMid = controller.currentMid;
|
||||
final isLive = data is LiveUserItem;
|
||||
final isCurrent = isLive || currentMid == data.mid || currentMid == -1;
|
||||
final isLive = item is LiveUserItem;
|
||||
final isCurrent = isLive || currentMid == item.mid || currentMid == -1;
|
||||
|
||||
final isAll = data.mid == -1;
|
||||
void toMemberPage() => Get.toNamed('/member?mid=${data.mid}');
|
||||
final isAll = item.mid == -1;
|
||||
void toMemberPage() => Get.toNamed('/member?mid=${item.mid}');
|
||||
|
||||
Widget avatar;
|
||||
if (isAll) {
|
||||
@@ -166,12 +159,12 @@ class _UpPanelState extends State<UpPanel> {
|
||||
);
|
||||
} else {
|
||||
avatar = Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
padding: const .symmetric(horizontal: 4),
|
||||
child: NetworkImgLayer(
|
||||
width: 38,
|
||||
height: 38,
|
||||
src: data.face,
|
||||
type: ImageType.avatar,
|
||||
src: item.face,
|
||||
type: .avatar,
|
||||
),
|
||||
);
|
||||
if (isLive) {
|
||||
@@ -191,7 +184,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (data.hasUpdate ?? false) {
|
||||
} else if (item.hasUpdate ?? false) {
|
||||
avatar = Stack(
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
@@ -216,9 +209,9 @@ class _UpPanelState extends State<UpPanel> {
|
||||
onTap: () {
|
||||
feedBack();
|
||||
if (isLive) {
|
||||
PageUtils.toLiveRoom(data.roomId);
|
||||
PageUtils.toLiveRoom(item.roomId);
|
||||
} else {
|
||||
_onSelect(data);
|
||||
_onSelect(item);
|
||||
}
|
||||
},
|
||||
// onDoubleTap: isLive ? () => _onSelect(data) : null,
|
||||
@@ -228,18 +221,18 @@ class _UpPanelState extends State<UpPanel> {
|
||||
opacity: isCurrent ? 1 : 0.6,
|
||||
child: Column(
|
||||
spacing: 4,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: .min,
|
||||
mainAxisAlignment: .center,
|
||||
children: [
|
||||
avatar,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
padding: const .symmetric(horizontal: 4),
|
||||
child: Text(
|
||||
isTop ? '${data.uname}\n' : data.uname!,
|
||||
isTop ? '${item.uname}\n' : item.uname!,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
textAlign: .center,
|
||||
style: TextStyle(
|
||||
color: currentMid == data.mid
|
||||
color: currentMid == item.mid
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
height: 1.1,
|
||||
|
||||
@@ -16,9 +16,10 @@ class DynamicsTabController
|
||||
with AccountMixin {
|
||||
DynamicsTabController({required this.dynamicsType});
|
||||
final DynamicsTabType dynamicsType;
|
||||
String offset = '';
|
||||
int? mid;
|
||||
late final MainController mainController = Get.find<MainController>();
|
||||
|
||||
String? offset;
|
||||
|
||||
late final mainController = Get.find<MainController>();
|
||||
final dynamicsController = Get.find<DynamicsController>();
|
||||
|
||||
@override
|
||||
@@ -29,25 +30,25 @@ class DynamicsTabController
|
||||
|
||||
@override
|
||||
Future<void> onRefresh() {
|
||||
if (dynamicsType == DynamicsTabType.all) {
|
||||
if (dynamicsType == .all) {
|
||||
mainController.setDynCount();
|
||||
}
|
||||
offset = '';
|
||||
offset = null;
|
||||
return super.onRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
List<DynamicItemModel>? getDataList(DynamicsDataModel response) {
|
||||
offset = response.offset ?? '';
|
||||
offset = response.offset;
|
||||
return response.items;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<DynamicsDataModel>> customGetData() =>
|
||||
DynamicsHttp.followDynamic(
|
||||
type: dynamicsType,
|
||||
offset: offset,
|
||||
mid: mid,
|
||||
type: dynamicsType,
|
||||
hostMid: dynamicsController.hostMid,
|
||||
tempBannedList: dynamicsController.tempBannedList,
|
||||
);
|
||||
|
||||
@@ -70,7 +71,7 @@ class DynamicsTabController
|
||||
}
|
||||
|
||||
void onBlock(int index) {
|
||||
if (dynamicsType != DynamicsTabType.up) {
|
||||
if (dynamicsType != .up) {
|
||||
loadingState
|
||||
..value.data!.removeAt(index)
|
||||
..refresh();
|
||||
|
||||
@@ -27,9 +27,7 @@ class DynamicsTabPage extends StatefulWidget {
|
||||
|
||||
class _DynamicsTabPageState extends State<DynamicsTabPage>
|
||||
with AutomaticKeepAliveClientMixin, DynMixin {
|
||||
StreamSubscription? _listener;
|
||||
|
||||
DynamicsController dynamicsController = Get.putOrFind(DynamicsController.new);
|
||||
final dynamicsController = Get.putOrFind(DynamicsController.new);
|
||||
late final DynamicsTabController controller;
|
||||
|
||||
@override
|
||||
@@ -38,38 +36,22 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
|
||||
@override
|
||||
void initState() {
|
||||
controller = Get.putOrFind(
|
||||
() =>
|
||||
DynamicsTabController(dynamicsType: widget.dynamicsType)
|
||||
..mid = dynamicsController.mid.value,
|
||||
() => DynamicsTabController(dynamicsType: widget.dynamicsType),
|
||||
tag: widget.dynamicsType.name,
|
||||
);
|
||||
super.initState();
|
||||
if (widget.dynamicsType == DynamicsTabType.up) {
|
||||
_listener = dynamicsController.mid.listen((mid) {
|
||||
if (mid != -1) {
|
||||
controller
|
||||
..mid = mid
|
||||
..onReload();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
dynamicsController.mid.close();
|
||||
super.dispose();
|
||||
Future<void> onRefresh() {
|
||||
dynamicsController.singleRefresh();
|
||||
return controller.onRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return refreshIndicator(
|
||||
onRefresh: () {
|
||||
dynamicsController.queryFollowUp();
|
||||
return controller.onRefresh();
|
||||
},
|
||||
onRefresh: onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: controller.scrollController,
|
||||
|
||||
Reference in New Issue
Block a user