almost done
This commit is contained in:
@@ -12,7 +12,6 @@ import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -26,6 +25,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.List
|
||||
import androidx.compose.material.icons.automirrored.filled.Logout
|
||||
@@ -36,17 +36,19 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.modifier.modifierLocalConsumer
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -55,22 +57,23 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.github.jan.supabase.auth.auth
|
||||
import io.github.jan.supabase.auth.status.SessionStatus
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import net.tinsae.clocked.components.ShowLoadingScreen
|
||||
import net.tinsae.clocked.dashboard.DashboardScreen
|
||||
import net.tinsae.clocked.data.Locale
|
||||
import net.tinsae.clocked.data.LogRepository
|
||||
import net.tinsae.clocked.data.Theme
|
||||
import net.tinsae.clocked.history.HistoryScreen
|
||||
import net.tinsae.clocked.settings.SettingsScreen
|
||||
import net.tinsae.clocked.settings.SettingsViewModel
|
||||
import net.tinsae.clocked.ui.theme.ClockedTheme
|
||||
import net.tinsae.clocked.util.SupabaseClient
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import io.github.jan.supabase.auth.status.SessionStatus
|
||||
import net.tinsae.clocked.data.LogRepository
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
@@ -126,6 +129,25 @@ fun AppEntry(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel)
|
||||
val settingsState by settingsViewModel.uiState.collectAsState()
|
||||
val sessionStatus by authViewModel.sessionStatus.collectAsState()
|
||||
|
||||
|
||||
/*LaunchedEffect(Unit) {
|
||||
SupabaseClient.client.auth.sessionStatus.collect { status ->
|
||||
if (status is SessionStatus.Authenticated &&
|
||||
SupabaseClient.client.auth.currentSessionOrNull() != null
|
||||
) {
|
||||
LogRepository.fetchLogs()
|
||||
} else {
|
||||
return@collect
|
||||
}
|
||||
}
|
||||
}*/
|
||||
LaunchedEffect(sessionStatus) {
|
||||
if (sessionStatus is SessionStatus.Authenticated){
|
||||
LogRepository.fetchLogs()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val useDarkTheme = when (settingsState.theme) {
|
||||
Theme.LIGHT -> false
|
||||
Theme.DARK -> true
|
||||
@@ -136,29 +158,21 @@ fun AppEntry(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel)
|
||||
updateLocale(context, settingsState.locale)
|
||||
|
||||
ClockedTheme(darkTheme = useDarkTheme) {
|
||||
// Use a 'when' statement to handle all possible states.
|
||||
when (sessionStatus) {
|
||||
is SessionStatus.Initializing -> {
|
||||
// Only show loading for the initial session check.
|
||||
ShowLoadingScreen()
|
||||
}
|
||||
|
||||
is SessionStatus.Authenticated -> {
|
||||
// If we know the user is authenticated, show the main app.
|
||||
ClockedApp(settingsViewModel, authViewModel,sessionStatus)
|
||||
// Just show the app. The ViewModels inside will manage their own loading UI.
|
||||
ClockedApp(settingsViewModel, authViewModel)
|
||||
}
|
||||
|
||||
is SessionStatus.NotAuthenticated -> {
|
||||
// Only if we are certain the user is not logged in, show the login screen.
|
||||
LoginScreen(authViewModel)
|
||||
}
|
||||
|
||||
is SessionStatus.Initializing -> {
|
||||
// While Supabase is loading the session, show a loading indicator.
|
||||
// This prevents the flicker.
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -175,67 +189,69 @@ fun updateLocale(context: Context, locale: Locale) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ClockedApp(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel, sessionStatus: SessionStatus) {
|
||||
fun ClockedApp(settingsViewModel: SettingsViewModel, authViewModel: AuthViewModel) {
|
||||
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
topBar = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(colorScheme.surface)
|
||||
.padding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top).asPaddingValues()),
|
||||
//contentAlignment = Alignment.CenterStart
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
text = stringResource(R.string.app_name),
|
||||
style = typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
|
||||
NavigationSuiteScaffold(
|
||||
navigationSuiteItems = {
|
||||
AppDestinations.entries.forEach { destination ->
|
||||
item(
|
||||
icon = { Icon(
|
||||
imageVector = destination.icon,
|
||||
contentDescription = stringResource(destination.label))
|
||||
},
|
||||
alwaysShowLabel = false,
|
||||
label = { Text(stringResource(destination.label)) },
|
||||
selected = destination == currentDestination,
|
||||
onClick = { currentDestination = destination }
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
// 2. Use IconButton to make the icon clickable with a ripple effect
|
||||
IconButton(onClick = { authViewModel.logout() }) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.Logout, // Replace with your logout icon
|
||||
contentDescription = "Logout"
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
) { innerPadding ->
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
val contentPadding = PaddingValues(
|
||||
start = innerPadding.calculateStartPadding(layoutDirection),
|
||||
end = innerPadding.calculateEndPadding(layoutDirection),
|
||||
top = innerPadding.calculateTopPadding(),
|
||||
bottom = 0.dp
|
||||
)
|
||||
}
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
||||
NavigationSuiteScaffold(
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
navigationSuiteItems = {
|
||||
AppDestinations.entries.forEach { destination ->
|
||||
item(
|
||||
icon = { Icon(
|
||||
imageVector = destination.icon,
|
||||
contentDescription = stringResource(destination.label))
|
||||
},
|
||||
label = { Text(stringResource(destination.label)) },
|
||||
selected = destination == currentDestination,
|
||||
onClick = { currentDestination = destination }
|
||||
)
|
||||
topBar = {
|
||||
Surface(
|
||||
color = colorScheme.surfaceContainer,
|
||||
shadowElevation = 2.dp, // Adds a subtle shadow to lift the bar
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
// No padding needed here on the Surface itself
|
||||
) {
|
||||
Row(
|
||||
// Apply safe area padding to the Row to push content down
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top).asPaddingValues()),
|
||||
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp), // Vertical padding is handled by Row's alignment
|
||||
text = stringResource(R.string.app_name),
|
||||
style = typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
IconButton(onClick = { authViewModel.logout() }, modifier = Modifier.padding(10.dp)) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.Logout,
|
||||
contentDescription = "Logout" // Use string resource
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
},
|
||||
) { innerPadding ->
|
||||
val modifier = Modifier.fillMaxWidth().padding(innerPadding)
|
||||
|
||||
when (currentDestination) {
|
||||
AppDestinations.HOME -> DashboardScreen( modifier = Modifier.fillMaxSize())
|
||||
AppDestinations.HISTORY -> HistoryScreen(modifier = Modifier.fillMaxSize())
|
||||
AppDestinations.HOME -> DashboardScreen( modifier = modifier)
|
||||
AppDestinations.HISTORY -> HistoryScreen(modifier = modifier)
|
||||
AppDestinations.SETTING -> SettingsScreen(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier,
|
||||
viewModel = settingsViewModel,
|
||||
authViewModel = authViewModel
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user