Requirements:
- Display
dialog
if internet isunavailable
throughout app - Pop off the
dialog
only ifretry
is clicked and internet isavailable
.
Needs suggestion in:
- Pop off the
dialog
only ifretry
is clicked and internet isavailable
.
Approach:
- I am listening to stream and if the connection is available display
rest of app
elsedialog
. But whenretry
is clicked nothing is done.
Why ?
isDialogDisplayed
variable changes is not listened and I can’t havesetState
there.
main
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
var isDialogDisplayed = false;
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
theme: CustomTheme.customTheme(),
home: MultiBlocProvider(
providers: Providers.getProviders,
child: BlocConsumer<ConnectivityCubit, ConnectivityState>(
listener: (context, state) {
});
if (state == ConnectivityState.disconnected) {
isDialogDisplayed = true;
}
if (state == ConnectivityState.connected &&
isDialogDisplayed == true) {
isDialogDisplayed = false;
}
}, builder: (context, state) {
if (state == ConnectivityState.init) {
return const Scaffold(body: ShimmerHome());
}
return isDialogDisplayed
? Scaffold(
body: NoDataHelper(
...
onTap: () {
if (state == ConnectivityState.connected) {
// isDialogDisplayed = false; // Doesn't work
}
}),
)
: state == ConnectivityState.connected
? MaterialApp.router(
...
)
: const Scaffold(body: Center(child: ShimmerHome()));
})),
));
}
Cubit
class ConnectivityCubit extends Cubit<ConnectivityState> {
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult>? _subscription;
late Stream<ConnectivityResult> streamValue;
ConnectivityCubit() : super(ConnectivityState.init) {
streamValue = _connectivity.onConnectivityChanged;
_subscription = _connectivity.onConnectivityChanged.listen((result) {
checkConnectivity(result);
});
}
checkConnectivity(ConnectivityResult result) async {
if (result == ConnectivityResult.none) {
emit(ConnectivityState.disconnected);
} else {
bool isInternetAvailable = await checkInternetConnectivity();
if (isInternetAvailable) {
emit(ConnectivityState.connected);
} else {
emit(ConnectivityState.disconnected);
}
}
}
Future<bool> checkInternetConnectivity() async {
try {
final response = await http
.get(Uri.parse("https://www.google.com"))
.timeout(Duration(seconds: 10)); // Set a 10-second timeout
if (response.statusCode == 200) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
}
@override
Future<void> close() {
_subscription?.cancel();
return super.close();
}
}
What am I looking for ?
- Fix would be highly appreciated.
- I am also open for different architecture and better approach.
2
Answers
I have made a few changes to your logic.
Here is the code I came up with
isDialogDisplayed, The state has not listening of this variables value. So when u update its value nothing happens & u r not using setState olso .. there r few ways to fix this.
declare this (var isDialogDisplayed = false;) into ur ConnectivityCubit then access it
Move ur BlocConsumer into a StateFull widget then update "isDialogDisplayed" with setState({});