Skip to content
Snippets Groups Projects
Commit 60b958be authored by doodlezucc's avatar doodlezucc
Browse files

introduce search bar in drawer

parent 1c23e3be
No related branches found
No related tags found
No related merge requests found
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:text_search/text_search.dart';
import '../context.dart'; import '../context.dart';
import '../dialogs/error_dialog.dart'; import '../dialogs/error_dialog.dart';
...@@ -15,12 +16,22 @@ class ClassDrawer extends StatefulWidget { ...@@ -15,12 +16,22 @@ class ClassDrawer extends StatefulWidget {
} }
class _ClassDrawerState extends State<ClassDrawer> { class _ClassDrawerState extends State<ClassDrawer> {
String activeQuery = '';
late final searchTextController = TextEditingController(text: activeQuery);
List<Class> get availableClasses => widget.appContext.classes ?? []; List<Class> get availableClasses => widget.appContext.classes ?? [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fetchLectures().onError((error, _) => _showErrorDialog(error)); fetchLectures().onError((error, _) => _showErrorDialog(error));
searchTextController.addListener(_onSearchChanged);
}
@override
void dispose() {
searchTextController.removeListener(_onSearchChanged);
super.dispose();
} }
void _showErrorDialog(Object? error) { void _showErrorDialog(Object? error) {
...@@ -33,6 +44,58 @@ class _ClassDrawerState extends State<ClassDrawer> { ...@@ -33,6 +44,58 @@ class _ClassDrawerState extends State<ClassDrawer> {
); );
} }
void _onSearchChanged() {
if (searchTextController.text != activeQuery) {
setState(() {
activeQuery = searchTextController.text;
});
}
}
bool _isSelected(int classId) {
return widget.appContext.profile.value!.selectedClasses.contains(classId);
}
List<Class> getFilteredClasses() {
if (activeQuery.trim().isEmpty) {
return availableClasses;
}
final searchables = availableClasses
.map((e) =>
TextSearchItem(e, [TextSearchItemTerm(e.codeWithoutFaculty)]))
.toList();
final search = TextSearch<Class>(searchables);
final results = search.search(activeQuery);
results.sort((a, b) {
if (a.score == b.score) {
return a.object.codeWithoutFaculty
.compareTo(b.object.codeWithoutFaculty);
}
return a.score.compareTo(b.score);
});
return results.map((e) => e.object).toList();
}
List<Class> getFilteredClassesSorted() {
final results = getFilteredClasses();
final modifiedResults =
results.where((cls) => _isSelected(cls.id)).toList();
for (final cls in results) {
if (!_isSelected(cls.id)) {
modifiedResults.add(cls);
}
}
return modifiedResults;
}
Future<void> fetchLectures() async { Future<void> fetchLectures() async {
final allLectures = await widget.appContext.untis.allLectures.fetched; final allLectures = await widget.appContext.untis.allLectures.fetched;
widget.appContext.lectures = allLectures; widget.appContext.lectures = allLectures;
...@@ -41,13 +104,30 @@ class _ClassDrawerState extends State<ClassDrawer> { ...@@ -41,13 +104,30 @@ class _ClassDrawerState extends State<ClassDrawer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final filteredClasses = getFilteredClasses();
return Drawer( return Drawer(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: searchTextController,
decoration: const InputDecoration(
hintText: 'Suche...',
),
),
),
Expanded(
child: ListView.builder( child: ListView.builder(
itemBuilder: (context, index) { itemBuilder: (context, index) {
final cls = availableClasses.elementAt(index); final cls = filteredClasses.elementAt(index);
return ClassListItem(cls: cls, appContext: widget.appContext); return ClassListItem(cls: cls, appContext: widget.appContext);
}, },
itemCount: availableClasses.length, itemCount: filteredClasses.length,
),
),
],
), ),
); );
} }
......
...@@ -5,6 +5,7 @@ class Class extends UntisElement { ...@@ -5,6 +5,7 @@ class Class extends UntisElement {
String get name => json['longName']; String get name => json['longName'];
String get code => json['name']; String get code => json['name'];
String get codeWithoutFaculty => code.substring(1);
Class(super.json); Class(super.json);
} }
...@@ -240,6 +240,22 @@ packages: ...@@ -240,6 +240,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.0" version: "0.6.0"
text_search:
dependency: "direct main"
description:
name: text_search
sha256: e2e826848ba452df6702dc8f1315de90e812eb2303ecec9cc1155f7715bec934
url: "https://pub.dev"
source: hosted
version: "1.0.1"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
......
...@@ -37,6 +37,7 @@ dependencies: ...@@ -37,6 +37,7 @@ dependencies:
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
path_provider: ^2.1.1 path_provider: ^2.1.1
path: ^1.8.3 path: ^1.8.3
text_search: ^1.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment