-
Notifications
You must be signed in to change notification settings - Fork 223
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Project] Up Next Shuffle - Update Shuffle Button for Free users (#3129)
- Loading branch information
Showing
5 changed files
with
155 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
...s/player/src/main/java/au/com/shiftyjelly/pocketcasts/player/viewmodel/UpNextViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package au.com.shiftyjelly.pocketcasts.player.viewmodel | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import au.com.shiftyjelly.pocketcasts.repositories.di.IoDispatcher | ||
import au.com.shiftyjelly.pocketcasts.repositories.user.UserManager | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.CoroutineDispatcher | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.reactive.asFlow | ||
|
||
@HiltViewModel | ||
class UpNextViewModel @Inject constructor( | ||
val userManager: UserManager, | ||
@IoDispatcher private val ioDispatcher: CoroutineDispatcher, | ||
) : ViewModel() { | ||
|
||
private val _isSignedInAsPaidUser = MutableStateFlow(false) | ||
val isSignedInAsPaidUser: StateFlow<Boolean> get() = _isSignedInAsPaidUser | ||
|
||
init { | ||
viewModelScope.launch(ioDispatcher) { | ||
userManager.getSignInState().asFlow().collect { signInState -> | ||
_isSignedInAsPaidUser.value = signInState.isSignedInAsPlusOrPatron | ||
} | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
...ayer/src/test/java/au/com/shiftyjelly/pocketcasts/player/viewmodel/UpNextViewModelTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package au.com.shiftyjelly.pocketcasts.player.viewmodel | ||
|
||
import au.com.shiftyjelly.pocketcasts.models.to.SignInState | ||
import au.com.shiftyjelly.pocketcasts.models.to.SubscriptionStatus | ||
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionFrequency | ||
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionPlatform | ||
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionTier | ||
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionType | ||
import au.com.shiftyjelly.pocketcasts.repositories.user.UserManager | ||
import io.reactivex.Flowable | ||
import java.util.Date | ||
import junit.framework.TestCase.assertEquals | ||
import kotlinx.coroutines.ExperimentalCoroutinesApi | ||
import kotlinx.coroutines.test.UnconfinedTestDispatcher | ||
import kotlinx.coroutines.test.runTest | ||
import org.junit.Test | ||
import org.mockito.kotlin.mock | ||
import org.mockito.kotlin.whenever | ||
|
||
class UpNextViewModelTest { | ||
|
||
@Test | ||
fun `initial state isSignedInAsPaidUser should be true for paid user`() = runTest { | ||
val viewModel = initViewModel(isPaidUser = true) | ||
|
||
assertEquals(true, viewModel.isSignedInAsPaidUser.value) | ||
} | ||
|
||
@Test | ||
fun `initial state isSignedInAsPaidUser should be false for free user`() = runTest { | ||
val viewModel = initViewModel(isPaidUser = false) | ||
|
||
assertEquals(false, viewModel.isSignedInAsPaidUser.value) | ||
} | ||
|
||
@OptIn(ExperimentalCoroutinesApi::class) | ||
private fun initViewModel( | ||
isPaidUser: Boolean = false, | ||
): UpNextViewModel { | ||
val userManager = mock<UserManager>() | ||
|
||
whenever(userManager.getSignInState()) | ||
.thenReturn( | ||
Flowable.just( | ||
SignInState.SignedIn( | ||
email = "", | ||
subscriptionStatus = if (isPaidUser) { | ||
SubscriptionStatus.Paid( | ||
expiry = Date(), | ||
autoRenew = true, | ||
giftDays = 0, | ||
frequency = SubscriptionFrequency.MONTHLY, | ||
platform = SubscriptionPlatform.ANDROID, | ||
subscriptionList = emptyList(), | ||
type = SubscriptionType.PLUS, | ||
tier = SubscriptionTier.PLUS, | ||
index = 0, | ||
) | ||
} else { | ||
SubscriptionStatus.Free() | ||
}, | ||
), | ||
), | ||
) | ||
return UpNextViewModel(userManager, UnconfinedTestDispatcher()) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
modules/services/images/src/main/res/drawable/shuffle_plus_feature_icon.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:aapt="http://schemas.android.com/aapt" | ||
android:width="24dp" | ||
android:height="24dp" | ||
android:viewportWidth="24" | ||
android:viewportHeight="24"> | ||
<path | ||
android:pathData="M2.961,16.523C2.961,16.07 3.313,15.742 3.797,15.742H5.578C6.445,15.742 7.008,15.438 7.68,14.641L9.578,12.383L7.68,10.125C7.008,9.328 6.398,9.023 5.523,9.023H3.797C3.313,9.023 2.961,8.695 2.961,8.242C2.961,7.789 3.313,7.469 3.797,7.469H5.586C6.922,7.469 7.766,7.859 8.688,8.945L10.578,11.195L12.398,9.031C13.391,7.844 14.242,7.461 15.633,7.461H17.188V5.617C17.188,5.234 17.414,5.023 17.789,5.023C17.961,5.023 18.117,5.078 18.25,5.188L21.313,7.742C21.609,8 21.609,8.375 21.313,8.617L18.25,11.172C18.117,11.273 17.961,11.336 17.789,11.336C17.414,11.336 17.188,11.117 17.188,10.742V9.023H15.625C14.719,9.023 14.172,9.313 13.492,10.117L11.578,12.383L13.484,14.641C14.148,15.438 14.75,15.742 15.672,15.742H17.188V14.055C17.188,13.672 17.414,13.461 17.789,13.461C17.961,13.461 18.117,13.516 18.25,13.625L21.313,16.18C21.609,16.438 21.609,16.813 21.313,17.055L18.25,19.609C18.117,19.711 17.961,19.773 17.789,19.773C17.414,19.773 17.188,19.555 17.188,19.18V17.297H15.625C14.281,17.297 13.391,16.906 12.445,15.781L10.578,13.57L8.688,15.82C7.766,16.906 6.977,17.297 5.633,17.297H3.797C3.313,17.297 2.961,16.977 2.961,16.523Z"> | ||
<aapt:attr name="android:fillColor"> | ||
<gradient | ||
android:startX="4.62" | ||
android:startY="5.023" | ||
android:endX="21.347" | ||
android:endY="6.846" | ||
android:type="linear"> | ||
<item android:offset="0" android:color="#FFFED745"/> | ||
<item android:offset="1" android:color="#FFFEB525"/> | ||
</gradient> | ||
</aapt:attr> | ||
</path> | ||
</vector> |