Advertisement
Guest User

Untitled

a guest
Dec 12th, 2024
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 4.45 KB | Source Code | 0 0
  1. import 'dart:async';
  2. import 'dart:math';
  3.  
  4. import 'package:dio/dio.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter_riverpod/flutter_riverpod.dart';
  7.  
  8. void main() {
  9.   runApp(
  10.     ProviderScope(child: const MainApp()),
  11.   );
  12. }
  13.  
  14. class MainApp extends StatelessWidget {
  15.   const MainApp({super.key});
  16.  
  17.   @override
  18.   Widget build(BuildContext context) {
  19.     return const MaterialApp(
  20.       home: PostScreen(),
  21.     );
  22.   }
  23. }
  24.  
  25. final baseUrlProvider = StateProvider<String>((ref) {
  26.   return 'https://mybackend.com';
  27. });
  28.  
  29. final perPageProvider = StateProvider<int>((ref) {
  30.   return 1;
  31. });
  32.  
  33. final dioProvider = Provider.family<Dio, String>((ref, url) {
  34.   final dio = Dio(
  35.     BaseOptions(
  36.       baseUrl: url,
  37.     ),
  38.   );
  39.  
  40.   return dio;
  41. });
  42.  
  43. final postRepoProvider =
  44.     Provider.autoDispose.family<PostRepository, String>((ref, baseUrl) {
  45.   final dio = ref.watch(dioProvider(baseUrl));
  46.  
  47.   return PostRepository(dio: dio);
  48. });
  49.  
  50. class PostRepository {
  51.   PostRepository({required this.dio});
  52.   final Dio dio;
  53.   final Random random = Random();
  54.  
  55.   Future<List<String>> fetchPosts({required int perPage}) async {
  56.     await Future.delayed(const Duration(milliseconds: 500));
  57.     return List.generate(
  58.         perPage,
  59.         (index) =>
  60.             'Post $perPage - ${random.nextInt(perPage)}, ${dio.options.baseUrl}');
  61.   }
  62. }
  63.  
  64. final postsProvider = AsyncNotifierProvider.autoDispose
  65.     .family<PostNotifier, List<String>, String>(PostNotifier.new);
  66.  
  67. class PostNotifier
  68.     extends AutoDisposeFamilyAsyncNotifier<List<String>, String> {
  69.   @override
  70.   FutureOr<List<String>> build(String arg) {
  71.     final perPage = ref.watch(perPageProvider);
  72.     return ref.watch(postRepoProvider(arg)).fetchPosts(
  73.           perPage: perPage,
  74.         );
  75.   }
  76. }
  77.  
  78. class PostScreen extends ConsumerWidget {
  79.   const PostScreen({super.key});
  80.  
  81.   @override
  82.   Widget build(BuildContext context, WidgetRef ref) {
  83.     return const Scaffold(
  84.       body: SafeArea(
  85.         child: Column(
  86.           children: [
  87.             Row(
  88.               children: [
  89.                 UpdateUrlButton(),
  90.                 UpdatePerPageButton(),
  91.               ],
  92.             ),
  93.             PerPageText(),
  94.             UrlDisplayText(),
  95.             Expanded(child: PostList()),
  96.           ],
  97.         ),
  98.       ),
  99.     );
  100.   }
  101. }
  102.  
  103. class UpdateUrlButton extends ConsumerWidget {
  104.   const UpdateUrlButton({super.key});
  105.  
  106.   @override
  107.   Widget build(BuildContext context, WidgetRef ref) {
  108.     final rnd = Random();
  109.  
  110.     return FilledButton(
  111.       onPressed: () {
  112.         ref.read(baseUrlProvider.notifier).state =
  113.             'https://example.com/${rnd.nextInt(100)}';
  114.       },
  115.       child: const Text('Update URL'),
  116.     );
  117.   }
  118. }
  119.  
  120. class UpdatePerPageButton extends ConsumerWidget {
  121.   const UpdatePerPageButton({super.key});
  122.  
  123.   @override
  124.   Widget build(BuildContext context, WidgetRef ref) {
  125.     final perPage = ref.watch(perPageProvider);
  126.  
  127.     return FilledButton(
  128.       onPressed: () {
  129.         ref.read(perPageProvider.notifier).state = perPage + 1;
  130.       },
  131.       child: const Text('Update Per Page'),
  132.     );
  133.   }
  134. }
  135.  
  136. class PostList extends ConsumerWidget {
  137.   const PostList({super.key});
  138.  
  139.   @override
  140.   Widget build(BuildContext context, WidgetRef ref) {
  141.     final baseUrl = ref.watch(baseUrlProvider);
  142.  
  143.     return ref.watch(postsProvider(baseUrl)).when(
  144.           data: (posts) {
  145.             return ListView.builder(
  146.               itemCount: posts.length,
  147.               itemBuilder: (context, index) {
  148.                 final data = posts[index].split(', ');
  149.  
  150.                 return ListTile(
  151.                   title: Text(data[0]),
  152.                   subtitle: Text(data[1]),
  153.                 );
  154.               },
  155.             );
  156.           },
  157.           loading: () => const Center(
  158.             child: CircularProgressIndicator(),
  159.           ),
  160.           error: (error, stackTrace) => Center(
  161.             child: Text('Error: $error'),
  162.           ),
  163.         );
  164.   }
  165. }
  166.  
  167. class PerPageText extends ConsumerWidget {
  168.   const PerPageText({super.key});
  169.  
  170.   @override
  171.   Widget build(BuildContext context, WidgetRef ref) {
  172.     final count = ref.watch(perPageProvider);
  173.  
  174.     return Text('Per page: $count');
  175.   }
  176. }
  177.  
  178. class UrlDisplayText extends ConsumerWidget {
  179.   const UrlDisplayText({super.key});
  180.  
  181.   @override
  182.   Widget build(BuildContext context, WidgetRef ref) {
  183.     final url = ref.watch(baseUrlProvider);
  184.  
  185.     return Text('URL: $url');
  186.   }
  187. }
  188.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement