From b5a9393a1e3c7fd60e296d978f55984e94a48ece Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 25 Oct 2024 18:50:24 +0800 Subject: [PATCH] feat: search video by pubtime --- lib/http/search.dart | 4 + lib/pages/search/widgets/search_text.dart | 3 + lib/pages/search_panel/controller.dart | 4 + .../search_panel/widgets/video_panel.dart | 338 +++++++++++++----- 4 files changed, 268 insertions(+), 81 deletions(-) diff --git a/lib/http/search.dart b/lib/http/search.dart index df907710..0dcdc256 100644 --- a/lib/http/search.dart +++ b/lib/http/search.dart @@ -79,6 +79,8 @@ class SearchHttp { int? orderSort, int? userType, int? categoryId, + int? pubBegin, + int? pubEnd, }) async { var reqData = { 'search_type': searchType.type, @@ -92,6 +94,8 @@ class SearchHttp { if (orderSort != null) 'order_sort': orderSort, if (userType != null) 'user_type': userType, if (categoryId != null) 'category_id': categoryId, + if (pubBegin != null) 'pubtime_begin_s': pubBegin, + if (pubEnd != null) 'pubtime_end_s': pubEnd, }; var res = await Request().get(Api.searchByType, data: reqData); if (res.data['code'] == 0) { diff --git a/lib/pages/search/widgets/search_text.dart b/lib/pages/search/widgets/search_text.dart index 5c5b3e42..501ae100 100644 --- a/lib/pages/search/widgets/search_text.dart +++ b/lib/pages/search/widgets/search_text.dart @@ -8,6 +8,7 @@ class SearchText extends StatelessWidget { final double? fontSize; final Color? bgColor; final Color? textColor; + final TextAlign? textAlign; const SearchText({ super.key, this.searchText, @@ -17,6 +18,7 @@ class SearchText extends StatelessWidget { this.fontSize, this.bgColor, this.textColor, + this.textAlign, }); @override @@ -40,6 +42,7 @@ class SearchText extends StatelessWidget { const EdgeInsets.only(top: 5, bottom: 5, left: 11, right: 11), child: Text( searchText!, + textAlign: textAlign, style: TextStyle( fontSize: fontSize, color: diff --git a/lib/pages/search_panel/controller.dart b/lib/pages/search_panel/controller.dart index 06a158b4..228079f1 100644 --- a/lib/pages/search_panel/controller.dart +++ b/lib/pages/search_panel/controller.dart @@ -20,6 +20,8 @@ class SearchPanelController extends CommonController { int? userType; int? categoryId; String? tag; + int? pubBegin; + int? pubEnd; late final searchResultController = Get.find(tag: tag); @@ -103,5 +105,7 @@ class SearchPanelController extends CommonController { orderSort: orderSort, userType: userType, categoryId: categoryId, + pubBegin: pubBegin, + pubEnd: pubEnd, ); } diff --git a/lib/pages/search_panel/widgets/video_panel.dart b/lib/pages/search_panel/widgets/video_panel.dart index 40cb1f6c..2366df9f 100644 --- a/lib/pages/search_panel/widgets/video_panel.dart +++ b/lib/pages/search_panel/widgets/video_panel.dart @@ -9,6 +9,7 @@ import 'package:get/get.dart'; import 'package:PiliPalaX/common/widgets/video_card_h.dart'; import 'package:PiliPalaX/models/common/search_type.dart'; import 'package:PiliPalaX/pages/search_panel/index.dart'; +import 'package:intl/intl.dart'; import '../../../common/constants.dart'; import '../../../utils/grid.dart'; @@ -177,6 +178,12 @@ class CustomFilterChip extends StatelessWidget { class VideoPanelController extends GetxController { RxList filterList = [{}].obs; Rx selectedType = ArchiveFilterType.values.first.obs; + List pubTimeFiltersList = [ + {'label': '不限', 'value': 0}, + {'label': '最近一天', 'value': 1}, + {'label': '最近一周', 'value': 2}, + {'label': '最近半年', 'value': 3}, + ]; List timeFiltersList = [ {'label': '全部时长', 'value': 0}, {'label': '0-10分钟', 'value': 1}, @@ -208,11 +215,33 @@ class VideoPanelController extends GetxController { {'label': '电影', 'value': 20, 'tids': 23}, {'label': '电视', 'value': 21, 'tids': 11}, ]; + int currentPubTimeFilterval = 0; + late DateTime pubBegin; + late DateTime pubEnd; + bool customPubBegin = false; + bool customPubEnd = false; int currentTimeFilterval = 0; int currentZoneFilterval = 0; @override void onInit() { + DateTime now = DateTime.now(); + pubBegin = DateTime( + now.year, + now.month, + 1, + 0, + 0, + 0, + ); + pubEnd = DateTime( + now.year, + now.month, + now.day, + 23, + 59, + 59, + ); List> list = ArchiveFilterType.values .map((type) => { 'label': type.description, @@ -230,90 +259,237 @@ class VideoPanelController extends GetxController { 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: timeFiltersList - .map( - (item) => SearchText( - searchText: item['label'], - onSelect: (text) async { - Get.back(); - currentTimeFilterval = item['value']; - SmartDialog.dismiss(); - SmartDialog.showToast("「${item['label']}」的筛选结果"); - SearchPanelController ctr = - Get.find( - tag: 'video${searchPanelCtr.keyword!}'); - ctr.duration.value = item['value']; - SmartDialog.showLoading(msg: 'loading'); - await ctr.onRefresh(); - SmartDialog.dismiss(); - }, - onLongSelect: (_) {}, - bgColor: item['value'] == currentTimeFilterval - ? Theme.of(context).colorScheme.primaryContainer - : null, - textColor: item['value'] == currentTimeFilterval - ? Theme.of(context).colorScheme.onPrimaryContainer - : null, - ), - ) - .toList(), + builder: (_) => StatefulBuilder( + builder: (context, setState) { + Widget dateWidget([bool isFirst = true]) { + return SearchText( + searchText: + DateFormat('yyyy-MM-dd').format(isFirst ? pubBegin : pubEnd), + textAlign: TextAlign.center, + onSelect: (text) { + showDatePicker( + context: context, + initialDate: isFirst ? pubBegin : pubEnd, + firstDate: isFirst ? DateTime(2009, 6, 26) : pubBegin, + lastDate: isFirst ? pubEnd : DateTime.now(), + ).then((selectedDate) async { + if (selectedDate != null) { + if (isFirst) { + customPubBegin = true; + pubBegin = selectedDate; + } else { + customPubEnd = true; + pubEnd = selectedDate; + } + currentPubTimeFilterval = -1; + SmartDialog.dismiss(); + // SmartDialog.showToast("「${item['label']}」的筛选结果"); + SearchPanelController ctr = Get.find( + tag: 'video${searchPanelCtr.keyword!}'); + ctr.pubBegin = DateTime( + pubBegin.year, + pubBegin.month, + pubBegin.day, + 0, + 0, + 0, + ).millisecondsSinceEpoch ~/ + 1000; + ctr.pubEnd = DateTime( + pubEnd.year, + pubEnd.month, + pubEnd.day, + 23, + 59, + 59, + ).millisecondsSinceEpoch ~/ + 1000; + setState(() {}); + SmartDialog.showLoading(msg: 'loading'); + await ctr.onRefresh(); + SmartDialog.dismiss(); + } + }); + }, + onLongSelect: (_) {}, + bgColor: currentPubTimeFilterval == -1 && + (isFirst ? customPubBegin : customPubEnd) + ? Theme.of(context).colorScheme.primaryContainer + : null, + textColor: currentPubTimeFilterval == -1 && + (isFirst ? customPubBegin : customPubEnd) + ? Theme.of(context).colorScheme.onPrimaryContainer + : Theme.of(context).colorScheme.outline.withOpacity(0.8), + ); + } + + return SingleChildScrollView( + child: Container( + width: double.infinity, + padding: EdgeInsets.only( + top: 20, + left: 16, + right: 16, + bottom: 80 + MediaQuery.of(context).padding.bottom, ), - 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: (text) async { - Get.back(); - currentZoneFilterval = item['value']; - SmartDialog.dismiss(); - SmartDialog.showToast("「${item['label']}」的筛选结果"); - SearchPanelController ctr = - Get.find( - tag: 'video${searchPanelCtr.keyword!}'); - ctr.tids = item['tids']; - SmartDialog.showLoading(msg: 'loading'); - await ctr.onRefresh(); - SmartDialog.dismiss(); - }, - onLongSelect: (_) {}, - bgColor: item['value'] == currentZoneFilterval - ? Theme.of(context).colorScheme.primaryContainer - : null, - textColor: item['value'] == currentZoneFilterval - ? Theme.of(context).colorScheme.onPrimaryContainer - : null, + 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: pubTimeFiltersList + .map( + (item) => SearchText( + searchText: item['label'], + onSelect: (text) async { + Get.back(); + currentPubTimeFilterval = item['value']; + SmartDialog.dismiss(); + SmartDialog.showToast("「${item['label']}」的筛选结果"); + SearchPanelController ctr = + Get.find( + tag: 'video${searchPanelCtr.keyword!}'); + DateTime now = DateTime.now(); + if (item['value'] == 0) { + ctr.pubBegin = null; + ctr.pubEnd = null; + } else { + ctr.pubBegin = DateTime( + now.year, + now.month, + now.day - + (item['value'] == 0 + ? 0 + : item['value'] == 1 + ? 6 + : 179), + 0, + 0, + 0, + ).millisecondsSinceEpoch ~/ + 1000; + ctr.pubEnd = DateTime( + now.year, + now.month, + now.day, + 23, + 59, + 59, + ).millisecondsSinceEpoch ~/ + 1000; + } + SmartDialog.showLoading(msg: 'loading'); + await ctr.onRefresh(); + SmartDialog.dismiss(); + }, + onLongSelect: (_) {}, + bgColor: item['value'] == currentPubTimeFilterval + ? Theme.of(context).colorScheme.primaryContainer + : null, + textColor: item['value'] == currentPubTimeFilterval + ? Theme.of(context) + .colorScheme + .onPrimaryContainer + : null, + ), + ) + .toList(), + ), + const SizedBox(height: 8), + Row( + children: [ + Expanded(child: dateWidget()), + const SizedBox(width: 8), + const Text( + '至', + style: TextStyle(fontSize: 13), ), - ) - .toList(), + const SizedBox(width: 8), + Expanded(child: dateWidget(false)), + ], + ), + const SizedBox(height: 20), + const Text('内容时长', style: TextStyle(fontSize: 16)), + const SizedBox(height: 10), + Wrap( + spacing: 8, + runSpacing: 8, + children: timeFiltersList + .map( + (item) => SearchText( + searchText: item['label'], + onSelect: (text) async { + Get.back(); + currentTimeFilterval = item['value']; + SmartDialog.dismiss(); + SmartDialog.showToast("「${item['label']}」的筛选结果"); + SearchPanelController ctr = + Get.find( + tag: 'video${searchPanelCtr.keyword!}'); + ctr.duration.value = item['value']; + SmartDialog.showLoading(msg: 'loading'); + await ctr.onRefresh(); + SmartDialog.dismiss(); + }, + onLongSelect: (_) {}, + bgColor: item['value'] == currentTimeFilterval + ? Theme.of(context).colorScheme.primaryContainer + : null, + textColor: item['value'] == currentTimeFilterval + ? 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: (text) async { + Get.back(); + currentZoneFilterval = item['value']; + SmartDialog.dismiss(); + SmartDialog.showToast("「${item['label']}」的筛选结果"); + SearchPanelController ctr = + Get.find( + tag: 'video${searchPanelCtr.keyword!}'); + ctr.tids = item['tids']; + SmartDialog.showLoading(msg: 'loading'); + await ctr.onRefresh(); + SmartDialog.dismiss(); + }, + onLongSelect: (_) {}, + bgColor: item['value'] == currentZoneFilterval + ? Theme.of(context).colorScheme.primaryContainer + : null, + textColor: item['value'] == currentZoneFilterval + ? Theme.of(context) + .colorScheme + .onPrimaryContainer + : null, + ), + ) + .toList(), + ), + ], ), - ], - ), - ), + ), + ); + }, ), ); }