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 androidx.lifecycle.viewmodel.compose.viewModel
import de.webfussel.soulecho.data.database.MoodDatabase import de.webfussel.soulecho.data.database.MoodDatabase
import de.webfussel.soulecho.data.repository.MoodRepository import de.webfussel.soulecho.data.repository.MoodRepository
import de.webfussel.soulecho.history.HistorySection
import de.webfussel.soulecho.mood.MoodSection import de.webfussel.soulecho.mood.MoodSection
import de.webfussel.soulecho.mood.MoodWithInfo import de.webfussel.soulecho.mood.MoodWithInfo
import de.webfussel.soulecho.mood.PossibleMood import de.webfussel.soulecho.mood.PossibleMood
import de.webfussel.soulecho.navigation.Drawer 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.ui.theme.SoulEchoTheme
import de.webfussel.soulecho.viewmodel.MoodViewModel import de.webfussel.soulecho.viewmodel.MoodViewModel
import de.webfussel.soulecho.viewmodel.MoodViewModelFactory import de.webfussel.soulecho.viewmodel.MoodViewModelFactory
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
val LocalMoodState = compositionLocalOf<MoodWithInfo> { error("No MoodState provided") } val LocalMoodState = compositionLocalOf<MoodWithInfo> { error("No MoodState provided") }
val LocalCurrentPage = compositionLocalOf<NavigationEntry> { error("No CurrentPage provided") }
@Composable @Composable
fun SoulEchoApp(moodViewModel: MoodViewModel) { fun SoulEchoApp(moodViewModel: MoodViewModel) {
var currentPage by remember { mutableStateOf(Navigation.home) }
var currentMood by remember { mutableStateOf(MoodWithInfo(mood = PossibleMood.HAPPY, info = "")) } var currentMood by remember { mutableStateOf(MoodWithInfo(mood = PossibleMood.HAPPY, info = "")) }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
val lastMood = moodViewModel.getLastMood() val lastMood = moodViewModel.getLastMood()
@ -31,17 +36,30 @@ fun SoulEchoApp(moodViewModel: MoodViewModel) {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
CompositionLocalProvider(LocalMoodState provides currentMood) { CompositionLocalProvider(
LocalMoodState provides currentMood,
LocalCurrentPage provides currentPage,
) {
SoulEchoTheme () { SoulEchoTheme () {
Drawer () { Drawer (
MoodSection( currentPage = currentPage,
onMoodChange = { onPageChange = { page -> currentPage = page },
currentMood = it ) { paddingValues ->
coroutineScope.launch { when (currentPage.id) {
moodViewModel.saveMood(it) "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 package de.webfussel.soulecho.navigation
import de.webfussel.soulecho.R
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.layout.*
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.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DrawerValue import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.*
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.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset 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.graphics.Shadow
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import de.webfussel.soulecho.LocalMoodState import de.webfussel.soulecho.LocalMoodState
import de.webfussel.soulecho.R
import de.webfussel.soulecho.mood.Moods.getMoodById import de.webfussel.soulecho.mood.Moods.getMoodById
import de.webfussel.soulecho.mood.PossibleMood
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
@ -135,7 +105,10 @@ fun DrawerTop() {
} }
@Composable @Composable
fun DrawerContent () { fun DrawerContent (
currentPage: NavigationEntry,
onPageSelected: (NavigationEntry) -> Unit
) {
var currentNavigation by remember { var currentNavigation by remember {
mutableStateOf(Navigation.getTopNavigation()[0]) mutableStateOf(Navigation.getTopNavigation()[0])
} }
@ -151,13 +124,19 @@ fun DrawerContent () {
NavigationBlock( NavigationBlock(
items = Navigation.getTopNavigation(), items = Navigation.getTopNavigation(),
currentNavigation = currentNavigation, currentNavigation = currentNavigation,
onNavigationItemClicked = { currentNavigation = it }, onNavigationItemClicked = {
currentNavigation = it
onPageSelected(it)
},
) )
Spacer(Modifier.weight(1f)) Spacer(Modifier.weight(1f))
NavigationBlock( NavigationBlock(
items = Navigation.getBottomNavigation(), items = Navigation.getBottomNavigation(),
currentNavigation = currentNavigation, currentNavigation = currentNavigation,
onNavigationItemClicked = { currentNavigation = it }, onNavigationItemClicked = {
currentNavigation = it
onPageSelected(it)
},
) )
} }
} }
@ -166,21 +145,30 @@ fun DrawerContent () {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun Drawer ( fun Drawer (
currentPage: NavigationEntry,
onPageChange: (NavigationEntry) -> Unit,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
val state = rememberDrawerState(initialValue = DrawerValue.Closed) val state = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val theme = MaterialTheme.colorScheme val theme = MaterialTheme.colorScheme
var currentPage by remember { mutableStateOf("Stimmung") }
ModalNavigationDrawer( ModalNavigationDrawer(
drawerContent = { DrawerContent() }, drawerContent = {
DrawerContent(
currentPage = currentPage,
onPageSelected = { page ->
onPageChange(page)
scope.launch { state.close() }
}
)
},
drawerState = state, drawerState = state,
) { ) {
Scaffold ( Scaffold (
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text(currentPage) }, title = { Text(currentPage.label) },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = theme.background, containerColor = theme.background,
titleContentColor = theme.primary, titleContentColor = theme.primary,

View file

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