Skip to content

Commit

Permalink
Merge pull request #953 from Automattic/task/patron-icons
Browse files Browse the repository at this point in the history
Patron - Add icons
  • Loading branch information
ashiagr committed May 12, 2023
2 parents 68f19c9 + f6f5a8a commit 66e3d73
Show file tree
Hide file tree
Showing 100 changed files with 256 additions and 49 deletions.
48 changes: 48 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,54 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".ui.MainActivity_14"
android:label="@string/app_name"
android:targetActivity=".ui.MainActivity"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher_patron_chrome">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".ui.MainActivity_15"
android:label="@string/app_name"
android:targetActivity=".ui.MainActivity"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher_patron_round">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".ui.MainActivity_16"
android:label="@string/app_name"
android:targetActivity=".ui.MainActivity"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher_patron_glow">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".ui.MainActivity_17"
android:label="@string/app_name"
android:targetActivity=".ui.MainActivity"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher_patron_dark">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>

<activity android:name=".profile.sonos.SonosAppLinkActivity" android:label="@string/profile_sonos"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ private fun Content(
is OnboardingFlow.PlusFlow -> defaultValue = flow.source
else -> Unit // Not a startDestination, default value should not be set.
}
},
navArgument(OnboardingNavRoute.PlusUpgrade.showPatronOnlyArgumentKey) {
type = NavType.BoolType
defaultValue = when (flow) {
is OnboardingFlow.PlusUpsell -> flow.showPatronOnly
else -> false
}
}
)
) { navBackStackEntry ->
Expand Down Expand Up @@ -258,9 +265,13 @@ private object OnboardingNavRoute {
private const val routeBase = "plus_upgrade"

const val sourceArgumentKey = "source"
const val showPatronOnlyArgumentKey = "show_patron_only"
// The route variable should only be used to navigate to the PlusUpgrade screens
// when they are the startDestination. In all other cases, use the routeWithSource function.
const val route = "$routeBase/{$sourceArgumentKey}"
// when they are the startDestination and the args for these startDestinations are set using default values.
// They are parsed based on this deep-link-like route by the navigation component.
// For more details check here: https://developer.android.com/jetpack/compose/navigation#nav-with-args
// In all other cases, use the routeWithSource function.
const val route = "$routeBase/{$sourceArgumentKey}?{$showPatronOnlyArgumentKey}={$showPatronOnlyArgumentKey}"
fun routeWithSource(source: OnboardingUpgradeSource) = "$routeBase/$source"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class OnboardingUpgradeFeaturesViewModel @Inject constructor(
val state: StateFlow<OnboardingUpgradeFeaturesState> = _state

private val source = savedStateHandle.get<OnboardingUpgradeSource>("source")
private val showPatronOnly = savedStateHandle.get<Boolean>("show_patron_only")

init {
if (BuildConfig.ADD_PATRON_ENABLED) {
Expand Down Expand Up @@ -89,7 +90,7 @@ class OnboardingUpgradeFeaturesViewModel @Inject constructor(
val lastSelectedTier = settings.getLastSelectedSubscriptionTier().takeIf { source in listOf(OnboardingUpgradeSource.LOGIN, OnboardingUpgradeSource.PROFILE) }
val lastSelectedFrequency = settings.getLastSelectedSubscriptionFrequency().takeIf { source in listOf(OnboardingUpgradeSource.LOGIN, OnboardingUpgradeSource.PROFILE) }

val showPatronOnly = source == OnboardingUpgradeSource.ACCOUNT_DETAILS
val showPatronOnly = source == OnboardingUpgradeSource.ACCOUNT_DETAILS || showPatronOnly == true
val updatedSubscriptions =
if (showPatronOnly) {
subscriptions.filter { it.tier == Subscription.SubscriptionTier.PATRON }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import au.com.shiftyjelly.pocketcasts.models.to.SignInState
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionType
import au.com.shiftyjelly.pocketcasts.settings.databinding.AdapterAppearanceAppiconItemBinding
import au.com.shiftyjelly.pocketcasts.ui.extensions.getThemeColor
import au.com.shiftyjelly.pocketcasts.ui.helper.AppIcon
Expand All @@ -18,7 +20,7 @@ import au.com.shiftyjelly.pocketcasts.ui.R as UR

class AppearanceIconSettingsAdapter(
private var mainWidth: Int?,
private var isPlusSignedIn: Boolean,
private var signInState: SignInState?,
private var selectedAppIcon: AppIcon.AppIconType,
private val list: List<AppIcon.AppIconType>,
private val clickListener: (AppIcon.AppIconType, AppIcon.AppIconType, Boolean) -> Unit
Expand Down Expand Up @@ -50,8 +52,8 @@ class AppearanceIconSettingsAdapter(

override fun getItemCount() = list.size

fun updatePlusSignedIn(value: Boolean) {
isPlusSignedIn = value
fun updatePlusSignedIn(signInState: SignInState?) {
this.signInState = signInState
notifyDataSetChanged()
}

Expand Down Expand Up @@ -82,20 +84,25 @@ class AppearanceIconSettingsAdapter(
}

fun bind(appIcon: AppIcon.AppIconType, selected: Boolean) {
val showOption = !appIcon.isPlus || isPlusSignedIn
binding.appIconItem.alpha = if (showOption) 1.0f else 0.65f
val isValidIcon = isValidIcon(appIcon)
binding.appIconItem.alpha = if (isValidIcon) 1.0f else 0.65f

val drawable = AppCompatResources.getDrawable(itemView.context, appIcon.settingsIcon)
binding.imgIcon.setImageDrawable(drawable)
var tickDrawable: Drawable? = null
if (showOption && selected) {
if (isValidIcon && selected) {
tickDrawable = AppCompatResources.getDrawable(itemView.context, R.drawable.ic_circle_tick)
} else if (!showOption) {
tickDrawable = AppCompatResources.getDrawable(itemView.context, R.drawable.ic_plus_bubble)
} else if (!isValidIcon) {
val iconDrawable = when (appIcon.type) {
SubscriptionType.PLUS -> R.drawable.ic_locked_plus
SubscriptionType.PATRON -> R.drawable.ic_locked_patron
SubscriptionType.NONE -> throw IllegalStateException("Unknown type found for AppIcon")
}
tickDrawable = AppCompatResources.getDrawable(itemView.context, iconDrawable)
}
binding.imgTick.setImageDrawable(tickDrawable)
binding.imgTick.contentDescription = binding.imgTick.resources.getString(if (selected) LR.string.on else LR.string.off)
binding.imgLock.isVisible = !showOption
binding.imgLock.isVisible = !isValidIcon
binding.txtTitle.setText(appIcon.labelId)

binding.outlinePanel1.setSelectedWithColors(selected, selectColor, deselectColor, strokeWidth)
Expand All @@ -107,11 +114,16 @@ class AppearanceIconSettingsAdapter(
}
val beforeAppIcon = selectedAppIcon
val afterAppIcon = list[bindingAdapterPosition]
val validAppIcon = !afterAppIcon.isPlus || isPlusSignedIn
val validAppIcon = isValidIcon(afterAppIcon)

selectedAppIcon = afterAppIcon
clickListener(beforeAppIcon, afterAppIcon, validAppIcon)
notifyDataSetChanged()
}

private fun isValidIcon(appIcon: AppIcon.AppIconType) =
(appIcon.type == SubscriptionType.NONE) ||
(appIcon.type == SubscriptionType.PLUS && signInState?.isSignedInAsPlus == true) ||
(appIcon.type == SubscriptionType.PATRON && signInState?.isSignedInAsPatron == true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionType
import au.com.shiftyjelly.pocketcasts.preferences.Settings
import au.com.shiftyjelly.pocketcasts.repositories.subscription.SubscriptionManager
import au.com.shiftyjelly.pocketcasts.settings.databinding.FragmentSettingsAppearanceBinding
Expand Down Expand Up @@ -85,7 +86,7 @@ class AppearanceSettingsFragment : BaseFragment() {
binding.themeRecyclerView.setHasFixedSize(true)
scrollToCurrentTheme()

binding.appIconRecyclerView.adapter = AppearanceIconSettingsAdapter(mainWidth, isSignedInAsPlus, state.currentAppIcon, state.iconList) { beforeAppIconType, afterAppIconType, validIcon ->
binding.appIconRecyclerView.adapter = AppearanceIconSettingsAdapter(mainWidth, viewModel.signInState.value, state.currentAppIcon, state.iconList) { beforeAppIconType, afterAppIconType, validIcon ->
if (validIcon) {
viewModel.updateGlobalIcon(afterAppIconType)

Expand All @@ -96,7 +97,7 @@ class AppearanceSettingsFragment : BaseFragment() {
.show()
} else {
viewModel.updateChangeAppIconType(Pair(beforeAppIconType, afterAppIconType))
openOnboardingFlow()
openOnboardingFlow(afterAppIconType.type)
}
}
binding.appIconRecyclerView.setHasFixedSize(true)
Expand Down Expand Up @@ -148,7 +149,7 @@ class AppearanceSettingsFragment : BaseFragment() {
}

(binding.themeRecyclerView.adapter as? AppearanceThemeSettingsAdapter)?.updatePlusSignedIn(signInState.isSignedInAsPlus)
(binding.appIconRecyclerView.adapter as? AppearanceIconSettingsAdapter)?.updatePlusSignedIn(signInState.isSignedInAsPlus)
(binding.appIconRecyclerView.adapter as? AppearanceIconSettingsAdapter)?.updatePlusSignedIn(signInState)
binding.upgradeGroup.isVisible = !signInState.isSignedInAsPlus && !settings.getUpgradeClosedAppearSettings()
}

Expand Down Expand Up @@ -191,8 +192,11 @@ class AppearanceSettingsFragment : BaseFragment() {
viewModel.onShown()
}

private fun openOnboardingFlow() {
OnboardingLauncher.openOnboardingFlow(activity, OnboardingFlow.PlusUpsell(OnboardingUpgradeSource.APPEARANCE))
private fun openOnboardingFlow(type: SubscriptionType? = null) {
val onboardingFlow = type?.takeIf { type == SubscriptionType.PATRON }?.let {
OnboardingFlow.PlusUpsell(source = OnboardingUpgradeSource.APPEARANCE, showPatronOnly = true)
} ?: OnboardingFlow.PlusUpsell(OnboardingUpgradeSource.APPEARANCE)
OnboardingLauncher.openOnboardingFlow(activity, onboardingFlow)
}

private fun scrollToCurrentTheme() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class AppearanceThemeSettingsAdapter(
if (showOption && selected) {
tickDrawable = AppCompatResources.getDrawable(itemView.context, R.drawable.ic_circle_tick)
} else if (!showOption) {
tickDrawable = AppCompatResources.getDrawable(itemView.context, R.drawable.ic_plus_bubble)
tickDrawable = AppCompatResources.getDrawable(itemView.context, R.drawable.ic_locked_plus)
}
binding.imgTick.setImageDrawable(tickDrawable)
binding.imgTick.contentDescription = binding.imgTick.resources.getString(if (selected) LR.string.on else LR.string.off)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ sealed class OnboardingFlow(val analyticsValue: String) : Parcelable {
@Parcelize object InitialOnboarding : OnboardingFlow("initial_onboarding")
@Parcelize class PlusAccountUpgrade(override val source: OnboardingUpgradeSource) : PlusFlow, OnboardingFlow("plus_account_upgrade")
@Parcelize object PlusAccountUpgradeNeedsLogin : OnboardingFlow("plus_account_upgrade_needs_login")
@Parcelize class PlusUpsell(override val source: OnboardingUpgradeSource) : PlusFlow, OnboardingFlow("plus_upsell")
@Parcelize class PlusUpsell(
override val source: OnboardingUpgradeSource,
val showPatronOnly: Boolean = false,
) : PlusFlow, OnboardingFlow(if (showPatronOnly) "patron_upsell" else "plus_upsell")
@Parcelize class PatronAccountUpgrade(override val source: OnboardingUpgradeSource) : PlusFlow, OnboardingFlow("patron_account_upgrade")

sealed interface PlusFlow {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.toLiveData
import au.com.shiftyjelly.pocketcasts.analytics.AnalyticsEvent
import au.com.shiftyjelly.pocketcasts.analytics.AnalyticsTrackerWrapper
import au.com.shiftyjelly.pocketcasts.analytics.BuildConfig
import au.com.shiftyjelly.pocketcasts.models.to.SignInState
import au.com.shiftyjelly.pocketcasts.preferences.Settings
import au.com.shiftyjelly.pocketcasts.repositories.podcast.UserEpisodeManager
Expand Down Expand Up @@ -64,11 +65,22 @@ class SettingsAppearanceViewModel @Inject constructor(

fun loadThemesAndIcons() {
createAccountState.postValue(SettingsAppearanceState.ThemesAndIconsLoading)

val appIcons = if (BuildConfig.ADD_PATRON_ENABLED) {
appIcon.allAppIconTypes.toList()
} else {
appIcon.allAppIconTypes.toList().filterNot {
it in listOf(
AppIcon.AppIconType.PATRON_CHROME,
AppIcon.AppIconType.PATRON_ROUND,
AppIcon.AppIconType.PATRON_GLOW,
AppIcon.AppIconType.PATRON_DARK,
)
}
}
createAccountState.postValue(
SettingsAppearanceState.ThemesAndIconsLoaded(
theme.activeTheme, theme.allThemes.toList(),
appIcon.activeAppIcon, appIcon.allAppIconTypes.toList()
appIcon.activeAppIcon, appIcons
)
)
}
Expand All @@ -94,6 +106,10 @@ class SettingsAppearanceViewModel @Inject constructor(
AppIcon.AppIconType.ELECTRIC_PINK -> "electric_pink"
AppIcon.AppIconType.RADIOACTIVE -> "radioactive"
AppIcon.AppIconType.HALLOWEEN -> "halloween"
AppIcon.AppIconType.PATRON_CHROME -> "patron_chrome"
AppIcon.AppIconType.PATRON_ROUND -> "patron_round"
AppIcon.AppIconType.PATRON_GLOW -> "patron_glow"
AppIcon.AppIconType.PATRON_DARK -> "patron_dark"
}
)
)
Expand Down
15 changes: 11 additions & 4 deletions modules/features/settings/src/main/res/drawable/ic_circle_tick.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<vector android:height="24dp" android:viewportHeight="30"
android:viewportWidth="30" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#03A9F4" android:pathData="M15,28.75C7.4061,28.75 1.25,22.5939 1.25,15C1.25,7.4061 7.4061,1.25 15,1.25C22.5939,1.25 28.75,7.4061 28.75,15C28.75,22.5939 22.5939,28.75 15,28.75Z"/>
<path android:fillColor="#ffffff" android:pathData="M19.0458,10.4426C19.4917,9.9156 20.2804,9.8499 20.8074,10.2958C21.3344,10.7417 21.4002,11.5304 20.9542,12.0575L13.2017,21.2195L8.4911,16.5089C8.0029,16.0208 8.0029,15.2293 8.4911,14.7411C8.9793,14.253 9.7707,14.253 10.2589,14.7411L13.0483,17.5305L19.0458,10.4426Z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M20,33.75C12.406,33.75 6.25,27.594 6.25,20C6.25,12.406 12.406,6.25 20,6.25C27.594,6.25 33.75,12.406 33.75,20C33.75,27.594 27.594,33.75 20,33.75Z"
android:fillColor="#03A9F4"/>
<path
android:pathData="M24.046,15.443C24.492,14.916 25.28,14.85 25.807,15.296C26.334,15.742 26.4,16.53 25.954,17.058L18.202,26.219L13.491,21.509C13.003,21.021 13.003,20.229 13.491,19.741C13.979,19.253 14.771,19.253 15.259,19.741L18.048,22.531L24.046,15.443Z"
android:fillColor="#ffffff"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M20.117,20.117m-13.749,-0.118a13.75,13.75 124.03,1 1,27.499 0.235a13.75,13.75 124.03,1 1,-27.499 -0.235"
android:fillColor="#6046F5"/>
<path
android:pathData="M16.75,18.031V17.5C16.75,15.705 18.205,14.25 20,14.25C21.795,14.25 23.25,15.705 23.25,17.5V18.031C23.681,18.142 24,18.534 24,19V24C24,24.552 23.552,25 23,25H17C16.448,25 16,24.552 16,24V19C16,18.534 16.319,18.142 16.75,18.031ZM18.25,17.5C18.25,16.534 19.034,15.75 20,15.75C20.966,15.75 21.75,16.534 21.75,17.5V18H18.25V17.5Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>
25 changes: 25 additions & 0 deletions modules/features/settings/src/main/res/drawable/ic_locked_plus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M20.117,20.117m-13.749,-0.118a13.75,13.75 124.03,1 1,27.499 0.235a13.75,13.75 124.03,1 1,-27.499 -0.235">
<aapt:attr name="android:fillColor">
<gradient
android:startX="8.941"
android:startY="6.271"
android:endX="33.794"
android:endY="8.635"
android:type="linear">
<item android:offset="0" android:color="#FFFED745"/>
<item android:offset="1" android:color="#FFFEB525"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M16.75,18.031V17.5C16.75,15.705 18.205,14.25 20,14.25C21.795,14.25 23.25,15.705 23.25,17.5V18.031C23.681,18.142 24,18.534 24,19V24C24,24.552 23.552,25 23,25H17C16.448,25 16,24.552 16,24V19C16,18.534 16.319,18.142 16.75,18.031ZM18.25,17.5C18.25,16.534 19.034,15.75 20,15.75C20.966,15.75 21.75,16.534 21.75,17.5V18H18.25V17.5Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

0 comments on commit 66e3d73

Please sign in to comment.