I am trying to greet the user based on the time of the day (i.e. Good Morning/Afternoon/Evening), and I am thinking of doing this using Riverpod, so that the message changes without the need of rebuild.
this is my attempt:
greeting_message_provider.dart
abstract class GreetingMessageClient {
Stream<String> getMessage();
}
class GreetingMessageProvider implements GreetingMessageClient {
@override
Stream<String> getMessage() async* {
while (true) {
int hour = DateTime.now().hour;
if (hour < 5) {
yield 'Good Evening,';
} else if (hour < 12) {
yield 'Good Morning,';
} else if (hour < 17) {
yield 'Good Afternoon,';
} else {
yield 'Good Evening,';
}
// to only update the value every one hour
await Future.delayed(const Duration(hours: 1));
}
}
}
home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'greeting_message_provider.dart';
final greetingMessageClient = Provider<GreetingMessageClient>(
(ref) => GreetingMessageProvider(),
);
final greetingMessageProvider = StreamProvider<String>(
(ref) => ref.watch(greetingMessageClient).getMessage(),
);
class HomeScreen extends ConsumerStatefulWidget {
const HomeScreen({super.key});
@override
ConsumerState<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends ConsumerState<HomeScreen> {
@override
Widget build(BuildContext context) {
final AsyncValue<String> greetingMessage =
ref.watch(greetingMessageProvider);
return Scaffold(
body: Center(
child: Text(
greetingMessage
.when(
data: (String msg) => msg,
error: (Object e, _) => e,
loading: () => 'Hi,')
.toString(),
),
),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'home_screen.dart';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'RiverPod Demo',
home: HomeScreen(),
);
}
}
I studies the Riverpod from there example apps and from ResoCoder's guide. And after that I tried to imitate them.
I am new to Flutter & Riverpod Statemanagement, so wanna ask is this how to do it or not. Also I am skeptical for the use of while(true)
function.
CodePudding user response:
your method will work just fine, you could also simplify it more using Stream.periodic
final greetMsgStream = StreamProvider<String>((ref) {
return Stream.periodic(const Duration(hours: 1), (_) {
int hour = DateTime.now().hour;
if (hour < 5) {
return 'Good Evening,';
} else if (hour < 12) {
return 'Good Morning,';
} else if (hour < 17) {
return 'Good Afternoon,';
} else {
return 'Good Evening,';
}
});
});