commit b9362b0f97961c9a97766d2690b6086717819f0e
parent 50fc855b1003d110569e23b40d4475391594483d
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Mon, 28 Jul 2025 19:50:17 +0200
Introduce the SidebarDrawerViewModel
Diffstat:
8 files changed, 186 insertions(+), 133 deletions(-)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/MainActivity.kt
@@ -245,7 +245,6 @@ fun CalendarView(backStackEntry: NavBackStackEntry, navController: NavHostContro
title = stringResource(R.string.app_name),
selectedDestination = "calendar",
navController = navController,
- calendarViewModel = calendarViewModel,
floatingActionButton = {
FloatingActionButton(onClick = { /* Event hinzufügen (später) */ }) {
Icon(
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt
@@ -23,7 +23,6 @@ import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import kotlinx.coroutines.launch
import space.midnightthoughts.nordiccalendar.R
-import space.midnightthoughts.nordiccalendar.viewmodels.CalendarViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -31,7 +30,6 @@ fun AppScaffold(
title: String? = null,
selectedDestination: String,
navController: NavController,
- calendarViewModel: CalendarViewModel? = null,
floatingActionButton: (@Composable () -> Unit)? = null,
content: @Composable (Modifier) -> Unit
) {
@@ -49,7 +47,6 @@ fun AppScaffold(
drawerContent = {
SidebarDrawer(
selectedDestination = selectedDestination,
- calendarViewModel = calendarViewModel,
navController = navController,
drawerState = drawerState,
)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/SidebarDrawer.kt
@@ -25,31 +25,33 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import kotlinx.coroutines.launch
import space.midnightthoughts.nordiccalendar.Destinations
import space.midnightthoughts.nordiccalendar.R
-import space.midnightthoughts.nordiccalendar.viewmodels.CalendarViewModel
+import space.midnightthoughts.nordiccalendar.viewmodels.SidebarDrawerViewModel
@Composable
fun SidebarDrawer(
- calendarViewModel: CalendarViewModel?,
navController: NavController,
selectedDestination: String,
drawerState: DrawerState
) {
- val calendars = remember(calendarViewModel) {
- calendarViewModel?.calendars
- }?.collectAsState(initial = emptyList())
+ val viewModel: SidebarDrawerViewModel = viewModel()
+
+ val calendars = remember(viewModel) {
+ viewModel.calendars
+ }.collectAsState(initial = emptyList())
val selectedCalendars = remember(calendars) {
derivedStateOf {
- calendars?.value?.filter { it.selected }
+ calendars.value.filter { it.selected }
}
}
Log.d(
"SidebarDrawer",
- "Selected Calendars: ${selectedCalendars.value}, Calendars: ${calendars?.value}"
+ "Selected Calendars: ${selectedCalendars.value}, Calendars: ${calendars.value}"
)
val scope = rememberCoroutineScope()
@@ -126,31 +128,28 @@ fun SidebarDrawer(
modifier = Modifier.fillMaxWidth(),
colors = NavigationDrawerItemDefaults.colors()
)
- if (selectedCalendars.value !== null && calendars?.value?.isEmpty() == false) {
- Spacer(Modifier.height(16.dp))
- HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color)
- Spacer(Modifier.height(8.dp))
- Text(
- stringResource(R.string.calendar_selection),
- style = MaterialTheme.typography.titleMedium,
- modifier =
- Modifier.padding(start = 8.dp, bottom = 8.dp, end = 8.dp, top = 8.dp)
- )
- Spacer(Modifier.height(8.dp))
- calendars?.value?.forEach { calendar ->
- Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) {
- Checkbox(
- checked = selectedCalendars.value?.contains(calendar) == true,
- onCheckedChange = {
- scope.launch {
- calendarViewModel?.toggleCalendar(calendar)
- }
+ Spacer(Modifier.height(16.dp))
+ HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color)
+ Spacer(Modifier.height(8.dp))
+ Text(
+ stringResource(R.string.calendar_selection),
+ style = MaterialTheme.typography.titleMedium,
+ modifier =
+ Modifier.padding(start = 8.dp, bottom = 8.dp, end = 8.dp, top = 8.dp)
+ )
+ Spacer(Modifier.height(8.dp))
+ calendars.value.forEach { calendar ->
+ Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) {
+ Checkbox(
+ checked = selectedCalendars.value.contains(calendar),
+ onCheckedChange = {
+ scope.launch {
+ viewModel.toggleCalendar(calendar)
}
- )
- Text(calendar.name, modifier = Modifier.padding(start = 8.dp))
- }
+ }
+ )
+ Text(calendar.name, modifier = Modifier.padding(start = 8.dp))
}
-
}
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/data/CalendarRepository.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/data/CalendarRepository.kt
@@ -1,21 +1,57 @@
package space.midnightthoughts.nordiccalendar.data
-import android.content.ContentResolver
import android.content.Context
-import android.content.SharedPreferences
import androidx.core.content.edit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.launch
import space.midnightthoughts.nordiccalendar.util.Calendar
import space.midnightthoughts.nordiccalendar.util.CalendarData
import space.midnightthoughts.nordiccalendar.util.Event
-class CalendarRepository(private val context: Context) {
+class CalendarRepository private constructor() {
private val calendarData = CalendarData()
- private val prefs: SharedPreferences by lazy {
- context.getSharedPreferences("calendar_prefs", Context.MODE_PRIVATE)
+
+ // StateFlow für Kalenderliste
+ private val _calendarsFlow = MutableStateFlow<List<Calendar>>(emptyList())
+ val calendarsFlow: StateFlow<List<Calendar>> = _calendarsFlow.asStateFlow()
+ private val repoScope = CoroutineScope(Dispatchers.IO)
+
+ // StateFlow für Zeitbereich und Events
+ private val _startMillis = MutableStateFlow(System.currentTimeMillis())
+ val startMillis: StateFlow<Long> = _startMillis.asStateFlow()
+ private val _endMillis = MutableStateFlow(System.currentTimeMillis())
+ val endMillis: StateFlow<Long> = _endMillis.asStateFlow()
+ private val _eventsFlow = MutableStateFlow<List<Event>>(emptyList())
+ val eventsFlow: StateFlow<List<Event>> = _eventsFlow.asStateFlow()
+
+ // Context muss jetzt bei jedem Aufruf übergeben werden
+ fun initialize(context: Context) {
+ loadCalendarsToFlow(context)
+ repoScope.launch {
+ combine(_calendarsFlow, _startMillis, _endMillis) { calendars, start, end ->
+ val selectedIds = calendars.filter { it.selected }.map { it.id }
+ getEventsForCalendars(context, selectedIds, start, end)
+ }.collect { events ->
+ _eventsFlow.value = events
+ }
+ }
+ }
+
+ private fun loadCalendarsToFlow(context: Context) {
+ repoScope.launch {
+ val calendars = getCalendars(context)
+ _calendarsFlow.value = calendars
+ }
}
- private val contentResolver: ContentResolver get() = context.contentResolver
- fun getCalendars(): List<Calendar> {
+ fun getCalendars(context: Context): List<Calendar> {
+ val contentResolver = context.contentResolver
+ val prefs = context.getSharedPreferences("calendar_prefs", Context.MODE_PRIVATE)
val calendars = calendarData.getCalendars(contentResolver)
val selectedIds = prefs.getStringSet("selected_calendar_ids", null)
return if (selectedIds != null) {
@@ -25,7 +61,8 @@ class CalendarRepository(private val context: Context) {
}
}
- fun setCalendarSelected(calendarId: Long, selected: Boolean) {
+ fun setCalendarSelected(context: Context, calendarId: Long, selected: Boolean) {
+ val prefs = context.getSharedPreferences("calendar_prefs", Context.MODE_PRIVATE)
val selectedIds =
prefs.getStringSet("selected_calendar_ids", null)?.toMutableSet() ?: mutableSetOf()
if (selected) {
@@ -34,16 +71,38 @@ class CalendarRepository(private val context: Context) {
selectedIds.remove(calendarId.toString())
}
prefs.edit { putStringSet("selected_calendar_ids", selectedIds) }
+ loadCalendarsToFlow(context)
+ }
+
+ fun setTimeRange(startMillis: Long, endMillis: Long) {
+ _startMillis.value = startMillis
+ _endMillis.value = endMillis
}
fun getEventsForCalendars(
+ context: Context,
calendarIds: List<Long>,
startMillis: Long,
endMillis: Long
): List<Event> =
- calendarData.getEventsForCalendars(contentResolver, calendarIds, startMillis, endMillis)
+ calendarData.getEventsForCalendars(
+ context.contentResolver,
+ calendarIds,
+ startMillis,
+ endMillis
+ )
- fun getEventById(eventId: Long): Event? {
- return calendarData.getEventById(contentResolver, eventId)
+ fun getEventById(context: Context, eventId: Long): Event? {
+ return calendarData.getEventById(context.contentResolver, eventId)
+ }
+
+ companion object {
+ @Volatile
+ private var INSTANCE: CalendarRepository? = null
+ fun getInstance(): CalendarRepository {
+ return INSTANCE ?: synchronized(this) {
+ INSTANCE ?: CalendarRepository().also { INSTANCE = it }
+ }
+ }
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/CalendarScreen.kt
@@ -90,7 +90,10 @@ fun CalendarScreen(
PullToRefreshBox(
state = pullToRefreshState,
modifier = modifier,
- onRefresh = { calendarViewModel.updateEvents() },
+ onRefresh = {
+ // updateEvents gibt es nicht mehr im ViewModel, stattdessen Tab neu setzen, um Zeitraum zu triggern
+ calendarViewModel.setTab(selectedTab)
+ },
isRefreshing = isRefreshing.value,
indicator = {
Indicator(
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/CalendarViewModel.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/CalendarViewModel.kt
@@ -4,57 +4,38 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.flow.stateIn
import space.midnightthoughts.nordiccalendar.data.CalendarRepository
-import space.midnightthoughts.nordiccalendar.util.Calendar
-import space.midnightthoughts.nordiccalendar.util.Event
class CalendarViewModel(app: Application) : AndroidViewModel(app) {
- val isRefreshing = MutableStateFlow(false)
- private val repository = CalendarRepository(app)
-
- private val _calendars = MutableStateFlow<List<Calendar>>(emptyList())
- val calendars: StateFlow<List<Calendar>> = _calendars.asStateFlow()
+ private val repository = CalendarRepository.getInstance()
- private val _events = MutableStateFlow<List<Event>>(emptyList())
- val events: StateFlow<List<Event>> = _events.asStateFlow()
+ val events = repository.eventsFlow.stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(5000),
+ emptyList()
+ )
+ val startMillis = repository.startMillis
+ val endMillis = repository.endMillis
+ val isRefreshing = MutableStateFlow(false)
private val _selectedTab = MutableStateFlow(0)
val selectedTab: StateFlow<Int> = _selectedTab.asStateFlow()
- private val _startMillis = MutableStateFlow(getDefaultStartMillis(0))
- val startMillis: StateFlow<Long> = _startMillis.asStateFlow()
- private val _endMillis = MutableStateFlow(getDefaultEndMillis(0))
- val endMillis: StateFlow<Long> = _endMillis.asStateFlow()
-
init {
- loadCalendars()
- }
-
- private fun loadCalendars() {
- isRefreshing.value = true
- viewModelScope.launch {
- val allCalendars = repository.getCalendars()
- _calendars.value = allCalendars
- updateEvents()
- isRefreshing.value = false
- }
- }
-
- fun toggleCalendar(calendar: Calendar) {
- viewModelScope.launch {
- repository.setCalendarSelected(calendar.id, !calendar.selected)
- loadCalendars()
- }
+ // Repository initialisieren (Context benötigt)
+ repository.initialize(app)
+ setTab(0)
}
fun setTab(tab: Int) {
_selectedTab.value = tab
- _startMillis.value = getDefaultStartMillis(tab)
- _endMillis.value = getDefaultEndMillis(tab)
- updateEvents()
+ val start = getDefaultStartMillis(tab)
+ val end = getDefaultEndMillis(tab)
+ repository.setTimeRange(start, end)
}
private fun getDefaultStartMillis(tab: Int): Long {
@@ -120,78 +101,63 @@ class CalendarViewModel(app: Application) : AndroidViewModel(app) {
}
}
- fun updateEvents() {
- viewModelScope.launch {
- isRefreshing.value = true
- try {
- val selectedIds = _calendars.value.filter { it.selected }.map { it.id }
- _events.value = repository.getEventsForCalendars(
- selectedIds,
- _startMillis.value,
- _endMillis.value
- )
- } finally {
- isRefreshing.value = false
- }
- }
- }
-
+ // Die folgenden Methoden ändern nur noch den Zeitraum im Repository
fun nextDay() {
if (_selectedTab.value != 2) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.DAY_OF_MONTH, 1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun prevDay() {
if (_selectedTab.value != 2) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.DAY_OF_MONTH, -1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun nextWeek() {
if (_selectedTab.value != 1) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.WEEK_OF_YEAR, 1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.add(java.util.Calendar.DAY_OF_WEEK, 6)
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun prevWeek() {
if (_selectedTab.value != 1) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.WEEK_OF_YEAR, -1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.add(java.util.Calendar.DAY_OF_WEEK, 6)
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun nextMonth() {
if (_selectedTab.value != 0) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.MONTH, 1)
cal.set(java.util.Calendar.DAY_OF_MONTH, 1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.set(
java.util.Calendar.DAY_OF_MONTH,
cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH)
@@ -199,16 +165,16 @@ class CalendarViewModel(app: Application) : AndroidViewModel(app) {
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun prevMonth() {
if (_selectedTab.value != 0) return
- val cal = java.util.Calendar.getInstance().apply { timeInMillis = _startMillis.value }
+ val cal = java.util.Calendar.getInstance().apply { timeInMillis = startMillis.value }
cal.add(java.util.Calendar.MONTH, -1)
cal.set(java.util.Calendar.DAY_OF_MONTH, 1)
- _startMillis.value = cal.timeInMillis
+ val start = cal.timeInMillis
cal.set(
java.util.Calendar.DAY_OF_MONTH,
cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH)
@@ -216,38 +182,38 @@ class CalendarViewModel(app: Application) : AndroidViewModel(app) {
cal.set(java.util.Calendar.HOUR_OF_DAY, 23)
cal.set(java.util.Calendar.MINUTE, 59)
cal.set(java.util.Calendar.SECOND, 59)
- _endMillis.value = cal.timeInMillis
- updateEvents()
+ val end = cal.timeInMillis
+ repository.setTimeRange(start, end)
}
fun setTodayWeek() {
if (_selectedTab.value != 1) return
val cal = java.util.Calendar.getInstance()
- _startMillis.value = cal.apply {
+ val start = cal.apply {
set(java.util.Calendar.DAY_OF_WEEK, firstDayOfWeek)
set(java.util.Calendar.HOUR_OF_DAY, 0)
set(java.util.Calendar.MINUTE, 0)
set(java.util.Calendar.SECOND, 0)
}.timeInMillis
- _endMillis.value = cal.apply {
+ val end = cal.apply {
add(java.util.Calendar.DAY_OF_WEEK, 6)
set(java.util.Calendar.HOUR_OF_DAY, 23)
set(java.util.Calendar.MINUTE, 59)
set(java.util.Calendar.SECOND, 59)
}.timeInMillis
- updateEvents()
+ repository.setTimeRange(start, end)
}
fun setTodayMonth() {
if (_selectedTab.value != 0) return
val cal = java.util.Calendar.getInstance()
- _startMillis.value = cal.apply {
+ val start = cal.apply {
set(java.util.Calendar.DAY_OF_MONTH, 1)
set(java.util.Calendar.HOUR_OF_DAY, 0)
set(java.util.Calendar.MINUTE, 0)
set(java.util.Calendar.SECOND, 0)
}.timeInMillis
- _endMillis.value = cal.apply {
+ val end = cal.apply {
set(
java.util.Calendar.DAY_OF_MONTH,
getActualMaximum(java.util.Calendar.DAY_OF_MONTH)
@@ -256,22 +222,22 @@ class CalendarViewModel(app: Application) : AndroidViewModel(app) {
set(java.util.Calendar.MINUTE, 59)
set(java.util.Calendar.SECOND, 59)
}.timeInMillis
- updateEvents()
+ repository.setTimeRange(start, end)
}
fun setTodayDay() {
if (_selectedTab.value != 2) return
val cal = java.util.Calendar.getInstance()
- _startMillis.value = cal.apply {
+ val start = cal.apply {
set(java.util.Calendar.HOUR_OF_DAY, 0)
set(java.util.Calendar.MINUTE, 0)
set(java.util.Calendar.SECOND, 0)
}.timeInMillis
- _endMillis.value = cal.apply {
+ val end = cal.apply {
set(java.util.Calendar.HOUR_OF_DAY, 23)
set(java.util.Calendar.MINUTE, 59)
set(java.util.Calendar.SECOND, 59)
}.timeInMillis
- updateEvents()
+ repository.setTimeRange(start, end)
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/EventDetailsViewModel.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/EventDetailsViewModel.kt
@@ -15,7 +15,7 @@ class EventDetailsViewModel(
app: Application,
savedStateHandle: SavedStateHandle
) : AndroidViewModel(app) {
- private val repository = CalendarRepository(app)
+ private val repository = CalendarRepository.getInstance()
private val _event = MutableStateFlow<Event?>(null)
val event: StateFlow<Event?> = _event.asStateFlow()
@@ -28,7 +28,7 @@ class EventDetailsViewModel(
private fun loadEvent(eventId: Long) {
viewModelScope.launch {
- val event = repository.getEventById(eventId)
+ val event = repository.getEventById(getApplication<Application>(), eventId)
_event.value = event
}
}
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/SidebarDrawerViewModel.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/viewmodels/SidebarDrawerViewModel.kt
@@ -0,0 +1,30 @@
+package space.midnightthoughts.nordiccalendar.viewmodels
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import space.midnightthoughts.nordiccalendar.data.CalendarRepository
+import space.midnightthoughts.nordiccalendar.util.Calendar
+
+class SidebarDrawerViewModel(app: Application) : AndroidViewModel(app) {
+ private val repository = CalendarRepository.getInstance()
+
+ val calendars = repository.calendarsFlow.stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(5000),
+ emptyList()
+ )
+
+ fun toggleCalendar(calendar: Calendar) {
+ viewModelScope.launch {
+ repository.setCalendarSelected(
+ getApplication<Application>(),
+ calendar.id,
+ !calendar.selected
+ )
+ }
+ }
+}