Compare commits
4 Commits
feature-ba
...
fix-replyI
Author | SHA1 | Date | |
---|---|---|---|
d0f036ec35 | |||
94f3b7c1e4 | |||
fb8b2de115 | |||
0d5d33a365 |
@ -214,6 +214,9 @@ class Api {
|
|||||||
// https://api.bilibili.com/x/relation/tags
|
// https://api.bilibili.com/x/relation/tags
|
||||||
static const String followingsClass = '/x/relation/tags';
|
static const String followingsClass = '/x/relation/tags';
|
||||||
|
|
||||||
|
// 搜索follow
|
||||||
|
static const followSearch = '/x/relation/followings/search';
|
||||||
|
|
||||||
// 粉丝
|
// 粉丝
|
||||||
// vmid 用户id pn 页码 ps 每页个数,最大50 order: desc
|
// vmid 用户id pn 页码 ps 每页个数,最大50 order: desc
|
||||||
// order_type 排序规则 最近访问传空,最常访问传 attention
|
// order_type 排序规则 最近访问传空,最常访问传 attention
|
||||||
|
@ -461,4 +461,41 @@ class MemberHttp {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 搜索follow
|
||||||
|
static Future getfollowSearch({
|
||||||
|
required int mid,
|
||||||
|
required int ps,
|
||||||
|
required int pn,
|
||||||
|
required String name,
|
||||||
|
}) async {
|
||||||
|
Map<String, dynamic> data = {
|
||||||
|
'vmid': mid,
|
||||||
|
'pn': pn,
|
||||||
|
'ps': ps,
|
||||||
|
'order': 'desc',
|
||||||
|
'order_type': 'attention',
|
||||||
|
'gaia_source': 'main_web',
|
||||||
|
'name': name,
|
||||||
|
'web_location': 333.999,
|
||||||
|
};
|
||||||
|
Map params = await WbiSign().makSign(data);
|
||||||
|
var res = await Request().get(Api.followSearch, data: {
|
||||||
|
...data,
|
||||||
|
'w_rid': params['w_rid'],
|
||||||
|
'wts': params['wts'],
|
||||||
|
});
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return {
|
||||||
|
'status': true,
|
||||||
|
'data': FollowDataModel.fromJson(res.data['data'])
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'status': false,
|
||||||
|
'data': [],
|
||||||
|
'msg': res.data['message'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,29 @@ class _FollowPageState extends State<FollowPage> {
|
|||||||
: '${_followController.name}的关注',
|
: '${_followController.name}的关注',
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => Get.toNamed('/followSearch?mid=$mid'),
|
||||||
|
icon: const Icon(Icons.search_outlined),
|
||||||
|
),
|
||||||
|
PopupMenuButton(
|
||||||
|
icon: const Icon(Icons.more_vert),
|
||||||
|
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: () => Get.toNamed('/blackListPage'),
|
||||||
|
child: const Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.block, size: 19),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
Text('黑名单管理'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: Obx(
|
body: Obx(
|
||||||
() => !_followController.isOwner.value
|
() => !_followController.isOwner.value
|
||||||
@ -87,3 +110,22 @@ class _FollowPageState extends State<FollowPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _FakeAPI {
|
||||||
|
static const List<String> _kOptions = <String>[
|
||||||
|
'aardvark',
|
||||||
|
'bobcat',
|
||||||
|
'chameleon',
|
||||||
|
];
|
||||||
|
// Searches the options, but injects a fake "network" delay.
|
||||||
|
static Future<Iterable<String>> search(String query) async {
|
||||||
|
await Future<void>.delayed(
|
||||||
|
const Duration(seconds: 1)); // Fake 1 second delay.
|
||||||
|
if (query == '') {
|
||||||
|
return const Iterable<String>.empty();
|
||||||
|
}
|
||||||
|
return _kOptions.where((String option) {
|
||||||
|
return option.contains(query.toLowerCase());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -42,7 +42,7 @@ class FollowItem extends StatelessWidget {
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
dense: true,
|
dense: true,
|
||||||
trailing: ctr!.isOwner.value
|
trailing: ctr != null && ctr!.isOwner.value
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
height: 34,
|
height: 34,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
|
73
lib/pages/follow_search/controller.dart
Normal file
73
lib/pages/follow_search/controller.dart
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/member.dart';
|
||||||
|
|
||||||
|
import '../../models/follow/result.dart';
|
||||||
|
|
||||||
|
class FollowSearchController extends GetxController {
|
||||||
|
Rx<TextEditingController> controller = TextEditingController().obs;
|
||||||
|
final FocusNode searchFocusNode = FocusNode();
|
||||||
|
RxString searchKeyWord = ''.obs;
|
||||||
|
String hintText = '搜索';
|
||||||
|
RxString loadingStatus = 'init'.obs;
|
||||||
|
late int mid = 1;
|
||||||
|
RxString uname = ''.obs;
|
||||||
|
int ps = 20;
|
||||||
|
int pn = 1;
|
||||||
|
RxList<FollowItemModel> followList = <FollowItemModel>[].obs;
|
||||||
|
RxInt total = 0.obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
mid = int.parse(Get.parameters['mid']!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空搜索
|
||||||
|
void onClear() {
|
||||||
|
if (searchKeyWord.value.isNotEmpty && controller.value.text != '') {
|
||||||
|
controller.value.clear();
|
||||||
|
searchKeyWord.value = '';
|
||||||
|
} else {
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onChange(value) {
|
||||||
|
searchKeyWord.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交搜索内容
|
||||||
|
void submit() {
|
||||||
|
loadingStatus.value = 'loading';
|
||||||
|
searchFollow();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future searchFollow({type = 'init'}) async {
|
||||||
|
if (controller.value.text == '') {
|
||||||
|
return {'status': true, 'data': <FollowItemModel>[].obs};
|
||||||
|
}
|
||||||
|
if (type == 'init') {
|
||||||
|
ps = 1;
|
||||||
|
}
|
||||||
|
var res = await MemberHttp.getfollowSearch(
|
||||||
|
mid: mid,
|
||||||
|
ps: ps,
|
||||||
|
pn: pn,
|
||||||
|
name: controller.value.text,
|
||||||
|
);
|
||||||
|
if (res['status']) {
|
||||||
|
if (type == 'init') {
|
||||||
|
followList.value = res['data'].list;
|
||||||
|
} else {
|
||||||
|
followList.addAll(res['data'].list);
|
||||||
|
}
|
||||||
|
total.value = res['data'].total;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLoad() {
|
||||||
|
searchFollow(type: 'onLoad');
|
||||||
|
}
|
||||||
|
}
|
4
lib/pages/follow_search/index.dart
Normal file
4
lib/pages/follow_search/index.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
library follow_search;
|
||||||
|
|
||||||
|
export './controller.dart';
|
||||||
|
export './view.dart';
|
121
lib/pages/follow_search/view.dart
Normal file
121
lib/pages/follow_search/view.dart
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
|
import 'package:pilipala/pages/follow_search/index.dart';
|
||||||
|
|
||||||
|
import '../follow/widgets/follow_item.dart';
|
||||||
|
|
||||||
|
class FollowSearchPage extends StatefulWidget {
|
||||||
|
const FollowSearchPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FollowSearchPage> createState() => _FollowSearchPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FollowSearchPageState extends State<FollowSearchPage> {
|
||||||
|
final FollowSearchController _followSearchController =
|
||||||
|
Get.put(FollowSearchController());
|
||||||
|
late Future? _futureBuilder;
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_futureBuilder = _followSearchController.searchFollow();
|
||||||
|
scrollController.addListener(
|
||||||
|
() {
|
||||||
|
if (scrollController.position.pixels >=
|
||||||
|
scrollController.position.maxScrollExtent - 200) {
|
||||||
|
EasyThrottle.throttle(
|
||||||
|
'my-throttler', const Duration(milliseconds: 500), () {
|
||||||
|
_followSearchController.onLoad();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reRequest() {
|
||||||
|
setState(() {
|
||||||
|
_futureBuilder = _followSearchController.searchFollow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
titleSpacing: 0,
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: reRequest,
|
||||||
|
icon: const Icon(CupertinoIcons.search, size: 22),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
],
|
||||||
|
title: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
focusNode: _followSearchController.searchFocusNode,
|
||||||
|
controller: _followSearchController.controller.value,
|
||||||
|
textInputAction: TextInputAction.search,
|
||||||
|
onChanged: (value) => _followSearchController.onChange(value),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: _followSearchController.hintText,
|
||||||
|
border: InputBorder.none,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
size: 22,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
onPressed: () => _followSearchController.onClear(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onSubmitted: (String value) => reRequest(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: _futureBuilder,
|
||||||
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
var data = snapshot.data;
|
||||||
|
if (data == null) {
|
||||||
|
return CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
HttpError(errMsg: snapshot.data['msg'], fn: reRequest)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data['status']) {
|
||||||
|
RxList followList = _followSearchController.followList;
|
||||||
|
return Obx(
|
||||||
|
() => followList.isNotEmpty
|
||||||
|
? ListView.builder(
|
||||||
|
controller: scrollController,
|
||||||
|
itemCount: followList.length,
|
||||||
|
itemBuilder: ((context, index) {
|
||||||
|
return FollowItem(
|
||||||
|
item: followList[index],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
: CustomScrollView(
|
||||||
|
slivers: [HttpError(errMsg: '未搜索到结果', fn: reRequest)],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
HttpError(errMsg: snapshot.data['msg'], fn: reRequest)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ class MemberArchiveController extends GetxController {
|
|||||||
|
|
||||||
// 获取用户投稿
|
// 获取用户投稿
|
||||||
Future getMemberArchive(type) async {
|
Future getMemberArchive(type) async {
|
||||||
if (type == 'onRefresh') {
|
if (type == 'init') {
|
||||||
pn = 1;
|
pn = 1;
|
||||||
}
|
}
|
||||||
var res = await MemberHttp.memberArchive(
|
var res = await MemberHttp.memberArchive(
|
||||||
@ -34,7 +34,12 @@ class MemberArchiveController extends GetxController {
|
|||||||
order: currentOrder['type']!,
|
order: currentOrder['type']!,
|
||||||
);
|
);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
|
if (type == 'init') {
|
||||||
|
archivesList.value = res['data'].list.vlist;
|
||||||
|
}
|
||||||
|
if (type == 'onLoad') {
|
||||||
archivesList.addAll(res['data'].list.vlist);
|
archivesList.addAll(res['data'].list.vlist);
|
||||||
|
}
|
||||||
count = res['data'].page['count'];
|
count = res['data'].page['count'];
|
||||||
pn += 1;
|
pn += 1;
|
||||||
}
|
}
|
||||||
@ -42,13 +47,14 @@ class MemberArchiveController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleSort() async {
|
toggleSort() async {
|
||||||
pn = 1;
|
List<String> typeList = orderList.map((e) => e['type']!).toList();
|
||||||
int index = orderList.indexOf(currentOrder);
|
int index = typeList.indexOf(currentOrder['type']!);
|
||||||
if (index == orderList.length - 1) {
|
if (index == orderList.length - 1) {
|
||||||
currentOrder.value = orderList.first;
|
currentOrder.value = orderList.first;
|
||||||
} else {
|
} else {
|
||||||
currentOrder.value = orderList[index + 1];
|
currentOrder.value = orderList[index + 1];
|
||||||
}
|
}
|
||||||
|
getMemberArchive('init');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上拉加载
|
// 上拉加载
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/common/widgets/video_card_h.dart';
|
import 'package:pilipala/common/widgets/video_card_h.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
import '../../common/constants.dart';
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
|
|
||||||
class MemberArchivePage extends StatefulWidget {
|
class MemberArchivePage extends StatefulWidget {
|
||||||
@ -48,39 +49,16 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
|
|||||||
titleSpacing: 0,
|
titleSpacing: 0,
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
title: Text('他的投稿', style: Theme.of(context).textTheme.titleMedium),
|
title: Text('他的投稿', style: Theme.of(context).textTheme.titleMedium),
|
||||||
// actions: [
|
actions: [
|
||||||
// Obx(
|
Obx(
|
||||||
// () => PopupMenuButton<String>(
|
() => TextButton.icon(
|
||||||
// padding: EdgeInsets.zero,
|
icon: const Icon(Icons.sort, size: 20),
|
||||||
// tooltip: '投稿排序',
|
onPressed: _memberArchivesController.toggleSort,
|
||||||
// icon: Icon(
|
label: Text(_memberArchivesController.currentOrder['label']!),
|
||||||
// Icons.more_vert_outlined,
|
),
|
||||||
// color: Theme.of(context).colorScheme.outline,
|
),
|
||||||
// ),
|
const SizedBox(width: 6),
|
||||||
// position: PopupMenuPosition.under,
|
],
|
||||||
// onSelected: (String type) {},
|
|
||||||
// itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
|
||||||
// for (var i in _memberArchivesController.orderList) ...[
|
|
||||||
// PopupMenuItem<String>(
|
|
||||||
// onTap: () {},
|
|
||||||
// value: _memberArchivesController.currentOrder['label'],
|
|
||||||
// child: Row(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// children: [
|
|
||||||
// Text(i['label']!),
|
|
||||||
// if (_memberArchivesController.currentOrder['label'] ==
|
|
||||||
// i['label']) ...[
|
|
||||||
// const SizedBox(width: 10),
|
|
||||||
// const Icon(Icons.done, size: 20),
|
|
||||||
// ],
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ]
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
),
|
),
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
controller: _memberArchivesController.scrollController,
|
controller: _memberArchivesController.scrollController,
|
||||||
|
@ -119,7 +119,7 @@ class MineController extends GetxController {
|
|||||||
SmartDialog.showToast('账号未登录');
|
SmartDialog.showToast('账号未登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Get.toNamed('/follow?mid=${userInfo.value.mid}');
|
Get.toNamed('/follow?mid=${userInfo.value.mid}', preventDuplicates: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pushFans() {
|
pushFans() {
|
||||||
@ -127,7 +127,7 @@ class MineController extends GetxController {
|
|||||||
SmartDialog.showToast('账号未登录');
|
SmartDialog.showToast('账号未登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Get.toNamed('/fan?mid=${userInfo.value.mid}');
|
Get.toNamed('/fan?mid=${userInfo.value.mid}', preventDuplicates: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pushDynamic() {
|
pushDynamic() {
|
||||||
@ -135,6 +135,7 @@ class MineController extends GetxController {
|
|||||||
SmartDialog.showToast('账号未登录');
|
SmartDialog.showToast('账号未登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Get.toNamed('/memberDynamics?mid=${userInfo.value.mid}');
|
Get.toNamed('/memberDynamics?mid=${userInfo.value.mid}',
|
||||||
|
preventDuplicates: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,8 +797,7 @@ InlineSpan buildContent(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
} else if (len > 1) {
|
||||||
if (len > 1) {
|
|
||||||
List<Widget> list = [];
|
List<Widget> list = [];
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
picList.add(content.pictures[i]['img_src']);
|
picList.add(content.pictures[i]['img_src']);
|
||||||
@ -819,7 +818,8 @@ InlineSpan buildContent(
|
|||||||
src: content.pictures[i]['img_src'],
|
src: content.pictures[i]['img_src'],
|
||||||
width: box.maxWidth,
|
width: box.maxWidth,
|
||||||
height: box.maxWidth,
|
height: box.maxWidth,
|
||||||
),
|
origAspectRatio: content.pictures[i]['img_width'] /
|
||||||
|
content.pictures[i]['img_height']),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/pages/follow_search/view.dart';
|
||||||
import 'package:pilipala/pages/setting/pages/logs.dart';
|
import 'package:pilipala/pages/setting/pages/logs.dart';
|
||||||
|
|
||||||
import '../pages/about/index.dart';
|
import '../pages/about/index.dart';
|
||||||
@ -104,7 +105,8 @@ class Routes {
|
|||||||
CustomGetPage(
|
CustomGetPage(
|
||||||
name: '/replyReply', page: () => const VideoReplyReplyPanel()),
|
name: '/replyReply', page: () => const VideoReplyReplyPanel()),
|
||||||
// 推荐设置
|
// 推荐设置
|
||||||
CustomGetPage(name: '/recommendSetting', page: () => const RecommendSetting()),
|
CustomGetPage(
|
||||||
|
name: '/recommendSetting', page: () => const RecommendSetting()),
|
||||||
// 播放设置
|
// 播放设置
|
||||||
CustomGetPage(name: '/playSetting', page: () => const PlaySetting()),
|
CustomGetPage(name: '/playSetting', page: () => const PlaySetting()),
|
||||||
// 外观设置
|
// 外观设置
|
||||||
@ -156,6 +158,8 @@ class Routes {
|
|||||||
name: '/memberSeasons', page: () => const MemberSeasonsPage()),
|
name: '/memberSeasons', page: () => const MemberSeasonsPage()),
|
||||||
// 日志
|
// 日志
|
||||||
CustomGetPage(name: '/logs', page: () => const LogsPage()),
|
CustomGetPage(name: '/logs', page: () => const LogsPage()),
|
||||||
|
// 搜索关注
|
||||||
|
CustomGetPage(name: '/followSearch', page: () => const FollowSearchPage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user