ponshu-room-lite/lib/widgets/sake_search_delegate.dart

100 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/sake_list_provider.dart';
import '../screens/sake_detail_screen.dart';
import 'dart:io';
import 'common/error_retry_widget.dart';
class SakeSearchDelegate extends SearchDelegate {
final WidgetRef ref;
SakeSearchDelegate(this.ref);
@override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
icon: const Icon(LucideIcons.x),
onPressed: () {
query = '';
},
),
];
}
@override
Widget? buildLeading(BuildContext context) {
return IconButton(
icon: const Icon(LucideIcons.arrowLeft),
onPressed: () {
close(context, null);
},
);
}
@override
Widget buildResults(BuildContext context) {
return _buildList(context);
}
@override
Widget buildSuggestions(BuildContext context) {
return _buildList(context);
}
Widget _buildList(BuildContext context) {
// Phase D6: Use filteredByModeProvider to respect personal/business mode filtering
final rawListAsync = ref.read(filteredByModeProvider);
return rawListAsync.when(
data: (list) {
final filtered = list.where((item) {
final q = query.toLowerCase();
return item.displayData.displayName.toLowerCase().contains(q) ||
item.displayData.displayBrewery.toLowerCase().contains(q) ||
item.displayData.displayPrefecture.toLowerCase().contains(q);
}).toList();
if (filtered.isEmpty) {
return const Center(child: Text('No results found'));
}
return ListView.builder(
itemCount: filtered.length,
itemBuilder: (context, index) {
final sake = filtered[index];
return ListTile(
leading: SizedBox(
width: 40,
height: 40,
child: sake.displayData.imagePaths.isNotEmpty
? Image.file(File(sake.displayData.imagePaths.first), fit: BoxFit.cover)
: const Icon(LucideIcons.image),
),
title: Text(sake.displayData.displayName),
subtitle: Text('${sake.displayData.displayBrewery} / ${sake.displayData.displayPrefecture}'),
onTap: () {
close(context, null);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SakeDetailScreen(sake: sake),
),
);
},
);
},
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, s) => ErrorRetryWidget(
message: '検索に失敗しました',
details: e.toString(),
onRetry: () => ref.refresh(filteredByModeProvider),
compact: true,
),
);
}
}