Testfilter, Listenbreite
This commit is contained in:
@@ -11,11 +11,45 @@ import 'movie_add_screen.dart';
|
||||
|
||||
enum _ExportFormat { csv, xlsx }
|
||||
|
||||
class MovieListScreen extends ConsumerWidget {
|
||||
class MovieListScreen extends ConsumerStatefulWidget {
|
||||
const MovieListScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
ConsumerState<MovieListScreen> createState() => _MovieListScreenState();
|
||||
}
|
||||
|
||||
class _MovieListScreenState extends ConsumerState<MovieListScreen> {
|
||||
final TextEditingController _moviePrefixController = TextEditingController();
|
||||
String _moviePrefix = '';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_moviePrefixController.addListener(() {
|
||||
final next = _moviePrefixController.text;
|
||||
if (next == _moviePrefix) return;
|
||||
setState(() {
|
||||
_moviePrefix = next;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_moviePrefixController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
String get _normalizedMoviePrefix => _moviePrefix.trim().toLowerCase();
|
||||
|
||||
bool _matchesMoviePrefix(String title) {
|
||||
final prefix = _normalizedMoviePrefix;
|
||||
if (prefix.isEmpty) return true;
|
||||
return title.trim().toLowerCase().startsWith(prefix);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final filter = ref.watch(movieFilterProvider);
|
||||
final moviesAsync = ref.watch(moviesStreamProvider);
|
||||
|
||||
@@ -24,9 +58,43 @@ class MovieListScreen extends ConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
StatusChip(
|
||||
selected: filter,
|
||||
onChanged: (f) => ref.read(movieFilterProvider.notifier).state = f,
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final searchWidth = constraints.maxWidth >= 360
|
||||
? 280.0
|
||||
: constraints.maxWidth;
|
||||
|
||||
return Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 8,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
StatusChip(
|
||||
selected: filter,
|
||||
onChanged: (f) => ref.read(movieFilterProvider.notifier).state = f,
|
||||
),
|
||||
SizedBox(
|
||||
width: searchWidth,
|
||||
child: TextField(
|
||||
controller: _moviePrefixController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Filme filtern...',
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
isDense: true,
|
||||
border: const OutlineInputBorder(),
|
||||
suffixIcon: _moviePrefix.isEmpty
|
||||
? null
|
||||
: IconButton(
|
||||
onPressed: _moviePrefixController.clear,
|
||||
icon: const Icon(Icons.clear),
|
||||
tooltip: 'Filter loeschen',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Align(
|
||||
@@ -137,8 +205,15 @@ class MovieListScreen extends ConsumerWidget {
|
||||
Expanded(
|
||||
child: moviesAsync.when(
|
||||
data: (items) {
|
||||
final itemsSorted = [...items]
|
||||
final itemsSorted = items
|
||||
.where((m) => _matchesMoviePrefix(m.title))
|
||||
.toList()
|
||||
..sort((a, b) => a.title.toLowerCase().compareTo(b.title.toLowerCase()));
|
||||
if (itemsSorted.isEmpty) {
|
||||
return const Center(
|
||||
child: Text('Keine Filme fuer den aktuellen Filter.'),
|
||||
);
|
||||
}
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
// ignore: unused_result
|
||||
@@ -398,3 +473,4 @@ class MovieListScreen extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user