diff --git a/app/src/main/java/com/todoroo/astrid/api/FilterListItem.java b/app/src/main/java/com/todoroo/astrid/api/FilterListItem.java index ad158f115..86d74c387 100644 --- a/app/src/main/java/com/todoroo/astrid/api/FilterListItem.java +++ b/app/src/main/java/com/todoroo/astrid/api/FilterListItem.java @@ -20,13 +20,15 @@ import org.tasks.R; */ 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 int icon = -1; public int tint = 0; public int count = -1; - public int order = 0; + public int order = NO_ORDER; public abstract Type getItemType(); diff --git a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java index 6b3891c65..693e73a1a 100644 --- a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java +++ b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java @@ -13,8 +13,10 @@ import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; +import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.timers.TimerPlugin; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -35,12 +37,15 @@ import org.tasks.themes.CustomIcons; public final class BuiltInFilterExposer { private final Preferences preferences; + private final TaskDao taskDao; private final Context context; @Inject - public BuiltInFilterExposer(@ForApplication Context context, Preferences preferences) { + public BuiltInFilterExposer( + @ForApplication Context context, Preferences preferences, TaskDao taskDao) { this.context = context; this.preferences = preferences; + this.taskDao = taskDao; } /** Build inbox filter */ @@ -100,6 +105,9 @@ public final class BuiltInFilterExposer { recentlyModifiedFilter.icon = CustomIcons.HISTORY; filters.add(recentlyModifiedFilter); } + if (taskDao.activeTimers() > 0) { + filters.add(TimerPlugin.createFilter(context)); + } return filters; } } diff --git a/app/src/main/java/org/tasks/data/CaldavCalendar.kt b/app/src/main/java/org/tasks/data/CaldavCalendar.kt index 5375711f7..5623cbcb4 100644 --- a/app/src/main/java/org/tasks/data/CaldavCalendar.kt +++ b/app/src/main/java/org/tasks/data/CaldavCalendar.kt @@ -7,6 +7,7 @@ import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey import com.todoroo.andlib.data.Table +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.data.Task import org.tasks.themes.CustomIcons.LIST @@ -38,7 +39,7 @@ class CaldavCalendar : Parcelable { private var icon: Int? = -1 @ColumnInfo(name = "cdl_order") - var order = 0 + var order = NO_ORDER constructor() diff --git a/app/src/main/java/org/tasks/data/Filter.kt b/app/src/main/java/org/tasks/data/Filter.kt index 784031bfc..352b4cd69 100644 --- a/app/src/main/java/org/tasks/data/Filter.kt +++ b/app/src/main/java/org/tasks/data/Filter.kt @@ -4,6 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import com.todoroo.andlib.utility.AndroidUtilities +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import org.tasks.Strings import org.tasks.themes.CustomIcons.FILTER @@ -33,7 +34,7 @@ class Filter { private var icon: Int? = -1 @ColumnInfo(name = "f_order") - var order = 0 + var order = NO_ORDER fun getSql(): String { // TODO: replace dirty hack for missing column diff --git a/app/src/main/java/org/tasks/data/GoogleTaskList.kt b/app/src/main/java/org/tasks/data/GoogleTaskList.kt index f3e3e05b1..0e01d7d67 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskList.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskList.kt @@ -7,6 +7,7 @@ import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey import com.todoroo.andlib.data.Table +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import org.tasks.themes.CustomIcons.LIST @Entity(tableName = "google_task_lists") @@ -26,7 +27,7 @@ class GoogleTaskList : Parcelable { var title: String? = null @ColumnInfo(name = "gtl_remote_order") - var order = 0 + var order = NO_ORDER @ColumnInfo(name = "gtl_last_sync") var lastSync: Long = 0 diff --git a/app/src/main/java/org/tasks/data/Place.kt b/app/src/main/java/org/tasks/data/Place.kt index a0d7fff7d..65f941426 100644 --- a/app/src/main/java/org/tasks/data/Place.kt +++ b/app/src/main/java/org/tasks/data/Place.kt @@ -11,6 +11,7 @@ import androidx.room.* import com.mapbox.api.geocoding.v5.GeocodingCriteria import com.mapbox.api.geocoding.v5.models.CarmenFeature import com.todoroo.andlib.data.Table +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.helper.UUIDHelper import net.fortuna.ical4j.model.property.Geo import org.tasks.R @@ -56,7 +57,7 @@ class Place : Serializable, Parcelable { private var icon = -1 @ColumnInfo(name = "place_order") - var order = 0 + var order = NO_ORDER constructor() diff --git a/app/src/main/java/org/tasks/data/TagData.kt b/app/src/main/java/org/tasks/data/TagData.kt index fc1efa80d..24fcb270b 100644 --- a/app/src/main/java/org/tasks/data/TagData.kt +++ b/app/src/main/java/org/tasks/data/TagData.kt @@ -7,6 +7,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.data.Task import org.tasks.backup.XmlReader import org.tasks.themes.CustomIcons.LABEL @@ -34,7 +35,7 @@ class TagData : Parcelable { private var icon: Int? = -1 @ColumnInfo(name = "td_order") - var order = 0 + var order = NO_ORDER @Ignore constructor(name: String?) { diff --git a/app/src/main/java/org/tasks/db/Migrations.kt b/app/src/main/java/org/tasks/db/Migrations.kt index 9c4a4acd7..676d1baf2 100644 --- a/app/src/main/java/org/tasks/db/Migrations.kt +++ b/app/src/main/java/org/tasks/db/Migrations.kt @@ -3,6 +3,7 @@ package org.tasks.db import android.database.sqlite.SQLiteException import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase +import com.todoroo.astrid.api.FilterListItem.NO_ORDER import timber.log.Timber object Migrations { @@ -349,10 +350,10 @@ object Migrations { private val MIGRATION_75_76: Migration = object : Migration(75, 76) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("ALTER TABLE `tagdata` ADD COLUMN `td_order` INTEGER NOT NULL DEFAULT 0") - database.execSQL("ALTER TABLE `caldav_lists` ADD COLUMN `cdl_order` INTEGER NOT NULL DEFAULT 0") - database.execSQL("ALTER TABLE `filters` ADD COLUMN `f_order` INTEGER NOT NULL DEFAULT 0") - database.execSQL("ALTER TABLE `places` ADD COLUMN `place_order` INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE `tagdata` ADD COLUMN `td_order` INTEGER NOT NULL DEFAULT $NO_ORDER") + database.execSQL("ALTER TABLE `caldav_lists` ADD COLUMN `cdl_order` INTEGER NOT NULL DEFAULT $NO_ORDER") + database.execSQL("ALTER TABLE `filters` ADD COLUMN `f_order` INTEGER NOT NULL DEFAULT $NO_ORDER") + database.execSQL("ALTER TABLE `places` ADD COLUMN `place_order` INTEGER NOT NULL DEFAULT $NO_ORDER") } } diff --git a/app/src/main/java/org/tasks/filters/FilterProvider.kt b/app/src/main/java/org/tasks/filters/FilterProvider.kt index 07bb59280..9af9b12fc 100644 --- a/app/src/main/java/org/tasks/filters/FilterProvider.kt +++ b/app/src/main/java/org/tasks/filters/FilterProvider.kt @@ -2,12 +2,11 @@ package org.tasks.filters import android.content.Context import android.content.Intent -import com.todoroo.andlib.utility.AndroidUtilities +import com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread import com.todoroo.astrid.api.CustomFilter +import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.FilterListItem import com.todoroo.astrid.core.BuiltInFilterExposer -import com.todoroo.astrid.dao.TaskDao -import com.todoroo.astrid.timers.TimerPlugin import org.tasks.BuildConfig import org.tasks.R import org.tasks.activities.GoogleTaskListSettingsActivity @@ -29,7 +28,6 @@ class FilterProvider @Inject constructor( @param:ForApplication private val context: Context, private val inventory: Inventory, private val builtInFilterExposer: BuiltInFilterExposer, - private val taskDao: TaskDao, private val filterDao: FilterDao, private val tagDataDao: TagDataDao, private val googleTaskListDao: GoogleTaskListDao, @@ -38,27 +36,15 @@ class FilterProvider @Inject constructor( private val locationDao: LocationDao) { val listPickerItems: List - get() { - AndroidUtilities.assertNotMainThread() - return googleTaskFilters(false).plus(caldavFilters(false)) - } + get() = googleTaskFilters(false).plus(caldavFilters(false)) val navDrawerItems: List - get() { - AndroidUtilities.assertNotMainThread() - return arrayListOf(builtInFilterExposer.myTasksFilter) - .plus(getAllFilters(true)) - .plus(navDrawerFooter) - } + get() = getAllFilters().plus(navDrawerFooter) val filterPickerItems: List - get() { - AndroidUtilities.assertNotMainThread() - return arrayListOf(builtInFilterExposer.myTasksFilter) - .plus(getAllFilters(false)) - } + get() = getAllFilters(showCreate = false) - private fun addFilters(showCreate: Boolean): List = + private fun addFilters(showCreate: Boolean, showBuiltIn: Boolean): List = if (!preferences.getBoolean(R.string.p_filters_enabled, true)) { emptyList() } else { @@ -71,9 +57,10 @@ class FilterProvider @Inject constructor( SubheaderType.PREFERENCE, R.string.p_collapse_filters.toLong())) .apply { if (collapsed) return this } - .plus(builtInFilterExposer.filters) - .plusIf(taskDao.activeTimers() > 0) { TimerPlugin.createFilter(context) } - .plus(filterDao.getFilters().map(::CustomFilter).sortedWith(AlphanumComparator.FILTER)) + .plusAllIf(showBuiltIn) { + builtInFilterExposer.filters + } + .plus(filterDao.getFilters().map(::CustomFilter).sort()) .plusIf(showCreate) { NavigationDrawerAction( context.getString(R.string.add_filter), @@ -100,7 +87,7 @@ class FilterProvider @Inject constructor( it.count > 0 } .map(TagFilters::toTagFilter) - .sortedWith(AlphanumComparator.FILTER)) + .sort()) .plusIf(showCreate) { NavigationDrawerAction( context.getString(R.string.new_tag), @@ -128,7 +115,7 @@ class FilterProvider @Inject constructor( it.count > 0 } .map(LocationFilters::toLocationFilter) - .sortedWith(AlphanumComparator.FILTER)) + .sort()) .plusIf(showCreate) { NavigationDrawerAction( context.getString(R.string.add_place), @@ -138,12 +125,19 @@ class FilterProvider @Inject constructor( } } - private fun getAllFilters(showCreate: Boolean): List = - addFilters(showCreate) + private fun getAllFilters(showCreate: Boolean = true, showBuiltIn: Boolean = true): List = + if (showBuiltIn) { + arrayListOf(builtInFilterExposer.myTasksFilter) + } else { + ArrayList() + } + .asSequence() + .plus(addFilters(showCreate, showBuiltIn)) .plus(addTags(showCreate)) .plus(addPlaces(showCreate)) .plus(googleTaskFilters(showCreate)) .plus(caldavFilters(showCreate)) + .toList() private val navDrawerFooter: List get() = listOf(NavigationDrawerSeparator()) @@ -170,8 +164,11 @@ class FilterProvider @Inject constructor( Intent(context, HelpAndFeedback::class.java), 0)) - private fun googleTaskFilters(showCreate: Boolean = true): List = - googleTaskListDao.getAccounts().flatMap { googleTaskFilter(it, showCreate) } + private fun googleTaskFilters(showCreate: Boolean = true): List { + assertNotMainThread() + return googleTaskListDao.getAccounts().flatMap { googleTaskFilter(it, showCreate) } + } + private fun googleTaskFilter(account: GoogleTaskAccount, showCreate: Boolean): List = listOf( @@ -185,7 +182,7 @@ class FilterProvider @Inject constructor( .plus(googleTaskListDao .getGoogleTaskFilters(account.account!!) .map(GoogleTaskFilters::toGtasksFilter) - .sortedWith(AlphanumComparator.FILTER)) + .sort()) .plusIf(showCreate) { NavigationDrawerAction( context.getString(R.string.new_list), @@ -217,7 +214,7 @@ class FilterProvider @Inject constructor( .plus(caldavDao .getCaldavFilters(account.uuid!!) .map(CaldavFilters::toCaldavFilter) - .sortedWith(AlphanumComparator.FILTER)) + .sort()) .plusIf(showCreate) { NavigationDrawerAction( context.getString(R.string.new_list), @@ -228,7 +225,20 @@ class FilterProvider @Inject constructor( } companion object { - private fun Collection.plusIf(predicate: Boolean, item: () -> T): List = + private val COMPARATOR = Comparator { f1, f2 -> + when { + f1.order < f2.order -> -1 + f1.order > f2.order -> 1 + else -> AlphanumComparator.FILTER.compare(f1, f2) + } + } + + private fun List.sort(): List = sortedWith(COMPARATOR) + + private fun Collection.plusAllIf(predicate: Boolean, item: () -> Iterable): List = + plus(if (predicate) item.invoke() else emptyList()) + + private fun Iterable.plusIf(predicate: Boolean, item: () -> T): List = if (predicate) plus(item.invoke()) else this.toList() private fun Iterable.filterIf(predicate: Boolean, predicate2: (T) -> Boolean): List =