Convert FilterListItem to interface

pull/2553/head
Alex Baker 2 years ago
parent a32d35720a
commit ee3d3fa4f5

@ -265,7 +265,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
fab.isVisible = filter.isWritable fab.isVisible = filter.isWritable
} }
themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor
filter.setFilterQueryOverride(null) filter.filterOverride = null
// set up list adapters // set up list adapters
taskAdapter = taskAdapterProvider.createTaskAdapter(filter) taskAdapter = taskAdapterProvider.createTaskAdapter(filter)

@ -5,14 +5,15 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.todoroo.astrid.api.FilterListItem
import org.tasks.databinding.FilterAdapterActionBinding import org.tasks.databinding.FilterAdapterActionBinding
import org.tasks.filters.NavigationDrawerAction
import org.tasks.themes.DrawableUtil import org.tasks.themes.DrawableUtil
class ActionViewHolder internal constructor( class ActionViewHolder internal constructor(
private val context: Context, private val context: Context,
itemView: View, itemView: View,
private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) { private val onClick: (NavigationDrawerAction) -> Unit
) : RecyclerView.ViewHolder(itemView) {
private val row: View private val row: View
private val text: TextView private val text: TextView
@ -26,13 +27,11 @@ class ActionViewHolder internal constructor(
} }
} }
fun bind(filter: FilterListItem) { fun bind(filter: NavigationDrawerAction) {
text.text = filter.listingTitle text.text = filter.listingTitle
icon.setImageDrawable(DrawableUtil.getWrapped(context, filter.icon)) icon.setImageDrawable(DrawableUtil.getWrapped(context, filter.icon))
if (onClick != null) {
row.setOnClickListener { row.setOnClickListener {
onClick.invoke(filter) onClick.invoke(filter)
} }
} }
} }
}

@ -7,7 +7,11 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.todoroo.astrid.api.* import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.CustomFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter
import org.tasks.R import org.tasks.R
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.databinding.FilterAdapterRowBinding import org.tasks.databinding.FilterAdapterRowBinding
@ -16,7 +20,7 @@ import org.tasks.filters.PlaceFilter
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons.getIconResId import org.tasks.themes.CustomIcons.getIconResId
import org.tasks.themes.DrawableUtil import org.tasks.themes.DrawableUtil
import java.util.* import java.util.Locale
class FilterViewHolder internal constructor( class FilterViewHolder internal constructor(
itemView: View, itemView: View,
@ -25,7 +29,7 @@ class FilterViewHolder internal constructor(
private val context: Context, private val context: Context,
private val inventory: Inventory, private val inventory: Inventory,
private val colorProvider: ColorProvider, private val colorProvider: ColorProvider,
private val onClick: ((FilterListItem?) -> Unit)? private val onClick: (Filter) -> Unit,
) : RecyclerView.ViewHolder(itemView) { ) : RecyclerView.ViewHolder(itemView) {
private val row: View private val row: View
@ -34,7 +38,7 @@ class FilterViewHolder internal constructor(
private val size: TextView private val size: TextView
private val shareIndicator: ImageView private val shareIndicator: ImageView
lateinit var filter: FilterListItem lateinit var filter: Filter
init { init {
FilterAdapterRowBinding.bind(itemView).let { FilterAdapterRowBinding.bind(itemView).let {
@ -53,7 +57,7 @@ class FilterViewHolder internal constructor(
itemView.isSelected = moving itemView.isSelected = moving
} }
fun bind(filter: FilterListItem, selected: Boolean, count: Int?) { fun bind(filter: Filter, selected: Boolean, count: Int?) {
this.filter = filter this.filter = filter
if (navigationDrawer) { if (navigationDrawer) {
itemView.isSelected = selected itemView.isSelected = selected
@ -71,21 +75,20 @@ class FilterViewHolder internal constructor(
size.visibility = View.VISIBLE size.visibility = View.VISIBLE
} }
shareIndicator.apply { shareIndicator.apply {
isVisible = filter.principals > 0 isVisible = filter is CaldavFilter && filter.principals > 0
setImageResource(when { setImageResource(when {
filter !is CaldavFilter -> 0
filter.principals <= 0 -> 0 filter.principals <= 0 -> 0
filter.principals == 1 -> R.drawable.ic_outline_perm_identity_24px filter.principals == 1 -> R.drawable.ic_outline_perm_identity_24px
else -> R.drawable.ic_outline_people_outline_24 else -> R.drawable.ic_outline_people_outline_24
}) })
} }
if (onClick != null) {
row.setOnClickListener { row.setOnClickListener {
onClick.invoke(filter) onClick.invoke(filter)
} }
} }
}
private fun getColor(filter: FilterListItem): Int { private fun getColor(filter: Filter): Int {
if (filter.tint != 0) { if (filter.tint != 0) {
val color = colorProvider.getThemeColor(filter.tint, true) val color = colorProvider.getThemeColor(filter.tint, true)
if (color.isFree || inventory.purchasedThemes()) { if (color.isFree || inventory.purchasedThemes()) {
@ -95,7 +98,7 @@ class FilterViewHolder internal constructor(
return context.getColor(R.color.text_primary) return context.getColor(R.color.text_primary)
} }
private fun getIcon(filter: FilterListItem): Int { private fun getIcon(filter: Filter): Int {
if (filter.icon < 1000 || inventory.hasPro) { if (filter.icon < 1000 || inventory.hasPro) {
val icon = getIconResId(filter.icon) val icon = getIconResId(filter.icon)
if (icon != null) { if (icon != null) {

@ -18,9 +18,12 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import org.tasks.activities.DragAndDropDiffer import org.tasks.activities.DragAndDropDiffer
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.filters.NavigationDrawerAction
import org.tasks.filters.NavigationDrawerSubheader import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import java.util.* import java.util.LinkedList
import java.util.Locale
import java.util.Queue
import java.util.concurrent.Executors import java.util.concurrent.Executors
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.max import kotlin.math.max
@ -79,8 +82,8 @@ class NavigationDrawerAdapter @Inject constructor(
val item = getItem(position) val item = getItem(position)
when (item.itemType) { when (item.itemType) {
FilterListItem.Type.ITEM -> FilterListItem.Type.ITEM ->
(holder as FilterViewHolder).bind(item, item == selected, max(item.count, 0)) (holder as FilterViewHolder).bind(item as Filter, item == selected, max(item.count, 0))
FilterListItem.Type.ACTION -> (holder as ActionViewHolder).bind(item) FilterListItem.Type.ACTION -> (holder as ActionViewHolder).bind(item as NavigationDrawerAction)
FilterListItem.Type.SUBHEADER -> FilterListItem.Type.SUBHEADER ->
(holder as SubheaderViewHolder).bind((item as NavigationDrawerSubheader)) (holder as SubheaderViewHolder).bind((item as NavigationDrawerSubheader))
else -> {} else -> {}

@ -9,7 +9,11 @@ import org.tasks.LocalBroadcastManager
import org.tasks.data.CaldavDao import org.tasks.data.CaldavDao
import org.tasks.dialogs.NewFilterDialog import org.tasks.dialogs.NewFilterDialog
import org.tasks.filters.NavigationDrawerSubheader import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.* import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.CALDAV
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.ETESYNC
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.GOOGLE_TASKS
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.PREFERENCE
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.TASKS
import org.tasks.preferences.MainPreferences import org.tasks.preferences.MainPreferences
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
import org.tasks.ui.NavigationDrawerFragment import org.tasks.ui.NavigationDrawerFragment
@ -30,6 +34,7 @@ class SubheaderClickHandler @Inject constructor(
CALDAV, CALDAV,
TASKS, TASKS,
ETESYNC -> caldavDao.setCollapsed(subheader.id, collapsed) ETESYNC -> caldavDao.setCollapsed(subheader.id, collapsed)
else -> throw IllegalArgumentException()
} }
localBroadcastManager.broadcastRefreshList() localBroadcastManager.broadcastRefreshList()
} }

@ -16,6 +16,8 @@ internal class SubheaderViewHolder(
private val clickHandler: ClickHandler, private val clickHandler: ClickHandler,
): RecyclerView.ViewHolder(itemView) { ): RecyclerView.ViewHolder(itemView) {
var listingTitle: String? = null
interface ClickHandler { interface ClickHandler {
fun onClick(subheader: NavigationDrawerSubheader) fun onClick(subheader: NavigationDrawerSubheader)
fun onAdd(subheader: NavigationDrawerSubheader) fun onAdd(subheader: NavigationDrawerSubheader)

@ -14,7 +14,8 @@ import org.tasks.data.CaldavTask
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
class CaldavFilter( class CaldavFilter(
val calendar: CaldavCalendar val calendar: CaldavCalendar,
val principals: Int = 0,
) : Filter(calendar.name, queryTemplate(calendar), getValuesForNewTask(calendar)) { ) : Filter(calendar.name, queryTemplate(calendar), getValuesForNewTask(calendar)) {
init { init {
@ -41,7 +42,7 @@ class CaldavFilter(
override val menu = R.menu.menu_caldav_list_fragment override val menu = R.menu.menu_caldav_list_fragment
override fun areContentsTheSame(other: FilterListItem): Boolean { override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && calendar == (other as CaldavFilter).calendar return super.areContentsTheSame(other) && calendar == (other as CaldavFilter).calendar && principals == other.principals
} }
companion object { companion object {

@ -36,7 +36,7 @@ class CustomFilter : Filter {
} }
override val menu: Int override val menu: Int
get() = if (getId() > 0) R.menu.menu_custom_filter else 0 get() = if (id > 0) R.menu.menu_custom_filter else 0
override fun areContentsTheSame(other: FilterListItem): Boolean { override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && criterion == (other as CustomFilter).criterion return super.areContentsTheSame(other) && criterion == (other as CustomFilter).criterion

@ -6,35 +6,15 @@ import androidx.annotation.MenuRes
import com.todoroo.andlib.sql.QueryTemplate import com.todoroo.andlib.sql.QueryTemplate
open class Filter : FilterListItem { open class Filter : FilterListItem {
/**
* Values to apply to a task when quick-adding a task from this filter. For example, when a user
* views tasks tagged 'ABC', the tasks they create should also be tagged 'ABC'. If set to null, no
* additional values will be stored for a task. Can use [PermaSql]
*/
val valuesForNewTasks: MutableMap<String, Any> = HashMap() val valuesForNewTasks: MutableMap<String, Any> = HashMap()
/**
* [PermaSql] query for this filter. The query will be appended to the select statement
* after "`SELECT fields FROM table %s`". It is recommended that you use a [ ] to construct your query.
*
*
* Examples:
*
*
* * `"WHERE completionDate = 0"`
* * `"INNER JOIN " +
* Constants.TABLE_METADATA + " ON metadata.task = tasks.id WHERE
* metadata.namespace = " + NAMESPACE + " AND metadata.key = 'a' AND
* metadata.value = 'b' GROUP BY tasks.id ORDER BY tasks.title"`
*
*/
var originalSqlQuery: String? = null var originalSqlQuery: String? = null
@Deprecated("for astrid manual order") var filterOverride: String? = null
/** var id = 0L
* Field for holding a modified sqlQuery based on sqlQuery. Useful for adjusting query for var icon = -1
* sort/subtasks without breaking the equality checking based on sqlQuery. var listingTitle: String? = null
*/ var tint = 0
private var filterOverride: String? = null var count = -1
var order = NO_ORDER
constructor(listingTitle: String?, sqlQuery: QueryTemplate?) : this( constructor(listingTitle: String?, sqlQuery: QueryTemplate?) : this(
listingTitle, listingTitle,
@ -77,85 +57,45 @@ open class Filter : FilterListItem {
return filterOverride ?: originalSqlQuery!! return filterOverride ?: originalSqlQuery!!
} }
// --- parcelable override val itemType = FilterListItem.Type.ITEM
fun setFilterQueryOverride(filterOverride: String?) {
this.filterOverride = filterOverride
}
override fun hashCode(): Int {
val prime = 31
var result = 1
result = prime * result + if (originalSqlQuery == null) 0 else originalSqlQuery.hashCode()
result = prime * result + if (listingTitle == null) 0 else listingTitle.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null) {
return false
}
if (javaClass != other.javaClass) {
return false
}
val filter = other as Filter
if (originalSqlQuery == null) {
if (filter.originalSqlQuery != null) {
return false
}
} else if (originalSqlQuery != filter.originalSqlQuery) {
return false
}
return if (listingTitle == null) {
filter.listingTitle == null
} else listingTitle == filter.listingTitle
}
override fun getItemType(): Type {
return Type.ITEM
}
/** {@inheritDoc} */ /** {@inheritDoc} */
override fun writeToParcel(dest: Parcel, flags: Int) { override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags) dest.writeLong(id)
dest.writeString("") // old title dest.writeInt(icon)
dest.writeString(listingTitle)
dest.writeInt(tint)
dest.writeInt(count)
dest.writeInt(order)
dest.writeString(originalSqlQuery) dest.writeString(originalSqlQuery)
dest.writeMap(valuesForNewTasks) dest.writeMap(valuesForNewTasks)
} }
override fun readFromParcel(source: Parcel) { open fun readFromParcel(source: Parcel) {
super.readFromParcel(source) id = source.readLong()
source.readString() // old title icon = source.readInt()
listingTitle = source.readString()
tint = source.readInt()
count = source.readInt()
order = source.readInt()
originalSqlQuery = source.readString() originalSqlQuery = source.readString()
source.readMap(valuesForNewTasks, javaClass.classLoader) source.readMap(valuesForNewTasks, javaClass.classLoader)
} }
open fun supportsAstridSorting(): Boolean { open fun supportsAstridSorting() = false
return false
}
open fun supportsManualSort(): Boolean { open fun supportsManualSort() = false
return false
}
open fun supportsHiddenTasks(): Boolean { open fun supportsHiddenTasks() = true
return true
}
open fun supportsSubtasks(): Boolean { open fun supportsSubtasks() = true
return true
}
open fun supportsSorting(): Boolean { open fun supportsSorting() = true
return true
} open val isReadOnly: Boolean = false
val isWritable: Boolean val isWritable: Boolean
get() = !isReadOnly get() = !isReadOnly
open val isReadOnly: Boolean
get() = false
fun hasBeginningMenu(): Boolean { fun hasBeginningMenu(): Boolean {
return beginningMenu != 0 return beginningMenu != 0
@ -173,28 +113,55 @@ open class Filter : FilterListItem {
open val menu: Int open val menu: Int
get() = 0 get() = 0
override fun toString(): String { override fun describeContents() = 0
return ("Filter{"
+ "sqlQuery='"
+ originalSqlQuery
+ '\''
+ ", filterOverride='"
+ filterOverride
+ '\''
+ ", valuesForNewTasks="
+ valuesForNewTasks
+ '}')
}
override fun areItemsTheSame(other: FilterListItem): Boolean { override fun areItemsTheSame(other: FilterListItem): Boolean {
return other is Filter && originalSqlQuery == other.originalSqlQuery return other is Filter && id == other.id && originalSqlQuery == other.originalSqlQuery
} }
override fun areContentsTheSame(other: FilterListItem): Boolean { override fun areContentsTheSame(other: FilterListItem): Boolean {
return super.areContentsTheSame(other) && originalSqlQuery == (other as Filter).originalSqlQuery return this == other
}
override fun toString(): String {
return "Filter(valuesForNewTasks=$valuesForNewTasks, originalSqlQuery=$originalSqlQuery, filterOverride=$filterOverride, id=$id, icon=$icon, listingTitle=$listingTitle, tint=$tint, count=$count, order=$order)"
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Filter
if (valuesForNewTasks != other.valuesForNewTasks) return false
if (originalSqlQuery != other.originalSqlQuery) return false
if (filterOverride != other.filterOverride) return false
if (id != other.id) return false
if (icon != other.icon) return false
if (listingTitle != other.listingTitle) return false
if (tint != other.tint) return false
if (count != other.count) return false
if (order != other.order) return false
return isReadOnly == other.isReadOnly
}
override fun hashCode(): Int {
var result = valuesForNewTasks.hashCode()
result = 31 * result + (originalSqlQuery?.hashCode() ?: 0)
result = 31 * result + (filterOverride?.hashCode() ?: 0)
result = 31 * result + id.hashCode()
result = 31 * result + icon
result = 31 * result + (listingTitle?.hashCode() ?: 0)
result = 31 * result + tint
result = 31 * result + count
result = 31 * result + order
result = 31 * result + isReadOnly.hashCode()
return result
} }
companion object { companion object {
const val NO_ORDER = -1
@JvmField @JvmField
val CREATOR: Parcelable.Creator<Filter> = object : Parcelable.Creator<Filter> { val CREATOR: Parcelable.Creator<Filter> = object : Parcelable.Creator<Filter> {
/** {@inheritDoc} */ /** {@inheritDoc} */

@ -1,110 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import org.tasks.R;
import java.util.Objects;
/**
* Represents an item displayed by Astrid's FilterListActivity
*
* @author Tim Su <tim@todoroo.com>
*/
public abstract class FilterListItem implements Parcelable {
public static final int NO_ORDER = -1;
/** Title of this item displayed on the Filters page */
public String listingTitle = null;
public long id = 0;
public int icon = -1;
public int tint = 0;
public int count = -1;
public int principals = 0;
public int order = NO_ORDER;
public abstract Type getItemType();
@Override
public int describeContents() {
return 0;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(listingTitle);
dest.writeInt(icon);
dest.writeInt(tint);
dest.writeInt(count);
dest.writeInt(order);
dest.writeLong(id);
}
// --- parcelable helpers
/** Utility method to read FilterListItem properties from a parcel. */
protected void readFromParcel(Parcel source) {
listingTitle = source.readString();
icon = source.readInt();
tint = source.readInt();
count = source.readInt();
order = source.readInt();
id = source.readLong();
}
public long getId() {
return id;
}
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return getClass().equals(other.getClass()) && id == other.id;
}
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return Objects.equals(listingTitle, other.listingTitle)
&& icon == other.icon
&& tint == other.tint
&& count == other.count
&& order == other.order
&& principals == other.principals;
}
@Override
public String toString() {
return "FilterListItem{" +
"listingTitle='" + listingTitle + '\'' +
", id=" + id +
", icon=" + icon +
", tint=" + tint +
", count=" + count +
", principals=" + principals +
", order=" + order +
'}';
}
public enum Type {
ITEM(R.layout.filter_adapter_row),
ACTION(R.layout.filter_adapter_action),
SUBHEADER(R.layout.filter_adapter_subheader),
SEPARATOR(R.layout.filter_adapter_separator);
public final int layout;
Type(@LayoutRes int layout) {
this.layout = layout;
}
}
}

@ -0,0 +1,19 @@
package com.todoroo.astrid.api
import android.os.Parcelable
import androidx.annotation.LayoutRes
import org.tasks.R
interface FilterListItem : Parcelable {
val itemType: Type
fun areItemsTheSame(other: FilterListItem): Boolean
fun areContentsTheSame(other: FilterListItem): Boolean
enum class Type(@param:LayoutRes val layout: Int) {
ITEM(R.layout.filter_adapter_row),
ACTION(R.layout.filter_adapter_action),
SUBHEADER(R.layout.filter_adapter_subheader),
SEPARATOR(R.layout.filter_adapter_separator)
}
}

@ -43,9 +43,11 @@ class TaskDeleter @Inject constructor(
} }
suspend fun clearCompleted(filter: Filter): Int { suspend fun clearCompleted(filter: Filter): Int {
val deleteFilter = Filter(null, null) val deleteFilter = Filter(
deleteFilter.setFilterQueryOverride( null,
QueryUtils.removeOrder(QueryUtils.showHiddenAndCompleted(filter.originalSqlQuery!!))) QueryUtils.removeOrder(QueryUtils.showHiddenAndCompleted(filter.originalSqlQuery!!)),
emptyMap()
)
val completed = taskDao.fetchTasks(preferences, deleteFilter) val completed = taskDao.fetchTasks(preferences, deleteFilter)
.filter(TaskContainer::isCompleted) .filter(TaskContainer::isCompleted)
.filterNot(TaskContainer::isReadOnly) .filterNot(TaskContainer::isReadOnly)

@ -48,7 +48,7 @@ class SubtasksFilterUpdater @Inject constructor(
query = query.replace("ORDER BY .*".toRegex(), "") query = query.replace("ORDER BY .*".toRegex(), "")
query += "ORDER BY $orderString" query += "ORDER BY $orderString"
query = showHiddenAndCompleted(query) query = showHiddenAndCompleted(query)
filter.setFilterQueryOverride(query) filter.filterOverride = query
} }
fun getIndentForTask(targetTaskId: String?): Int { fun getIndentForTask(targetTaskId: String?): Int {

@ -18,7 +18,6 @@ import org.tasks.data.TaskListMetadataDao
import org.tasks.db.QueryUtils.showHiddenAndCompleted import org.tasks.db.QueryUtils.showHiddenAndCompleted
import org.tasks.preferences.QueryPreferences import org.tasks.preferences.QueryPreferences
import timber.log.Timber import timber.log.Timber
import java.util.*
import javax.inject.Inject import javax.inject.Inject
class SubtasksHelper @Inject constructor( class SubtasksHelper @Inject constructor(
@ -33,7 +32,7 @@ class SubtasksHelper @Inject constructor(
): String { ): String {
var query = originalQuery var query = originalQuery
if (filter.supportsAstridSorting() && preferences.isAstridSort) { if (filter.supportsAstridSorting() && preferences.isAstridSort) {
val tagData = tagDataDao.getTagByName(filter.listingTitle) val tagData = tagDataDao.getTagByName(filter.listingTitle!!)
val tlm = when { val tlm = when {
tagData != null -> tagData != null ->
taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!) taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!)
@ -47,7 +46,7 @@ class SubtasksHelper @Inject constructor(
query = query.replace("ORDER BY .*".toRegex(), "") query = query.replace("ORDER BY .*".toRegex(), "")
query += " ORDER BY ${getOrderString(tagData, tlm)}" query += " ORDER BY ${getOrderString(tagData, tlm)}"
query = showHiddenAndCompleted(query) query = showHiddenAndCompleted(query)
filter.setFilterQueryOverride(query) filter.filterOverride = query
} }
} }
return query return query

@ -9,20 +9,32 @@ import android.view.MenuItem
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.ItemTouchHelper.* import androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_DRAG
import androidx.recyclerview.widget.ItemTouchHelper.Callback
import androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags import androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags
import androidx.recyclerview.widget.ItemTouchHelper.DOWN
import androidx.recyclerview.widget.ItemTouchHelper.UP
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.todoroo.astrid.adapter.FilterViewHolder import com.todoroo.astrid.adapter.FilterViewHolder
import com.todoroo.astrid.adapter.NavigationDrawerAdapter import com.todoroo.astrid.adapter.NavigationDrawerAdapter
import com.todoroo.astrid.api.* import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.CustomFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.api.FilterListItem.Type.ITEM import com.todoroo.astrid.api.FilterListItem.Type.ITEM
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
import org.tasks.R import org.tasks.R
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
import org.tasks.data.* import org.tasks.data.CaldavDao
import org.tasks.data.FilterDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.LocationDao
import org.tasks.data.TagDataDao
import org.tasks.databinding.ActivityTagOrganizerBinding import org.tasks.databinding.ActivityTagOrganizerBinding
import org.tasks.filters.FilterProvider import org.tasks.filters.FilterProvider
import org.tasks.filters.PlaceFilter import org.tasks.filters.PlaceFilter
@ -88,7 +100,11 @@ class NavigationDrawerCustomization : ThemedInjectingAppCompatActivity(), Toolba
private fun updateFilters() = lifecycleScope.launch { private fun updateFilters() = lifecycleScope.launch {
filterProvider filterProvider
.drawerCustomizationItems() .drawerCustomizationItems()
.onEach { f -> f.count = 0 } .onEach { f ->
if (f is Filter) {
f.count = 0
}
}
.let { adapter.submitList(it) } .let { adapter.submitList(it) }
} }
@ -203,9 +219,11 @@ class NavigationDrawerCustomization : ThemedInjectingAppCompatActivity(), Toolba
} }
.filter(getPredicate(viewHolder.filter)) .filter(getPredicate(viewHolder.filter))
.forEachIndexed { order, filter -> .forEachIndexed { order, filter ->
if (filter is Filter) {
filter.order = order filter.order = order
setOrder(order, filter) setOrder(order, filter)
} }
}
updateFilters() updateFilters()
} }
} }
@ -223,7 +241,7 @@ class NavigationDrawerCustomization : ThemedInjectingAppCompatActivity(), Toolba
} }
} }
private suspend fun setOrder(order: Int, filter: FilterListItem) { private suspend fun setOrder(order: Int, filter: Filter) {
when (filter) { when (filter) {
is GtasksFilter -> caldavDao.setOrder(filter.list.id, order) is GtasksFilter -> caldavDao.setOrder(filter.list.id, order)
is CaldavFilter -> caldavDao.setOrder(filter.calendar.id, order) is CaldavFilter -> caldavDao.setOrder(filter.calendar.id, order)

@ -18,6 +18,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import org.tasks.R import org.tasks.R
import org.tasks.compose.collectAsStateLifecycleAware import org.tasks.compose.collectAsStateLifecycleAware
@ -40,7 +41,7 @@ fun FilterPicker(
when (filter) { when (filter) {
is NavigationDrawerSubheader -> { is NavigationDrawerSubheader -> {
CollapsibleRow( CollapsibleRow(
text = filter.listingTitle, text = filter.listingTitle!!,
collapsed = filter.isCollapsed, collapsed = filter.isCollapsed,
onClick = { viewModel.onClick(filter) }, onClick = { viewModel.onClick(filter) },
) )
@ -54,13 +55,13 @@ fun FilterPicker(
) { ) {
Row(verticalAlignment = CenterVertically) { Row(verticalAlignment = CenterVertically) {
Text( Text(
text = filter.listingTitle, text = filter.listingTitle!!,
style = MaterialTheme.typography.body2.copy( style = MaterialTheme.typography.body2.copy(
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
), ),
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) )
if (filter.principals > 0) { if (filter is CaldavFilter && filter.principals > 0) {
Icon( Icon(
painter = painterResource( painter = painterResource(
id = when (filter.principals) { id = when (filter.principals) {

@ -5,7 +5,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.tasks.themes.CustomIcons.LIST import org.tasks.themes.CustomIcons.LIST

@ -2,9 +2,14 @@ package org.tasks.data
import android.content.Context import android.content.Context
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import com.todoroo.andlib.utility.DateUtilities.now import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.core.SortHelper.APPLE_EPOCH import com.todoroo.astrid.core.SortHelper.APPLE_EPOCH
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper

@ -4,7 +4,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import org.tasks.Strings import org.tasks.Strings
import org.tasks.themes.CustomIcons.FILTER import org.tasks.themes.CustomIcons.FILTER

@ -1,7 +1,11 @@
package org.tasks.data package org.tasks.data
import androidx.room.* import androidx.room.Dao
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
@Dao @Dao
interface FilterDao { interface FilterDao {

@ -1,6 +1,6 @@
package org.tasks.data package org.tasks.data
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
@Deprecated("Only used for backup migration") @Deprecated("Only used for backup migration")
data class GoogleTaskList( data class GoogleTaskList(

@ -8,7 +8,7 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import com.todoroo.andlib.utility.DateUtilities.now import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import org.tasks.data.Alarm.Companion.TYPE_SNOOZE import org.tasks.data.Alarm.Companion.TYPE_SNOOZE
import org.tasks.filters.LocationFilters import org.tasks.filters.LocationFilters

@ -9,7 +9,7 @@ import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.tasks.Strings import org.tasks.Strings

@ -7,7 +7,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import org.tasks.themes.CustomIcons.LABEL import org.tasks.themes.CustomIcons.LABEL

@ -8,7 +8,7 @@ import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
import org.tasks.db.DbUtils import org.tasks.db.DbUtils

@ -7,7 +7,7 @@ import androidx.room.DeleteColumn
import androidx.room.migration.AutoMigrationSpec import androidx.room.migration.AutoMigrationSpec
import androidx.room.migration.Migration import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.NOTIFY_AFTER_DEADLINE import com.todoroo.astrid.data.Task.Companion.NOTIFY_AFTER_DEADLINE
import com.todoroo.astrid.data.Task.Companion.NOTIFY_AT_DEADLINE import com.todoroo.astrid.data.Task.Companion.NOTIFY_AT_DEADLINE

@ -73,6 +73,8 @@ class FilterPickerViewModel @Inject constructor(
NavigationDrawerSubheader.SubheaderType.TASKS, NavigationDrawerSubheader.SubheaderType.TASKS,
NavigationDrawerSubheader.SubheaderType.ETESYNC -> NavigationDrawerSubheader.SubheaderType.ETESYNC ->
caldavDao.setCollapsed(subheader.id, collapsed) caldavDao.setCollapsed(subheader.id, collapsed)
else -> throw IllegalStateException()
} }
localBroadcastManager.broadcastRefreshList() localBroadcastManager.broadcastRefreshList()
} }

@ -1,44 +0,0 @@
package org.tasks.filters;
import androidx.room.Embedded;
import com.todoroo.astrid.api.CaldavFilter;
import org.tasks.data.CaldavCalendar;
import java.util.Objects;
public class CaldavFilters {
@Embedded public CaldavCalendar caldavCalendar;
public int count;
public int principals;
CaldavFilter toCaldavFilter() {
CaldavFilter filter = new CaldavFilter(caldavCalendar);
filter.count = count;
filter.principals = principals;
return filter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CaldavFilters)) {
return false;
}
CaldavFilters that = (CaldavFilters) o;
return count == that.count && Objects.equals(caldavCalendar, that.caldavCalendar);
}
@Override
public int hashCode() {
return Objects.hash(caldavCalendar, count);
}
@Override
public String toString() {
return "CaldavFilters{" + "caldavCalendar=" + caldavCalendar + ", count=" + count + '}';
}
}

@ -0,0 +1,20 @@
package org.tasks.filters
import androidx.room.Embedded
import com.todoroo.astrid.api.CaldavFilter
import org.tasks.data.CaldavCalendar
data class CaldavFilters(
@JvmField @Embedded val caldavCalendar: CaldavCalendar,
@JvmField val count: Int,
@JvmField val principals: Int,
) {
fun toCaldavFilter(): CaldavFilter {
val filter = CaldavFilter(
calendar = caldavCalendar,
principals = principals,
)
filter.count = count
return filter
}
}

@ -4,21 +4,27 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import com.todoroo.astrid.api.CustomFilter import com.todoroo.astrid.api.CustomFilter
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.Filter.Companion.NO_ORDER
import com.todoroo.astrid.api.FilterListItem import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.api.FilterListItem.NO_ORDER
import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.core.BuiltInFilterExposer
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import org.tasks.BuildConfig import org.tasks.BuildConfig
import org.tasks.R import org.tasks.R
import org.tasks.Tasks.Companion.IS_GENERIC
import org.tasks.activities.GoogleTaskListSettingsActivity import org.tasks.activities.GoogleTaskListSettingsActivity
import org.tasks.activities.NavigationDrawerCustomization import org.tasks.activities.NavigationDrawerCustomization
import org.tasks.activities.TagSettingsActivity import org.tasks.activities.TagSettingsActivity
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
import org.tasks.data.* import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavAccount.Companion.TYPE_ETESYNC import org.tasks.data.CaldavAccount.Companion.TYPE_ETESYNC
import org.tasks.data.CaldavAccount.Companion.TYPE_LOCAL import org.tasks.data.CaldavAccount.Companion.TYPE_LOCAL
import org.tasks.data.CaldavAccount.Companion.TYPE_OPENTASKS import org.tasks.data.CaldavAccount.Companion.TYPE_OPENTASKS
import org.tasks.data.CaldavDao
import org.tasks.data.FilterDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.LocationDao
import org.tasks.data.TagDataDao
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType import org.tasks.filters.NavigationDrawerSubheader.SubheaderType
import org.tasks.location.LocationPickerActivity import org.tasks.location.LocationPickerActivity
import org.tasks.preferences.HelpAndFeedback import org.tasks.preferences.HelpAndFeedback
@ -172,7 +178,7 @@ class FilterProvider @Inject constructor(
private val navDrawerFooter: List<FilterListItem> private val navDrawerFooter: List<FilterListItem>
get() = listOf(NavigationDrawerSeparator()) get() = listOf(NavigationDrawerSeparator())
.plusIf(BuildConfig.FLAVOR == "generic" && !inventory.hasTasksAccount) { .plusIf(IS_GENERIC && !inventory.hasTasksAccount) {
NavigationDrawerAction( NavigationDrawerAction(
context.getString(R.string.TLA_menu_donate), context.getString(R.string.TLA_menu_donate),
R.drawable.ic_outline_attach_money_24px, R.drawable.ic_outline_attach_money_24px,
@ -184,21 +190,30 @@ class FilterProvider @Inject constructor(
R.drawable.ic_outline_attach_money_24px, R.drawable.ic_outline_attach_money_24px,
NavigationDrawerFragment.REQUEST_PURCHASE) NavigationDrawerFragment.REQUEST_PURCHASE)
} }
.plus(NavigationDrawerAction( .plus(
NavigationDrawerAction(
context.getString(R.string.manage_drawer), context.getString(R.string.manage_drawer),
R.drawable.ic_outline_edit_24px, R.drawable.ic_outline_edit_24px,
Intent(context, NavigationDrawerCustomization::class.java), 0,
0)) Intent(context, NavigationDrawerCustomization::class.java)
.plus(NavigationDrawerAction( )
)
.plus(
NavigationDrawerAction(
context.getString(R.string.TLA_menu_settings), context.getString(R.string.TLA_menu_settings),
R.drawable.ic_outline_settings_24px, R.drawable.ic_outline_settings_24px,
Intent(context, MainPreferences::class.java), NavigationDrawerFragment.REQUEST_SETTINGS,
NavigationDrawerFragment.REQUEST_SETTINGS)) Intent(context, MainPreferences::class.java)
.plus(NavigationDrawerAction( )
)
.plus(
NavigationDrawerAction(
context.getString(R.string.help_and_feedback), context.getString(R.string.help_and_feedback),
R.drawable.ic_outline_help_outline_24px, R.drawable.ic_outline_help_outline_24px,
Intent(context, HelpAndFeedback::class.java), 0,
0)) Intent(context, HelpAndFeedback::class.java)
)
)
private suspend fun googleTaskFilter(account: CaldavAccount, showCreate: Boolean): List<FilterListItem> = private suspend fun googleTaskFilter(account: CaldavAccount, showCreate: Boolean): List<FilterListItem> =
listOf( listOf(

@ -1,42 +0,0 @@
package org.tasks.filters;
import androidx.room.Embedded;
import com.todoroo.astrid.api.GtasksFilter;
import org.tasks.data.CaldavCalendar;
import java.util.Objects;
public class GoogleTaskFilters {
@Embedded public CaldavCalendar googleTaskList;
public int count;
GtasksFilter toGtasksFilter() {
GtasksFilter filter = new GtasksFilter(googleTaskList);
filter.count = count;
return filter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof GoogleTaskFilters)) {
return false;
}
GoogleTaskFilters that = (GoogleTaskFilters) o;
return count == that.count && Objects.equals(googleTaskList, that.googleTaskList);
}
@Override
public int hashCode() {
return Objects.hash(googleTaskList, count);
}
@Override
public String toString() {
return "GoogleTaskFilters{" + "googleTaskList=" + googleTaskList + ", count=" + count + '}';
}
}

@ -0,0 +1,16 @@
package org.tasks.filters
import androidx.room.Embedded
import com.todoroo.astrid.api.GtasksFilter
import org.tasks.data.CaldavCalendar
data class GoogleTaskFilters(
@JvmField @Embedded val googleTaskList: CaldavCalendar,
@JvmField val count: Int,
) {
fun toGtasksFilter(): GtasksFilter {
val filter = GtasksFilter(googleTaskList)
filter.count = count
return filter
}
}

@ -1,38 +0,0 @@
package org.tasks.filters;
import androidx.room.Embedded;
import java.util.Objects;
import org.tasks.data.Place;
public class LocationFilters {
@Embedded public Place place;
public int count;
PlaceFilter toLocationFilter() {
PlaceFilter filter = new PlaceFilter(place);
filter.count = count;
return filter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof LocationFilters)) {
return false;
}
LocationFilters that = (LocationFilters) o;
return count == that.count && Objects.equals(place, that.place);
}
@Override
public int hashCode() {
return Objects.hash(place, count);
}
@Override
public String toString() {
return "LocationFilters{" + "place=" + place + ", count=" + count + '}';
}
}

@ -0,0 +1,15 @@
package org.tasks.filters
import androidx.room.Embedded
import org.tasks.data.Place
data class LocationFilters(
@JvmField @Embedded var place: Place,
@JvmField var count: Int
) {
fun toLocationFilter(): PlaceFilter {
val filter = PlaceFilter(place)
filter.count = count
return filter
}
}

@ -1,71 +0,0 @@
package org.tasks.filters;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerAction extends FilterListItem {
/** Parcelable Creator Object */
public static final Parcelable.Creator<NavigationDrawerAction> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public NavigationDrawerAction createFromParcel(Parcel source) {
NavigationDrawerAction item = new NavigationDrawerAction();
item.readFromParcel(source);
return item;
}
/** {@inheritDoc} */
@Override
public NavigationDrawerAction[] newArray(int size) {
return new NavigationDrawerAction[size];
}
};
public Intent intent;
public int requestCode;
private NavigationDrawerAction() {}
public NavigationDrawerAction(String listingTitle, int icon, int requestCode) {
this(listingTitle, icon, null, requestCode);
}
public NavigationDrawerAction(String listingTitle, int icon, Intent intent, int requestCode) {
this.listingTitle = listingTitle;
this.icon = icon;
this.intent = intent;
this.requestCode = requestCode;
}
@Override
public Type getItemType() {
return Type.ACTION;
}
/** {@inheritDoc} */
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(intent, 0);
dest.writeInt(requestCode);
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
intent = source.readParcelable(Intent.class.getClassLoader());
requestCode = source.readInt();
}
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerAction
&& requestCode == ((NavigationDrawerAction) other).requestCode;
}
}

@ -0,0 +1,21 @@
package org.tasks.filters
import android.content.Intent
import com.todoroo.astrid.api.FilterListItem
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
@Parcelize
data class NavigationDrawerAction(
val listingTitle: String,
val icon: Int,
val requestCode: Int,
val intent: Intent? = null,
) : FilterListItem {
@IgnoredOnParcel
override val itemType = FilterListItem.Type.ACTION
override fun areItemsTheSame(other: FilterListItem) = this == other
override fun areContentsTheSame(other: FilterListItem) = true
}

@ -1,42 +0,0 @@
package org.tasks.filters;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerSeparator extends FilterListItem {
public static final Parcelable.Creator<NavigationDrawerSeparator> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public NavigationDrawerSeparator createFromParcel(Parcel source) {
NavigationDrawerSeparator navigationDrawerSeparator = new NavigationDrawerSeparator();
navigationDrawerSeparator.readFromParcel(source);
return navigationDrawerSeparator;
}
/** {@inheritDoc} */
@Override
public NavigationDrawerSeparator[] newArray(int size) {
return new NavigationDrawerSeparator[size];
}
};
@Override
public Type getItemType() {
return Type.SEPARATOR;
}
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerSeparator;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return true;
}
}

@ -0,0 +1,19 @@
package org.tasks.filters
import com.todoroo.astrid.api.FilterListItem
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
@Parcelize
class NavigationDrawerSeparator : FilterListItem {
@IgnoredOnParcel
override val itemType = FilterListItem.Type.SEPARATOR
override fun areItemsTheSame(other: FilterListItem): Boolean {
return other is NavigationDrawerSeparator
}
override fun areContentsTheSame(other: FilterListItem): Boolean {
return true
}
}

@ -1,157 +0,0 @@
package org.tasks.filters;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.os.ParcelCompat;
import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerSubheader extends FilterListItem {
public static final Parcelable.Creator<NavigationDrawerSubheader> CREATOR =
new Parcelable.Creator<>() {
/** {@inheritDoc} */
@Override
public NavigationDrawerSubheader createFromParcel(Parcel source) {
NavigationDrawerSubheader navigationDrawerSubheader = new NavigationDrawerSubheader();
navigationDrawerSubheader.readFromParcel(source);
return navigationDrawerSubheader;
}
/** {@inheritDoc} */
@Override
public NavigationDrawerSubheader[] newArray(int size) {
return new NavigationDrawerSubheader[size];
}
};
public boolean error;
private boolean collapsed;
private SubheaderType subheaderType;
private long id;
@Nullable
private Intent addIntent;
private int addIntentRc;
private NavigationDrawerSubheader() {}
public NavigationDrawerSubheader(
String listingTitle,
boolean error,
boolean collapsed,
SubheaderType subheaderType,
long id,
int addIntentRc,
@Nullable Intent addIntent
) {
this.error = error;
this.collapsed = collapsed;
this.subheaderType = subheaderType;
this.id = id;
this.addIntent = addIntent;
this.addIntentRc = addIntentRc;
this.listingTitle = listingTitle;
}
public long getId() {
return id;
}
public boolean isCollapsed() {
return collapsed;
}
@Nullable
public Intent getAddIntent() {
return addIntent;
}
public int getAddIntentRc() {
return addIntentRc;
}
public SubheaderType getSubheaderType() {
return subheaderType;
}
@Override
protected void readFromParcel(Parcel source) {
super.readFromParcel(source);
error = ParcelCompat.readBoolean(source);
collapsed = ParcelCompat.readBoolean(source);
subheaderType = (SubheaderType) source.readSerializable();
id = source.readLong();
addIntent = source.readParcelable(getClass().getClassLoader());
addIntentRc = source.readInt();
}
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerSubheader
&& subheaderType == ((NavigationDrawerSubheader) other).getSubheaderType()
&& id == other.getId();
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return this.equals(other);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof NavigationDrawerSubheader)) {
return false;
}
NavigationDrawerSubheader that = (NavigationDrawerSubheader) o;
if (error != that.error) {
return false;
}
if (collapsed != that.collapsed) {
return false;
}
if (id != that.id) {
return false;
}
return subheaderType == that.subheaderType;
}
@Override
public int hashCode() {
int result = (error ? 1 : 0);
result = 31 * result + (collapsed ? 1 : 0);
result = 31 * result + (subheaderType != null ? subheaderType.hashCode() : 0);
result = 31 * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
ParcelCompat.writeBoolean(dest, error);
ParcelCompat.writeBoolean(dest, collapsed);
dest.writeSerializable(subheaderType);
dest.writeLong(id);
dest.writeParcelable(addIntent, 0);
dest.writeInt(addIntentRc);
}
@Override
public Type getItemType() {
return Type.SUBHEADER;
}
public enum SubheaderType {
PREFERENCE,
GOOGLE_TASKS,
CALDAV,
TASKS,
@Deprecated ETESYNC
}
}

@ -0,0 +1,37 @@
package org.tasks.filters
import android.content.Intent
import com.todoroo.astrid.api.FilterListItem
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
@Parcelize
data class NavigationDrawerSubheader(
val listingTitle: String?,
val error: Boolean,
val isCollapsed: Boolean,
val subheaderType: SubheaderType,
val id: Long,
val addIntentRc: Int,
val addIntent: Intent?,
) : FilterListItem {
override fun areItemsTheSame(other: FilterListItem): Boolean {
return other is NavigationDrawerSubheader && subheaderType == other.subheaderType && id == other.id
}
override fun areContentsTheSame(other: FilterListItem): Boolean {
return this == other
}
@IgnoredOnParcel
override val itemType = FilterListItem.Type.SUBHEADER
enum class SubheaderType {
PREFERENCE,
GOOGLE_TASKS,
CALDAV,
TASKS,
@Deprecated("")
ETESYNC
}
}

@ -1,39 +0,0 @@
package org.tasks.filters;
import androidx.room.Embedded;
import com.todoroo.astrid.api.TagFilter;
import java.util.Objects;
import org.tasks.data.TagData;
public class TagFilters {
@Embedded public TagData tagData;
public int count;
TagFilter toTagFilter() {
TagFilter filter = new TagFilter(tagData);
filter.count = count;
return filter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof TagFilters)) {
return false;
}
TagFilters that = (TagFilters) o;
return count == that.count && Objects.equals(tagData, that.tagData);
}
@Override
public int hashCode() {
return Objects.hash(tagData, count);
}
@Override
public String toString() {
return "TagFilters{" + "tagData=" + tagData + ", count=" + count + '}';
}
}

@ -0,0 +1,16 @@
package org.tasks.filters
import androidx.room.Embedded
import com.todoroo.astrid.api.TagFilter
import org.tasks.data.TagData
data class TagFilters(
@JvmField @Embedded var tagData: TagData,
@JvmField var count: Int,
) {
fun toTagFilter(): TagFilter {
val filter = TagFilter(tagData)
filter.count = count
return filter
}
}

@ -94,7 +94,9 @@ class NavigationDrawerFragment : BottomSheetDialogFragment() {
REQUEST_PURCHASE -> REQUEST_PURCHASE ->
startActivity(Intent(context, PurchaseActivity::class.java)) startActivity(Intent(context, PurchaseActivity::class.java))
REQUEST_DONATE -> context?.openUri(R.string.url_donate) REQUEST_DONATE -> context?.openUri(R.string.url_donate)
else -> activity?.startActivityForResult(item.intent, item.requestCode) else -> item.intent?.let {
activity?.startActivityForResult(it, item.requestCode)
}
} }
} }
dismiss() dismiss()

Loading…
Cancel
Save