Migrate calendar widget to Compose
This commit is contained in:
parent
386083ede9
commit
ca813f3f70
@ -21,9 +21,16 @@ fun ColumnScope.CalendarResults() {
|
|||||||
|
|
||||||
AnimatedVisibility(calendarEvents.isNotEmpty()) {
|
AnimatedVisibility(calendarEvents.isNotEmpty()) {
|
||||||
LauncherCard(
|
LauncherCard(
|
||||||
modifier = Modifier.padding(bottom = 8.dp).fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
SearchResultList(items = calendarEvents)
|
SearchResultList(
|
||||||
|
items = calendarEvents,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(12.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.common.list
|
package de.mm20.launcher2.ui.launcher.search.common.list
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@ -11,11 +10,12 @@ import androidx.compose.ui.unit.dp
|
|||||||
import de.mm20.launcher2.search.data.Searchable
|
import de.mm20.launcher2.search.data.Searchable
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SearchResultList(items: List<Searchable>) {
|
fun SearchResultList(
|
||||||
|
items: List<Searchable>,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(12.dp)
|
|
||||||
) {
|
) {
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
key(item.key) {
|
key(item.key) {
|
||||||
|
|||||||
@ -21,9 +21,16 @@ fun ColumnScope.ContactResults() {
|
|||||||
|
|
||||||
AnimatedVisibility(contacts.isNotEmpty()) {
|
AnimatedVisibility(contacts.isNotEmpty()) {
|
||||||
LauncherCard(
|
LauncherCard(
|
||||||
modifier = Modifier.padding(bottom = 8.dp).fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
SearchResultList(items = contacts)
|
SearchResultList(
|
||||||
|
items = contacts,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(12.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,9 +21,16 @@ fun ColumnScope.FileResults() {
|
|||||||
|
|
||||||
AnimatedVisibility(files.isNotEmpty()) {
|
AnimatedVisibility(files.isNotEmpty()) {
|
||||||
LauncherCard(
|
LauncherCard(
|
||||||
modifier = Modifier.padding(bottom = 8.dp).fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
SearchResultList(items = files)
|
SearchResultList(
|
||||||
|
items = files,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(12.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package de.mm20.launcher2.ui.launcher.widgets.calendar
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.*
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import de.mm20.launcher2.ui.R
|
||||||
|
import de.mm20.launcher2.ui.component.InnerCard
|
||||||
|
import de.mm20.launcher2.ui.component.MissingPermissionBanner
|
||||||
|
import de.mm20.launcher2.ui.launcher.search.common.list.SearchResultList
|
||||||
|
import de.mm20.launcher2.ui.pluralResource
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CalendarWidget() {
|
||||||
|
val viewModel: CalendarWidgetVM = viewModel()
|
||||||
|
val context = LocalContext.current
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
|
||||||
|
LaunchedEffect(null) {
|
||||||
|
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
|
viewModel.onActive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 4.dp)
|
||||||
|
) {
|
||||||
|
IconButton(onClick = { viewModel.previousDay() }) {
|
||||||
|
Icon(imageVector = Icons.Rounded.ChevronLeft, contentDescription = null)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
val selectedDate by viewModel.selectedDate.observeAsState(LocalDate.now())
|
||||||
|
var showDropdown by remember { mutableStateOf(false) }
|
||||||
|
TextButton(onClick = { showDropdown = true }) {
|
||||||
|
Text(
|
||||||
|
text = formatDay(context, selectedDate),
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.ArrowDropDown,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenu(expanded = showDropdown, onDismissRequest = { showDropdown = false }) {
|
||||||
|
val availableDates = viewModel.availableDates
|
||||||
|
for (date in availableDates) {
|
||||||
|
DropdownMenuItem(text = {
|
||||||
|
Text(formatDay(context, date))
|
||||||
|
}, onClick = {
|
||||||
|
viewModel.selectDate(date)
|
||||||
|
showDropdown = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton(onClick = { viewModel.nextDay() }) {
|
||||||
|
Icon(imageVector = Icons.Rounded.ChevronRight, contentDescription = null)
|
||||||
|
}
|
||||||
|
IconButton(onClick = { viewModel.createEvent(context) }) {
|
||||||
|
Icon(imageVector = Icons.Rounded.Add, contentDescription = null)
|
||||||
|
}
|
||||||
|
IconButton(onClick = { viewModel.openCalendarApp(context) }) {
|
||||||
|
Icon(imageVector = Icons.Rounded.OpenInNew, contentDescription = null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val events by viewModel.calendarEvents.observeAsState(emptyList())
|
||||||
|
val hasPermission by viewModel.hasPermission.observeAsState()
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 12.dp)
|
||||||
|
.padding(bottom = 12.dp)
|
||||||
|
) {
|
||||||
|
if (hasPermission == false) {
|
||||||
|
MissingPermissionBanner(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(4.dp),
|
||||||
|
text = stringResource(R.string.permission_calendar_widget),
|
||||||
|
onClick = { viewModel.requestCalendarPermission(context as AppCompatActivity) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (events.isEmpty() && hasPermission == true) {
|
||||||
|
Info(text = stringResource(R.string.calendar_widget_no_events))
|
||||||
|
}
|
||||||
|
SearchResultList(
|
||||||
|
events,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
val runningEvents by viewModel.hiddenPastEvents.observeAsState(0)
|
||||||
|
if (runningEvents > 0) {
|
||||||
|
Info(
|
||||||
|
text = pluralResource(
|
||||||
|
R.plurals.calendar_widget_running_events,
|
||||||
|
runningEvents,
|
||||||
|
runningEvents
|
||||||
|
),
|
||||||
|
onClick = {
|
||||||
|
viewModel.showAllEvents()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val pinnedEvents by viewModel.pinnedCalendarEvents.observeAsState(emptyList())
|
||||||
|
if (pinnedEvents.size > 0) {
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.calendar_widget_pinned_events),
|
||||||
|
modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = 4.dp),
|
||||||
|
style = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
SearchResultList(
|
||||||
|
pinnedEvents,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Info(
|
||||||
|
text: String,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
InnerCard(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(4.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(12.dp)
|
||||||
|
.clickable(enabled = onClick != null, onClick = { onClick?.invoke() })
|
||||||
|
) {
|
||||||
|
Text(text, style = MaterialTheme.typography.bodySmall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun formatDay(context: Context, day: LocalDate): String {
|
||||||
|
val today = LocalDate.now()
|
||||||
|
return when {
|
||||||
|
today == day -> context.getString(R.string.date_today)
|
||||||
|
today.plusDays(1) == day -> context.getString(R.string.date_tomorrow)
|
||||||
|
else -> DateUtils.formatDateTime(
|
||||||
|
context,
|
||||||
|
day.atStartOfDay(ZoneId.systemDefault()).toEpochSecond() * 1000,
|
||||||
|
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_WEEKDAY or DateUtils.FORMAT_ABBREV_WEEKDAY
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import android.content.ContentUris
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
@ -47,7 +48,7 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
|||||||
val startDate =
|
val startDate =
|
||||||
Instant.ofEpochMilli(it.startTime).atZone(ZoneId.systemDefault()).toLocalDate()
|
Instant.ofEpochMilli(it.startTime).atZone(ZoneId.systemDefault()).toLocalDate()
|
||||||
val endDate =
|
val endDate =
|
||||||
Instant.ofEpochMilli(it.startTime).atZone(ZoneId.systemDefault()).toLocalDate()
|
Instant.ofEpochMilli(it.endTime).atZone(ZoneId.systemDefault()).toLocalDate()
|
||||||
return@flatMap listOf(
|
return@flatMap listOf(
|
||||||
startDate,
|
startDate,
|
||||||
endDate
|
endDate
|
||||||
@ -121,7 +122,8 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
|||||||
val totalCount = events.size
|
val totalCount = events.size
|
||||||
|
|
||||||
events = events.filter {
|
events = events.filter {
|
||||||
it.startTime >= date.atStartOfDay().toEpochSecond(offset) * 1000
|
it.startTime >= date.atStartOfDay().toEpochSecond(offset) * 1000 ||
|
||||||
|
it.endTime < date.atStartOfDay().plusDays(1).toEpochSecond(offset) * 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
val hiddenCount = totalCount - events.size
|
val hiddenCount = totalCount - events.size
|
||||||
@ -138,4 +140,8 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
|||||||
upcomingEvents = it
|
upcomingEvents = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun requestCalendarPermission(context: AppCompatActivity) {
|
||||||
|
permissionsManager.requestPermission(context, PermissionGroup.Calendar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,30 +1,18 @@
|
|||||||
package de.mm20.launcher2.ui.legacy.widget
|
package de.mm20.launcher2.ui.legacy.widget
|
||||||
|
|
||||||
import android.animation.LayoutTransition
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.format.DateUtils
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import androidx.compose.foundation.layout.Column
|
||||||
import android.view.Menu
|
import androidx.compose.material3.LocalAbsoluteTonalElevation
|
||||||
import android.view.View
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.activity.viewModels
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import de.mm20.launcher2.ui.MdcLauncherTheme
|
||||||
import de.mm20.launcher2.ktx.lifecycleOwner
|
|
||||||
import de.mm20.launcher2.ktx.lifecycleScope
|
|
||||||
import de.mm20.launcher2.permissions.PermissionGroup
|
|
||||||
import de.mm20.launcher2.search.data.CalendarEvent
|
|
||||||
import de.mm20.launcher2.search.data.MissingPermission
|
|
||||||
import de.mm20.launcher2.search.data.Searchable
|
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.databinding.ViewCalendarWidgetBinding
|
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||||
import de.mm20.launcher2.ui.launcher.widgets.calendar.CalendarWidgetVM
|
import de.mm20.launcher2.ui.launcher.widgets.calendar.CalendarWidget
|
||||||
import de.mm20.launcher2.ui.legacy.data.InformationText
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.ZoneId
|
|
||||||
|
|
||||||
class CalendarWidget : LauncherWidget {
|
class CalendarWidget : LauncherWidget {
|
||||||
|
|
||||||
@ -39,141 +27,25 @@ class CalendarWidget : LauncherWidget {
|
|||||||
defStyleRes
|
defStyleRes
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun formatDay(day: LocalDate): String {
|
|
||||||
val today = LocalDate.now()
|
|
||||||
return when {
|
|
||||||
today == day -> context.getString(R.string.date_today)
|
|
||||||
today.plusDays(1) == day -> context.getString(R.string.date_tomorrow)
|
|
||||||
else -> DateUtils.formatDateTime(
|
|
||||||
context,
|
|
||||||
day.atStartOfDay(ZoneId.systemDefault()).toEpochSecond() * 1000,
|
|
||||||
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_WEEKDAY or DateUtils.FORMAT_ABBREV_WEEKDAY
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val binding =
|
|
||||||
ViewCalendarWidgetBinding.inflate(LayoutInflater.from(context), this, true)
|
|
||||||
|
|
||||||
private val viewModel: CalendarWidgetVM by (context as AppCompatActivity).viewModels()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
clipToPadding = false
|
val composeView = ComposeView(context)
|
||||||
clipChildren = false
|
composeView.setContent {
|
||||||
|
MdcLauncherTheme {
|
||||||
lifecycleScope.launch {
|
ProvideSettings {
|
||||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
// TODO: Temporary solution until parent widget card is rewritten in Compose
|
||||||
viewModel.onActive()
|
CompositionLocalProvider(
|
||||||
|
LocalContentColor provides MaterialTheme.colorScheme.onSurface,
|
||||||
|
LocalAbsoluteTonalElevation provides 1.dp
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
CalendarWidget()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addView(composeView)
|
||||||
|
|
||||||
binding.calendarNewEvent.setOnClickListener {
|
|
||||||
viewModel.createEvent(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.calendarDate.setOnClickListener {
|
|
||||||
val menu = PopupMenu(context, binding.calendarDate)
|
|
||||||
val availableDates = viewModel.availableDates
|
|
||||||
for ((i, d) in availableDates.withIndex()) {
|
|
||||||
menu.menu.add(
|
|
||||||
Menu.NONE,
|
|
||||||
i,
|
|
||||||
Menu.NONE,
|
|
||||||
formatDay(d)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
menu.setOnMenuItemClickListener {
|
|
||||||
viewModel.selectDate(availableDates[it.itemId])
|
|
||||||
true
|
|
||||||
}
|
|
||||||
menu.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.calendarOpenApp.setOnClickListener {
|
|
||||||
viewModel.openCalendarApp(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.calendarDateNext.setOnClickListener {
|
|
||||||
viewModel.nextDay()
|
|
||||||
}
|
|
||||||
binding.calendarDatePrev.setOnClickListener {
|
|
||||||
viewModel.previousDay()
|
|
||||||
}
|
|
||||||
|
|
||||||
val calendarEvents = viewModel.calendarEvents
|
|
||||||
val pinnedCalendarEvents = viewModel.pinnedCalendarEvents
|
|
||||||
val hiddenPastEvents = viewModel.hiddenPastEvents
|
|
||||||
val selectedDate = viewModel.selectedDate
|
|
||||||
val hasPermission = viewModel.hasPermission
|
|
||||||
|
|
||||||
calendarEvents.observe(context as AppCompatActivity) {
|
|
||||||
updateEventList(it, hiddenPastEvents.value ?: 0, hasPermission.value == false)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPermission.observe(context as AppCompatActivity) {
|
|
||||||
updateEventList(
|
|
||||||
calendarEvents.value ?: emptyList(),
|
|
||||||
hiddenPastEvents.value ?: 0,
|
|
||||||
it == false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pinnedCalendarEvents.observe(context as AppCompatActivity) {
|
|
||||||
binding.calendarWidgetPinnedList.submitItems(it)
|
|
||||||
if (it.isEmpty()) {
|
|
||||||
binding.calendarWidgetPinnedList.visibility = View.GONE
|
|
||||||
binding.calendarUpcomingEventsTitle.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
binding.calendarWidgetPinnedList.visibility = View.VISIBLE
|
|
||||||
binding.calendarUpcomingEventsTitle.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedDate.observe(context as AppCompatActivity) {
|
|
||||||
binding.calendarDate.text = formatDay(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.calendarWidgetRoot.layoutTransition = LayoutTransition().apply {
|
|
||||||
enableTransitionType(LayoutTransition.CHANGING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateEventList(
|
|
||||||
events: List<CalendarEvent>,
|
|
||||||
hiddenPastDayEvents: Int,
|
|
||||||
missingPermission: Boolean
|
|
||||||
) {
|
|
||||||
val items = events.toMutableList<Searchable>()
|
|
||||||
|
|
||||||
if (missingPermission) {
|
|
||||||
items.add(
|
|
||||||
MissingPermission(
|
|
||||||
context.getString(R.string.permission_calendar_widget),
|
|
||||||
PermissionGroup.Calendar
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events.isEmpty() && !missingPermission) {
|
|
||||||
items.add(
|
|
||||||
InformationText(context.getString(R.string.calendar_widget_no_events))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hiddenPastDayEvents > 0) {
|
|
||||||
items.add(
|
|
||||||
InformationText(
|
|
||||||
resources.getQuantityString(
|
|
||||||
R.plurals.calendar_widget_running_events,
|
|
||||||
hiddenPastDayEvents,
|
|
||||||
hiddenPastDayEvents
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
viewModel.showAllEvents()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.calendarWidgetList.submitItems(items)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user