feat: 搜索历史

This commit is contained in:
guozhigq
2023-06-22 22:40:48 +08:00
parent ee250e1aaa
commit d0175c91b5
4 changed files with 141 additions and 23 deletions

View File

@ -5,7 +5,6 @@ import 'package:hive/hive.dart';
import 'package:pilipala/http/search.dart';
import 'package:pilipala/models/search/hot.dart';
import 'package:pilipala/models/search/suggest.dart';
import 'package:pilipala/utils/id_utils.dart';
import 'package:pilipala/utils/storage.dart';
class SearchController extends GetxController {
@ -14,6 +13,9 @@ class SearchController extends GetxController {
Rx<TextEditingController> controller = TextEditingController().obs;
List<HotSearchItem> hotSearchList = [];
Box hotKeyword = GStrorage.hotKeyword;
Box histiryWord = GStrorage.historyword;
List historyCacheList = [];
RxList historyList = [].obs;
RxList<SearchSuggestItem> searchSuggestList = [SearchSuggestItem()].obs;
final _debouncer =
Debouncer(delay: const Duration(milliseconds: 200)); // 设置延迟时间
@ -33,6 +35,8 @@ class SearchController extends GetxController {
if (Get.parameters.keys.isNotEmpty) {
onClickKeyword(Get.parameters['keyword']!);
}
historyCacheList = histiryWord.get('cacheList') ?? [];
historyList.value = historyCacheList;
}
void onChange(value) {
@ -45,9 +49,13 @@ class SearchController extends GetxController {
}
void onClear() {
if (searchKeyWord.value.isNotEmpty) {
controller.value.clear();
searchKeyWord.value = '';
searchSuggestList.value = [];
} else {
Get.back();
}
}
// 搜索
@ -56,6 +64,14 @@ class SearchController extends GetxController {
if (searchKeyWord == '') {
return;
}
List arr = historyCacheList.where((e) => e != searchKeyWord.value).toList();
arr.insert(0, searchKeyWord.value);
historyCacheList = arr;
historyList.value = historyCacheList;
// 手动刷新
historyList.refresh();
histiryWord.put('cacheList', historyCacheList);
Get.toNamed('/searchResult', parameters: {'keyword': searchKeyWord.value});
}
@ -84,4 +100,17 @@ class SearchController extends GetxController {
searchSuggestList.value = result['data'].tag;
}
}
onSelect(word) {
searchKeyWord.value = word;
controller.value.text = word;
submit();
}
onClearHis() {
historyList.value = [];
historyCacheList = [];
historyList.refresh();
histiryWord.put('cacheList', []);
}
}

View File

@ -5,6 +5,7 @@ import 'package:get/get.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'controller.dart';
import 'widgets/hotKeyword.dart';
import 'widgets/search_text.dart';
class SearchPage extends StatefulWidget {
const SearchPage({super.key});
@ -63,29 +64,32 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
decoration: InputDecoration(
hintText: '搜索',
border: InputBorder.none,
suffixIcon: _searchController.searchKeyWord.value.isNotEmpty
? IconButton(
suffixIcon: IconButton(
icon: Icon(
Icons.clear,
size: 22,
color: Theme.of(context).colorScheme.outline,
),
onPressed: () => _searchController.onClear())
: null,
onPressed: () => _searchController.onClear(),
),
),
onSubmitted: (String value) => _searchController.submit(),
),
),
),
body: Column(
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 12),
// 搜索建议
_searchSuggest(),
// 热搜
hotSearch(),
// 搜索历史
_history()
],
),
),
);
}
@ -143,7 +147,7 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(6, 0, 0, 0),
padding: const EdgeInsets.fromLTRB(6, 0, 0, 6),
child: Text(
'大家都在搜',
style: Theme.of(context)
@ -152,7 +156,6 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
.copyWith(fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 6),
LayoutBuilder(
builder: (context, boxConstraints) {
final double width = boxConstraints.maxWidth;
@ -197,4 +200,53 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
),
);
}
Widget _history() {
return Obx(
() => Container(
width: double.infinity,
padding: const EdgeInsets.fromLTRB(10, 25, 4, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_searchController.historyList.isNotEmpty)
Padding(
padding: const EdgeInsets.fromLTRB(6, 0, 1, 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'搜索历史',
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(fontWeight: FontWeight.bold),
),
TextButton(
onPressed: () => _searchController.onClearHis(),
child: const Text('清空'),
)
],
),
),
// if (_searchController.historyList.isNotEmpty)
Wrap(
spacing: 8,
runSpacing: 8,
direction: Axis.horizontal,
textDirection: TextDirection.ltr,
children: [
for (int i = 0; i < _searchController.historyList.length; i++)
SearchText(
searchText: _searchController.historyList[i],
searchTextIdx: i,
onSelect: (value) => _searchController.onSelect(value),
)
],
),
],
),
),
);
}
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class SearchText extends StatelessWidget {
String? searchText;
Function? onSelect;
int? searchTextIdx;
SearchText({super.key, this.searchText, this.onSelect, this.searchTextIdx});
@override
Widget build(BuildContext context) {
return Material(
color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5),
borderRadius: BorderRadius.circular(6),
child: Padding(
padding: EdgeInsets.zero,
child: InkWell(
onTap: () {
onSelect!(searchText);
},
borderRadius: BorderRadius.circular(6),
child: Padding(
padding:
const EdgeInsets.only(top: 5, bottom: 5, left: 11, right: 11),
child: Text(
searchText!,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant),
),
),
),
),
);
}
}

View File

@ -11,6 +11,7 @@ class GStrorage {
static late final Box recVideo;
static late final Box userInfo;
static late final Box hotKeyword;
static late final Box historyword;
static Future<void> init() async {
final dir = await getApplicationDocumentsDirectory();
@ -25,6 +26,8 @@ class GStrorage {
userInfo = await Hive.openBox('userInfo');
// 热搜关键词
hotKeyword = await Hive.openBox('hotKeyword');
// 搜索历史
historyword = await Hive.openBox('historyWord');
}
static regAdapter() {