Calendar widget: separate running tasks from running events
This commit is contained in:
@@ -366,7 +366,7 @@ fun CalendarItemGridPopup(
|
||||
|
||||
private fun CalendarEvent.formatTime(context: Context): String {
|
||||
val startTime = startTime
|
||||
if (startTime == null) {
|
||||
if (startTime == null || isTask) {
|
||||
if (allDay) {
|
||||
return DateUtils.formatDateRange(
|
||||
context,
|
||||
@@ -400,7 +400,7 @@ private fun CalendarEvent.formatTime(context: Context): String {
|
||||
|
||||
private fun CalendarEvent.getSummary(context: Context): String {
|
||||
val startTime = startTime
|
||||
if (startTime == null) {
|
||||
if (isTask || startTime == null) {
|
||||
val isToday = DateUtils.isToday(endTime)
|
||||
if (isToday) {
|
||||
if (allDay) {
|
||||
|
||||
+22
-10
@@ -52,6 +52,7 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.Quadruple
|
||||
import de.mm20.launcher2.Quintuple
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.InnerCard
|
||||
import de.mm20.launcher2.ui.component.MissingPermissionBanner
|
||||
@@ -132,6 +133,7 @@ fun CalendarWidget(
|
||||
val events by viewModel.calendarEvents
|
||||
val nextEvents by viewModel.nextEvents
|
||||
val runningEvents by viewModel.hiddenPastEvents
|
||||
val runningTasks by viewModel.hiddenRunningTasks
|
||||
val hasPermission by viewModel.hasPermission.collectAsState()
|
||||
Column {
|
||||
if (hasPermission == false) {
|
||||
@@ -145,10 +147,11 @@ fun CalendarWidget(
|
||||
)
|
||||
}
|
||||
AnimatedContent(
|
||||
Quadruple(
|
||||
Quintuple(
|
||||
selectedDate,
|
||||
events,
|
||||
runningEvents,
|
||||
runningTasks,
|
||||
nextEvents
|
||||
),
|
||||
transitionSpec = {
|
||||
@@ -185,7 +188,7 @@ fun CalendarWidget(
|
||||
}
|
||||
}
|
||||
}
|
||||
) { (_, events, runningEvents, nextEvents) ->
|
||||
) { (_, events, runningEvents, runningTasks, nextEvents) ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 12.dp)
|
||||
@@ -212,6 +215,20 @@ fun CalendarWidget(
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (runningTasks > 0) {
|
||||
Info(
|
||||
text = pluralStringResource(
|
||||
R.plurals.calendar_widget_running_tasks,
|
||||
runningTasks,
|
||||
runningTasks
|
||||
),
|
||||
onClick = {
|
||||
viewModel.showAllTasks()
|
||||
},
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
if (nextEvents.isNotEmpty()) {
|
||||
Text(
|
||||
stringResource(R.string.calendar_widget_next_events),
|
||||
@@ -272,15 +289,10 @@ private fun Info(
|
||||
.fillMaxWidth()
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.border(1.dp, MaterialTheme.colorScheme.outlineVariant, MaterialTheme.shapes.small)
|
||||
.clickable(enabled = onClick != null, onClick = { onClick?.invoke() })
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
modifier = Modifier
|
||||
.clickable(enabled = onClick != null, onClick = { onClick?.invoke() })
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Text(text, style = MaterialTheme.typography.bodySmall)
|
||||
}
|
||||
Text(text, style = MaterialTheme.typography.bodySmall)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-4
@@ -54,7 +54,9 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
|
||||
|
||||
private var showRunningPastDayEvents = false
|
||||
private var showRunningTasks = false
|
||||
val hiddenPastEvents = mutableStateOf(0)
|
||||
val hiddenRunningTasks = mutableStateOf(0)
|
||||
|
||||
val selectedDate = mutableStateOf(LocalDate.now())
|
||||
|
||||
@@ -102,6 +104,7 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
||||
fun selectDate(date: LocalDate) {
|
||||
val dates = availableDates
|
||||
showRunningPastDayEvents = false
|
||||
showRunningTasks = false
|
||||
if (dates.contains(date)) {
|
||||
selectedDate.value = date
|
||||
updateEvents()
|
||||
@@ -113,6 +116,11 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
||||
updateEvents()
|
||||
}
|
||||
|
||||
fun showAllTasks() {
|
||||
showRunningTasks = true
|
||||
updateEvents()
|
||||
}
|
||||
|
||||
fun createEvent(context: Context) {
|
||||
val intent = Intent(Intent.ACTION_EDIT)
|
||||
intent.data = CalendarContract.Events.CONTENT_URI
|
||||
@@ -136,15 +144,23 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
||||
val dayStart = max(now, date.atStartOfDay().toEpochSecond(offset) * 1000)
|
||||
val dayEnd = date.plusDays(1).atStartOfDay().toEpochSecond(offset) * 1000
|
||||
var events = upcomingEvents.filter {
|
||||
it.endTime >= dayStart && (it.startTime ?: it.endTime) < dayEnd
|
||||
if (it.isTask && it.isCompleted == true) {
|
||||
it.endTime >= dayStart && it.endTime < dayEnd
|
||||
} else {
|
||||
it.endTime >= dayStart && (it.startTime ?: 0L) < dayEnd
|
||||
}
|
||||
}
|
||||
|
||||
val startOfDay = date.atStartOfDay().toEpochSecond(offset) * 1000
|
||||
val startOfNextDay = date.atStartOfDay().plusDays(1).toEpochSecond(offset) * 1000
|
||||
|
||||
if (!showRunningPastDayEvents) {
|
||||
val totalCount = events.size
|
||||
|
||||
|
||||
events = events.filter {
|
||||
(it.startTime != null && it.startTime!! >= date.atStartOfDay().toEpochSecond(offset) * 1000) ||
|
||||
it.endTime < date.atStartOfDay().plusDays(1).toEpochSecond(offset) * 1000
|
||||
((it.startTime != null && it.startTime!! >= startOfDay) ||
|
||||
it.endTime < startOfNextDay) || it.isTask
|
||||
}
|
||||
|
||||
val hiddenCount = totalCount - events.size
|
||||
@@ -152,11 +168,27 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
|
||||
} else {
|
||||
hiddenPastEvents.value = 0
|
||||
}
|
||||
if (!showRunningTasks) {
|
||||
val totalCount = events.size
|
||||
|
||||
events = events.filter {
|
||||
((it.startTime != null && it.startTime!! >= startOfDay) ||
|
||||
it.endTime < startOfNextDay) || !it.isTask
|
||||
}
|
||||
|
||||
val hiddenCount = totalCount - events.size
|
||||
hiddenRunningTasks.value = hiddenCount
|
||||
} else {
|
||||
hiddenRunningTasks.value = 0
|
||||
}
|
||||
|
||||
calendarEvents.value = events
|
||||
val e = this.upcomingEvents
|
||||
if (events.isEmpty() && e.isNotEmpty()) {
|
||||
nextEvents.value = listOf(e[0])
|
||||
nextEvents.value = listOfNotNull(
|
||||
e.sortedBy { if (it.isTask) it.endTime else (it.startTime ?: 0L) }
|
||||
.find { now < if (it.isTask) it.endTime else (it.startTime ?: 0L) }
|
||||
)
|
||||
} else {
|
||||
nextEvents.value = emptyList()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user