diff --git a/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt b/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt index 2f48c7e18..c363e7612 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt @@ -2,9 +2,7 @@ package com.todoroo.astrid.adapter import com.natpryce.makeiteasy.MakeItEasy.with import com.natpryce.makeiteasy.PropertyValue -import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.dao.TaskDao -import org.tasks.data.entity.Task import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules import kotlinx.coroutines.runBlocking @@ -13,7 +11,9 @@ import org.junit.Before import org.junit.Ignore import org.junit.Test import org.tasks.data.TaskListQuery.getQuery +import org.tasks.data.entity.Task import org.tasks.date.DateTimeUtils.newDateTime +import org.tasks.filters.TodayFilter import org.tasks.injection.InjectingTestCase import org.tasks.injection.ProductionModule import org.tasks.makers.TaskMaker.DUE_DATE @@ -76,7 +76,7 @@ class RecursiveLoopTest : InjectingTestCase() { } private suspend fun getTasks() = taskDao.fetchTasks { - getQuery(preferences, BuiltInFilterExposer.getTodayFilter(context.resources)) + getQuery(preferences, TodayFilter.create()) } private suspend fun addTask(vararg properties: PropertyValue): Long { diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt index 24a7038bb..95063390f 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt @@ -62,7 +62,6 @@ import com.todoroo.astrid.adapter.TaskAdapterProvider import com.todoroo.astrid.api.AstridApiConstants.EXTRAS_OLD_DUE_DATE import com.todoroo.astrid.api.AstridApiConstants.EXTRAS_TASK_ID import com.todoroo.astrid.api.CustomFilter -import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.repeats.RepeatTaskHelper import com.todoroo.astrid.service.TaskCompleter @@ -123,6 +122,7 @@ import org.tasks.filters.CaldavFilter import org.tasks.filters.Filter import org.tasks.filters.FilterImpl import org.tasks.filters.GtasksFilter +import org.tasks.filters.MyTasksFilter import org.tasks.filters.PlaceFilter import org.tasks.filters.TagFilter import org.tasks.markdown.MarkdownProvider @@ -220,8 +220,9 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL if (result.resultCode != RESULT_OK) return@registerForActivityResult val data = result.data ?: return@registerForActivityResult when (data.action) { - ACTION_DELETED -> - mainViewModel.setFilter(BuiltInFilterExposer.getMyTasksFilter(resources)) + ACTION_DELETED -> lifecycleScope.launch { + mainViewModel.setFilter(MyTasksFilter.create()) + } ACTION_RELOAD -> IntentCompat.getParcelableExtra(data, MainActivity.OPEN_FILTER, Filter::class.java)?.let { mainViewModel.setFilter(it) diff --git a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapterProvider.kt b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapterProvider.kt index 436a50712..c9ba2b335 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapterProvider.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/TaskAdapterProvider.kt @@ -1,10 +1,6 @@ package com.todoroo.astrid.adapter import android.content.Context -import org.tasks.filters.CaldavFilter -import org.tasks.filters.GtasksFilter -import org.tasks.filters.TagFilter -import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.service.TaskMover import com.todoroo.astrid.subtasks.SubtasksFilterUpdater @@ -19,7 +15,12 @@ import org.tasks.data.dao.TaskListMetadataDao import org.tasks.data.entity.Task.Companion.isUuidEmpty import org.tasks.data.entity.TaskListMetadata import org.tasks.filters.AstridOrderingFilter +import org.tasks.filters.CaldavFilter import org.tasks.filters.Filter +import org.tasks.filters.GtasksFilter +import org.tasks.filters.MyTasksFilter +import org.tasks.filters.TagFilter +import org.tasks.filters.TodayFilter import org.tasks.preferences.Preferences import javax.inject.Inject @@ -71,10 +72,10 @@ class TaskAdapterProvider @Inject constructor( private fun createManualFilterTaskAdapter(filter: AstridOrderingFilter): TaskAdapter? = runBlocking { var filterId: String? = null var prefId: String? = null - if (BuiltInFilterExposer.isInbox(context, filter)) { + if (filter is MyTasksFilter) { filterId = TaskListMetadata.FILTER_ID_ALL prefId = SubtasksFilterUpdater.ACTIVE_TASKS_ORDER - } else if (BuiltInFilterExposer.isTodayFilter(context, filter)) { + } else if (filter is TodayFilter) { filterId = TaskListMetadata.FILTER_ID_TODAY prefId = SubtasksFilterUpdater.TODAY_TASKS_ORDER } diff --git a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt index eafdb23ac..4a37b78f5 100644 --- a/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt +++ b/app/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.kt @@ -5,164 +5,38 @@ */ package com.todoroo.astrid.core -import android.content.Context -import android.content.res.Resources -import dagger.hilt.android.qualifiers.ApplicationContext import org.tasks.R import org.tasks.data.dao.TaskDao -import org.tasks.data.entity.CaldavAccount -import org.tasks.data.entity.CaldavCalendar -import org.tasks.data.entity.CaldavTask -import org.tasks.data.entity.Task -import org.tasks.data.sql.Criterion.Companion.and -import org.tasks.data.sql.Criterion.Companion.or -import org.tasks.data.sql.Join -import org.tasks.data.sql.QueryTemplate import org.tasks.filters.Filter -import org.tasks.filters.FilterImpl -import org.tasks.filters.MyTasksFilter import org.tasks.filters.NotificationsFilter import org.tasks.filters.RecentlyModifiedFilter import org.tasks.filters.SnoozedFilter import org.tasks.filters.TimerFilter import org.tasks.filters.TodayFilter import org.tasks.preferences.Preferences -import org.tasks.themes.TasksIcons import javax.inject.Inject class BuiltInFilterExposer @Inject constructor( - @param:ApplicationContext private val context: Context, private val preferences: Preferences, private val taskDao: TaskDao ) { - - val myTasksFilter: Filter - get() = getMyTasksFilter(context.resources) - suspend fun filters(): List { - val r = context.resources val filters: MutableList = ArrayList() if (preferences.getBoolean(R.string.p_show_today_filter, true)) { - filters.add(getTodayFilter(r)) + filters.add(TodayFilter.create()) } if (preferences.getBoolean(R.string.p_show_recently_modified_filter, true)) { - filters.add(getRecentlyModifiedFilter(r)) + filters.add(RecentlyModifiedFilter.create()) } if (taskDao.snoozedReminders() > 0) { - filters.add(getSnoozedFilter(r)) + filters.add(SnoozedFilter.create()) } if (taskDao.activeTimers() > 0) { - filters.add(getTimerFilter(r)) + filters.add(TimerFilter.create()) } if (taskDao.hasNotifications() > 0) { - filters.add(getNotificationsFilter(context)) + filters.add(NotificationsFilter.create()) } return filters } - - companion object { - fun getMyTasksFilter(r: Resources) = MyTasksFilter(r.getString(R.string.BFE_Active)) - - fun getTodayFilter(r: Resources): Filter { - return TodayFilter(r.getString(R.string.today)) - } - - fun getNoListFilter() = - FilterImpl( - title = "No list", - sql = QueryTemplate() - .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) - .where(CaldavTask.ID.eq(null)) - .toString(), - icon = TasksIcons.CLOUD_OFF, - ) - - fun getDeleted() = - FilterImpl( - title = "Deleted", - sql = QueryTemplate().where(Task.DELETION_DATE.gt(0)).toString(), - icon = TasksIcons.DELETE, - ) - - fun getMissingListFilter() = - FilterImpl( - title = "Missing list", - sql = QueryTemplate() - .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) - .join( - Join.left( - CaldavCalendar.TABLE, - CaldavCalendar.UUID.eq(CaldavTask.CALENDAR) - ) - ) - .where(and(CaldavTask.ID.gt(0), CaldavCalendar.UUID.eq(null))) - .toString(), - icon = TasksIcons.CLOUD_OFF, - ) - - fun getMissingAccountFilter() = - FilterImpl( - title = "Missing account", - sql = QueryTemplate() - .join( - Join.left(CaldavTask.TABLE, and(CaldavTask.TASK.eq(Task.ID))) - ).join( - Join.left(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR)) - ).join( - Join.left( - CaldavAccount.TABLE, CaldavAccount.UUID.eq(CaldavCalendar.ACCOUNT) - ) - ) - .where(and(CaldavTask.ID.gt(0), CaldavAccount.UUID.eq(null))) - .toString(), - icon = TasksIcons.CLOUD_OFF, - ) - - fun getNoTitleFilter() = - FilterImpl( - title = "No title", - sql = QueryTemplate().where(or(Task.TITLE.eq(null), Task.TITLE.eq(""))).toString(), - icon = TasksIcons.CLEAR, - ) - - fun getNoCreateDateFilter() = - FilterImpl( - title = "No create time", - sql = QueryTemplate().where(Task.CREATION_DATE.eq(0)).toString(), - icon = TasksIcons.ADD, - ) - - fun getNoModificationDateFilter() = - FilterImpl( - title = "No modify time", - sql = QueryTemplate().where(Task.MODIFICATION_DATE.eq(0)).toString(), - icon = TasksIcons.EDIT, - ) - - fun getRecentlyModifiedFilter(r: Resources) = - RecentlyModifiedFilter(r.getString(R.string.BFE_Recent)) - - fun getSnoozedFilter(r: Resources) = SnoozedFilter(r.getString(R.string.filter_snoozed)) - - fun getTimerFilter(r: Resources) = TimerFilter(r.getString(R.string.TFE_workingOn)) - - fun getNotificationsFilter(context: Context) = NotificationsFilter(context.getString(R.string.notifications)) - - @JvmStatic - fun isInbox(context: Context, filter: Filter?) = - filter == getMyTasksFilter(context.resources) - - @JvmStatic - fun isTodayFilter(context: Context, filter: Filter?) = - filter == getTodayFilter(context.resources) - - fun isRecentlyModifiedFilter(context: Context, filter: Filter?) = - filter == getRecentlyModifiedFilter(context.resources) - - fun isSnoozedFilter(context: Context, filter: Filter?) = - filter == getSnoozedFilter(context.resources) - - fun isNotificationsFilter(context: Context, filter: Filter?) = - filter == getNotificationsFilter(context) - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/todoroo/astrid/subtasks/SubtasksHelper.kt b/app/src/main/java/com/todoroo/astrid/subtasks/SubtasksHelper.kt index 47f027458..525ee5d10 100644 --- a/app/src/main/java/com/todoroo/astrid/subtasks/SubtasksHelper.kt +++ b/app/src/main/java/com/todoroo/astrid/subtasks/SubtasksHelper.kt @@ -1,8 +1,6 @@ package com.todoroo.astrid.subtasks import android.content.Context -import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isInbox -import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isTodayFilter import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildOrderString import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildTreeModel @@ -17,6 +15,8 @@ import org.tasks.data.entity.TaskListMetadata import org.tasks.db.QueryUtils.showHiddenAndCompleted import org.tasks.filters.AstridOrderingFilter import org.tasks.filters.Filter +import org.tasks.filters.MyTasksFilter +import org.tasks.filters.TodayFilter import org.tasks.preferences.QueryPreferences import timber.log.Timber import javax.inject.Inject @@ -38,9 +38,9 @@ class SubtasksHelper @Inject constructor( val tlm = when { tagData != null -> taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!) - isInbox(context, filter) -> + filter is MyTasksFilter -> taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_ALL) - isTodayFilter(context, filter) -> + filter is TodayFilter -> taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_TODAY) else -> null } diff --git a/app/src/main/java/org/tasks/filters/FilterProvider.kt b/app/src/main/java/org/tasks/filters/FilterProvider.kt index 102d68932..d379eb3d5 100644 --- a/app/src/main/java/org/tasks/filters/FilterProvider.kt +++ b/app/src/main/java/org/tasks/filters/FilterProvider.kt @@ -73,13 +73,13 @@ class FilterProvider @Inject constructor( ) .apply { if (collapsed) return this } .plus(listOf( - BuiltInFilterExposer.getNoListFilter(), - BuiltInFilterExposer.getNoTitleFilter(), - BuiltInFilterExposer.getMissingListFilter(), - BuiltInFilterExposer.getMissingAccountFilter(), - BuiltInFilterExposer.getNoCreateDateFilter(), - BuiltInFilterExposer.getNoModificationDateFilter(), - BuiltInFilterExposer.getDeleted() + DebugFilters.getNoListFilter(), + DebugFilters.getNoTitleFilter(), + DebugFilters.getMissingListFilter(), + DebugFilters.getMissingAccountFilter(), + DebugFilters.getNoCreateDateFilter(), + DebugFilters.getNoModificationDateFilter(), + DebugFilters.getDeleted() )) } else { @@ -175,7 +175,7 @@ class FilterProvider @Inject constructor( forceExpand: Boolean = false, ): List = if (showBuiltIn) { - arrayListOf(builtInFilterExposer.myTasksFilter) + arrayListOf(MyTasksFilter.create()) } else { ArrayList() } diff --git a/app/src/main/java/org/tasks/notifications/NotificationManager.kt b/app/src/main/java/org/tasks/notifications/NotificationManager.kt index 61cf60752..6f0eec08f 100644 --- a/app/src/main/java/org/tasks/notifications/NotificationManager.kt +++ b/app/src/main/java/org/tasks/notifications/NotificationManager.kt @@ -8,7 +8,6 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat.InterruptionFilter import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities.preUpsideDownCake -import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.utility.Constants import dagger.hilt.android.qualifiers.ApplicationContext import org.tasks.LocalBroadcastManager @@ -19,6 +18,8 @@ import org.tasks.data.dao.TaskDao import org.tasks.data.displayName import org.tasks.data.entity.Alarm import org.tasks.data.entity.Notification +import org.tasks.filters.NotificationsFilter +import org.tasks.filters.TimerFilter import org.tasks.intents.TaskIntents import org.tasks.markdown.MarkdownProvider import org.tasks.preferences.PermissionChecker @@ -267,7 +268,7 @@ class NotificationManager @Inject constructor( PendingIntent.getActivity( context, 0, - TaskIntents.getTaskListIntent(context, BuiltInFilterExposer.getNotificationsFilter(context)), + TaskIntents.getTaskListIntent(context, NotificationsFilter.create()), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) ) @@ -401,7 +402,7 @@ class NotificationManager @Inject constructor( if (count == 0) { cancel(Constants.NOTIFICATION_TIMER.toLong()) } else { - val filter = BuiltInFilterExposer.getTimerFilter(context.resources) + val filter = TimerFilter.create() val notifyIntent = TaskIntents.getTaskListIntent(context, filter) val pendingIntent = PendingIntent.getActivity( context, @@ -412,21 +413,24 @@ class NotificationManager @Inject constructor( val r = context.resources val appName = r.getString(R.string.app_name) val text = r.getString( - R.string.TPl_notification, r.getQuantityString(R.plurals.Ntasks, count, count)) - val builder = NotificationCompat.Builder(context, NotificationManager.NOTIFICATION_CHANNEL_TIMERS) - .setContentIntent(pendingIntent) - .setContentTitle(appName) - .setContentText(text) - .setWhen(currentTimeMillis()) - .setSmallIcon(R.drawable.ic_timer_white_24dp) - .setAutoCancel(false) - .setOngoing(true) + R.string.TPl_notification, r.getQuantityString(R.plurals.Ntasks, count, count) + ) + val builder = + NotificationCompat.Builder(context, NotificationManager.NOTIFICATION_CHANNEL_TIMERS) + .setContentIntent(pendingIntent) + .setContentTitle(appName) + .setContentText(text) + .setWhen(currentTimeMillis()) + .setSmallIcon(R.drawable.ic_timer_white_24dp) + .setAutoCancel(false) + .setOngoing(true) notify( Constants.NOTIFICATION_TIMER.toLong(), builder, alert = false, nonstop = false, - fiveTimes = false) + fiveTimes = false + ) } } diff --git a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt index 8e510c911..de6e2149e 100644 --- a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt +++ b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.kt @@ -1,12 +1,7 @@ package org.tasks.preferences import android.content.Context -import org.tasks.filters.CaldavFilter import com.todoroo.astrid.api.CustomFilter -import org.tasks.filters.GtasksFilter -import org.tasks.filters.TagFilter -import com.todoroo.astrid.core.BuiltInFilterExposer -import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.getMyTasksFilter import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.runBlocking import org.tasks.R @@ -22,8 +17,16 @@ import org.tasks.data.entity.CaldavCalendar.Companion.ACCESS_READ_ONLY import org.tasks.data.entity.CaldavTask import org.tasks.data.entity.Task import org.tasks.data.getLocalList +import org.tasks.filters.CaldavFilter import org.tasks.filters.Filter +import org.tasks.filters.GtasksFilter +import org.tasks.filters.MyTasksFilter +import org.tasks.filters.NotificationsFilter import org.tasks.filters.PlaceFilter +import org.tasks.filters.RecentlyModifiedFilter +import org.tasks.filters.SnoozedFilter +import org.tasks.filters.TagFilter +import org.tasks.filters.TodayFilter import timber.log.Timber import javax.inject.Inject @@ -85,7 +88,7 @@ class DefaultFilterProvider @Inject constructor( getFilterFromPreference(preferences.getStringValue(resId)) suspend fun getFilterFromPreference(prefString: String?): Filter = - getFilterFromPreference(prefString, getMyTasksFilter(context.resources))!! + getFilterFromPreference(prefString, MyTasksFilter.create())!! private suspend fun getAnyList(): Filter { val filter = caldavDao.getGoogleTaskLists().getOrNull(0)?.let(::GtasksFilter) @@ -142,12 +145,12 @@ class DefaultFilterProvider @Inject constructor( else -> TYPE_FILTER } - private fun getBuiltInFilter(id: Int): Filter = when (id) { - FILTER_TODAY -> BuiltInFilterExposer.getTodayFilter(context.resources) - FILTER_RECENTLY_MODIFIED -> BuiltInFilterExposer.getRecentlyModifiedFilter(context.resources) - FILTER_SNOOZED -> BuiltInFilterExposer.getSnoozedFilter(context.resources) - FILTER_NOTIFICATIONS -> BuiltInFilterExposer.getNotificationsFilter(context) - else -> getMyTasksFilter(context.resources) + private suspend fun getBuiltInFilter(id: Int): Filter = when (id) { + FILTER_TODAY -> TodayFilter.create() + FILTER_RECENTLY_MODIFIED -> RecentlyModifiedFilter.create() + FILTER_SNOOZED -> SnoozedFilter.create() + FILTER_NOTIFICATIONS -> NotificationsFilter.create() + else -> MyTasksFilter.create() } private fun getBuiltInFilterId(filter: Filter) = with(filter) { @@ -194,17 +197,13 @@ class DefaultFilterProvider @Inject constructor( return originalList ?: getDefaultList() } - private fun Filter.isToday() = - BuiltInFilterExposer.isTodayFilter(context, this) + private fun Filter.isToday() = this is TodayFilter - private fun Filter.isRecentlyModified() = - BuiltInFilterExposer.isRecentlyModifiedFilter(context, this) + private fun Filter.isRecentlyModified() = this is RecentlyModifiedFilter - private fun Filter.isSnoozed() = - BuiltInFilterExposer.isSnoozedFilter(context, this) + private fun Filter.isSnoozed() = this is SnoozedFilter - private fun Filter.isNotifications() = - BuiltInFilterExposer.isNotificationsFilter(context, this) + private fun Filter.isNotifications() = this is NotificationsFilter companion object { private const val TYPE_FILTER = 0 diff --git a/app/src/main/java/org/tasks/ui/TaskListViewModel.kt b/app/src/main/java/org/tasks/ui/TaskListViewModel.kt index f4feb2fc7..9d906ccd1 100644 --- a/app/src/main/java/org/tasks/ui/TaskListViewModel.kt +++ b/app/src/main/java/org/tasks/ui/TaskListViewModel.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.Intent import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.todoroo.astrid.core.BuiltInFilterExposer import com.todoroo.astrid.service.TaskDeleter import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext @@ -36,6 +35,7 @@ import org.tasks.filters.AstridOrderingFilter import org.tasks.filters.EmptyFilter import org.tasks.filters.Filter import org.tasks.filters.FilterImpl +import org.tasks.filters.MyTasksFilter import org.tasks.filters.SearchFilter import org.tasks.preferences.Preferences import org.tasks.preferences.QueryPreferences @@ -147,7 +147,7 @@ class TaskListViewModel @Inject constructor( .map { val filter = when { it.searchQuery == null -> it.filter - it.searchQuery.isBlank() -> BuiltInFilterExposer.getMyTasksFilter(context.resources) + it.searchQuery.isBlank() -> MyTasksFilter.create() else -> context.createSearchQuery(it.searchQuery) } taskDao.fetchTasks { getQuery(preferences, filter) } diff --git a/data/src/androidMain/kotlin/org/tasks/Platform.android.kt b/data/src/androidMain/kotlin/org/tasks/Platform.android.kt index a689aab6a..be65a7b98 100644 --- a/data/src/androidMain/kotlin/org/tasks/Platform.android.kt +++ b/data/src/androidMain/kotlin/org/tasks/Platform.android.kt @@ -3,6 +3,7 @@ package org.tasks import android.os.Parcelable +import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.RawValue import org.tasks.data.BuildConfig import java.util.Date @@ -11,6 +12,8 @@ actual typealias CommonParcelable = Parcelable actual typealias CommonRawValue = RawValue +actual typealias CommonIgnoredOnParcel = IgnoredOnParcel + actual val IS_DEBUG = BuildConfig.DEBUG actual fun Long.printTimestamp(): String = Date(this).toString() \ No newline at end of file diff --git a/data/src/commonMain/kotlin/org/tasks/Platform.kt b/data/src/commonMain/kotlin/org/tasks/Platform.kt index 07daef4de..3fb49cf89 100644 --- a/data/src/commonMain/kotlin/org/tasks/Platform.kt +++ b/data/src/commonMain/kotlin/org/tasks/Platform.kt @@ -10,6 +10,10 @@ annotation class CommonParcelize @Retention(AnnotationRetention.BINARY) expect annotation class CommonRawValue() +@Target(AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.SOURCE) +expect annotation class CommonIgnoredOnParcel() + expect interface CommonParcelable expect val IS_DEBUG: Boolean diff --git a/data/src/jvmMain/kotlin/org/tasks/Platform.jvm.kt b/data/src/jvmMain/kotlin/org/tasks/Platform.jvm.kt index 0db807cf4..b11d7ae01 100644 --- a/data/src/jvmMain/kotlin/org/tasks/Platform.jvm.kt +++ b/data/src/jvmMain/kotlin/org/tasks/Platform.jvm.kt @@ -8,8 +8,14 @@ actual interface CommonParcelable @Retention(AnnotationRetention.BINARY) annotation class RawValue +@Target(AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.SOURCE) +annotation class IgnoredOnParcel + actual typealias CommonRawValue = RawValue +actual typealias CommonIgnoredOnParcel = IgnoredOnParcel + actual val IS_DEBUG = false actual fun Long.printTimestamp(): String = this.toString() diff --git a/kmp/build.gradle.kts b/kmp/build.gradle.kts index 21c4b3717..e14284483 100644 --- a/kmp/build.gradle.kts +++ b/kmp/build.gradle.kts @@ -42,6 +42,11 @@ kotlin { task("testClasses") } +compose.resources { + publicResClass = true + generateResClass = always +} + android { namespace = "org.tasks.kmp" compileSdk = libs.versions.android.compileSdk.get().toInt() diff --git a/kmp/src/commonMain/composeResources/values/strings.xml b/kmp/src/commonMain/composeResources/values/strings.xml index fda759859..b50ad70b2 100644 --- a/kmp/src/commonMain/composeResources/values/strings.xml +++ b/kmp/src/commonMain/composeResources/values/strings.xml @@ -5,4 +5,10 @@ Pro feature Unlock all features for as little as $1 USD/year Subscribe + My Tasks + Notifications + Snoozed + Tasks Being Timed + Today + Recently modified \ No newline at end of file diff --git a/kmp/src/commonMain/kotlin/org/tasks/filters/DebugFilters.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/DebugFilters.kt new file mode 100644 index 000000000..4c5c8b6ed --- /dev/null +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/DebugFilters.kt @@ -0,0 +1,85 @@ +package org.tasks.filters + +import org.tasks.data.entity.CaldavAccount +import org.tasks.data.entity.CaldavCalendar +import org.tasks.data.entity.CaldavTask +import org.tasks.data.entity.Task +import org.tasks.data.sql.Criterion.Companion.and +import org.tasks.data.sql.Criterion.Companion.or +import org.tasks.data.sql.Join +import org.tasks.data.sql.QueryTemplate +import org.tasks.themes.TasksIcons + +object DebugFilters { + fun getNoListFilter() = + FilterImpl( + title = "No list", + sql = QueryTemplate() + .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) + .where(CaldavTask.ID.eq(null)) + .toString(), + icon = TasksIcons.CLOUD_OFF, + ) + + fun getDeleted() = + FilterImpl( + title = "Deleted", + sql = QueryTemplate().where(Task.DELETION_DATE.gt(0)).toString(), + icon = TasksIcons.DELETE, + ) + + fun getMissingListFilter() = + FilterImpl( + title = "Missing list", + sql = QueryTemplate() + .join(Join.left(CaldavTask.TABLE, CaldavTask.TASK.eq(Task.ID))) + .join( + Join.left( + CaldavCalendar.TABLE, + CaldavCalendar.UUID.eq(CaldavTask.CALENDAR) + ) + ) + .where(and(CaldavTask.ID.gt(0), CaldavCalendar.UUID.eq(null))) + .toString(), + icon = TasksIcons.CLOUD_OFF, + ) + + fun getMissingAccountFilter() = + FilterImpl( + title = "Missing account", + sql = QueryTemplate() + .join( + Join.left(CaldavTask.TABLE, and(CaldavTask.TASK.eq(Task.ID))) + ).join( + Join.left(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR)) + ).join( + Join.left( + CaldavAccount.TABLE, CaldavAccount.UUID.eq(CaldavCalendar.ACCOUNT) + ) + ) + .where(and(CaldavTask.ID.gt(0), CaldavAccount.UUID.eq(null))) + .toString(), + icon = TasksIcons.CLOUD_OFF, + ) + + fun getNoTitleFilter() = + FilterImpl( + title = "No title", + sql = QueryTemplate().where(or(Task.TITLE.eq(null), Task.TITLE.eq(""))).toString(), + icon = TasksIcons.CLEAR, + ) + + fun getNoCreateDateFilter() = + FilterImpl( + title = "No create time", + sql = QueryTemplate().where(Task.CREATION_DATE.eq(0)).toString(), + icon = TasksIcons.ADD, + ) + + fun getNoModificationDateFilter() = + FilterImpl( + title = "No modify time", + sql = QueryTemplate().where(Task.MODIFICATION_DATE.eq(0)).toString(), + icon = TasksIcons.EDIT, + ) +} \ No newline at end of file diff --git a/kmp/src/commonMain/kotlin/org/tasks/filters/MyTasksFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/MyTasksFilter.kt index ec8b7e38e..e06b28a96 100644 --- a/kmp/src/commonMain/kotlin/org/tasks/filters/MyTasksFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/MyTasksFilter.kt @@ -1,11 +1,14 @@ package org.tasks.filters +import org.jetbrains.compose.resources.getString import org.tasks.CommonParcelize import org.tasks.data.dao.TaskDao import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion import org.tasks.data.sql.QueryTemplate import org.tasks.themes.TasksIcons +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_my_tasks @CommonParcelize data class MyTasksFilter( @@ -26,4 +29,8 @@ data class MyTasksFilter( override fun areItemsTheSame(other: FilterListItem): Boolean { return other is MyTasksFilter } + + companion object { + suspend fun create() = MyTasksFilter(getString(Res.string.filter_my_tasks)) + } } diff --git a/app/src/main/java/org/tasks/filters/NotificationsFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/NotificationsFilter.kt similarity index 68% rename from app/src/main/java/org/tasks/filters/NotificationsFilter.kt rename to kmp/src/commonMain/kotlin/org/tasks/filters/NotificationsFilter.kt index 9e8639f0e..a915f8c9d 100644 --- a/app/src/main/java/org/tasks/filters/NotificationsFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/NotificationsFilter.kt @@ -1,13 +1,16 @@ package org.tasks.filters -import kotlinx.parcelize.Parcelize +import org.jetbrains.compose.resources.getString +import org.tasks.CommonParcelize import org.tasks.data.entity.Notification import org.tasks.data.entity.Task import org.tasks.data.sql.Join import org.tasks.data.sql.QueryTemplate import org.tasks.themes.TasksIcons +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_notifications -@Parcelize +@CommonParcelize data class NotificationsFilter( override val title: String, ) : Filter { @@ -24,4 +27,8 @@ data class NotificationsFilter( override fun areItemsTheSame(other: FilterListItem): Boolean { return other is NotificationsFilter } + + companion object { + suspend fun create() = NotificationsFilter(getString(Res.string.filter_notifications)) + } } \ No newline at end of file diff --git a/kmp/src/commonMain/kotlin/org/tasks/filters/RecentlyModifiedFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/RecentlyModifiedFilter.kt index bcb9041d2..4d07b346d 100644 --- a/kmp/src/commonMain/kotlin/org/tasks/filters/RecentlyModifiedFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/RecentlyModifiedFilter.kt @@ -1,5 +1,6 @@ package org.tasks.filters +import org.jetbrains.compose.resources.getString import org.tasks.CommonParcelize import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion.Companion.and @@ -9,6 +10,8 @@ import org.tasks.themes.TasksIcons import org.tasks.time.DateTimeUtils2.currentTimeMillis import org.tasks.time.minusDays import org.tasks.time.startOfMinute +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_recently_modified @CommonParcelize data class RecentlyModifiedFilter( @@ -39,4 +42,9 @@ data class RecentlyModifiedFilter( override fun areItemsTheSame(other: FilterListItem): Boolean { return other is RecentlyModifiedFilter } + + companion object { + suspend fun create() = + RecentlyModifiedFilter(getString(Res.string.filter_recently_modified)) + } } diff --git a/app/src/main/java/org/tasks/filters/SnoozedFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/SnoozedFilter.kt similarity index 77% rename from app/src/main/java/org/tasks/filters/SnoozedFilter.kt rename to kmp/src/commonMain/kotlin/org/tasks/filters/SnoozedFilter.kt index 09f5414c9..c5d6d31a8 100644 --- a/app/src/main/java/org/tasks/filters/SnoozedFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/SnoozedFilter.kt @@ -1,16 +1,19 @@ package org.tasks.filters +import org.jetbrains.compose.resources.getString +import org.tasks.CommonParcelize +import org.tasks.data.dao.TaskDao.TaskCriteria.activeAndVisible +import org.tasks.data.entity.Alarm +import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion.Companion.and import org.tasks.data.sql.Functions.now import org.tasks.data.sql.Join.Companion.inner import org.tasks.data.sql.QueryTemplate -import org.tasks.data.entity.Task -import kotlinx.parcelize.Parcelize -import org.tasks.data.entity.Alarm -import org.tasks.data.dao.TaskDao.TaskCriteria.activeAndVisible import org.tasks.themes.TasksIcons +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_snoozed -@Parcelize +@CommonParcelize data class SnoozedFilter( override val title: String, ) : Filter { @@ -34,4 +37,8 @@ data class SnoozedFilter( override fun areItemsTheSame(other: FilterListItem): Boolean { return other is SnoozedFilter } + + companion object { + suspend fun create() = SnoozedFilter(getString(Res.string.filter_snoozed)) + } } diff --git a/app/src/main/java/org/tasks/filters/SubtaskFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/SubtaskFilter.kt similarity index 83% rename from app/src/main/java/org/tasks/filters/SubtaskFilter.kt rename to kmp/src/commonMain/kotlin/org/tasks/filters/SubtaskFilter.kt index 33ccc793d..ff8c8d3a6 100644 --- a/app/src/main/java/org/tasks/filters/SubtaskFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/SubtaskFilter.kt @@ -1,20 +1,20 @@ package org.tasks.filters -import kotlinx.parcelize.IgnoredOnParcel -import kotlinx.parcelize.Parcelize +import org.tasks.CommonIgnoredOnParcel +import org.tasks.CommonParcelize import org.tasks.data.dao.TaskDao import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion import org.tasks.data.sql.QueryTemplate -@Parcelize +@CommonParcelize data class SubtaskFilter( private val parent: Long, ) : Filter { - @IgnoredOnParcel + @CommonIgnoredOnParcel override val title: String = "subtasks" - @IgnoredOnParcel + @CommonIgnoredOnParcel override val sql: String = QueryTemplate() .where( diff --git a/app/src/main/java/org/tasks/filters/TimerFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/TimerFilter.kt similarity index 60% rename from app/src/main/java/org/tasks/filters/TimerFilter.kt rename to kmp/src/commonMain/kotlin/org/tasks/filters/TimerFilter.kt index fa3ce3774..80fa57472 100644 --- a/app/src/main/java/org/tasks/filters/TimerFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/TimerFilter.kt @@ -1,13 +1,16 @@ package org.tasks.filters +import org.jetbrains.compose.resources.getString +import org.tasks.CommonParcelize +import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion import org.tasks.data.sql.QueryTemplate -import org.tasks.data.entity.Task -import kotlinx.parcelize.Parcelize import org.tasks.themes.TasksIcons +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_timer -@Parcelize -data class TimerFilter(override val title: String?) : Filter { +@CommonParcelize +data class TimerFilter(override val title: String) : Filter { override val icon get() = TasksIcons.TIMER @@ -21,4 +24,8 @@ data class TimerFilter(override val title: String?) : Filter { ).toString() override fun areItemsTheSame(other: FilterListItem) = other is TimerFilter + + companion object { + suspend fun create() = TimerFilter(getString(Res.string.filter_timer)) + } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/filters/TodayFilter.kt b/kmp/src/commonMain/kotlin/org/tasks/filters/TodayFilter.kt similarity index 77% rename from app/src/main/java/org/tasks/filters/TodayFilter.kt rename to kmp/src/commonMain/kotlin/org/tasks/filters/TodayFilter.kt index 5841427a0..b56c5278a 100644 --- a/app/src/main/java/org/tasks/filters/TodayFilter.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/filters/TodayFilter.kt @@ -1,14 +1,17 @@ package org.tasks.filters import com.todoroo.astrid.api.PermaSql -import kotlinx.parcelize.Parcelize +import org.jetbrains.compose.resources.getString +import org.tasks.CommonParcelize import org.tasks.data.dao.TaskDao import org.tasks.data.entity.Task import org.tasks.data.sql.Criterion import org.tasks.data.sql.QueryTemplate import org.tasks.themes.TasksIcons +import tasks.kmp.generated.resources.Res +import tasks.kmp.generated.resources.filter_today -@Parcelize +@CommonParcelize data class TodayFilter( override val title: String, override var filterOverride: String? = null, @@ -33,4 +36,8 @@ data class TodayFilter( override fun areItemsTheSame(other: FilterListItem): Boolean { return other is TodayFilter } + + companion object { + suspend fun create() = TodayFilter(getString(Res.string.filter_today)) + } } \ No newline at end of file