Make chips skippable

pull/2586/head
Alex Baker 7 months ago
parent 11fa9a2bbd
commit 82103eb477

@ -0,0 +1,56 @@
package org.tasks.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.time.DateTimeUtils.startOfDay
import java.time.format.FormatStyle
@Composable
fun StartDateChip(
sortGroup: Long?,
startDate: Long,
compact: Boolean,
timeOnly: Boolean,
colorProvider: (Int) -> Int,
) {
val context = LocalContext.current
val text by remember(sortGroup, startDate, timeOnly, compact) {
derivedStateOf {
if (
timeOnly &&
sortGroup?.startOfDay() == startDate.startOfDay()
) {
startDate
.takeIf { Task.hasDueTime(it) }
?.let { DateUtilities.getTimeString(context, it.toDateTime()) }
} else {
DateUtilities.getRelativeDateTime(
context,
startDate,
context.resources.configuration.locales[0],
if (compact) FormatStyle.SHORT else FormatStyle.MEDIUM,
false,
false
)
}
}
}
if (text != null) {
Chip(
icon = R.drawable.ic_pending_actions_24px,
name = text,
theme = 0,
showText = true,
showIcon = true,
onClick = {},
colorProvider = colorProvider,
)
}
}

@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.TextView
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
@ -15,17 +16,24 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter
import com.todoroo.astrid.core.SortHelper.SORT_DUE
import com.todoroo.astrid.core.SortHelper.SORT_LIST
import com.todoroo.astrid.core.SortHelper.SORT_START
import com.todoroo.astrid.ui.CheckableImageView
import org.tasks.R
import org.tasks.compose.ChipGroup
import org.tasks.compose.FilterChip
import org.tasks.compose.StartDateChip
import org.tasks.compose.SubtaskChip
import org.tasks.data.TaskContainer
import org.tasks.databinding.TaskAdapterRowBinding
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.Linkify
import org.tasks.filters.PlaceFilter
import org.tasks.markdown.Markdown
import org.tasks.preferences.Preferences
import org.tasks.time.DateTimeUtils.startOfDay
@ -221,6 +229,22 @@ class TaskViewHolder internal constructor(
}
private fun setupChips(filter: Filter, sortByStartDate: Boolean, sortByList: Boolean) {
val id = task.id
val children = task.children
val collapsed = task.isCollapsed
val isHidden = task.isHidden
val sortGroup = task.sortGroup
val startDate = task.task.hideUntil
val place = task.location?.place
val list = task.caldav
val tagsString = task.tagsString
val isSubtask = task.hasParent()
val isGoogleTask = task.isGoogleTask
val appearance = preferences.getIntegerFromString(R.string.p_chip_appearance, 0)
val showText = appearance != 2
val showIcon = appearance != 1
val toggleSubtasks = { task: Long, collapsed: Boolean -> callback.toggleSubtasks(task, collapsed) }
val onClick = { it: Filter -> callback.onClick(it) }
chipGroup.setContent {
MdcTheme {
ChipGroup(
@ -229,24 +253,76 @@ class TaskViewHolder internal constructor(
bottom = rowPaddingDp.dp
)
) {
chipProvider.Chips(
filter = filter,
id = task.id,
children = task.children,
collapsed = task.isCollapsed,
isHidden = task.isHidden,
sortGroup = task.sortGroup,
startDate = task.task.hideUntil,
place = task.location?.place,
list = task.caldav,
tagsString = task.tagsString,
isSubtask = task.hasParent(),
isGoogleTask = task.isGoogleTask,
sortByStartDate = sortByStartDate,
sortByList = sortByList,
toggleSubtasks = { task: Long, collapsed: Boolean -> callback.toggleSubtasks(task, collapsed) },
onClick = { it: Filter -> callback.onClick(it) },
)
if (children > 0 && remember { preferences.showSubtaskChip }) {
SubtaskChip(
collapsed = collapsed,
children = children,
compact = !showText,
onClick = { toggleSubtasks(id, !collapsed) }
)
}
if (isHidden && remember { preferences.showStartDateChip }) {
StartDateChip(
sortGroup = sortGroup,
startDate = startDate,
compact = !showText,
timeOnly = sortByStartDate,
colorProvider = { chipProvider.getColor(it) },
)
}
if (place != null && filter !is PlaceFilter && remember { preferences.showPlaceChip }) {
FilterChip(
filter = PlaceFilter(place),
defaultIcon = R.drawable.ic_outline_place_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = { chipProvider.getColor(it) },
)
}
if (
!isSubtask &&
!sortByList &&
preferences.showListChip &&
filter !is CaldavFilter &&
filter !is GtasksFilter
) {
remember(list, isGoogleTask) {
chipProvider.lists
.getCaldavList(list)
?.let { if (isGoogleTask) GtasksFilter(it) else CaldavFilter(it) }
}?.let {
FilterChip(
filter = it,
defaultIcon = R.drawable.ic_list_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = { chipProvider.getColor(it) },
)
}
}
if (!tagsString.isNullOrBlank() && remember { preferences.showTagChip }) {
remember(tagsString, filter) {
val tags = tagsString.split(",").toHashSet()
if (filter is TagFilter) {
tags.remove(filter.uuid)
}
tags.mapNotNull { chipProvider.lists.getTag(it) }
.sortedBy(TagFilter::title)
}
.forEach {
FilterChip(
filter = it,
defaultIcon = R.drawable.ic_outline_label_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = { chipProvider.getColor(it) },
)
}
}
}
}
}

@ -1,173 +1,18 @@
package org.tasks.ui
import android.app.Activity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.billing.Inventory
import org.tasks.compose.Chip
import org.tasks.compose.FilterChip
import org.tasks.compose.SubtaskChip
import org.tasks.data.Place
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.filters.PlaceFilter
import org.tasks.preferences.Preferences
import org.tasks.themes.ColorProvider
import org.tasks.time.DateTimeUtils.startOfDay
import java.time.format.FormatStyle
import java.util.Locale
import javax.inject.Inject
@Deprecated("remove me")
class ChipProvider @Inject constructor(
private val activity: Activity,
private val inventory: Inventory,
private val lists: ChipListCache,
private val preferences: Preferences,
val lists: ChipListCache,
private val colorProvider: ColorProvider,
private val locale: Locale
) {
private val showIcon: Boolean
private val showText: Boolean
init {
val appearance = preferences.getIntegerFromString(R.string.p_chip_appearance, 0)
showText = appearance != 2
showIcon = appearance != 1
}
@Composable
private fun StartDateChip(
sortGroup: Long?,
startDate: Long,
compact: Boolean,
timeOnly: Boolean
) {
val text by remember(sortGroup, startDate, timeOnly, compact) {
derivedStateOf {
if (
timeOnly &&
sortGroup?.startOfDay() == startDate.startOfDay()
) {
startDate
.takeIf { Task.hasDueTime(it) }
?.let { DateUtilities.getTimeString(activity, it.toDateTime()) }
} else {
DateUtilities.getRelativeDateTime(
activity,
startDate,
locale,
if (compact) FormatStyle.SHORT else FormatStyle.MEDIUM,
false,
false
)
}
}
}
if (text != null) {
Chip(
R.drawable.ic_pending_actions_24px,
text,
0,
showText = true,
showIcon = true,
onClick = {},
colorProvider = this::getColor,
)
}
}
@Composable
fun Chips(
filter: Filter?,
id: Long,
children: Int,
collapsed: Boolean,
isHidden: Boolean,
sortGroup: Long?,
startDate: Long,
place: Place?,
tagsString: String?,
sortByStartDate: Boolean,
sortByList: Boolean,
list: String?,
isSubtask: Boolean,
isGoogleTask: Boolean,
toggleSubtasks: (Long, Boolean) -> Unit,
onClick: (Filter) -> Unit,
) {
if (children > 0 && remember { preferences.showSubtaskChip }) {
SubtaskChip(
collapsed = collapsed,
children = children,
compact = !showText,
onClick = { toggleSubtasks(id, !collapsed) }
)
}
if (isHidden && remember { preferences.showStartDateChip }) {
StartDateChip(sortGroup, startDate, !showText, sortByStartDate)
}
if (place != null && filter !is PlaceFilter && remember { preferences.showPlaceChip }) {
FilterChip(
filter = PlaceFilter(place),
defaultIcon = R.drawable.ic_outline_place_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = this::getColor,
)
}
if (
!isSubtask &&
!sortByList &&
preferences.showListChip &&
filter !is CaldavFilter &&
filter !is GtasksFilter
) {
remember(list, isGoogleTask) {
lists
.getCaldavList(list)
?.let { if (isGoogleTask) GtasksFilter(it) else CaldavFilter(it) }
}?.let {
FilterChip(
filter = it,
defaultIcon = R.drawable.ic_list_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = this::getColor,
)
}
}
if (!tagsString.isNullOrBlank() && remember { preferences.showTagChip }) {
remember(tagsString, filter) {
val tags = tagsString.split(",").toHashSet()
if (filter is TagFilter) {
tags.remove(filter.uuid)
}
tags.mapNotNull(lists::getTag)
.sortedBy(TagFilter::title)
}
.forEach {
FilterChip(
filter = it,
defaultIcon = R.drawable.ic_outline_label_24px,
onClick = onClick,
showText = showText,
showIcon = showIcon,
colorProvider = this::getColor,
)
}
}
}
fun getColor(theme: Int): Int {
if (theme != 0) {

@ -3037,11 +3037,7 @@ unstable class ChipProvider {
unstable val activity: Activity
unstable val inventory: Inventory
unstable val lists: ChipListCache
unstable val preferences: Preferences
unstable val colorProvider: ColorProvider
unstable val locale: Locale
stable val showIcon: Boolean
stable val showText: Boolean
<runtime stability> = Unstable
}
unstable class CompletableViewModel {

@ -289,6 +289,13 @@ restartable fun Spinner(
stable onSelected: Function1<T, Unit>
stable setExpanded: Function1<Boolean, Unit>
)
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun StartDateChip(
stable sortGroup: Long?
stable startDate: Long
stable compact: Boolean
stable timeOnly: Boolean
stable colorProvider: Function1<Int, Int>
)
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun PurchaseText(
stable nameYourPrice: MutableState<Boolean>? = @dynamic mutableStateOf(
value = false
@ -766,29 +773,3 @@ restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun OrderingB
stable onClick: Function0<Unit>
)
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun PreviewSortBottomSheet()
restartable scheme("[androidx.compose.ui.UiComposable]") fun StartDateChip(
stable sortGroup: Long?
stable startDate: Long
stable compact: Boolean
stable timeOnly: Boolean
unstable <this>: ChipProvider
)
restartable scheme("[androidx.compose.ui.UiComposable]") fun Chips(
filter: Filter?
stable id: Long
stable children: Int
stable collapsed: Boolean
stable isHidden: Boolean
stable sortGroup: Long?
stable startDate: Long
stable place: Place?
stable tagsString: String?
stable sortByStartDate: Boolean
stable sortByList: Boolean
stable list: String?
stable isSubtask: Boolean
stable isGoogleTask: Boolean
stable toggleSubtasks: Function2<Long, Boolean, Unit>
stable onClick: Function1<Filter, Unit>
unstable <this>: ChipProvider
)

@ -1,16 +1,16 @@
{
"skippableComposables": 364,
"restartableComposables": 490,
"skippableComposables": 365,
"restartableComposables": 489,
"readonlyComposables": 0,
"totalComposables": 496,
"restartGroups": 490,
"totalGroups": 599,
"totalComposables": 495,
"restartGroups": 489,
"totalGroups": 598,
"staticArguments": 762,
"certainArguments": 328,
"knownStableArguments": 4878,
"certainArguments": 314,
"knownStableArguments": 4864,
"knownUnstableArguments": 139,
"unknownStableArguments": 10,
"totalArguments": 5027,
"unknownStableArguments": 9,
"totalArguments": 5012,
"markedStableClasses": 0,
"inferredStableClasses": 100,
"inferredUnstableClasses": 345,
@ -21,5 +21,5 @@
"singletonLambdas": 182,
"singletonComposableLambdas": 90,
"composableLambdas": 223,
"totalLambdas": 631
"totalLambdas": 633
}
Loading…
Cancel
Save