From 041dce8617d1ef8fa620284c9e107dad44353545 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Mon, 18 Mar 2024 00:23:00 -0500 Subject: [PATCH] Add dynamic widget theme --- .../andlib/utility/AndroidUtilities.java | 6 +++- .../main/java/org/tasks/billing/Inventory.kt | 2 +- .../org/tasks/dialogs/ThemePickerDialog.kt | 7 ++-- .../preferences/fragments/WidgetSettings.kt | 4 ++- .../main/java/org/tasks/widget/TasksWidget.kt | 17 ++------- .../tasks/widget/TasksWidgetViewFactory.kt | 14 +++----- .../org/tasks/widget/WidgetPreferences.kt | 35 +++++++++++++++++++ app/src/main/res/values/arrays.xml | 1 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 56 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java index 8b94d049d..7090ce63b 100644 --- a/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java +++ b/app/src/main/java/com/todoroo/andlib/utility/AndroidUtilities.java @@ -140,8 +140,12 @@ public class AndroidUtilities { return !atLeastOreo(); } + public static boolean preS() { + return !atLeastS(); + } + public static boolean preTiramisu() { - return VERSION.SDK_INT < VERSION_CODES.TIRAMISU; + return !atLeastTiramisu(); } public static boolean preUpsideDownCake() { diff --git a/app/src/main/java/org/tasks/billing/Inventory.kt b/app/src/main/java/org/tasks/billing/Inventory.kt index bb67870e8..6e1cf1c67 100644 --- a/app/src/main/java/org/tasks/billing/Inventory.kt +++ b/app/src/main/java/org/tasks/billing/Inventory.kt @@ -12,7 +12,6 @@ import org.tasks.data.CaldavDao import org.tasks.extensions.Context.openUri import org.tasks.preferences.Preferences import timber.log.Timber -import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -59,6 +58,7 @@ class Inventory @Inject constructor( var hasPro = false get() { + @Suppress("KotlinConstantConditions") return BuildConfig.FLAVOR == "generic" || (BuildConfig.DEBUG && preferences.getBoolean(R.string.p_debug_pro, false)) || hasTasksAccount diff --git a/app/src/main/java/org/tasks/dialogs/ThemePickerDialog.kt b/app/src/main/java/org/tasks/dialogs/ThemePickerDialog.kt index 3ca1bddba..d67edf2b3 100644 --- a/app/src/main/java/org/tasks/dialogs/ThemePickerDialog.kt +++ b/app/src/main/java/org/tasks/dialogs/ThemePickerDialog.kt @@ -14,6 +14,7 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment +import com.todoroo.andlib.utility.AndroidUtilities.preS import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.billing.Inventory @@ -58,9 +59,9 @@ class ThemePickerDialog : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { selected = savedInstanceState?.getInt(EXTRA_SELECTED) ?: requireArguments().getInt(EXTRA_SELECTED) widget = arguments?.getBoolean(EXTRA_WIDGET) ?: false - val themes = resources.getStringArray( - if (widget) R.array.widget_themes else R.array.base_theme_names - ) + val themes = resources + .getStringArray(if (widget) R.array.widget_themes else R.array.base_theme_names) + .let { if (widget && (preS() || !inventory.hasPro)) it.dropLast(1).toTypedArray() else it } adapter = object : ArrayAdapter(requireActivity(), R.layout.simple_list_item_single_choice, themes) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { diff --git a/app/src/main/java/org/tasks/preferences/fragments/WidgetSettings.kt b/app/src/main/java/org/tasks/preferences/fragments/WidgetSettings.kt index f0a5a5aac..441a8a4f6 100644 --- a/app/src/main/java/org/tasks/preferences/fragments/WidgetSettings.kt +++ b/app/src/main/java/org/tasks/preferences/fragments/WidgetSettings.kt @@ -200,8 +200,10 @@ class WidgetSettings : InjectingPreferenceFragment() { } private fun updateTheme() { + val index = widgetPreferences.themeIndex val widgetNames = resources.getStringArray(R.array.widget_themes) - findPreference(R.string.p_widget_theme).summary = widgetNames[widgetPreferences.themeIndex] + findPreference(R.string.p_widget_theme).summary = widgetNames[index] + findPreference(R.string.p_widget_color_v2).isVisible = index != 4 } private fun updateColor() { diff --git a/app/src/main/java/org/tasks/widget/TasksWidget.kt b/app/src/main/java/org/tasks/widget/TasksWidget.kt index bf97e03b8..8e2644470 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidget.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidget.kt @@ -9,7 +9,6 @@ import android.net.Uri import android.os.Bundle import android.view.View import android.widget.RemoteViews -import androidx.annotation.ColorInt import com.todoroo.andlib.utility.AndroidUtilities.atLeastS import com.todoroo.astrid.api.Filter import dagger.hilt.android.AndroidEntryPoint @@ -75,15 +74,14 @@ class TasksWidget : AppWidgetProvider() { } else { setViewVisibility(R.id.widget_header, View.GONE) } - val bgColor = getBackgroundColor(widgetPreferences.themeIndex) setBackgroundColor( viewId = R.id.list_view, - color = bgColor, + color = settings.backgroundColor, opacity = widgetPreferences.rowOpacity, ) setBackgroundColor( viewId = R.id.empty_view, - color = bgColor, + color = settings.backgroundColor, opacity = widgetPreferences.footerOpacity, ) setOnClickPendingIntent(R.id.empty_view, getOpenListIntent(context, filter, id)) @@ -168,17 +166,6 @@ class TasksWidget : AppWidgetProvider() { } } - @ColorInt - private fun getBackgroundColor(themeIndex: Int): Int { - val background: Int = when (themeIndex) { - 1 -> android.R.color.black - 2 -> R.color.md_background_dark - 3 -> R.color.widget_background_follow_system - else -> android.R.color.white - } - return context.getColor(background) - } - private fun getPendingIntentTemplate(context: Context): PendingIntent = PendingIntent.getActivity( context, diff --git a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt index abc418a98..634bf55eb 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt @@ -18,7 +18,6 @@ import org.tasks.data.TaskContainer import org.tasks.data.TaskDao import org.tasks.data.TaskListQuery.getQuery import org.tasks.date.DateTimeUtils -import org.tasks.extensions.Context.isNightMode import org.tasks.extensions.setBackgroundResource import org.tasks.extensions.setColorFilter import org.tasks.extensions.setMaxLines @@ -56,16 +55,11 @@ internal class TasksWidgetViewFactory( || (filter.supportsManualSort() && widgetPreferences.isManualSort) || (filter is AstridOrderingFilter && widgetPreferences.isAstridSort) private var tasks = SectionedDataSource() - private val isDark = when (widgetPreferences.themeIndex) { - 0 -> false - 3 -> context.isNightMode - else -> true - } - private val onSurface = context.getColor(if (isDark) R.color.white_87 else R.color.black_87) - private val onSurfaceVariant = context.getColor(if (isDark) R.color.white_60 else R.color.black_60) + private val onSurface = context.getColor(if (settings.isDark) R.color.white_87 else R.color.black_87) + private val onSurfaceVariant = context.getColor(if (settings.isDark) R.color.white_60 else R.color.black_60) init { - chipProvider.isDark = isDark + chipProvider.isDark = settings.isDark } override fun onCreate() {} @@ -134,7 +128,7 @@ internal class TasksWidgetViewFactory( section.headerColor( context, settings.groupMode, - if (isDark) R.color.white_60 else R.color.black_60 + if (settings.isDark) R.color.white_60 else R.color.black_60 ) ) if (!settings.showDividers) { diff --git a/app/src/main/java/org/tasks/widget/WidgetPreferences.kt b/app/src/main/java/org/tasks/widget/WidgetPreferences.kt index 7e3aab5c1..3d1fd29b9 100644 --- a/app/src/main/java/org/tasks/widget/WidgetPreferences.kt +++ b/app/src/main/java/org/tasks/widget/WidgetPreferences.kt @@ -1,11 +1,13 @@ package org.tasks.widget import android.content.Context +import androidx.core.content.ContextCompat import com.google.common.base.Joiner import com.google.common.base.Splitter import com.todoroo.astrid.core.SortHelper import com.todoroo.astrid.service.Upgrader.Companion.getLegacyColor import org.tasks.R +import org.tasks.extensions.Context.isNightMode import org.tasks.preferences.Preferences import org.tasks.preferences.QueryPreferences import org.tasks.tasklist.SectionedDataSource.Companion.HEADER_COMPLETED @@ -23,8 +25,10 @@ class WidgetPreferences( val showSettings: Boolean, val showMenu: Boolean, val color: Int, + val backgroundColor: Int, val headerOpacity: Int, val headerSpacing: Int, + val isDark: Boolean, ) data class WidgetRowSettings( @@ -44,6 +48,7 @@ class WidgetPreferences( val compact: Boolean, val groupMode: Int, val dueDatePosition: Int, + val isDark: Boolean, ) { val showDueDates get() = dueDatePosition != 2 val endDueDate get() = dueDatePosition != 1 @@ -55,8 +60,10 @@ class WidgetPreferences( showSettings = getBoolean(R.string.p_widget_show_settings, true), showMenu = getBoolean(R.string.p_widget_show_menu, true), color = color, + backgroundColor = backgroundColor, headerOpacity = getAlphaValue(R.string.p_widget_header_opacity), headerSpacing = getSpacing(R.string.p_widget_header_spacing), + isDark = isDark, ) fun getWidgetListSettings() = WidgetRowSettings( @@ -76,10 +83,28 @@ class WidgetPreferences( compact = getBoolean(R.string.p_widget_compact, false), groupMode = groupMode, dueDatePosition = dueDatePosition, + isDark = isDark, ) val dueDatePosition: Int get() = getIntegerFromString(R.string.p_widget_due_date_position) + private val isDark: Boolean + get() = when (themeIndex) { + 0 -> false + 3, 4 -> context.isNightMode + else -> true + } + + private val backgroundColor: Int + get() = context.getColor( + when (themeIndex) { + 1 -> android.R.color.black + 2 -> R.color.md_background_dark + 3, 4 -> R.color.widget_background_follow_system + else -> android.R.color.white + } + ) + var collapsed: Set get() { val value = getString(R.string.p_widget_collapsed) @@ -113,6 +138,16 @@ class WidgetPreferences( get() = getInt(R.string.p_widget_theme, 3) val color: Int get() { + if (themeIndex == 4) { + return ContextCompat.getColor( + context, + if (isDark) { + com.google.android.material.R.color.m3_sys_color_dynamic_dark_primary + } else { + com.google.android.material.R.color.m3_sys_color_dynamic_light_primary + } + ) + } var color = getInt(R.string.p_widget_color_v2, 0) if (color != 0) { return color diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 800a5ef98..e27ac97f6 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -27,6 +27,7 @@ @string/theme_black @string/theme_dark @string/theme_system_default + @string/theme_dynamic diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c48e87c36..fc85a21dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -389,6 +389,7 @@ File %1$s contained %2$s.\n\n Wallpaper Day/Night System default + Dynamic Language Restart Tasks for this change to take effect Restart now