mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-01 00:10:16 +08:00
handle relation url
Closes #1566 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -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,160 +11,63 @@ 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),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context).colorScheme;
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: widget.mid != null
|
||||
? 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,
|
||||
late final FansController controller = Get.put(
|
||||
FansController(widget.showName ?? true),
|
||||
tag: Utils.generateRandomString(8),
|
||||
);
|
||||
late final flag = widget.onSelect == null && controller.isOwner;
|
||||
|
||||
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,
|
||||
),
|
||||
};
|
||||
}
|
||||
@override
|
||||
PreferredSizeWidget? get appBar => widget.showName == false
|
||||
? null
|
||||
: AppBar(
|
||||
title: controller.isOwner
|
||||
? const Text('我的粉丝')
|
||||
: Obx(() {
|
||||
final name = controller.name.value;
|
||||
if (name != null) return Text('$name的粉丝');
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
);
|
||||
|
||||
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(
|
||||
onTap: () {
|
||||
if (widget.onSelect != null) {
|
||||
widget.onSelect!(
|
||||
UserModel(
|
||||
mid: item.mid!,
|
||||
name: item.uname!,
|
||||
avatar: item.face!,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
Get.toNamed('/member?mid=${item.mid}');
|
||||
},
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
return FollowTypeItem(
|
||||
item: item,
|
||||
onTap: () {
|
||||
if (widget.onSelect != null) {
|
||||
widget.onSelect!(
|
||||
UserModel(
|
||||
mid: item.mid,
|
||||
name: item.uname!,
|
||||
avatar: item.face!,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
Get.toNamed('/member?mid=${item.mid}');
|
||||
},
|
||||
onLongPress: flag ? onRemove : null,
|
||||
onSecondaryTap: flag && !Utils.isMobile ? onRemove : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user