home_screen.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. void initState() {
  24. super.initState();
  25. ref.listenManual(sourceChangeProvider, (_, __) {
  26. ref.invalidate(creatorsProvider);
  27. ref.invalidate(_searchQuery);
  28. _searchController.clear();
  29. });
  30. }
  31. @override
  32. Widget build(BuildContext context) {
  33. ref.watch(sourceChangeProvider);
  34. final filteredCreators = ref.watch(filteredCreatorsProvider(ref.watch(_searchQuery)));
  35. return DefaultTabController(
  36. length: 2,
  37. child: Scaffold(
  38. appBar: AppBar(
  39. title: _buildSearchField(ref),
  40. actions: [
  41. IconButton(
  42. icon: const Icon(Icons.refresh),
  43. onPressed: () => ref.invalidate(creatorsProvider),
  44. ),
  45. ],
  46. ),
  47. body: _buildCreatorsList(filteredCreators),
  48. ),
  49. );
  50. }
  51. Widget _buildSearchField(WidgetRef ref) {
  52. return TextField(
  53. controller: _searchController,
  54. decoration: InputDecoration(
  55. hintText: 'Search creators...',
  56. border: InputBorder.none,
  57. suffixIcon: IconButton(
  58. icon: const Icon(Icons.clear),
  59. onPressed: () {
  60. _searchController.clear();
  61. ref.read(_searchQuery.notifier).state = '';
  62. },
  63. ),
  64. ),
  65. onChanged: (value) => ref.read(_searchQuery.notifier).state = value,
  66. );
  67. }
  68. Widget _buildCreatorsList(AsyncValue<List<Creator>> creatorsAsync) {
  69. return RefreshIndicator(
  70. onRefresh: () => ref.refresh(filteredCreatorsProvider(ref.read(_searchQuery)).future),
  71. child: creatorsAsync.when(
  72. loading: () => const Center(child: CircularProgressIndicator()),
  73. error: (error, _) => Center(child: Text(error.toString())),
  74. data: (creators) => creators.isEmpty
  75. ? const Center(child: Text('No matching creators found'))
  76. : ListView.separated(
  77. padding: const EdgeInsets.all(16),
  78. itemCount: creators.length,
  79. separatorBuilder: (_, __) => const SizedBox(height: 8),
  80. itemBuilder: (context, index) => CreatorCard(creator: creators[index]),
  81. ),
  82. ),
  83. );
  84. }
  85. /*
  86. Widget _buildGlobalPostsGrid() {
  87. final postsAsync = ref.watch(postsProvider(('82522', 'patreon','')));
  88. return postsAsync.when(
  89. loading: () => const Center(child: CircularProgressIndicator()),
  90. error: (error, _) => Center(child: Text(error.toString())),
  91. data: (posts) => CustomScrollView(
  92. slivers: [
  93. SliverAppBar(),
  94. SliverList(
  95. delegate: SliverChildBuilderDelegate(
  96. (context, index) => PostContainer(post: posts[index]),
  97. childCount: posts.length,
  98. ),
  99. ),
  100. ],
  101. ),
  102. );
  103. }
  104. */
  105. }