home_screen.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:veloe_kemono_party_flutter/main.dart';
  4. import 'package:veloe_kemono_party_flutter/models/creator.dart';
  5. import 'package:veloe_kemono_party_flutter/pages/widgets/creator_card.dart';
  6. class HomeScreen extends ConsumerStatefulWidget {
  7. const HomeScreen({super.key});
  8. @override
  9. ConsumerState<HomeScreen> createState() => _HomeScreenState();
  10. }
  11. class _HomeScreenState extends ConsumerState<HomeScreen> {
  12. final TextEditingController _searchController = TextEditingController();
  13. final _searchQuery = StateProvider<String>((ref) => '');
  14. final filteredCreatorsProvider = FutureProvider.autoDispose.family<List<Creator>, String>(
  15. (ref, query) async {
  16. final originalList = await ref.watch(creatorsProvider.future);
  17. return originalList.where(
  18. (creator) => creator.name.toLowerCase().contains(query.toLowerCase())
  19. ).toList();
  20. },
  21. );
  22. @override
  23. Widget build(BuildContext context) {
  24. return DefaultTabController(
  25. length: 2,
  26. child: Scaffold(
  27. appBar: AppBar(
  28. title: _buildSearchField(),
  29. actions: [
  30. IconButton(
  31. icon: const Icon(Icons.refresh),
  32. onPressed: () => ref.invalidate(filteredCreatorsProvider),
  33. ),
  34. ],
  35. ),
  36. body: _buildCreatorsList(ref.watch(
  37. filteredCreatorsProvider(ref.watch(_searchQuery))
  38. )),
  39. ),
  40. );
  41. }
  42. Widget _buildSearchField() {
  43. return TextField(
  44. controller: _searchController,
  45. decoration: InputDecoration(
  46. hintText: 'Search creators...',
  47. border: InputBorder.none,
  48. suffixIcon: IconButton(
  49. icon: const Icon(Icons.clear),
  50. onPressed: () {
  51. _searchController.clear();
  52. ref.read(_searchQuery.notifier).state = '';
  53. },
  54. ),
  55. ),
  56. onChanged: (value) => ref.read(_searchQuery.notifier).state = value,
  57. );
  58. }
  59. Widget _buildCreatorsList(AsyncValue<List<Creator>> creatorsAsync) {
  60. return RefreshIndicator(
  61. onRefresh: () => ref.refresh(filteredCreatorsProvider(ref.read(_searchQuery)).future),
  62. child: creatorsAsync.when(
  63. loading: () => const Center(child: CircularProgressIndicator()),
  64. error: (error, _) => Center(child: Text(error.toString())),
  65. data: (creators) => creators.isEmpty
  66. ? const Center(child: Text('No matching creators found'))
  67. : ListView.separated(
  68. padding: const EdgeInsets.all(16),
  69. itemCount: creators.length,
  70. separatorBuilder: (_, __) => const SizedBox(height: 8),
  71. itemBuilder: (context, index) => CreatorCard(creator: creators[index]),
  72. ),
  73. ),
  74. );
  75. }
  76. /*
  77. Widget _buildGlobalPostsGrid() {
  78. final postsAsync = ref.watch(postsProvider(('82522', 'patreon','')));
  79. return postsAsync.when(
  80. loading: () => const Center(child: CircularProgressIndicator()),
  81. error: (error, _) => Center(child: Text(error.toString())),
  82. data: (posts) => CustomScrollView(
  83. slivers: [
  84. SliverAppBar(),
  85. SliverList(
  86. delegate: SliverChildBuilderDelegate(
  87. (context, index) => PostContainer(post: posts[index]),
  88. childCount: posts.length,
  89. ),
  90. ),
  91. ],
  92. ),
  93. );
  94. }
  95. */
  96. }