feat: sort article search

This commit is contained in:
bggRGjQaUbCoE
2024-09-28 12:30:40 +08:00
parent 80f8c88d0d
commit 579ed0103a
3 changed files with 265 additions and 79 deletions

View File

@@ -78,6 +78,7 @@ class SearchHttp {
int? tids, int? tids,
int? orderSort, int? orderSort,
int? userType, int? userType,
int? categoryId,
}) async { }) async {
var reqData = { var reqData = {
'search_type': searchType.type, 'search_type': searchType.type,
@@ -90,6 +91,7 @@ class SearchHttp {
if (tids != null) 'tids': tids, if (tids != null) 'tids': tids,
if (orderSort != null) 'order_sort': orderSort, if (orderSort != null) 'order_sort': orderSort,
if (userType != null) 'user_type': userType, if (userType != null) 'user_type': userType,
if (categoryId != null) 'category_id': categoryId,
}; };
var res = await Request().get(Api.searchByType, data: reqData); var res = await Request().get(Api.searchByType, data: reqData);
if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) { if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) {

View File

@@ -17,6 +17,7 @@ class SearchPanelController extends CommonController {
int? tids; int? tids;
int? orderSort; int? orderSort;
int? userType; int? userType;
int? categoryId;
@override @override
void onInit() { void onInit() {
@@ -75,5 +76,6 @@ class SearchPanelController extends CommonController {
tids: tids, tids: tids,
orderSort: orderSort, orderSort: orderSort,
userType: userType, userType: userType,
categoryId: categoryId,
); );
} }

View File

@@ -1,4 +1,9 @@
import 'package:PiliPalaX/pages/search/widgets/search_text.dart';
import 'package:PiliPalaX/pages/search_panel/controller.dart';
import 'package:PiliPalaX/pages/video/detail/reply/view.dart'
show MySliverPersistentHeaderDelegate;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPalaX/common/constants.dart'; import 'package:PiliPalaX/common/constants.dart';
import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
@@ -6,11 +11,66 @@ import 'package:PiliPalaX/utils/utils.dart';
import '../../../utils/grid.dart'; import '../../../utils/grid.dart';
Widget searchArticlePanel(BuildContext context, ctr, list) { Widget searchArticlePanel(BuildContext context, searchPanelCtr, list) {
TextStyle textStyle = TextStyle( TextStyle textStyle = TextStyle(
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize, fontSize: Theme.of(context).textTheme.labelSmall!.fontSize,
color: Theme.of(context).colorScheme.outline); color: Theme.of(context).colorScheme.outline);
return CustomScrollView(controller: ctr.scrollController, slivers: [ final ctr = Get.put(ArticlePanelController());
return CustomScrollView(
controller: searchPanelCtr.scrollController,
slivers: [
SliverPersistentHeader(
pinned: false,
floating: true,
delegate: MySliverPersistentHeaderDelegate(
child: Container(
height: 40,
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
children: [
Obx(
() => Text(
'排序: ${ctr.orderFiltersList[ctr.currentOrderFilterval.value]['label']}',
maxLines: 1,
style:
TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
const Spacer(),
Obx(
() => Text(
'分区: ${ctr.zoneFiltersList[ctr.currentZoneFilterval.value]['label']}',
maxLines: 1,
style:
TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
const Spacer(),
SizedBox(
width: 32,
height: 32,
child: IconButton(
tooltip: '筛选',
style: ButtonStyle(
padding: WidgetStateProperty.all(EdgeInsets.zero),
),
onPressed: () {
ctr.onShowFilterDialog(context, searchPanelCtr);
},
icon: Icon(
Icons.filter_list_outlined,
size: 18,
color: Theme.of(context).colorScheme.primary,
),
),
),
],
),
),
),
),
SliverGrid( SliverGrid(
gridDelegate: SliverGridDelegateWithExtentAndRatio( gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisSpacing: StyleString.safeSpace, mainAxisSpacing: StyleString.safeSpace,
@@ -32,7 +92,8 @@ Widget searchArticlePanel(BuildContext context, ctr, list) {
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace), horizontal: StyleString.safeSpace),
child: LayoutBuilder(builder: (context, boxConstraints) { child: LayoutBuilder(
builder: (context, boxConstraints) {
final double width = (boxConstraints.maxWidth - final double width = (boxConstraints.maxWidth -
StyleString.cardSpace * StyleString.cardSpace *
6 / 6 /
@@ -110,11 +171,132 @@ Widget searchArticlePanel(BuildContext context, ctr, list) {
], ],
), ),
); );
}), },
),
), ),
); );
}, },
childCount: list.length, childCount: list.length,
)) ),
]); ),
],
);
}
class ArticlePanelController extends GetxController {
List orderFiltersList = [
{'label': '综合排序', 'value': 0, 'order': 'totalrank'},
{'label': '最新发布', 'value': 1, 'order': 'pubdate'},
{'label': '最多点击', 'value': 2, 'order': 'click'},
{'label': '最多喜欢', 'value': 3, 'order': 'attention'},
{'label': '最多评论', 'value': 4, 'order': 'scores'},
];
List zoneFiltersList = [
{'label': '全部分区', 'value': 0, 'categoryId': 0},
{'label': '动画', 'value': 1, 'categoryId': 2},
{'label': '游戏', 'value': 2, 'categoryId': 1},
{'label': '影视', 'value': 3, 'categoryId': 28},
{'label': '生活', 'value': 4, 'categoryId': 3},
{'label': '兴趣', 'value': 5, 'categoryId': 29},
{'label': '轻小说', 'value': 6, 'categoryId': 16},
{'label': '科技', 'value': 7, 'categoryId': 17},
{'label': '笔记', 'value': 8, 'categoryId': 41},
];
RxInt currentOrderFilterval = 0.obs;
RxInt currentZoneFilterval = 0.obs;
onShowFilterDialog(
BuildContext context,
SearchPanelController searchPanelCtr,
) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (_) => SingleChildScrollView(
child: Container(
width: double.infinity,
padding: EdgeInsets.only(
top: 20,
left: 16,
right: 16,
bottom: 80 + MediaQuery.of(context).padding.bottom,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
const Text('排序', style: TextStyle(fontSize: 16)),
const SizedBox(height: 10),
Wrap(
spacing: 8,
runSpacing: 8,
children: orderFiltersList
.map(
(item) => SearchText(
searchText: item['label'],
onSelect: (_) async {
Get.back();
currentOrderFilterval.value = item['value'];
SmartDialog.dismiss();
SmartDialog.showToast("${item['label']}」的筛选结果");
SearchPanelController ctr =
Get.find<SearchPanelController>(
tag: 'article${searchPanelCtr.keyword!}');
ctr.order.value = item['order'];
SmartDialog.showLoading(msg: 'loading');
await ctr.onRefresh();
SmartDialog.dismiss();
},
onLongSelect: (_) {},
bgColor: item['value'] == currentOrderFilterval.value
? Theme.of(context).colorScheme.primaryContainer
: null,
textColor: item['value'] == currentOrderFilterval.value
? Theme.of(context).colorScheme.onPrimaryContainer
: null,
),
)
.toList(),
),
const SizedBox(height: 20),
const Text('分区', style: TextStyle(fontSize: 16)),
const SizedBox(height: 10),
Wrap(
spacing: 8,
runSpacing: 8,
children: zoneFiltersList
.map(
(item) => SearchText(
searchText: item['label'],
onSelect: (_) async {
Get.back();
currentZoneFilterval.value = item['value'];
SmartDialog.dismiss();
SmartDialog.showToast("${item['label']}」的筛选结果");
SearchPanelController ctr =
Get.find<SearchPanelController>(
tag: 'article${searchPanelCtr.keyword!}');
ctr.categoryId = item['categoryId'];
SmartDialog.showLoading(msg: 'loading');
await ctr.onRefresh();
SmartDialog.dismiss();
},
onLongSelect: (_) {},
bgColor: item['value'] == currentZoneFilterval.value
? Theme.of(context).colorScheme.primaryContainer
: null,
textColor: item['value'] == currentZoneFilterval.value
? Theme.of(context).colorScheme.onPrimaryContainer
: null,
),
)
.toList(),
),
],
),
),
),
);
}
} }