Add infinite scroll for word search results

This commit is contained in:
2025-07-13 19:41:00 +02:00
parent ae0789b133
commit 6c0342ac6c
4 changed files with 84 additions and 24 deletions

View File

@@ -2,6 +2,10 @@
(TODO: add description)
## New features ✨
- Added infinite scroll for word search results.
## Changes 🔧
- Display proper language names for "From language" references.

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:jadb/models/word_search/word_search_result.dart';
import 'package:jadb/search.dart' show JaDBConnection;
import 'package:mdi/mdi.dart';
@@ -10,6 +11,9 @@ import 'package:sqflite/sqflite.dart';
import '../../components/search/search_results_body/search_card.dart';
const int pageSize = 50;
const int invisibleItemsThreshold = 25;
class WordSearchResultPage extends StatefulWidget {
final String searchTerm;
@@ -23,10 +27,37 @@ class WordSearchResultPage extends StatefulWidget {
}
class _WordSearchResultPageState extends State<WordSearchResultPage> {
final List<WordSearchResult> results = [];
bool addedToDatabase = false;
late final _pagingController = PagingController<int, WordSearchResult>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => GetIt.instance
.get<Database>()
.jadbSearchWord(
widget.searchTerm,
page: pageKey,
pageSize: pageSize,
)
.then((v) => v ?? <WordSearchResult>[]),
);
@override
void initState() {
super.initState();
if (!incognitoModeEnabled && !addedToDatabase) {
HistoryEntry.insertWord(word: widget.searchTerm);
addedToDatabase = true;
}
}
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -42,44 +73,44 @@ class _WordSearchResultPageState extends State<WordSearchResultPage> {
],
),
body: FutureBuilder(
future: (() async {
final jadbConnection = GetIt.instance.get<Database>();
final results = await Future.wait([
jadbConnection
.jadbSearchWordCount(widget.searchTerm)
.then((v) => v ?? 0),
jadbConnection
.jadbSearchWord(widget.searchTerm)
.then((v) => v ?? <WordSearchResult>[]),
]);
return (results[0] as int, results[1] as List<WordSearchResult>);
})(),
future: GetIt.instance
.get<Database>()
.jadbSearchWordCount(widget.searchTerm)
.then((v) => v ?? 0),
builder: (context, snapshot) {
if (snapshot.hasError) return ErrorWidget(snapshot.error!);
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
if (!incognitoModeEnabled && !addedToDatabase) {
HistoryEntry.insertWord(word: widget.searchTerm);
addedToDatabase = true;
}
final searchCount = snapshot.data!;
return ListView(
return Column(
children: [
Center(
child: Text(
'Found ${snapshot.data!.$1} results for "${widget.searchTerm}"',
'Found $searchCount results for "${widget.searchTerm}"',
style: const TextStyle(
fontSize: 10,
color: Colors.grey,
),
),
),
for (final result in snapshot.data!.$2)
SearchResultCard(result: result)
Expanded(
child: PagingListener(
controller: _pagingController,
builder: (context, state, fetchNextPage) =>
PagedListView<int, WordSearchResult>(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate(
invisibleItemsThreshold: invisibleItemsThreshold,
itemBuilder: (context, item, index) =>
SearchResultCard(result: item),
),
),
),
),
],
);
},

View File

@@ -230,6 +230,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.0"
flutter_staggered_grid_view:
dependency: transitive
description:
name: flutter_staggered_grid_view
sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_svg:
dependency: "direct main"
description:
@@ -296,6 +304,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.5.4"
infinite_scroll_pagination:
dependency: "direct main"
description:
name: infinite_scroll_pagination
sha256: "9b8f95362928a1de835658835194b435c40f2bfc386f6545c1fd706203df0cd4"
url: "https://pub.dev"
source: hosted
version: "5.1.0"
jadb:
dependency: "direct main"
description:
@@ -622,6 +638,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
sliver_tools:
dependency: transitive
description:
name: sliver_tools
sha256: eae28220badfb9d0559207badcbbc9ad5331aac829a88cb0964d330d2a4636a6
url: "https://pub.dev"
source: hosted
version: "0.2.12"
source_span:
dependency: transitive
description:

View File

@@ -41,6 +41,7 @@ dependencies:
flutter_markdown_plus: ^1.0.3
markdown: ^7.3.0
sealed_languages: ^2.1.0
infinite_scroll_pagination: ^5.1.0
dev_dependencies:
flutter_test: