I’m trying to loop the AlertDialog that says "No Internet Connection. Please check your internet connection and try again.". I want the dialog to keep showing when I press the "Retry" button if there’s no internet connection but once its already connected to the internet, the alertdialog will stop and continue to login.
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:namer_app/Passenger_Widgets/GuestRegistration.dart';
import 'package:namer_app/login_auth/login_method.dart';
import 'package:namer_app/login_auth/resetpass_method.dart';
import 'package:namer_app/Passenger_Widgets/ScheduleWindow.dart';
import 'package:namer_app/prf_login/my_buttons.dart';
import 'package:namer_app/prf_login/my_textfields.dart';
import 'package:namer_app/prf_login/snackbar_ext.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: 'https://',
anonKey:
'0000',
);
final prefs = await SharedPreferences.getInstance();
final bool isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
List<ConnectivityResult> connectivityResults = await (Connectivity().checkConnectivity());
ConnectivityResult connectivityResult = connectivityResults.first;
runApp(
MaterialApp(
home: MyApp(connectivityResult, prefs, isLoggedIn),
),
);
}
class MyApp extends StatelessWidget {
final ConnectivityResult connectivityResult;
final SharedPreferences prefs;
final bool isLoggedIn;
MyApp(this.connectivityResult, this.prefs, this.isLoggedIn);
@override
Widget build(BuildContext context) {
if (connectivityResult == ConnectivityResult.none) {
// Show a popup to inform the user that there's no internet connection
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('No Internet Connection'),
content: Text('Please check your internet connection and try again.'),
actions: [
ElevatedButton(
child: Text('Retry'),
onPressed: () => Navigator.pop(context),
),
],
),
);
});
}
return MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(
color: Colors.white,
), // Set back button color to white
),
),
home: isLoggedIn ? ScheduleWindow(prefs: prefs) : LOGIN_passenger(),
);
}
}
class LOGIN_passenger extends StatefulWidget {
LOGIN_passenger({super.key});
@override
State<LOGIN_passenger> createState() => _LOGIN_passengerState();
}
class _LOGIN_passengerState extends State<LOGIN_passenger> {
GlobalKey<FormState> _formkey = GlobalKey();
bool _isLoading = false;
late TextEditingController emailController;
late TextEditingController passController;
//LOGIN ATTEMPTS TIMER
int _loginAttempts = 0;
bool _isCooldown = false;
Timer? _cooldownTimer;
int _cooldownTime = 60; // Cooldown time in seconds
@override
void initState() {
super.initState();
emailController = TextEditingController();
passController = TextEditingController();
}
@override
void dispose() {
emailController.dispose();
passController.dispose();
_cooldownTimer?.cancel();
super.dispose();
}
bool isValidEmail(String input) {
final emailRegex = RegExp(r'^[^@]+@[^@]+.[^@]+');
return emailRegex.hasMatch(input);
}
bool isValidPhoneNumber(String input) {
final phoneWithPrefix = '63$input';
final phoneRegex = RegExp(r'^63d{10}$');
return phoneRegex.hasMatch(phoneWithPrefix);
}
void insertPrefs(AuthResponse response) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
if (response.user != null) {
final user = response.user?.id;
final selectQuery = await Supabase.instance.client
.from('registered_passenger')
.select()
.eq('user_id', user.toString());
if (selectQuery.isNotEmpty) {
prefs.setBool('isLoggedIn', true);
prefs.setString('userId', selectQuery[0]['user_id']);
prefs.setString('lastName', selectQuery[0]['last_name']);
prefs.setString('firstName', selectQuery[0]['first_name']);
prefs.setString('middleInitial', selectQuery[0]['middle_initial']);
prefs.setString('email', selectQuery[0]['email']);
prefs.setString('password', selectQuery[0]['password']);
prefs.setString('profession', selectQuery[0]['profession']);
String contactNumber = selectQuery[0]['phone'];
prefs.setString('contactNumber', contactNumber.substring(2));
prefs.setString('age', selectQuery[0]['age']);
prefs.setString('gender', selectQuery[0]['gender']);
prefs.setString('region', selectQuery[0]['region']);
prefs.setString('province', selectQuery[0]['province']);
prefs.setString('municipality', selectQuery[0]['municipality']);
prefs.setString('barangay', selectQuery[0]['barangay']);
prefs.setString('titlePage', 'Schedule');
navigatetoSched(prefs);
}
}
}
void _login() async {
final connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
context.showSnackbar(
message: 'No internet connection. Please check your internet connection and try again.',
backgroundColor: Colors.red,
);
setState(() {
_isLoading = false; // Reset _isLoading so the button can be clicked again
});
return;
}
if (_isCooldown) {
context.showSnackbar(
message: 'Too many attempts. Please wait $_cooldownTime seconds.',
backgroundColor: Colors.red,
);
return;
}
final isValid = _formkey.currentState?.validate();
if (isValid != null && isValid) {
setState(() {
_isLoading = true;
});
try {
final input = emailController.text;
final password = passController.text;
final response;
if (isValidEmail(input)) {
response = await Supabase.instance.client.auth.signInWithPassword(
email: input,
password: password,
);
insertPrefs(response);
} else if (isValidPhoneNumber(input)) {
response = await Supabase.instance.client.auth.signInWithPassword(
phone: '63$input',
password: password,
);
insertPrefs(response);
} else {
throw AuthException('Invalid email or phone number');
}
setState(() {
_isLoading = false;
});
context.showSnackbar(
message: 'LOGIN SUCCESSFUL',
backgroundColor: Colors.green,
);
} on AuthException catch (e) {
if (e.message.contains('SocketException')) {
context.showSnackbar(
message: 'No internet connection. Please check your internet connection and try again.',
backgroundColor: Colors.red,
);
} else {
context.showSnackbar(
message: e.message,
backgroundColor: Colors.red,
);
}
setState(() {
_isLoading = false; // Reset _isLoading in case of an error
});
} catch (e) {
context.showSnackbar(
message: e.toString(),
backgroundColor: Colors.red,
);
setState(() {
_isLoading = false; // Reset _isLoading for other types of errors
});
}
}
}
/*Future<void> _logout() async {
if (selectedFerry != null) {
await _supabaseClient
.from('boats')
.update({'is_active': false}) // Set ferry as inactive
.eq('boat_name', selectedFerry!)
}
// Continue with logout process
}*/
void _handleLoginFailure(String errorMessage) {
context.showSnackbar(message: errorMessage, backgroundColor: Colors.red);
setState(() {
_isLoading = false;
_loginAttempts++;
});
if (_loginAttempts >= 3) {
_startCooldown();
}
}
void _startCooldown() {
setState(() {
_isCooldown = true;
});
_cooldownTimer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
_cooldownTime--;
});
if (_cooldownTime == 0) {
timer.cancel();
setState(() {
_isCooldown = false;
_loginAttempts = 0;
_cooldownTime = 60; // Reset cooldown time
});
}
});
}
void navigatetoSched(SharedPreferences prefs) {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => ScheduleWindow(prefs: prefs)),
(route) => false);
}
void _forgotPassword() {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => ResetpassMethod()),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(270.0),
child: AppBar(
centerTitle: true,
flexibleSpace: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/bgprf1.png'),
fit: BoxFit.fill,
),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/prf_logo.png',
width: 155.0,
height: 155.0,
),
SizedBox(height: 10.0),
Text(
'PASIG RIVER FERRY PORTAL',
style: TextStyle(
color: Color(0xFF33385F),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
),
backgroundColor: Colors.white,
body: Container(
padding: EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Form(
key: _formkey, // Associate the Form with the GlobalKey
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 30.0),
Text(
'WELCOME',
style: TextStyle(
color: Color(0xFF33385F),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Text(
'Please, Login to your account!',
style: TextStyle(
color: Color(0xFF666666),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20.0),
// Textfield for Email/Username
Textfield_auth(
controller: emailController,
prefixIcon: Icon(Icons.person),
hintText: 'Enter Email/Username',
labelText: 'Email/Username',
obscureText: false,
),
const SizedBox(height: 15.0),
// Textfield for Password
Textfield_authpass(
controller: passController,
prefixIcon: Icon(Icons.lock),
hintText: 'Enter Password',
labelText: 'Password',
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: _forgotPassword,
child: Text(
'Forgot Password?',
style: TextStyle(
color: Color(0xFF666666),
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
],
),
SizedBox(height: 30.0),
LoginButton(
onTap: _isLoading || _isCooldown ? null : _login,
),
if (_isCooldown)
Center(
child: Text(
'Please wait $_cooldownTime seconds to try again.',
style: TextStyle(
color: Colors.red,
fontSize: 16,
),
),
),
const SizedBox(height: 20.0),
// Continue with Google account
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: Row(
children: [
Expanded(
child: Divider(
thickness: 1,
color: Colors.grey,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Text(
'OR',
style: TextStyle(color: Colors.grey),
),
),
Expanded(
child: Divider(
thickness: 1,
color: Colors.grey,
),
),
],
),
),
SizedBox(height: 30.0),
// GOOGLE SIGN IN
Center(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
const SizedBox(height: 5),
GuestButton(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PrfGuestRegistration(),
),
);
},
),
SignUpButton(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChooseLoginMethod(),
),
);
},
),
],
),
),
],
),
),
),
),
);
}
}
I already tried using Connectivity().checkConnectivity()
and ConnectivityResult.none
on the retry logic.
2
Answers
To loop the
AlertDialog
until there is an internet connection, you can modify your code to continuously check the internet connection whenever the "Retry" button is pressed. If there’s still no internet, the dialog will show again; otherwise, it will close and allow further actions.Here’s how you can implement this:
Here’s the updated code:
Explanation:
initState()
, the app checks the internet connection usingConnectivity().checkConnectivity()
._showNoInternetDialog()
method shows the alert dialog. This dialog will remain on the screen until the user presses "Retry."This approach ensures that the alert dialog keeps appearing until a valid internet connection is detected.
So basically you need to add logic inside the
retry
button. When user pressretry
button, check the connectivity then trigger an action based on the result. I provide simple reproducible code to give you an idea how it’s work.What this code do:
Stream
will be notified