diff options
13 files changed, 240 insertions, 75 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 909b7a5a2..b790bc005 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -3,32 +3,29 @@ package de.test.antennapod.ui; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; - import androidx.annotation.StringRes; import androidx.preference.PreferenceManager; import androidx.test.espresso.matcher.RootMatchers; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; - -import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithmFactory; -import org.awaitility.Awaitility; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.storage.preferences.UserPreferences; -import de.danoeh.antennapod.storage.preferences.UserPreferences.EnqueueLocation; import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithmFactory; import de.danoeh.antennapod.core.storage.ExceptFavoriteCleanupAlgorithm; +import de.danoeh.antennapod.storage.preferences.UserPreferences; +import de.danoeh.antennapod.storage.preferences.UserPreferences.EnqueueLocation; import de.test.antennapod.EspressoTestUtils; +import org.awaitility.Awaitility; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; import static androidx.test.espresso.Espresso.onData; import static androidx.test.espresso.Espresso.onView; @@ -78,22 +75,6 @@ public class PreferencesTest { } @Test - public void testSwitchTheme() { - final UserPreferences.ThemePreference theme = UserPreferences.getTheme(); - int otherThemeText; - if (theme == UserPreferences.ThemePreference.DARK) { - otherThemeText = R.string.pref_theme_title_light; - } else { - otherThemeText = R.string.pref_theme_title_dark; - } - clickPreference(R.string.user_interface_label); - clickPreference(R.string.pref_set_theme_title); - onView(withText(otherThemeText)).perform(click()); - Awaitility.await().atMost(1000, MILLISECONDS) - .until(() -> UserPreferences.getTheme() != theme); - } - - @Test public void testEnablePersistentPlaybackControls() { final boolean persistNotify = UserPreferences.isPersistNotify(); clickPreference(R.string.user_interface_label); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java index caf555964..66f592af2 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java @@ -5,18 +5,19 @@ import android.os.Build; import android.os.Bundle; import android.widget.ListView; import androidx.appcompat.app.AlertDialog; -import com.google.android.material.snackbar.Snackbar; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import androidx.core.app.ActivityCompat; +import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.storage.preferences.UserPreferences; import de.danoeh.antennapod.dialog.DrawerPreferencesDialog; import de.danoeh.antennapod.dialog.FeedSortDialog; import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog; import de.danoeh.antennapod.event.PlayerStatusEvent; import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; +import de.danoeh.antennapod.storage.preferences.UserPreferences; import org.greenrobot.eventbus.EventBus; import java.util.List; @@ -37,22 +38,16 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat { } private void setupInterfaceScreen() { - findPreference(UserPreferences.PREF_THEME) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - ActivityCompat.recreate(getActivity()); - return true; - }); - + Preference.OnPreferenceChangeListener restartApp = (preference, newValue) -> { + ActivityCompat.recreate(getActivity()); + return true; + }; + findPreference(UserPreferences.PREF_THEME).setOnPreferenceChangeListener(restartApp); + findPreference(UserPreferences.PREF_THEME_BLACK).setOnPreferenceChangeListener(restartApp); + findPreference(UserPreferences.PREF_TINTED_COLORS).setOnPreferenceChangeListener(restartApp); if (Build.VERSION.SDK_INT < 31) { findPreference(UserPreferences.PREF_TINTED_COLORS).setVisible(false); } - findPreference(UserPreferences.PREF_TINTED_COLORS) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - ActivityCompat.recreate(getActivity()); - return true; - }); findPreference(UserPreferences.PREF_SHOW_TIME_LEFT) .setOnPreferenceChangeListener( diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java index e093c067d..79d06de59 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java @@ -133,5 +133,13 @@ public class PreferenceUpgrader { "" + UserPreferences.EPISODE_CACHE_SIZE_UNLIMITED).apply(); } } + if (oldVersion < 3010000) { + if (prefs.getString(UserPreferences.PREF_THEME, "system").equals("2")) { + prefs.edit() + .putString(UserPreferences.PREF_THEME, "1") + .putBoolean(UserPreferences.PREF_THEME_BLACK, true) + .apply(); + } + } } } diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/ThemePreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/ThemePreference.java new file mode 100644 index 000000000..30cbeb523 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/preferences/ThemePreference.java @@ -0,0 +1,53 @@ +package de.danoeh.antennapod.preferences; + +import android.content.Context; +import android.util.AttributeSet; +import androidx.cardview.widget.CardView; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; +import com.google.android.material.elevation.SurfaceColors; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.databinding.ThemePreferenceBinding; +import de.danoeh.antennapod.storage.preferences.UserPreferences; + +public class ThemePreference extends Preference { + ThemePreferenceBinding viewBinding; + + public ThemePreference(Context context) { + super(context); + setLayoutResource(R.layout.theme_preference); + } + + public ThemePreference(Context context, AttributeSet attrs) { + super(context, attrs); + setLayoutResource(R.layout.theme_preference); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + viewBinding = ThemePreferenceBinding.bind(holder.itemView); + updateUi(); + } + + void updateThemeCard(CardView card, UserPreferences.ThemePreference theme) { + float density = getContext().getResources().getDisplayMetrics().density; + int surfaceColor = SurfaceColors.getColorForElevation(getContext(), 1 * density); + int surfaceColorActive = SurfaceColors.getColorForElevation(getContext(), 32 * density); + UserPreferences.ThemePreference activeTheme = UserPreferences.getTheme(); + card.setCardBackgroundColor(theme == activeTheme ? surfaceColorActive : surfaceColor); + card.setOnClickListener(v -> { + UserPreferences.setTheme(theme); + if (getOnPreferenceChangeListener() != null) { + getOnPreferenceChangeListener().onPreferenceChange(this, UserPreferences.getTheme()); + } + updateUi(); + }); + } + + void updateUi() { + updateThemeCard(viewBinding.themeSystemCard, UserPreferences.ThemePreference.SYSTEM); + updateThemeCard(viewBinding.themeLightCard, UserPreferences.ThemePreference.LIGHT); + updateThemeCard(viewBinding.themeDarkCard, UserPreferences.ThemePreference.DARK); + } +} diff --git a/app/src/main/res/drawable-nodpi/theme_preview_dark.png b/app/src/main/res/drawable-nodpi/theme_preview_dark.png Binary files differnew file mode 100644 index 000000000..b4e1e0376 --- /dev/null +++ b/app/src/main/res/drawable-nodpi/theme_preview_dark.png diff --git a/app/src/main/res/drawable-nodpi/theme_preview_light.png b/app/src/main/res/drawable-nodpi/theme_preview_light.png Binary files differnew file mode 100644 index 000000000..39ef47b4f --- /dev/null +++ b/app/src/main/res/drawable-nodpi/theme_preview_light.png diff --git a/app/src/main/res/drawable-nodpi/theme_preview_system.png b/app/src/main/res/drawable-nodpi/theme_preview_system.png Binary files differnew file mode 100644 index 000000000..cc6403a98 --- /dev/null +++ b/app/src/main/res/drawable-nodpi/theme_preview_system.png diff --git a/app/src/main/res/layout/theme_preference.xml b/app/src/main/res/layout/theme_preference.xml new file mode 100644 index 000000000..32a7ed1e8 --- /dev/null +++ b/app/src/main/res/layout/theme_preference.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="?android:attr/windowBackground" + android:gravity="top" + android:padding="8dp"> + + <androidx.cardview.widget.CardView + android:id="@+id/themeSystemCard" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:clickable="true" + android:foreground="?android:attr/selectableItemBackground" + android:layout_weight="1" + app:cardElevation="0dp" + app:cardCornerRadius="16dp" + app:contentPadding="16dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center"> + + <ImageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + android:src="@drawable/theme_preview_system" /> + + <TextView + android:id="@+id/themeSystemRadio" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/pref_theme_title_automatic" + android:clickable="false" /> + + </LinearLayout> + + </androidx.cardview.widget.CardView> + + <androidx.cardview.widget.CardView + android:id="@+id/themeLightCard" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:clickable="true" + android:foreground="?android:attr/selectableItemBackground" + android:layout_weight="1" + app:cardElevation="0dp" + app:cardCornerRadius="16dp" + app:contentPadding="16dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center"> + + <ImageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + android:src="@drawable/theme_preview_light" /> + + <TextView + android:id="@+id/themeLightRadio" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/pref_theme_title_light" + android:clickable="false" /> + + </LinearLayout> + + </androidx.cardview.widget.CardView> + + <androidx.cardview.widget.CardView + android:id="@+id/themeDarkCard" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:clickable="true" + android:foreground="?android:attr/selectableItemBackground" + android:layout_weight="1" + app:cardElevation="0dp" + app:cardCornerRadius="16dp" + app:contentPadding="16dp"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center"> + + <ImageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:adjustViewBounds="true" + android:src="@drawable/theme_preview_dark" /> + + <TextView + android:id="@+id/themeDarkCardRadio" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:textColor="?android:attr/textColorPrimary" + android:text="@string/pref_theme_title_dark" + android:clickable="false" /> + + </LinearLayout> + + </androidx.cardview.widget.CardView> + +</LinearLayout> diff --git a/app/src/main/res/xml/preferences_user_interface.xml b/app/src/main/res/xml/preferences_user_interface.xml index f11b89be7..ed3f5777a 100644 --- a/app/src/main/res/xml/preferences_user_interface.xml +++ b/app/src/main/res/xml/preferences_user_interface.xml @@ -4,13 +4,13 @@ xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch"> <PreferenceCategory android:title="@string/appearance"> - <de.danoeh.antennapod.preferences.MaterialListPreference - android:entryValues="@array/theme_values" - android:entries="@array/theme_options" - android:title="@string/pref_set_theme_title" - android:key="prefTheme" - android:summary="@string/pref_set_theme_sum" - android:defaultValue="system"/> + <de.danoeh.antennapod.preferences.ThemePreference + android:key="prefTheme" /> + <SwitchPreferenceCompat + android:title="@string/pref_black_theme_title" + android:key="prefThemeBlack" + android:summary="@string/pref_black_theme_message" + android:defaultValue="false" /> <SwitchPreferenceCompat android:title="@string/pref_tinted_theme_title" android:key="prefTintedColors" diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java index b7e4934f5..afe814fcb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java @@ -59,12 +59,15 @@ public abstract class ThemeSwitcher { if (theme == UserPreferences.ThemePreference.SYSTEM) { int nightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; if (nightMode == Configuration.UI_MODE_NIGHT_YES) { - return UserPreferences.ThemePreference.DARK; + theme = UserPreferences.ThemePreference.DARK; } else { - return UserPreferences.ThemePreference.LIGHT; + theme = UserPreferences.ThemePreference.LIGHT; } } + if (theme == UserPreferences.ThemePreference.DARK && UserPreferences.getIsBlackTheme()) { + theme = UserPreferences.ThemePreference.BLACK; + } return theme; } } diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index b08541771..090d5e2e4 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -135,20 +135,6 @@ <item>-2</item> </string-array> - <string-array name="theme_options"> - <item>@string/pref_theme_title_use_system</item> - <item>@string/pref_theme_title_light</item> - <item>@string/pref_theme_title_dark</item> - <item>@string/pref_theme_title_trueblack</item> - </string-array> - - <string-array name="theme_values"> - <item>system</item> - <item>0</item> - <item>1</item> - <item>2</item> - </string-array> - <string-array name="nav_drawer_titles"> <item>@string/home_label</item> <item>@string/queue_label</item> diff --git a/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java b/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java index 8d9b099fc..c7758d40e 100644 --- a/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java +++ b/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java @@ -48,6 +48,7 @@ public class UserPreferences { // User Interface public static final String PREF_THEME = "prefTheme"; + public static final String PREF_THEME_BLACK = "prefThemeBlack"; public static final String PREF_TINTED_COLORS = "prefTintedColors"; public static final String PREF_HIDDEN_DRAWER_ITEMS = "prefHiddenDrawerItems"; public static final String PREF_DRAWER_FEED_ORDER = "prefDrawerFeedOrder"; @@ -159,19 +160,35 @@ public class UserPreferences { LIGHT, DARK, BLACK, SYSTEM } + public static void setTheme(ThemePreference theme) { + switch (theme) { + case LIGHT: + prefs.edit().putString(PREF_THEME, "0").apply(); + break; + case DARK: + prefs.edit().putString(PREF_THEME, "1").apply(); + break; + default: + prefs.edit().putString(PREF_THEME, "system").apply(); + break; + } + } + public static ThemePreference getTheme() { switch (prefs.getString(PREF_THEME, "system")) { case "0": return ThemePreference.LIGHT; case "1": return ThemePreference.DARK; - case "2": - return ThemePreference.BLACK; default: return ThemePreference.SYSTEM; } } + public static boolean getIsBlackTheme() { + return prefs.getBoolean(PREF_THEME_BLACK, false); + } + public static boolean getIsThemeColorTinted() { return Build.VERSION.SDK_INT >= 31 && prefs.getBoolean(PREF_TINTED_COLORS, false); } diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml index 40015630f..db91c43ae 100644 --- a/ui/i18n/src/main/res/values/strings.xml +++ b/ui/i18n/src/main/res/values/strings.xml @@ -432,8 +432,9 @@ <string name="pref_mobileUpdate_streaming">Streaming</string> <string name="user_interface_label">User Interface</string> <string name="user_interface_sum">Appearance, Subscriptions, Lockscreen</string> - <string name="pref_set_theme_title">Select Theme</string> - <string name="pref_tinted_theme_title">Use Tinted Colors</string> + <string name="pref_black_theme_title">Full Black</string> + <string name="pref_black_theme_message">Use full black for the dark theme</string> + <string name="pref_tinted_theme_title">Tinted Colors</string> <string name="pref_tinted_theme_message">Tint app colors based on the background image</string> <string name="pref_nav_drawer_items_title">Set Navigation Drawer items</string> <string name="pref_nav_drawer_items_sum">Change which items appear in the navigation drawer.</string> @@ -441,7 +442,6 @@ <string name="pref_nav_drawer_feed_order_sum">Change the order of your subscriptions</string> <string name="pref_nav_drawer_feed_counter_title">Set Subscription Counter</string> <string name="pref_nav_drawer_feed_counter_sum">Change the information displayed by the subscription counter. Also affects the sorting of subscriptions if \'Subscription Order\' is set to \'Counter\'.</string> - <string name="pref_set_theme_sum">Change the appearance of AntennaPod.</string> <string name="pref_automatic_download_title">Automatic Download</string> <string name="pref_automatic_download_sum">Configure the automatic download of episodes.</string> <string name="pref_autodl_wifi_filter_title">Enable Wi-Fi filter</string> @@ -455,10 +455,9 @@ <string name="pref_episode_cover_summary">Use the episode specific cover in lists whenever available. If unchecked, the app will always use the podcast cover image.</string> <string name="pref_show_remain_time_title">Show Remaining Time</string> <string name="pref_show_remain_time_summary">Display remaining time of episodes when checked. If unchecked, display total duration of episodes.</string> - <string name="pref_theme_title_use_system">Use system theme</string> + <string name="pref_theme_title_automatic">Automatic</string> <string name="pref_theme_title_light">Light</string> <string name="pref_theme_title_dark">Dark</string> - <string name="pref_theme_title_trueblack">Black (AMOLED ready)</string> <string name="pref_episode_cache_unlimited">Unlimited</string> <string name="pref_playback_speed_sum">Customize the speeds available for variable speed playback</string> <string name="pref_feed_playback_speed_sum">The speed to use when starting audio playback for episodes in this podcast</string> |