Skip to content

Commit

Permalink
Search improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Yustas committed Feb 5, 2025
1 parent 9e83fe6 commit 29ea6d5
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 46 deletions.
4 changes: 2 additions & 2 deletions lib/i18n/ua.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ const String appTitle = "Правопис";
const String searchTitle = "Пошук";
const String searchHint = "літера або слово";
const String searchNotFond = "нічого не знайдено";
const String searchTry = "Cпробуйте:";
const searchExamples = ["архі", "ї", "апостроф", "чергування"];
const String searchTry = "Cпробуйте";
const searchExamples = ["архі", "ї", "апостроф", "чергування", "при", "крапка"];
1 change: 1 addition & 0 deletions lib/models/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ class Content {
final int pos;

get numeration => prefix.isEmpty ? '' : '$prefix ';
get name => numeration + data;
}
18 changes: 11 additions & 7 deletions lib/models/search_data.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
class SearchData {
import 'content.dart';

class SearchData extends Content {
const SearchData({
required this.contentId,
required this.data,
required this.prefix,
required super.data,
required super.id,
required super.level,
required super.parent,
required super.pos,
required super.prefix,
required this.path,
});

final int contentId;
final String data;
final String prefix;
final String path;
}
48 changes: 37 additions & 11 deletions lib/repository/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:mova/models/article.dart';
import 'package:mova/models/page_data.dart';

import '../i18n/ua.dart';
import '../models/search_data.dart';

Iterable<int> uniqueList(Iterable<int> list) {
return list.toSet().toList();
Expand Down Expand Up @@ -92,26 +93,42 @@ Content contentRow(Map row) {
);
}

Content searchRow(Map row) {
return Content(
SearchData searchRow(Map row, List<Content> content) {
return SearchData(
id: row['content_id'] as int,
level: row['content_level'] as int,
data: row['content_data'] as String,
prefix: row['content_prefix'] as String,
parent: row['content_parent'] as int,
pos: row['content_pos'] as int,
prefix: row['content_prefix'] as String,
data: row['content_data'] as String,
path: content.firstWhere((c) => c.id == row['content_parent']).name,
);
}

Future<List<Content>> loadContent({int parent = 0}) async {
Future<List<Content>> loadContentByParent({int parent = 0}) async {
Database db = await initDb();

List<Map> rows = await db.query(
'content',
columns: ['id', 'level', 'parent', 'data', 'prefix', 'pos'],
where: 'parent = ?',
whereArgs: [parent],
orderBy: 'pos',
);

return rows.isNotEmpty
? rows.map((row) => contentRow(row)).toList()
: List.empty();
}

Future<List<Content>> loadContentById(Iterable<int> ids) async {
Database db = await initDb();
Iterable<String> placeholders = ids.map((id) => '?');

List<Map> rows = await db.query(
'content',
columns: ['id', 'level', 'parent', 'data', 'prefix', 'pos'],
where: 'id IN (${placeholders.join(',')})',
whereArgs: [...ids],
);

return rows.isNotEmpty
Expand Down Expand Up @@ -158,7 +175,7 @@ Future<List<Article>> loadArticles({int parentId = 0}) async {
}

Future<PageData> loadPage({int parentContentId = 0}) async {
List<Content> content = await loadContent(parent: parentContentId);
List<Content> content = await loadContentByParent(parent: parentContentId);
List<int> contentIds = content.map((c) => c.id).toList();

List<Article> articles = contentIds.isEmpty
Expand All @@ -168,7 +185,7 @@ Future<PageData> loadPage({int parentContentId = 0}) async {
return PageData(content: content, articles: articles);
}

Future<List<Content>> findContent({String needle = ''}) async {
Future<List<SearchData>> findContent({String needle = ''}) async {
var db = await initDb();
if (needle.isEmpty) {
return List.empty();
Expand Down Expand Up @@ -197,6 +214,7 @@ Future<List<Content>> findContent({String needle = ''}) async {
where: where,
whereArgs: whereArgs,
groupBy: 'content_id',

);

Iterable<int> ids = rowsExactly.map((row) => row['content_id'] as int);
Expand Down Expand Up @@ -224,10 +242,17 @@ Future<List<Content>> findContent({String needle = ''}) async {
);

List<Map> rows = rowsExactly + rowsStarFrom;
Iterable<int> contentIds = rows.isNotEmpty
? rows.map((row) => row['content_parent'] as int)
: [];

return rows.isNotEmpty
? rows.map((row) => searchRow(row)).toList()
List<Content> content = contentIds.isNotEmpty
? await loadContentById(contentIds)
: List.empty();

return rows.isNotEmpty
? rows.map((row) => searchRow(row, content)).toList()
: List<SearchData>.empty();
}

const homeContent = Content(
Expand All @@ -239,11 +264,12 @@ const homeContent = Content(
prefix: '',
);

const searchContent = Content(
const searchContent = SearchData(
id: 0,
level: 0,
data: searchTitle,
parent: 0,
pos: 0,
prefix: '',
path: ""
);
30 changes: 19 additions & 11 deletions lib/utils/search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:mova/widgets/error.dart';
import 'package:mova/widgets/loading.dart';
import 'package:mova/widgets/search_list.dart';

import '../models/content.dart';
import '../models/search_data.dart';

class ContentSearchDelegate extends SearchDelegate {
ContentSearchDelegate() : super(searchFieldLabel: searchHint);
Expand Down Expand Up @@ -45,11 +45,11 @@ class ContentSearchDelegate extends SearchDelegate {

@override
Widget buildSuggestions(BuildContext context) {
final Future<List<Content>> searchData = findContent(needle: query);
final Future<List<SearchData>> searchData = findContent(needle: query);

return FutureBuilder<List<Content>>(
return FutureBuilder<List<SearchData>>(
future: searchData,
builder: (BuildContext context, AsyncSnapshot<List<Content>> snapshot) {
builder: (BuildContext context, AsyncSnapshot<List<SearchData>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.isNotEmpty) {
return SearchList(results: snapshot.data!);
Expand Down Expand Up @@ -80,12 +80,20 @@ Widget SearchHint(BuildContext context, callback) {
child: Column(
children:[
const SizedBox(height: 20,),
const Text(searchTry),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
...examples.map((text) => SearchExample(context, text, callback))
],
Text(
searchTry,
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
color: Theme.of(context).hintColor,
),
),
const SizedBox(height: 20,),
Expanded(
child: GridView.count(
crossAxisCount: 4,
children: List.from([
...examples.map((text) => SearchExample(context, text, callback))
],),
),
)
]
),
Expand All @@ -97,7 +105,7 @@ Widget SearchExample(BuildContext context, text, onTap) {
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text),
child: Center(child: Text(text, textAlign: TextAlign.center,)),
),
),
onTap: () => onTap(text),
Expand Down
9 changes: 2 additions & 7 deletions lib/widgets/content_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ContentList extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(16.0, 10.0, 16.0, 0),
child: Container(
decoration: BoxDecoration(
//color: Theme.of(context).colorScheme.surfaceContainerLowest,
// color: Theme.of(context).colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.symmetric(horizontal: 16.0),
Expand All @@ -39,10 +39,6 @@ class ContentList extends StatelessWidget {
// ? Text(content[index].numeration, style: Theme.of(context).textTheme.titleLarge)
// : Text('•', style: Theme.of(context).textTheme.titleLarge);

String numerationText = content[index].numeration.toString().isNotEmpty
? content[index].numeration + ' '
: '';

return InkWell(
onTap: () {
openContent(
Expand All @@ -55,7 +51,6 @@ class ContentList extends StatelessWidget {
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
//color: Color.fromARGB(70, 150, 150, 150)
color: Theme.of(context).colorScheme.outlineVariant,
))),
child: Row(
Expand All @@ -71,7 +66,7 @@ class ContentList extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('$numerationText${content[index].data}',
Text('${content[index].name}',
style: Theme.of(context).textTheme.titleLarge)
],
),
Expand Down
27 changes: 19 additions & 8 deletions lib/widgets/search_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import 'package:flutter/material.dart';
import 'package:mova/repository/content.dart';

import '../models/content.dart';
import '../models/search_data.dart';
import '../screens/pravopys.dart';

class SearchList extends StatelessWidget {
const SearchList({super.key, required this.results});

final List<Content> results;
final List<SearchData> results;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -37,21 +38,31 @@ class SearchList extends StatelessWidget {
);
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 6.0),
decoration: const BoxDecoration(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerLowest,
borderRadius: BorderRadius.circular(20),
border: Border(
bottom: BorderSide(
color: Color.fromARGB(70, 150, 150, 150)))),
color: Theme.of(context).colorScheme.outlineVariant,
))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [Text(results[index].prefix)],
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(results[index].data)],
children: [
Text(
results[index].path,
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant
),

),
const SizedBox(height: 10,),
Text(results[index].name),
],
),
),
const Column(
Expand Down

0 comments on commit 29ea6d5

Please sign in to comment.