commit 7367b8d7cb2928e52c1814d0a629dc4933ed5899
parent 63e6fbad8de2b80cdbb7a029cad4f1dea050962e
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Tue, 29 Jul 2025 22:03:50 +0200
Use modern tabs instead and clean up some code
Diffstat:
4 files changed, 42 insertions(+), 40 deletions(-)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt
@@ -31,7 +31,6 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -43,8 +42,6 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
@@ -63,7 +60,6 @@ import space.midnightthoughts.nordiccalendar.screens.EventDetailsView
import space.midnightthoughts.nordiccalendar.screens.SettingsView
import space.midnightthoughts.nordiccalendar.ui.theme.NordicCalendarTheme
import space.midnightthoughts.nordiccalendar.util.OnboardingPrefs
-import space.midnightthoughts.nordiccalendar.viewmodels.CalendarViewModel
sealed class Destinations(val route: String) {
object Intro : Destinations("intro")
@@ -130,7 +126,6 @@ class MainActivity : ComponentActivity() {
)
) { backStackEntry ->
CalendarView(
- backStackEntry = backStackEntry,
navController = navController
)
}
@@ -270,21 +265,8 @@ fun IntroScreen(navController: NavHostController, onFinish: (() -> Unit)? = null
@Composable
fun CalendarView(
- backStackEntry: NavBackStackEntry,
navController: NavHostController
) {
- val calendarViewModel: CalendarViewModel = hiltViewModel()
-
- val selectedTab = remember(calendarViewModel) {
- calendarViewModel.selectedTab
- }.collectAsState(initial = 0)
- val tabArg = backStackEntry.arguments?.getInt("tab")
-
- LaunchedEffect(tabArg) {
- if (tabArg != null) {
- calendarViewModel.setTab(tabArg)
- }
- }
AppScaffold(
title = stringResource(R.string.app_name),
@@ -308,8 +290,6 @@ fun CalendarView(
}
) { innerPadding ->
CalendarScreen(
- selectedTab = selectedTab.value,
- onTabSelected = { calendarViewModel.setTab(it) },
modifier = innerPadding,
navController = navController,
)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/data/CalendarRepository.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/data/CalendarRepository.kt
@@ -96,4 +96,13 @@ class CalendarRepository @Inject constructor(@ApplicationContext context: Contex
fun getEventById(context: Context, eventId: Long): Event? {
return calendarData.getEventById(context.contentResolver, eventId)
}
+
+ fun refreshEvents(context: Context) {
+ repoScope.launch {
+ val calendars = getCalendars(context)
+ val selectedIds = calendars.filter { it.selected }.map { it.id }
+ _eventsFlow.value =
+ getEventsForCalendars(context, selectedIds, _startMillis.value, _endMillis.value)
+ }
+ }
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt
@@ -34,8 +34,8 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
-import androidx.compose.material3.TabRow
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
@@ -66,7 +66,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import kotlinx.coroutines.delay
import space.midnightthoughts.nordiccalendar.R
@@ -83,29 +83,29 @@ import java.util.Date
@Composable
fun CalendarScreen(
modifier: Modifier = Modifier,
- calendarViewModel: CalendarViewModel = viewModel(),
- selectedTab: Int,
- onTabSelected: (Int) -> Unit,
navController: NavController,
) {
+ val calendarViewModel: CalendarViewModel = hiltViewModel()
val events = remember(calendarViewModel) {
calendarViewModel.events
}.collectAsState(initial = emptyList())
val isRefreshing = remember(calendarViewModel) {
calendarViewModel.isRefreshing
}.collectAsState(initial = false)
+ val selectedTab = remember(calendarViewModel) {
+ calendarViewModel.selectedTab
+ }.collectAsState(initial = 0)
Log.d(
"CalendarScreen",
- "Rendering with selectedTab: $selectedTab, events count: ${events.value.size}, isRefreshing: $isRefreshing"
+ "Rendering with selectedTab: $selectedTab.value, events count: ${events.value.size}, isRefreshing: $isRefreshing"
)
val pullToRefreshState = rememberPullToRefreshState()
PullToRefreshBox(
state = pullToRefreshState,
modifier = modifier,
onRefresh = {
- // updateEvents gibt es nicht mehr im ViewModel, stattdessen Tab neu setzen, um Zeitraum zu triggern
- calendarViewModel.setTab(selectedTab)
+ calendarViewModel.refreshEvents()
},
isRefreshing = isRefreshing.value,
indicator = {
@@ -119,27 +119,28 @@ fun CalendarScreen(
},
) {
Column(modifier = Modifier.fillMaxSize()) {
- CalendarTabBar(selectedTab = selectedTab, onTabSelected = onTabSelected)
- // DateRangeHeader sollte direkt unter den Tabs stehen, IMMER sichtbar
+ CalendarTabBar(
+ selectedTab = selectedTab.value,
+ onTabSelected = { calendarViewModel.setTab(it) })
DateRangeHeader(
- selectedTab = selectedTab,
+ selectedTab = selectedTab.value,
calendarViewModel = calendarViewModel,
onPrev = {
- when (selectedTab) {
+ when (selectedTab.value) {
0 -> calendarViewModel.prevMonth()
1 -> calendarViewModel.prevWeek()
2 -> calendarViewModel.prevDay()
}
},
onNext = {
- when (selectedTab) {
+ when (selectedTab.value) {
0 -> calendarViewModel.nextMonth()
1 -> calendarViewModel.nextWeek()
2 -> calendarViewModel.nextDay()
}
},
onToday = {
- when (selectedTab) {
+ when (selectedTab.value) {
0 -> calendarViewModel.setTodayMonth()
1 -> calendarViewModel.setTodayWeek()
2 -> calendarViewModel.setTodayDay()
@@ -149,7 +150,7 @@ fun CalendarScreen(
Spacer(Modifier.height(8.dp))
if (events.value.isEmpty()) {
Text(stringResource(R.string.no_events_found), modifier = Modifier.padding(16.dp))
- } else if (selectedTab == 2) {
+ } else if (selectedTab.value == 2) {
DayView(
navController = navController,
calendarViewModel = calendarViewModel,
@@ -158,7 +159,7 @@ fun CalendarScreen(
EventList(
navController = navController,
calendarViewModel = calendarViewModel,
- selectedTab = selectedTab
+ selectedTab = selectedTab.value
)
}
}
@@ -352,6 +353,7 @@ fun DayView(
}
}
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarTabBar(selectedTab: Int, onTabSelected: (Int) -> Unit) {
val tabTitles = listOf(
@@ -359,7 +361,7 @@ fun CalendarTabBar(selectedTab: Int, onTabSelected: (Int) -> Unit) {
stringResource(R.string.tab_week),
stringResource(R.string.tab_day)
)
- TabRow(
+ PrimaryTabRow(
selectedTabIndex = selectedTab,
modifier = Modifier.semantics {
collectionInfo = CollectionInfo(
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/CalendarViewModel.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/CalendarViewModel.kt
@@ -1,6 +1,7 @@
package space.midnightthoughts.nordiccalendar.viewmodels
import android.content.Context
+import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -16,7 +17,8 @@ import javax.inject.Inject
@HiltViewModel
class CalendarViewModel @Inject constructor(
@param:ApplicationContext private val context: Context,
- private val repository: CalendarRepository
+ private val repository: CalendarRepository,
+ savedStateHandle: SavedStateHandle
) : ViewModel() {
val events = repository.eventsFlow.stateIn(
viewModelScope,
@@ -31,8 +33,10 @@ class CalendarViewModel @Inject constructor(
val selectedTab: StateFlow<Int> = _selectedTab.asStateFlow()
init {
- // Repository initialisieren (Context benötigt)
- setTab(0)
+ val tab = savedStateHandle.get<Int?>("tab")
+ if (tab != null) {
+ setTab(tab)
+ }
}
fun setTab(tab: Int) {
@@ -244,4 +248,11 @@ class CalendarViewModel @Inject constructor(
}.timeInMillis
repository.setTimeRange(start, end)
}
+
+ fun refreshEvents() {
+ isRefreshing.value = true
+ repository.refreshEvents(context).apply {
+ isRefreshing.value = false
+ }
+ }
}