diff --git a/app/src/main/java/com/github/se/travelpouch/model/authentication/NetworkConnectivityHelper.kt b/app/src/main/java/com/github/se/travelpouch/model/authentication/NetworkConnectivityHelper.kt new file mode 100644 index 00000000..853a3a5a --- /dev/null +++ b/app/src/main/java/com/github/se/travelpouch/model/authentication/NetworkConnectivityHelper.kt @@ -0,0 +1,47 @@ +package com.github.se.travelpouch.model.authentication + +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.util.Log +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class NetworkConnectivityHelper(private val connectivityManager: ConnectivityManager) { + + private val _isConnected: MutableStateFlow = MutableStateFlow(null) + val isConnected: StateFlow = _isConnected.asStateFlow() + + fun registerNetworkCallback() { + connectivityManager.registerDefaultNetworkCallback( + object : ConnectivityManager.NetworkCallback() { + override fun onAvailable(network: Network) { + super.onAvailable(network) + Log.d("NetworkConnectivityHelper", "Connection available") + _isConnected.value = true + } + + override fun onUnavailable() { + super.onUnavailable() + Log.d("NetworkConnectivityHelper", "Connection unavailable") + _isConnected.value = false + } + }) + + val activeNetwork = connectivityManager.activeNetwork + val initialCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) + if (initialCapabilities != null) { + if (initialCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { + Log.d("NetworkConnectivityHelper", "Connected to the internet") + _isConnected.value = true + } else { + Log.d("NetworkConnectivityHelper", "Not connected to the internet") + _isConnected.value = false + } + } else { + Log.d("NetworkConnectivityHelper", "No network capabilities") + _isConnected.value = false + } + } +} diff --git a/app/src/main/java/com/github/se/travelpouch/ui/authentication/SignIn.kt b/app/src/main/java/com/github/se/travelpouch/ui/authentication/SignIn.kt index 7314277e..55512810 100644 --- a/app/src/main/java/com/github/se/travelpouch/ui/authentication/SignIn.kt +++ b/app/src/main/java/com/github/se/travelpouch/ui/authentication/SignIn.kt @@ -1,6 +1,8 @@ // Portions of this code were generated and or inspired by the help of GitHub Copilot or Chatgpt package com.github.se.travelpouch.ui.authentication +import android.content.Context +import android.net.ConnectivityManager import android.util.Log import android.widget.Toast import androidx.compose.animation.AnimatedVisibility @@ -24,6 +26,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment @@ -38,6 +41,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.github.se.travelpouch.R +import com.github.se.travelpouch.model.authentication.NetworkConnectivityHelper import com.github.se.travelpouch.model.profile.ProfileModelView import com.github.se.travelpouch.model.travels.ListTravelViewModel import com.github.se.travelpouch.ui.navigation.NavigationActions @@ -74,7 +78,16 @@ fun SignInScreen( } // this extra state is necessary to prevent token refresh errors val waitUntilProfileFetched = rememberSaveable { mutableStateOf(false) } + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val networkHelper = NetworkConnectivityHelper(connectivityManager) + networkHelper.registerNetworkCallback() + val isConnectedToNetwork = networkHelper.isConnected.collectAsState() + val currentUser = auth.currentUser + if (currentUser != null) { + Log.d("SignInScreen", "Current user: ${currentUser.email}") + } // launcher for Firebase authentication val launcher = @@ -195,15 +208,21 @@ fun SignInScreen( } } if (currentUser != null && - !signInCompleted - .value) { // extra condition on sign-in completion to avoid unnecessary + !signInCompleted.value && + isConnectedToNetwork.value != + null) { // extra condition on sign-in completion to avoid unnecessary // recompositions LaunchedEffect(Unit) { try { isLoading.value = true methodChosen.value = true - currentUser.getIdToken(true).await() // We shouldn't continue until this passes + if (isConnectedToNetwork.value == true) { + Log.d("SignInScreen", "User connected to network, refresh id token...") + currentUser.getIdToken(true).await() // We shouldn't continue until this passes + } else { + Log.d("SignInScreen", "User offline, skipping id token refresh.") + } Log.d( "SignInScreen",