refactor container selection pattern and improve search UI

This commit is contained in:
Fabian Freund
2026-02-25 15:47:38 +01:00
parent 702b4b27ca
commit dc5f7902ab
45 changed files with 1713 additions and 735 deletions
@@ -148,6 +148,7 @@ class ArticleDao extends DatabaseAccessor<FeedDatabase> with $ArticleDaoMixin {
required int snippetLength,
required String searchString,
required Uri? feedId,
int limit = 25,
}) {
final ftsQuery = db.buildFtsQuery(searchString);
@@ -159,11 +160,13 @@ class ArticleDao extends DatabaseAccessor<FeedDatabase> with $ArticleDaoMixin {
beforeMatch: matchPrefix,
afterMatch: matchSuffix,
ellipsis: ellipsis,
limit: limit,
);
} else {
return db.definitionsDrift.queryArticlesBasic(
feedId: feedId?.toString(),
query: db.buildLikeQuery(searchString),
limit: limit,
);
}
}
@@ -102,7 +102,8 @@ queryArticlesBasic(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
(:feed_id IS NULL OR a.feed_id = :feed_id)
ORDER BY
weighted_rank ASC,
a.created DESC NULLS LAST;
a.created DESC NULLS LAST
LIMIT :limit;
queryArticlesFullContent(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
WITH weights AS (
@@ -132,4 +133,5 @@ queryArticlesFullContent(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
:feed_id IS NULL OR a.feed_id = :feed_id
ORDER BY
weighted_rank ASC,
a.created DESC NULLS LAST;
a.created DESC NULLS LAST
LIMIT :limit;
@@ -2644,10 +2644,15 @@ class DefinitionsDrift extends i10.ModularAccessor {
i0.Selectable<i11.FeedArticleQueryResult> queryArticlesBasic({
required String query,
String? feedId,
required int limit,
}) {
return customSelect(
'WITH weights AS (SELECT 1.0 AS title_weight) SELECT a.*, f.icon,(bm25(article_fts, weights.title_weight))AS weighted_rank FROM article_fts AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE fts.title LIKE ?1 AND(?2 IS NULL OR a.feed_id = ?2)ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
variables: [i0.Variable<String>(query), i0.Variable<String>(feedId)],
'WITH weights AS (SELECT 1.0 AS title_weight) SELECT a.*, f.icon,(bm25(article_fts, weights.title_weight))AS weighted_rank FROM article_fts AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE fts.title LIKE ?1 AND(?2 IS NULL OR a.feed_id = ?2)ORDER BY weighted_rank ASC, a.created DESC NULLS LAST LIMIT ?3',
variables: [
i0.Variable<String>(query),
i0.Variable<String>(feedId),
i0.Variable<int>(limit),
],
readsFrom: {feed, articleFts, article},
).map(
(i0.QueryRow row) => i11.FeedArticleQueryResult(
@@ -2691,9 +2696,10 @@ class DefinitionsDrift extends i10.ModularAccessor {
required int snippetLength,
required String query,
String? feedId,
required int limit,
}) {
return customSelect(
'WITH weights AS (SELECT 10.0 AS title_weight, 3.0 AS summary_weight, 1.0 AS content_weight) SELECT a.*, f.icon, highlight(article_fts, 0, ?1, ?2) AS title_highlight, snippet(article_fts, 1, ?1, ?2, ?3, ?4) AS summary_snippet, snippet(article_fts, 2, ?1, ?2, ?3, ?4) AS content_snippet,(bm25(article_fts, weights.title_weight, weights.summary_weight, weights.content_weight))AS weighted_rank FROM article_fts(?5)AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE ?6 IS NULL OR a.feed_id = ?6 ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
'WITH weights AS (SELECT 10.0 AS title_weight, 3.0 AS summary_weight, 1.0 AS content_weight) SELECT a.*, f.icon, highlight(article_fts, 0, ?1, ?2) AS title_highlight, snippet(article_fts, 1, ?1, ?2, ?3, ?4) AS summary_snippet, snippet(article_fts, 2, ?1, ?2, ?3, ?4) AS content_snippet,(bm25(article_fts, weights.title_weight, weights.summary_weight, weights.content_weight))AS weighted_rank FROM article_fts(?5)AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE ?6 IS NULL OR a.feed_id = ?6 ORDER BY weighted_rank ASC, a.created DESC NULLS LAST LIMIT ?7',
variables: [
i0.Variable<String>(beforeMatch),
i0.Variable<String>(afterMatch),
@@ -2701,6 +2707,7 @@ class DefinitionsDrift extends i10.ModularAccessor {
i0.Variable<int>(snippetLength),
i0.Variable<String>(query),
i0.Variable<String>(feedId),
i0.Variable<int>(limit),
],
readsFrom: {feed, articleFts, article},
).map(
@@ -39,6 +39,7 @@ class ArticleSearch extends _$ArticleSearch {
Future<void> search(
String input, {
int snippetLength = 120,
int maxResults = 25,
String matchPrefix = '***',
String matchSuffix = '***',
String ellipsis = '',
@@ -54,6 +55,7 @@ class ArticleSearch extends _$ArticleSearch {
snippetLength: snippetLength,
searchString: input,
feedId: feedId,
limit: maxResults,
)
.get()
.then((value) {
@@ -50,7 +50,7 @@ final class ArticleSearchProvider
}
}
String _$articleSearchHash() => r'cc59a5d3c4b926db9f03ed96db592965ff925b04';
String _$articleSearchHash() => r'48ed3baa560c0e731626f79a8f6ff3dab1e9bc95';
final class ArticleSearchFamily extends $Family
with
@@ -18,7 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:collection/collection.dart';
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
@@ -26,6 +25,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart';
import 'package:weblibre/core/providers/format.dart';
import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/domain/entities/tab_container_selection.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
import 'package:weblibre/features/web_feed/data/models/feed_link.dart';
@@ -206,7 +206,8 @@ class FeedArticleScreen extends HookConsumerWidget {
.addTab(
url: articleLink.uri,
private: isPrivate,
container: const Value(null),
containerSelection:
const TabContainerSelection.unassigned(),
selectTab: true,
);