Add promotional apps section on ForYou page
This commit is contained in:
@@ -44,7 +44,7 @@ open class GenericCarouselController(private val callbacks: Callbacks) :
|
|||||||
open fun applyFilter(streamBundle: StreamCluster): Boolean {
|
open fun applyFilter(streamBundle: StreamCluster): Boolean {
|
||||||
return streamBundle.clusterTitle.isNotBlank() //Filter noisy cluster
|
return streamBundle.clusterTitle.isNotBlank() //Filter noisy cluster
|
||||||
&& streamBundle.clusterAppList.isNotEmpty() //Filter empty clusters
|
&& streamBundle.clusterAppList.isNotEmpty() //Filter empty clusters
|
||||||
&& streamBundle.clusterAppList.count() > 1 //Filter clusters with single apps (mostly promotions)
|
&& streamBundle.clusterAppList.count() >= 1 //Filter clusters with single apps (mostly promotions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildModels(streamBundle: StreamBundle?) {
|
override fun buildModels(streamBundle: StreamBundle?) {
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ import com.airbnb.epoxy.CallbackProp
|
|||||||
import com.airbnb.epoxy.ModelProp
|
import com.airbnb.epoxy.ModelProp
|
||||||
import com.airbnb.epoxy.ModelView
|
import com.airbnb.epoxy.ModelView
|
||||||
import com.airbnb.epoxy.OnViewRecycled
|
import com.airbnb.epoxy.OnViewRecycled
|
||||||
import com.aurora.gplayapi.data.models.Artwork
|
|
||||||
import com.aurora.store.R
|
|
||||||
import com.aurora.store.databinding.ViewScreenshotMiniBinding
|
|
||||||
import com.aurora.extensions.clear
|
import com.aurora.extensions.clear
|
||||||
import com.aurora.extensions.load
|
import com.aurora.extensions.load
|
||||||
import com.aurora.extensions.px
|
import com.aurora.extensions.px
|
||||||
|
import com.aurora.gplayapi.data.models.Artwork
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.databinding.ViewScreenshotMiniBinding
|
||||||
import com.aurora.store.view.epoxy.views.BaseView
|
import com.aurora.store.view.epoxy.views.BaseView
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
@@ -79,7 +79,11 @@ class MiniScreenshotView : RelativeLayout {
|
|||||||
@ModelProp
|
@ModelProp
|
||||||
fun artwork(artwork: Artwork) {
|
fun artwork(artwork: Artwork) {
|
||||||
normalizeSize(artwork)
|
normalizeSize(artwork)
|
||||||
B.img.load("${artwork.url}=rw-w480-v1-e15", DrawableTransitionOptions.withCrossFade()) {
|
val imgUrl = if (artwork.url.endsWith(".webp"))
|
||||||
|
artwork.url
|
||||||
|
else
|
||||||
|
"${artwork.url}=rw-w480-v1-e15"
|
||||||
|
B.img.load(imgUrl, DrawableTransitionOptions.withCrossFade()) {
|
||||||
placeholder(R.drawable.bg_rounded)
|
placeholder(R.drawable.bg_rounded)
|
||||||
transform(RoundedCorners(8.px.toInt()))
|
transform(RoundedCorners(8.px.toInt()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ import com.airbnb.epoxy.CallbackProp
|
|||||||
import com.airbnb.epoxy.ModelProp
|
import com.airbnb.epoxy.ModelProp
|
||||||
import com.airbnb.epoxy.ModelView
|
import com.airbnb.epoxy.ModelView
|
||||||
import com.airbnb.epoxy.OnViewRecycled
|
import com.airbnb.epoxy.OnViewRecycled
|
||||||
import com.aurora.gplayapi.data.models.Artwork
|
|
||||||
import com.aurora.store.R
|
|
||||||
import com.aurora.store.databinding.ViewScreenshotBinding
|
|
||||||
import com.aurora.extensions.clear
|
import com.aurora.extensions.clear
|
||||||
import com.aurora.extensions.load
|
import com.aurora.extensions.load
|
||||||
import com.aurora.extensions.px
|
import com.aurora.extensions.px
|
||||||
|
import com.aurora.gplayapi.data.models.Artwork
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.databinding.ViewScreenshotBinding
|
||||||
import com.aurora.store.view.epoxy.views.BaseView
|
import com.aurora.store.view.epoxy.views.BaseView
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
@@ -79,7 +79,11 @@ class ScreenshotView : RelativeLayout {
|
|||||||
@ModelProp
|
@ModelProp
|
||||||
fun artwork(artwork: Artwork) {
|
fun artwork(artwork: Artwork) {
|
||||||
normalizeSize(artwork)
|
normalizeSize(artwork)
|
||||||
B.img.load("${artwork.url}=rw-w480-v1-e15", DrawableTransitionOptions.withCrossFade()) {
|
val imgUrl = if (artwork.url.endsWith(".webp"))
|
||||||
|
artwork.url
|
||||||
|
else
|
||||||
|
"${artwork.url}=rw-w480-v1-e15"
|
||||||
|
B.img.load(imgUrl, DrawableTransitionOptions.withCrossFade()) {
|
||||||
placeholder(R.drawable.bg_rounded)
|
placeholder(R.drawable.bg_rounded)
|
||||||
transform(RoundedCorners(8.px.toInt()))
|
transform(RoundedCorners(8.px.toInt()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
B = ActivityDetailsBinding.inflate(layoutInflater)
|
B = ActivityDetailsBinding.inflate(layoutInflater)
|
||||||
|
authData = AuthProvider.with(this).getAuthData()
|
||||||
setContentView(B.root)
|
setContentView(B.root)
|
||||||
|
|
||||||
onNewIntent(intent)
|
onNewIntent(intent)
|
||||||
@@ -174,7 +175,9 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
} else {
|
} else {
|
||||||
isExternal = true
|
isExternal = true
|
||||||
app = App(packageName)
|
app = App(packageName)
|
||||||
fetchCompleteApp()
|
if (app.inPlayStore) {
|
||||||
|
fetchCompleteApp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val rawApp: String? = intent.getStringExtra(Constants.STRING_EXTRA)
|
val rawApp: String? = intent.getStringExtra(Constants.STRING_EXTRA)
|
||||||
@@ -183,7 +186,11 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
isInstalled = PackageUtil.isInstalled(this, app.packageName)
|
isInstalled = PackageUtil.isInstalled(this, app.packageName)
|
||||||
|
|
||||||
inflatePartialApp()
|
inflatePartialApp()
|
||||||
fetchCompleteApp()
|
if (app.inPlayStore) {
|
||||||
|
fetchCompleteApp()
|
||||||
|
} else {
|
||||||
|
inflateExtraDetails(app)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
@@ -317,7 +324,6 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
|
|
||||||
private fun fetchCompleteApp() {
|
private fun fetchCompleteApp() {
|
||||||
task {
|
task {
|
||||||
authData = AuthProvider.with(this).getAuthData()
|
|
||||||
return@task AppDetailsHelper(authData)
|
return@task AppDetailsHelper(authData)
|
||||||
.using(HttpClient.getPreferredClient())
|
.using(HttpClient.getPreferredClient())
|
||||||
.getAppByPackageName(app.packageName)
|
.getAppByPackageName(app.packageName)
|
||||||
@@ -379,23 +385,30 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
app?.let {
|
app?.let {
|
||||||
B.viewFlipper.displayedChild = 1
|
B.viewFlipper.displayedChild = 1
|
||||||
inflateAppDescription(B.layoutDetailDescription, app)
|
inflateAppDescription(B.layoutDetailDescription, app)
|
||||||
inflateAppRatingAndReviews(B.layoutDetailsReview, app)
|
|
||||||
inflateAppDevInfo(B.layoutDetailsDev, app)
|
inflateAppDevInfo(B.layoutDetailsDev, app)
|
||||||
inflateAppPrivacy(B.layoutDetailsPrivacy, app)
|
inflateAppPrivacy(B.layoutDetailsPrivacy, app)
|
||||||
inflateAppPermission(B.layoutDetailsPermissions, app)
|
inflateAppPermission(B.layoutDetailsPermissions, app)
|
||||||
|
|
||||||
if (!authData.isAnonymous) {
|
if (app.inPlayStore) {
|
||||||
app.testingProgram?.let {
|
inflateAppRatingAndReviews(B.layoutDetailsReview, app)
|
||||||
if (it.isAvailable && it.isSubscribed) {
|
if (!authData.isAnonymous) {
|
||||||
B.layoutDetailsApp.txtLine1.text = it.displayName
|
app.testingProgram?.let {
|
||||||
|
if (it.isAvailable && it.isSubscribed) {
|
||||||
|
B.layoutDetailsApp.txtLine1.text = it.displayName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inflateBetaSubscription(B.layoutDetailsBeta, app)
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateBetaSubscription(B.layoutDetailsBeta, app)
|
if (Preferences.getBoolean(this, Preferences.PREFERENCE_SIMILAR)) {
|
||||||
}
|
inflateAppStream(B.epoxyRecyclerStream, app)
|
||||||
|
}
|
||||||
if (Preferences.getBoolean(this, Preferences.PREFERENCE_SIMILAR)) {
|
} else {
|
||||||
inflateAppStream(B.epoxyRecyclerStream, app)
|
B.layoutDetailsReview.root.hide()
|
||||||
|
B.layoutDetailsBeta.root.hide()
|
||||||
|
B.epoxyRecyclerStream.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,13 +438,16 @@ class AppDetailsActivity : BaseDetailsActivity() {
|
|||||||
updateActionState(State.PROGRESS)
|
updateActionState(State.PROGRESS)
|
||||||
|
|
||||||
task {
|
task {
|
||||||
val authData = AuthProvider
|
if (app.inPlayStore) {
|
||||||
.with(this)
|
PurchaseHelper(authData)
|
||||||
.getAuthData()
|
.using(HttpClient.getPreferredClient())
|
||||||
|
.purchase(app.packageName, app.versionCode, app.offerType)
|
||||||
PurchaseHelper(authData)
|
} else {
|
||||||
.using(HttpClient.getPreferredClient())
|
val metaFile = app.fileList[0]
|
||||||
.purchase(app.packageName, app.versionCode, app.offerType)
|
val fileList: MutableList<File> = mutableListOf()
|
||||||
|
fileList.add(metaFile)
|
||||||
|
fileList
|
||||||
|
}
|
||||||
} successUi { files ->
|
} successUi { files ->
|
||||||
if (files.isNotEmpty()) {
|
if (files.isNotEmpty()) {
|
||||||
var hasOBB = false
|
var hasOBB = false
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ abstract class BaseClusterViewModel(application: Application) : BaseAndroidViewM
|
|||||||
val liveData: MutableLiveData<ViewState> = MutableLiveData()
|
val liveData: MutableLiveData<ViewState> = MutableLiveData()
|
||||||
var streamBundle: StreamBundle = StreamBundle()
|
var streamBundle: StreamBundle = StreamBundle()
|
||||||
|
|
||||||
|
/* Should certainly do it in a better way :(*/
|
||||||
|
var promotionsAdded: Boolean = false
|
||||||
|
|
||||||
lateinit var type: StreamHelper.Type
|
lateinit var type: StreamHelper.Type
|
||||||
lateinit var category: StreamHelper.Category
|
lateinit var category: StreamHelper.Category
|
||||||
|
|
||||||
@@ -72,6 +75,13 @@ abstract class BaseClusterViewModel(application: Application) : BaseAndroidViewM
|
|||||||
type
|
type
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Add promotional cluster
|
||||||
|
if (!promotionsAdded) {
|
||||||
|
val promotionalCluster = promotionalCluster()
|
||||||
|
newBundle.streamClusters[promotionalCluster.id] = promotionalCluster
|
||||||
|
promotionsAdded = true
|
||||||
|
}
|
||||||
|
|
||||||
//Update old bundle
|
//Update old bundle
|
||||||
streamBundle.apply {
|
streamBundle.apply {
|
||||||
streamClusters.putAll(newBundle.streamClusters)
|
streamClusters.putAll(newBundle.streamClusters)
|
||||||
@@ -118,4 +128,15 @@ abstract class BaseClusterViewModel(application: Application) : BaseAndroidViewM
|
|||||||
clusterNextPageUrl = newCluster.clusterNextPageUrl
|
clusterNextPageUrl = newCluster.clusterNextPageUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun promotionalCluster(): StreamCluster {
|
||||||
|
val response = HttpClient.getPreferredClient().get(
|
||||||
|
"https://promotions.auroraoss.com",
|
||||||
|
hashMapOf()
|
||||||
|
)
|
||||||
|
return if (response.isSuccessful)
|
||||||
|
gson.fromJson(String(response.responseBytes), StreamCluster::class.java)
|
||||||
|
else
|
||||||
|
StreamCluster()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user