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

introduce search bar in drawer

parent 1c23e3be
Branches feature/AliciMuhamed
No related tags found
No related merge requests found
import 'package:flutter/material.dart';
import 'package:text_search/text_search.dart';
import '../context.dart';
import '../dialogs/error_dialog.dart';
......@@ -15,12 +16,22 @@ class ClassDrawer extends StatefulWidget {
}
class _ClassDrawerState extends State<ClassDrawer> {
String activeQuery = '';
late final searchTextController = TextEditingController(text: activeQuery);
List<Class> get availableClasses => widget.appContext.classes ?? [];
@override
void initState() {
super.initState();
fetchLectures().onError((error, _) => _showErrorDialog(error));
searchTextController.addListener(_onSearchChanged);
}
@override
void dispose() {
searchTextController.removeListener(_onSearchChanged);
super.dispose();
}
void _showErrorDialog(Object? error) {
......@@ -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 {
final allLectures = await widget.appContext.untis.allLectures.fetched;
widget.appContext.lectures = allLectures;
......@@ -41,13 +104,30 @@ class _ClassDrawerState extends State<ClassDrawer> {
@override
Widget build(BuildContext context) {
final filteredClasses = getFilteredClasses();
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(
itemBuilder: (context, index) {
final cls = availableClasses.elementAt(index);
final cls = filteredClasses.elementAt(index);
return ClassListItem(cls: cls, appContext: widget.appContext);
},
itemCount: availableClasses.length,
itemCount: filteredClasses.length,
),
),
],
),
);
}
......
......@@ -5,6 +5,7 @@ class Class extends UntisElement {
String get name => json['longName'];
String get code => json['name'];
String get codeWithoutFaculty => code.substring(1);
Class(super.json);
}
......@@ -240,6 +240,22 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
......
......@@ -37,6 +37,7 @@ dependencies:
cupertino_icons: ^1.0.2
path_provider: ^2.1.1
path: ^1.8.3
text_search: ^1.0.1
dev_dependencies:
flutter_test:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment