diff --git a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.kt b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.kt index e47f1990b..76d7bad57 100644 --- a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.kt +++ b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.kt @@ -75,6 +75,10 @@ object AndroidUtilities { return Build.VERSION.SDK_INT >= VERSION_CODES.TIRAMISU } + fun atLeastAndroid16(): Boolean { + return Build.VERSION.SDK_INT >= VERSION_CODES.BAKLAVA + } + fun assertMainThread() { check(!(BuildConfig.DEBUG && !isMainThread)) { "Should be called from main thread" } } diff --git a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt index 52bdd9d8e..33c5900af 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.view.View import android.widget.RemoteViews import android.widget.RemoteViewsService.RemoteViewsFactory +import com.todoroo.andlib.utility.AndroidUtilities.atLeastAndroid16 import com.todoroo.astrid.core.SortHelper import com.todoroo.astrid.subtasks.SubtasksHelper import kotlinx.coroutines.runBlocking @@ -50,6 +51,7 @@ internal class TasksWidgetViewFactory( private val markdown: Markdown, private val headerFormatter: HeaderFormatter, ) : RemoteViewsFactory { + private val taskLimit = if (atLeastAndroid16()) 25 + 1 else Int.MAX_VALUE private val indentPadding = (20 * context.resources.displayMetrics.density).toInt() private val settings = widgetPreferences.getWidgetListSettings() private val hPad = context.resources.getDimension(R.dimen.widget_padding).toInt() @@ -87,10 +89,11 @@ internal class TasksWidgetViewFactory( override fun onDestroy() {} - override fun getCount() = tasks.size + override fun getCount() = tasks.size.coerceAtMost(taskLimit) override fun getViewAt(position: Int): RemoteViews? = tasks.let { when { + position == taskLimit - 1 && it.size > taskLimit -> buildFooter() it.isHeader(position) -> buildHeader(it.getSection(position)) position < it.size -> buildUpdate(it.getItem(position)) else -> null @@ -99,10 +102,11 @@ internal class TasksWidgetViewFactory( override fun getLoadingView(): RemoteViews = newRemoteView() - override fun getViewTypeCount(): Int = 2 + override fun getViewTypeCount(): Int = 3 override fun getItemId(position: Int) = tasks.let { when { + position == taskLimit - 1 && it.size > taskLimit -> 0 it.isHeader(position) -> it.getSection(position).value position < it.size -> it.getItem(position).id else -> 0 @@ -113,6 +117,16 @@ internal class TasksWidgetViewFactory( private fun newRemoteView() = RemoteViews(BuildConfig.APPLICATION_ID, R.layout.widget_row) + private fun buildFooter(): RemoteViews { + return RemoteViews(BuildConfig.APPLICATION_ID, R.layout.widget_footer).apply { + setOnClickFillInIntent( + R.id.widget_view_more, + Intent(WidgetClickActivity.OPEN_TASK_LIST) + .putExtra(WidgetClickActivity.EXTRA_FILTER, filter) + ) + } + } + private fun buildHeader(section: AdapterSection): RemoteViews { val sortGroup = section.value val header: String? = if (filter.supportsSorting()) { diff --git a/app/src/main/java/org/tasks/widget/WidgetClickActivity.kt b/app/src/main/java/org/tasks/widget/WidgetClickActivity.kt index a26ab28e7..e6cf9b9d6 100644 --- a/app/src/main/java/org/tasks/widget/WidgetClickActivity.kt +++ b/app/src/main/java/org/tasks/widget/WidgetClickActivity.kt @@ -57,6 +57,16 @@ class WidgetClickActivity : AppCompatActivity(), OnDismissHandler { ) finish() } + OPEN_TASK_LIST -> { + val filter = intent.getParcelableExtra(EXTRA_FILTER) + Timber.tag("$action filter=$filter") + startActivity( + TaskIntents + .getTaskListIntent(this, filter) + .putExtra(FINISH_AFFINITY, true) + ) + finish() + } TOGGLE_SUBTASKS -> { val task = task val collapsed = intent.getBooleanExtra(EXTRA_COLLAPSED, false) @@ -110,6 +120,7 @@ class WidgetClickActivity : AppCompatActivity(), OnDismissHandler { companion object { const val COMPLETE_TASK = "COMPLETE_TASK" const val EDIT_TASK = "EDIT_TASK" + const val OPEN_TASK_LIST = "OPEN_TASK_LIST" const val TOGGLE_SUBTASKS = "TOGGLE_SUBTASKS" const val RESCHEDULE_TASK = "RESCHEDULE_TASK" const val TOGGLE_GROUP = "TOGGLE_GROUP" diff --git a/app/src/main/res/layout/widget_footer.xml b/app/src/main/res/layout/widget_footer.xml new file mode 100644 index 000000000..0f7a4302a --- /dev/null +++ b/app/src/main/res/layout/widget_footer.xml @@ -0,0 +1,16 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1f0104f68..3f620604d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -726,4 +726,5 @@ File %1$s contained %2$s.\n\n About Google Task sync Not all task details sync with Google Tasks Learn more + View more tasks