ADD: navigation concept

This commit is contained in:
webfussel 2025-08-02 08:22:01 +02:00
parent ee21050e73
commit f6bdb49cab
4 changed files with 89 additions and 51 deletions

View file

@ -8,19 +8,24 @@ import androidx.compose.runtime.*
import androidx.lifecycle.viewmodel.compose.viewModel
import de.webfussel.soulecho.data.database.MoodDatabase
import de.webfussel.soulecho.data.repository.MoodRepository
import de.webfussel.soulecho.history.HistorySection
import de.webfussel.soulecho.mood.MoodSection
import de.webfussel.soulecho.mood.MoodWithInfo
import de.webfussel.soulecho.mood.PossibleMood
import de.webfussel.soulecho.navigation.Drawer
import de.webfussel.soulecho.navigation.Navigation
import de.webfussel.soulecho.navigation.NavigationEntry
import de.webfussel.soulecho.ui.theme.SoulEchoTheme
import de.webfussel.soulecho.viewmodel.MoodViewModel
import de.webfussel.soulecho.viewmodel.MoodViewModelFactory
import kotlinx.coroutines.launch
val LocalMoodState = compositionLocalOf<MoodWithInfo> { error("No MoodState provided") }
val LocalCurrentPage = compositionLocalOf<NavigationEntry> { error("No CurrentPage provided") }
@Composable
fun SoulEchoApp(moodViewModel: MoodViewModel) {
var currentPage by remember { mutableStateOf(Navigation.home) }
var currentMood by remember { mutableStateOf(MoodWithInfo(mood = PossibleMood.HAPPY, info = "")) }
LaunchedEffect(Unit) {
val lastMood = moodViewModel.getLastMood()
@ -31,17 +36,30 @@ fun SoulEchoApp(moodViewModel: MoodViewModel) {
val coroutineScope = rememberCoroutineScope()
CompositionLocalProvider(LocalMoodState provides currentMood) {
CompositionLocalProvider(
LocalMoodState provides currentMood,
LocalCurrentPage provides currentPage,
) {
SoulEchoTheme () {
Drawer () {
MoodSection(
onMoodChange = {
currentMood = it
coroutineScope.launch {
moodViewModel.saveMood(it)
}
Drawer (
currentPage = currentPage,
onPageChange = { page -> currentPage = page },
) { paddingValues ->
when (currentPage.id) {
"current" -> {
MoodSection(
onMoodChange = {
currentMood = it
coroutineScope.launch {
moodViewModel.saveMood(it)
}
}
)
}
)
"history" -> {
HistorySection()
}
}
}
}
}

View file

@ -0,0 +1,32 @@
package de.webfussel.soulecho.history
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun HistorySection() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Verlauf",
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Hier wird der Stimmungsverlauf angezeigt",
style = MaterialTheme.typography.bodyLarge
)
}
}

View file

@ -1,39 +1,10 @@
package de.webfussel.soulecho.navigation
import de.webfussel.soulecho.R
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@ -41,12 +12,11 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.webfussel.soulecho.LocalMoodState
import de.webfussel.soulecho.R
import de.webfussel.soulecho.mood.Moods.getMoodById
import de.webfussel.soulecho.mood.PossibleMood
import kotlinx.coroutines.launch
@Composable
@ -135,7 +105,10 @@ fun DrawerTop() {
}
@Composable
fun DrawerContent () {
fun DrawerContent (
currentPage: NavigationEntry,
onPageSelected: (NavigationEntry) -> Unit
) {
var currentNavigation by remember {
mutableStateOf(Navigation.getTopNavigation()[0])
}
@ -151,13 +124,19 @@ fun DrawerContent () {
NavigationBlock(
items = Navigation.getTopNavigation(),
currentNavigation = currentNavigation,
onNavigationItemClicked = { currentNavigation = it },
onNavigationItemClicked = {
currentNavigation = it
onPageSelected(it)
},
)
Spacer(Modifier.weight(1f))
NavigationBlock(
items = Navigation.getBottomNavigation(),
currentNavigation = currentNavigation,
onNavigationItemClicked = { currentNavigation = it },
onNavigationItemClicked = {
currentNavigation = it
onPageSelected(it)
},
)
}
}
@ -166,21 +145,30 @@ fun DrawerContent () {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Drawer (
currentPage: NavigationEntry,
onPageChange: (NavigationEntry) -> Unit,
content: @Composable (PaddingValues) -> Unit
) {
val state = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
val theme = MaterialTheme.colorScheme
var currentPage by remember { mutableStateOf("Stimmung") }
ModalNavigationDrawer(
drawerContent = { DrawerContent() },
drawerContent = {
DrawerContent(
currentPage = currentPage,
onPageSelected = { page ->
onPageChange(page)
scope.launch { state.close() }
}
)
},
drawerState = state,
) {
Scaffold (
topBar = {
TopAppBar(
title = { Text(currentPage) },
title = { Text(currentPage.label) },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = theme.background,
titleContentColor = theme.primary,

View file

@ -10,9 +10,9 @@ data class NavigationEntry (
)
object Navigation {
private val home = NavigationEntry(
val home = NavigationEntry(
id = "current",
label = "Aktuell",
label = "Stimmung",
icon = R.drawable.face_smile,
)