mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
handle relation url
Closes #1566 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
34
lib/common/widgets/button/more_btn.dart
Normal file
34
lib/common/widgets/button/more_btn.dart
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget moreTextButton({
|
||||
String text = '查看更多',
|
||||
required VoidCallback onTap,
|
||||
EdgeInsets? padding,
|
||||
Color? color,
|
||||
}) {
|
||||
Widget child = Text.rich(
|
||||
style: TextStyle(color: color, height: 1),
|
||||
strutStyle: const StrutStyle(leading: 0, height: 1),
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(text: text),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
size: 22,
|
||||
color: color,
|
||||
Icons.keyboard_arrow_right,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (padding != null) {
|
||||
child = Padding(padding: padding, child: child);
|
||||
}
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onTap,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@@ -966,4 +966,8 @@ class Api {
|
||||
static const String danmakuRecall = '/x/dm/recall';
|
||||
|
||||
static const String danmakuEditState = '/x/v2/dm/edit/state';
|
||||
|
||||
static const String followedUp = '/x/relation/followings/followed_upper';
|
||||
|
||||
static const String sameFollowing = '/x/relation/same/followings';
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/fans/data.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
|
||||
class FanHttp {
|
||||
static Future<LoadingState<FansData>> fans({
|
||||
static Future<LoadingState<FollowData>> fans({
|
||||
int? vmid,
|
||||
int? pn,
|
||||
int ps = 20,
|
||||
@@ -21,7 +21,7 @@ class FanHttp {
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return Success(FansData.fromJson(res.data['data']));
|
||||
return Success(FollowData.fromJson(res.data['data']));
|
||||
} else {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
|
||||
@@ -328,7 +328,9 @@ class MemberHttp {
|
||||
}
|
||||
}
|
||||
|
||||
static Future memberCardInfo({int? mid}) async {
|
||||
static Future<LoadingState<MemberCardInfoData>> memberCardInfo({
|
||||
int? mid,
|
||||
}) async {
|
||||
var res = await Request().get(
|
||||
Api.memberCardInfo,
|
||||
queryParameters: {
|
||||
@@ -337,12 +339,9 @@ class MemberHttp {
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
'status': true,
|
||||
'data': MemberCardInfoData.fromJson(res.data['data']),
|
||||
};
|
||||
return Success(MemberCardInfoData.fromJson(res.data['data']));
|
||||
} else {
|
||||
return {'status': false, 'msg': res.data['message']};
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/user/info.dart';
|
||||
import 'package:PiliPlus/models/user/stat.dart';
|
||||
import 'package:PiliPlus/models_new/coin_log/data.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/models_new/history/data.dart';
|
||||
import 'package:PiliPlus/models_new/later/data.dart';
|
||||
import 'package:PiliPlus/models_new/login_log/data.dart';
|
||||
@@ -496,4 +497,48 @@ class UserHttp {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState<FollowData>> followedUp({
|
||||
required Object mid,
|
||||
required int pn,
|
||||
}) async {
|
||||
final res = await Request().get(
|
||||
Api.followedUp,
|
||||
queryParameters: {
|
||||
'csrf': Accounts.main.csrf,
|
||||
'pn': pn,
|
||||
'vmid': mid,
|
||||
'web_location': 333.789,
|
||||
'x-bili-device-req-json':
|
||||
'{"platform":"web","device":"pc","spmid":"333.789"}',
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return Success(FollowData.fromJson(res.data['data']));
|
||||
} else {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState<FollowData>> sameFollowing({
|
||||
required Object mid,
|
||||
int? pn,
|
||||
}) async {
|
||||
final res = await Request().get(
|
||||
Api.sameFollowing,
|
||||
queryParameters: {
|
||||
'csrf': Accounts.main.csrf,
|
||||
'pn': ?pn,
|
||||
'vmid': mid,
|
||||
'web_location': 333.789,
|
||||
'x-bili-device-req-json':
|
||||
'{"platform":"web","device":"pc","spmid":"333.789"}',
|
||||
},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return Success(FollowData.fromJson(res.data['data']));
|
||||
} else {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import 'package:PiliPlus/models_new/fans/list.dart';
|
||||
|
||||
class FansData {
|
||||
List<FansItemModel>? list;
|
||||
String? offset;
|
||||
int? reVersion;
|
||||
int? total;
|
||||
|
||||
FansData({this.list, this.offset, this.reVersion, this.total});
|
||||
|
||||
factory FansData.fromJson(Map<String, dynamic> json) => FansData(
|
||||
list: (json['list'] as List<dynamic>?)
|
||||
?.map((e) => FansItemModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
offset: json['offset'] as String?,
|
||||
reVersion: json['re_version'] as int?,
|
||||
total: json['total'] as int?,
|
||||
);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import 'package:PiliPlus/models/model_avatar.dart';
|
||||
|
||||
class FansItemModel {
|
||||
int? mid;
|
||||
int? attribute;
|
||||
int? mtime;
|
||||
dynamic tag;
|
||||
int? special;
|
||||
String? uname;
|
||||
String? face;
|
||||
String? sign;
|
||||
int? faceNft;
|
||||
BaseOfficialVerify? officialVerify;
|
||||
Vip? vip;
|
||||
String? nftIcon;
|
||||
String? recReason;
|
||||
String? trackId;
|
||||
String? followTime;
|
||||
|
||||
FansItemModel({
|
||||
this.mid,
|
||||
this.attribute,
|
||||
this.mtime,
|
||||
this.tag,
|
||||
this.special,
|
||||
this.uname,
|
||||
this.face,
|
||||
this.sign,
|
||||
this.faceNft,
|
||||
this.officialVerify,
|
||||
this.vip,
|
||||
this.nftIcon,
|
||||
this.recReason,
|
||||
this.trackId,
|
||||
this.followTime,
|
||||
});
|
||||
|
||||
factory FansItemModel.fromJson(Map<String, dynamic> json) => FansItemModel(
|
||||
mid: json['mid'] as int?,
|
||||
attribute: json['attribute'] as int?,
|
||||
mtime: json['mtime'] as int?,
|
||||
tag: json['tag'] as dynamic,
|
||||
special: json['special'] as int?,
|
||||
uname: json['uname'] as String?,
|
||||
face: json['face'] as String?,
|
||||
sign: json['sign'] as String?,
|
||||
faceNft: json['face_nft'] as int?,
|
||||
officialVerify: json['official_verify'] == null
|
||||
? null
|
||||
: BaseOfficialVerify.fromJson(
|
||||
json['official_verify'] as Map<String, dynamic>,
|
||||
),
|
||||
vip: json['vip'] == null
|
||||
? null
|
||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
||||
nftIcon: json['nft_icon'] as String?,
|
||||
recReason: json['rec_reason'] as String?,
|
||||
trackId: json['track_id'] as String?,
|
||||
followTime: json['follow_time'] as String?,
|
||||
);
|
||||
}
|
||||
@@ -2,10 +2,9 @@ import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
|
||||
class FollowData {
|
||||
late List<FollowItemModel> list;
|
||||
int? reVersion;
|
||||
int? total;
|
||||
|
||||
FollowData({required this.list, this.reVersion, this.total});
|
||||
FollowData({required this.list, this.total});
|
||||
|
||||
factory FollowData.fromJson(Map<String, dynamic> json) => FollowData(
|
||||
list:
|
||||
@@ -13,7 +12,6 @@ class FollowData {
|
||||
?.map((e) => FollowItemModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
<FollowItemModel>[],
|
||||
reVersion: json['re_version'] as int?,
|
||||
total: json['total'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,8 @@ class FollowItemModel extends UpItem {
|
||||
dynamic tag;
|
||||
int? special;
|
||||
String? sign;
|
||||
int? faceNft;
|
||||
BaseOfficialVerify? officialVerify;
|
||||
Vip? vip;
|
||||
String? nftIcon;
|
||||
String? recReason;
|
||||
String? trackId;
|
||||
String? followTime;
|
||||
|
||||
FollowItemModel({
|
||||
@@ -24,12 +20,8 @@ class FollowItemModel extends UpItem {
|
||||
super.uname,
|
||||
super.face,
|
||||
this.sign,
|
||||
this.faceNft,
|
||||
this.officialVerify,
|
||||
this.vip,
|
||||
this.nftIcon,
|
||||
this.recReason,
|
||||
this.trackId,
|
||||
this.followTime,
|
||||
});
|
||||
|
||||
@@ -43,7 +35,6 @@ class FollowItemModel extends UpItem {
|
||||
uname: json['uname'] as String?,
|
||||
face: json['face'] as String?,
|
||||
sign: json['sign'] as String?,
|
||||
faceNft: json['face_nft'] as int?,
|
||||
officialVerify: json['official_verify'] == null
|
||||
? null
|
||||
: BaseOfficialVerify.fromJson(
|
||||
@@ -52,9 +43,6 @@ class FollowItemModel extends UpItem {
|
||||
vip: json['vip'] == null
|
||||
? null
|
||||
: Vip.fromJson(json['vip'] as Map<String, dynamic>),
|
||||
nftIcon: json['nft_icon'] as String?,
|
||||
recReason: json['rec_reason'] as String?,
|
||||
trackId: json['track_id'] as String?,
|
||||
followTime: json['follow_time'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,10 +10,4 @@ class RejectPage {
|
||||
text: json['text'] as String?,
|
||||
img: json['img'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'title': title,
|
||||
'text': text,
|
||||
'img': img,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class _ContactPageState extends State<ContactPage>
|
||||
onSelect: widget.isFromSelect ? onSelect : null,
|
||||
),
|
||||
FansPage(
|
||||
mid: accountService.mid,
|
||||
showName: false,
|
||||
onSelect: widget.isFromSelect ? onSelect : null,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
import 'package:PiliPlus/http/fan.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/video.dart';
|
||||
import 'package:PiliPlus/models_new/fans/data.dart';
|
||||
import 'package:PiliPlus/models_new/fans/list.dart';
|
||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/controller.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FansController extends CommonListController<FansData, FansItemModel> {
|
||||
FansController(this.mid);
|
||||
int total = 0;
|
||||
int mid;
|
||||
class FansController extends FollowTypeController {
|
||||
FansController(this.showName);
|
||||
final bool showName;
|
||||
late final bool isOwner;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
void init() {
|
||||
final ownerMid = Accounts.main.mid;
|
||||
final mid = Get.parameters['mid'];
|
||||
this.mid = mid != null ? int.parse(mid) : ownerMid;
|
||||
isOwner = ownerMid == this.mid;
|
||||
if (showName && !isOwner) {
|
||||
final name = Get.parameters['name'];
|
||||
this.name = RxnString(name);
|
||||
if (name == null) {
|
||||
queryUserName();
|
||||
}
|
||||
}
|
||||
queryData();
|
||||
}
|
||||
|
||||
@override
|
||||
List<FansItemModel>? getDataList(FansData response) {
|
||||
return response.list;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<FansData>> customGetData() => FanHttp.fans(
|
||||
Future<LoadingState<FollowData>> customGetData() => FanHttp.fans(
|
||||
vmid: mid,
|
||||
pn: page,
|
||||
orderType: 'attention',
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models_new/fans/list.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:PiliPlus/pages/fan/controller.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/view.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/widgets/item.dart';
|
||||
import 'package:PiliPlus/pages/share/view.dart' show UserModel;
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/utils/grid.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -18,115 +11,53 @@ import 'package:get/get.dart';
|
||||
class FansPage extends StatefulWidget {
|
||||
const FansPage({
|
||||
super.key,
|
||||
this.mid,
|
||||
this.showName,
|
||||
this.onSelect,
|
||||
});
|
||||
|
||||
final int? mid;
|
||||
final bool? showName;
|
||||
final ValueChanged<UserModel>? onSelect;
|
||||
|
||||
@override
|
||||
State<FansPage> createState() => _FansPageState();
|
||||
}
|
||||
|
||||
class _FansPageState extends State<FansPage> {
|
||||
late int mid;
|
||||
String? name;
|
||||
late bool isOwner;
|
||||
late FansController _fansController;
|
||||
|
||||
class _FansPageState extends FollowTypePageState<FansPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
AccountService accountService = Get.find<AccountService>();
|
||||
late final mid = Get.parameters['mid'];
|
||||
this.mid =
|
||||
widget.mid ?? (mid != null ? int.parse(mid) : accountService.mid);
|
||||
isOwner = this.mid == accountService.mid;
|
||||
name = Get.parameters['name'] ?? accountService.name.value;
|
||||
_fansController = Get.put(
|
||||
FansController(this.mid),
|
||||
tag: Utils.makeHeroTag(this.mid),
|
||||
late final FansController controller = Get.put(
|
||||
FansController(widget.showName ?? true),
|
||||
tag: Utils.generateRandomString(8),
|
||||
);
|
||||
}
|
||||
late final flag = widget.onSelect == null && controller.isOwner;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context).colorScheme;
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: widget.mid != null
|
||||
PreferredSizeWidget? get appBar => widget.showName == false
|
||||
? null
|
||||
: AppBar(title: Text(isOwner ? '我的粉丝' : '$name的粉丝')),
|
||||
body: refreshIndicator(
|
||||
onRefresh: _fansController.onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: _fansController.scrollController,
|
||||
slivers: [
|
||||
ViewSliverSafeArea(
|
||||
sliver: Obx(
|
||||
() => _buildBody(theme, _fansController.loadingState.value),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: Grid.smallCardWidth * 2,
|
||||
mainAxisExtent: 66,
|
||||
: AppBar(
|
||||
title: controller.isOwner
|
||||
? const Text('我的粉丝')
|
||||
: Obx(() {
|
||||
final name = controller.name.value;
|
||||
if (name != null) return Text('$name的粉丝');
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
);
|
||||
|
||||
Widget _buildBody(
|
||||
ColorScheme theme,
|
||||
LoadingState<List<FansItemModel>?> loadingState,
|
||||
) {
|
||||
return switch (loadingState) {
|
||||
Loading() => SliverGrid.builder(
|
||||
gridDelegate: gridDelegate,
|
||||
itemBuilder: (context, index) => const MsgFeedTopSkeleton(),
|
||||
itemCount: 16,
|
||||
),
|
||||
Success(:var response) =>
|
||||
response?.isNotEmpty == true
|
||||
? SliverGrid.builder(
|
||||
gridDelegate: gridDelegate,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == response.length - 1) {
|
||||
_fansController.onLoadMore();
|
||||
}
|
||||
return _buildItem(theme, index, response[index]);
|
||||
},
|
||||
itemCount: response!.length,
|
||||
)
|
||||
: HttpError(onReload: _fansController.onReload),
|
||||
Error(:var errMsg) => HttpError(
|
||||
errMsg: errMsg,
|
||||
onReload: _fansController.onReload,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Widget _buildItem(ColorScheme theme, int index, FansItemModel item) {
|
||||
final isSelect = widget.onSelect != null;
|
||||
@override
|
||||
Widget buildItem(int index, FollowItemModel item) {
|
||||
void onRemove() => showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定移除 ${item.uname} ?',
|
||||
onConfirm: () => _fansController.onRemoveFan(index, item.mid!),
|
||||
onConfirm: () => controller.onRemoveFan(index, item.mid),
|
||||
);
|
||||
|
||||
final flag = !isSelect && isOwner;
|
||||
return SizedBox(
|
||||
height: 66,
|
||||
child: InkWell(
|
||||
return FollowTypeItem(
|
||||
item: item,
|
||||
onTap: () {
|
||||
if (widget.onSelect != null) {
|
||||
widget.onSelect!(
|
||||
UserModel(
|
||||
mid: item.mid!,
|
||||
mid: item.mid,
|
||||
name: item.uname!,
|
||||
avatar: item.face!,
|
||||
),
|
||||
@@ -137,41 +68,6 @@ class _FansPageState extends State<FansPage> {
|
||||
},
|
||||
onLongPress: flag ? onRemove : null,
|
||||
onSecondaryTap: flag && !Utils.isMobile ? onRemove : null,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
child: Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: 45,
|
||||
height: 45,
|
||||
type: ImageType.avatar,
|
||||
src: item.face,
|
||||
),
|
||||
Column(
|
||||
spacing: 3,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.uname!,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
if (item.sign != null)
|
||||
Text(
|
||||
item.sign!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 13, color: theme.outline),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/http/follow.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/member.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models/common/follow_order_type.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
@@ -14,6 +15,11 @@ class FollowChildController
|
||||
final FollowController? controller;
|
||||
final int? tagid;
|
||||
final int mid;
|
||||
int? total;
|
||||
|
||||
late final loadSameFollow = controller?.isOwner == false;
|
||||
late final Rx<LoadingState<List<FollowItemModel>?>> sameState =
|
||||
LoadingState<List<FollowItemModel>?>.loading().obs;
|
||||
|
||||
late final Rx<FollowOrderType> orderType = FollowOrderType.def.obs;
|
||||
|
||||
@@ -21,13 +27,24 @@ class FollowChildController
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
queryData();
|
||||
if (loadSameFollow) {
|
||||
_loadSameFollow();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
List<FollowItemModel>? getDataList(FollowData response) {
|
||||
total = response.total;
|
||||
return response.list;
|
||||
}
|
||||
|
||||
@override
|
||||
void checkIsEnd(int length) {
|
||||
if (total != null && length >= total!) {
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(bool isRefresh, Success<FollowData> response) {
|
||||
if (controller != null) {
|
||||
@@ -57,4 +74,11 @@ class FollowChildController
|
||||
orderType: orderType.value.type,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _loadSameFollow() async {
|
||||
final res = await UserHttp.sameFollowing(mid: mid);
|
||||
if (res.isSuccess) {
|
||||
sameState.value = Success(res.data.list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/more_btn.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -42,7 +43,24 @@ class _FollowChildPageState extends State<FollowChildPage>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final colorScheme = ColorScheme.of(context);
|
||||
final padding = MediaQuery.viewPaddingOf(context);
|
||||
Widget sliver = Obx(
|
||||
() => _buildBody(_followController.loadingState.value),
|
||||
);
|
||||
if (_followController.loadSameFollow) {
|
||||
sliver = SliverMainAxisGroup(
|
||||
slivers: [
|
||||
Obx(
|
||||
() => _buildSameFollowing(
|
||||
colorScheme,
|
||||
_followController.sameState.value,
|
||||
),
|
||||
),
|
||||
sliver,
|
||||
],
|
||||
);
|
||||
}
|
||||
Widget child = refreshIndicator(
|
||||
onRefresh: _followController.onRefresh,
|
||||
child: CustomScrollView(
|
||||
@@ -55,9 +73,7 @@ class _FollowChildPageState extends State<FollowChildPage>
|
||||
right: padding.right,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
sliver: Obx(
|
||||
() => _buildBody(_followController.loadingState.value),
|
||||
),
|
||||
sliver: sliver,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -122,6 +138,68 @@ class _FollowChildPageState extends State<FollowChildPage>
|
||||
};
|
||||
}
|
||||
|
||||
Widget _buildSameFollowing(
|
||||
ColorScheme colorScheme,
|
||||
LoadingState<List<FollowItemModel>?> state,
|
||||
) {
|
||||
return switch (state) {
|
||||
Success(:var response) =>
|
||||
response?.isNotEmpty == true
|
||||
? SliverMainAxisGroup(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: 6,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'我们的共同关注',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
moreTextButton(
|
||||
onTap: () => Get.toNamed(
|
||||
'/sameFollowing?mid=${_followController.mid}&name=${widget.controller?.name.value}',
|
||||
),
|
||||
color: colorScheme.outline,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: response!.length,
|
||||
itemBuilder: (_, index) =>
|
||||
FollowItem(item: response[index]),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
top: 16,
|
||||
bottom: 6,
|
||||
),
|
||||
child: Text(
|
||||
'全部关注',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SliverToBoxAdapter(),
|
||||
_ => const SliverToBoxAdapter(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive =>
|
||||
widget.onSelect != null || widget.controller?.tabController != null;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/member.dart';
|
||||
import 'package:PiliPlus/models/member/tags.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FollowController extends GetxController with GetTickerProviderStateMixin {
|
||||
late int mid;
|
||||
String? name;
|
||||
late bool isOwner;
|
||||
late final int mid;
|
||||
late final RxnString name;
|
||||
late final bool isOwner;
|
||||
|
||||
late final Rx<LoadingState> followState = LoadingState.loading().obs;
|
||||
late final RxList<MemberTagItemModel> tabs = <MemberTagItemModel>[].obs;
|
||||
@@ -19,15 +18,25 @@ class FollowController extends GetxController with GetTickerProviderStateMixin {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
int ownerMid = Accounts.main.mid;
|
||||
final ownerMid = Accounts.main.mid;
|
||||
final mid = Get.parameters['mid'];
|
||||
this.mid = mid != null ? int.parse(mid) : ownerMid;
|
||||
isOwner = ownerMid == this.mid;
|
||||
name = Get.parameters['name'] ?? Get.find<AccountService>().name.value;
|
||||
if (isOwner) {
|
||||
queryFollowUpTags();
|
||||
} else {
|
||||
final name = Get.parameters['name'];
|
||||
this.name = RxnString(name);
|
||||
if (name == null) {
|
||||
_queryUserName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _queryUserName() async {
|
||||
final res = await MemberHttp.memberCardInfo(mid: mid);
|
||||
name.value = res.dataOrNull?.card?.name;
|
||||
}
|
||||
|
||||
Future<void> queryFollowUpTags() async {
|
||||
var res = await MemberHttp.followUpTags();
|
||||
|
||||
@@ -31,9 +31,13 @@ class _FollowPageState extends State<FollowPage> {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
_followController.isOwner ? '我的关注' : '${_followController.name}的关注',
|
||||
),
|
||||
title: _followController.isOwner
|
||||
? const Text('我的关注')
|
||||
: Obx(() {
|
||||
final name = _followController.name.value;
|
||||
if (name != null) return Text('$name的关注');
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
actions: _followController.isOwner
|
||||
? [
|
||||
IconButton(
|
||||
|
||||
50
lib/pages/follow_type/controller.dart
Normal file
50
lib/pages/follow_type/controller.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:PiliPlus/http/member.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
abstract class FollowTypeController
|
||||
extends CommonListController<FollowData, FollowItemModel> {
|
||||
late final int mid;
|
||||
late final RxnString name;
|
||||
|
||||
RxInt total = 0.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
final ownerMid = Accounts.main.mid;
|
||||
final mid = Get.parameters['mid'];
|
||||
this.mid = mid != null ? int.parse(mid) : ownerMid;
|
||||
final name = Get.parameters['name'];
|
||||
this.name = RxnString(name);
|
||||
if (name == null) {
|
||||
queryUserName();
|
||||
}
|
||||
queryData();
|
||||
}
|
||||
|
||||
Future<void> queryUserName() async {
|
||||
final res = await MemberHttp.memberCardInfo(mid: mid);
|
||||
name.value = res.dataOrNull?.card?.name;
|
||||
}
|
||||
|
||||
@override
|
||||
List<FollowItemModel>? getDataList(FollowData response) {
|
||||
total.value = response.total ?? 0;
|
||||
return response.list;
|
||||
}
|
||||
|
||||
@override
|
||||
void checkIsEnd(int length) {
|
||||
if (length >= total.value) {
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
lib/pages/follow_type/follow_same/controller.dart
Normal file
10
lib/pages/follow_type/follow_same/controller.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/controller.dart';
|
||||
|
||||
class FollowSameController extends FollowTypeController {
|
||||
@override
|
||||
Future<LoadingState<FollowData>> customGetData() =>
|
||||
UserHttp.sameFollowing(mid: mid, pn: page);
|
||||
}
|
||||
30
lib/pages/follow_type/follow_same/view.dart
Normal file
30
lib/pages/follow_type/follow_same/view.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'package:PiliPlus/pages/follow_type/follow_same/controller.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/view.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FollowSamePage extends StatefulWidget {
|
||||
const FollowSamePage({super.key});
|
||||
|
||||
@override
|
||||
State<FollowSamePage> createState() => _FollowSamePageState();
|
||||
}
|
||||
|
||||
class _FollowSamePageState extends FollowTypePageState<FollowSamePage> {
|
||||
@override
|
||||
final controller = Get.put(
|
||||
FollowSameController(),
|
||||
tag: Utils.generateRandomString(8),
|
||||
);
|
||||
|
||||
@override
|
||||
PreferredSizeWidget get appBar => AppBar(
|
||||
title: Obx(
|
||||
() {
|
||||
final name = controller.name.value;
|
||||
return Text('${name == null ? '' : '我与$name的'}共同关注');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
10
lib/pages/follow_type/followed/controller.dart
Normal file
10
lib/pages/follow_type/followed/controller.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/controller.dart';
|
||||
|
||||
class FollowedController extends FollowTypeController {
|
||||
@override
|
||||
Future<LoadingState<FollowData>> customGetData() =>
|
||||
UserHttp.followedUp(mid: mid, pn: page);
|
||||
}
|
||||
29
lib/pages/follow_type/followed/view.dart
Normal file
29
lib/pages/follow_type/followed/view.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:PiliPlus/pages/follow_type/followed/controller.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/view.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FollowedPage extends StatefulWidget {
|
||||
const FollowedPage({super.key});
|
||||
|
||||
@override
|
||||
State<FollowedPage> createState() => _FollowedPageState();
|
||||
}
|
||||
|
||||
class _FollowedPageState extends FollowTypePageState<FollowedPage> {
|
||||
@override
|
||||
final controller = Get.put(
|
||||
FollowedController(),
|
||||
tag: Utils.generateRandomString(8),
|
||||
);
|
||||
|
||||
@override
|
||||
PreferredSizeWidget get appBar => AppBar(
|
||||
title: Obx(
|
||||
() => Text(
|
||||
'我关注的${controller.total.value}人也关注了${controller.name.value ?? 'TA'}',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
77
lib/pages/follow_type/view.dart
Normal file
77
lib/pages/follow_type/view.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:PiliPlus/pages/follow/widgets/follow_item.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/controller.dart';
|
||||
import 'package:PiliPlus/utils/grid.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
abstract class FollowTypePageState<T extends StatefulWidget> extends State<T> {
|
||||
FollowTypeController get controller;
|
||||
|
||||
PreferredSizeWidget? get appBar;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context).colorScheme;
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: appBar,
|
||||
body: refreshIndicator(
|
||||
onRefresh: controller.onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: controller.scrollController,
|
||||
slivers: [
|
||||
ViewSliverSafeArea(
|
||||
sliver: Obx(
|
||||
() => _buildBody(theme, controller.loadingState.value),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: Grid.smallCardWidth * 2,
|
||||
mainAxisExtent: 66,
|
||||
);
|
||||
|
||||
Widget _buildBody(
|
||||
ColorScheme theme,
|
||||
LoadingState<List<FollowItemModel>?> loadingState,
|
||||
) {
|
||||
return switch (loadingState) {
|
||||
Loading() => SliverGrid.builder(
|
||||
gridDelegate: gridDelegate,
|
||||
itemBuilder: (context, index) => const MsgFeedTopSkeleton(),
|
||||
itemCount: 16,
|
||||
),
|
||||
Success(:var response) =>
|
||||
response?.isNotEmpty == true
|
||||
? SliverGrid.builder(
|
||||
gridDelegate: gridDelegate,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == response.length - 1) {
|
||||
controller.onLoadMore();
|
||||
}
|
||||
return buildItem(index, response[index]);
|
||||
},
|
||||
itemCount: response!.length,
|
||||
)
|
||||
: HttpError(onReload: controller.onReload),
|
||||
Error(:var errMsg) => HttpError(
|
||||
errMsg: errMsg,
|
||||
onReload: controller.onReload,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Widget buildItem(int index, FollowItemModel item) => FollowItem(item: item);
|
||||
}
|
||||
71
lib/pages/follow_type/widgets/item.dart
Normal file
71
lib/pages/follow_type/widgets/item.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models_new/follow/list.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FollowTypeItem extends StatelessWidget {
|
||||
const FollowTypeItem({
|
||||
super.key,
|
||||
required this.item,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onSecondaryTap,
|
||||
});
|
||||
|
||||
final FollowItemModel item;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onLongPress;
|
||||
final VoidCallback? onSecondaryTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 66,
|
||||
child: InkWell(
|
||||
onTap: onTap ?? () => Get.toNamed('/member?mid=${item.mid}'),
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: onSecondaryTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
child: Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: 45,
|
||||
height: 45,
|
||||
type: ImageType.avatar,
|
||||
src: item.face,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
spacing: 3,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.uname!,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
if (item.sign case final sign?)
|
||||
Text(
|
||||
sign,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: ColorScheme.of(context).outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_card_v.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/more_btn.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
@@ -251,26 +252,10 @@ class _LivePageState extends CommonPageState<LivePage, LiveController>
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
moreTextButton(
|
||||
onTap: () => Get.to(const LiveFollowPage()),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'查看更多',
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
size: 20,
|
||||
Icons.keyboard_arrow_right_outlined,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (item.cardData?.myIdolV1?.list?.isNotEmpty == true)
|
||||
|
||||
@@ -652,17 +652,9 @@ class UserInfoCard extends StatelessWidget {
|
||||
const SizedBox(width: 10),
|
||||
],
|
||||
);
|
||||
if (item.jumpUrl?.isNotEmpty == true) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
final isDark = Get.isDarkMode;
|
||||
PageUtils.handleWebview(
|
||||
'${item.jumpUrl}&native.theme=${isDark ? 2 : 1}&night=${isDark ? 1 : 0}',
|
||||
);
|
||||
},
|
||||
onTap: () => Get.toNamed('/followed?mid=${card.mid}&name=${card.name}'),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/more_btn.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/space/space/data.dart';
|
||||
@@ -301,7 +302,7 @@ class _MemberHomeState extends State<MemberHome>
|
||||
],
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
moreTextButton(
|
||||
onTap: () {
|
||||
int index = _ctr.tab2!.indexWhere(
|
||||
(item) => item.param == param,
|
||||
@@ -361,26 +362,8 @@ class _MemberHomeState extends State<MemberHome>
|
||||
SmartDialog.showToast('view $param');
|
||||
}
|
||||
},
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '查看更多',
|
||||
style: TextStyle(color: color),
|
||||
),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color: color,
|
||||
),
|
||||
style: TextStyle(fontSize: 13, color: color),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/more_btn.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
@@ -231,8 +232,8 @@ class _PgcPageState extends CommonPageState<PgcPage, PgcController>
|
||||
'推荐',
|
||||
style: theme.textTheme.titleMedium,
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
moreTextButton(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
onTap: () {
|
||||
if (widget.tabType == HomeTabType.bangumi) {
|
||||
Get.to(const PgcIndexPage());
|
||||
@@ -291,27 +292,8 @@ class _PgcPageState extends CommonPageState<PgcPage, PgcController>
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'查看更多',
|
||||
strutStyle: const StrutStyle(leading: 0, height: 1),
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -394,35 +376,17 @@ class _PgcPageState extends CommonPageState<PgcPage, PgcController>
|
||||
() => controller.accountService.isLogin.value
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: moreTextButton(
|
||||
text: '查看全部',
|
||||
onTap: () => Get.toNamed(
|
||||
'/fav',
|
||||
arguments: widget.tabType == HomeTabType.bangumi
|
||||
? FavTabType.bangumi.index
|
||||
: FavTabType.cinema.index,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'查看全部',
|
||||
strutStyle: const StrutStyle(leading: 0, height: 1),
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
|
||||
@@ -157,8 +157,8 @@ class UgcIntroController extends CommonIntroController with ReloadMixin {
|
||||
return;
|
||||
}
|
||||
var result = await MemberHttp.memberCardInfo(mid: mid);
|
||||
if (result['status']) {
|
||||
userStat.value = result['data'];
|
||||
if (result.isSuccess) {
|
||||
userStat.value = result.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import 'package:PiliPlus/pages/fav_detail/view.dart';
|
||||
import 'package:PiliPlus/pages/fav_search/view.dart';
|
||||
import 'package:PiliPlus/pages/follow/view.dart';
|
||||
import 'package:PiliPlus/pages/follow_search/view.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/follow_same/view.dart';
|
||||
import 'package:PiliPlus/pages/follow_type/followed/view.dart';
|
||||
import 'package:PiliPlus/pages/history/view.dart';
|
||||
import 'package:PiliPlus/pages/history_search/view.dart';
|
||||
import 'package:PiliPlus/pages/home/view.dart';
|
||||
@@ -223,6 +225,8 @@ class Routes {
|
||||
),
|
||||
CustomGetPage(name: '/audio', page: () => const AudioPage()),
|
||||
CustomGetPage(name: '/mainReply', page: () => const MainReplyPage()),
|
||||
CustomGetPage(name: '/followed', page: () => const FollowedPage()),
|
||||
CustomGetPage(name: '/sameFollowing', page: () => const FollowSamePage()),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -633,16 +633,53 @@ abstract class PiliScheme {
|
||||
launchURL();
|
||||
return false;
|
||||
} else if (host.contains('space.bilibili.com')) {
|
||||
String? sid =
|
||||
uri.queryParameters['sid'] ??
|
||||
void toType({
|
||||
required String mid,
|
||||
required String? type,
|
||||
}) {
|
||||
switch (type) {
|
||||
case 'follow':
|
||||
Get.toNamed('/follow?mid=$mid');
|
||||
break;
|
||||
case 'fans':
|
||||
Get.toNamed('/fan?mid=$mid');
|
||||
break;
|
||||
case 'followed':
|
||||
Get.toNamed('/followed?mid=$mid');
|
||||
break;
|
||||
default:
|
||||
PageUtils.toDupNamed('/member?mid=$mid', off: off);
|
||||
}
|
||||
}
|
||||
|
||||
late final queryParameters = uri.queryParameters;
|
||||
|
||||
// space.bilibili.com/h5/follow?mid={{mid}}&type={{type}}
|
||||
if (path.startsWith('/h5/follow')) {
|
||||
final mid = queryParameters['mid'];
|
||||
final type = queryParameters['type'];
|
||||
if (mid != null) {
|
||||
toType(mid: mid, type: type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// space.bilibili.com/{{uid}}/lists/{{season_id}}
|
||||
// space.bilibili.com/{{uid}}/lists?sid={{season_id}}
|
||||
// space.bilibili.com/{{uid}}/channel/collectiondetail?sid={{season_id}}
|
||||
final sid =
|
||||
queryParameters['sid'] ??
|
||||
RegExp(r'lists/(\d+)').firstMatch(path)?.group(1);
|
||||
if (sid != null) {
|
||||
SubDetailPage.toSubDetailPage(int.parse(sid));
|
||||
return true;
|
||||
}
|
||||
String? mid = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||
|
||||
// space.bilibili.com/{{mid}}/relation/{{type}}
|
||||
final mid = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||
final type = RegExp(r'relation/([a-z]+)').firstMatch(path)?.group(1);
|
||||
if (mid != null) {
|
||||
PageUtils.toDupNamed('/member?mid=$mid', off: off);
|
||||
toType(mid: mid, type: type);
|
||||
return true;
|
||||
}
|
||||
launchURL();
|
||||
|
||||
Reference in New Issue
Block a user