legacy: remove Epoxy views and custom view layouts

Drops the Epoxy carousel controllers, view models, shimmer placeholders,
custom layouts (ActionHeader, StateButton, UpdateButton) and bespoke
preference helpers, all now superseded by the Compose composables.
This commit is contained in:
Rahul Patel
2026-05-19 12:13:42 +05:30
parent 0270dc6f39
commit fef75cb5b3
25 changed files with 0 additions and 1735 deletions

View File

@@ -1,82 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.custom.layouts
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.RelativeLayout
import com.aurora.store.R
import com.aurora.store.databinding.ViewActionHeaderBinding
class ActionHeaderLayout : RelativeLayout {
private lateinit var binding: ViewActionHeaderBinding
constructor(context: Context) : super(context) {
init(context, null)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context, attrs)
}
private fun init(context: Context, attrs: AttributeSet?) {
val view = inflate(context, R.layout.view_action_header, this)
binding = ViewActionHeaderBinding.bind(view)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ActionHeaderLayout)
val textTitle = typedArray.getString(R.styleable.ActionHeaderLayout_headerTitle)
val textSubtitle = typedArray.getString(R.styleable.ActionHeaderLayout_headerSubtitle)
typedArray.recycle()
textTitle?.let {
binding.txtTitle.text = it
}
textSubtitle?.let {
binding.txtSubtitle.visibility = View.VISIBLE
binding.txtSubtitle.text = it
}
}
fun setTitle(header: String?) {
binding.txtTitle.text = header
}
fun setSubTitle(subHeader: String?) {
binding.txtSubtitle.visibility = View.VISIBLE
binding.txtSubtitle.text = subHeader
}
fun addClickListener(onclickListener: OnClickListener?) {
binding.imgAction.visibility = View.VISIBLE
binding.imgAction.setOnClickListener(onclickListener)
}
}

View File

@@ -1,77 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.custom.layouts.button
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
import com.aurora.store.R
import com.aurora.store.databinding.ViewStateButtonBinding
class StateButton : RelativeLayout {
private lateinit var binding: ViewStateButtonBinding
constructor(context: Context) : super(context) {
init(context, null)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context, attrs)
}
private fun init(context: Context, attrs: AttributeSet?) {
val view = inflate(context, R.layout.view_state_button, this)
binding = ViewStateButtonBinding.bind(view)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.StateButton)
val btnTxt = typedArray.getString(R.styleable.StateButton_btnStateText)
val btnIcon = typedArray.getResourceId(
R.styleable.StateButton_btnStateIcon,
R.drawable.ic_arrow_right
)
binding.btn.text = btnTxt
binding.btn.icon = ContextCompat.getDrawable(context, btnIcon)
typedArray.recycle()
}
fun updateProgress(isVisible: Boolean) {
if (isVisible) {
binding.progress.visibility = View.VISIBLE
} else {
binding.progress.visibility = View.INVISIBLE
}
}
fun addOnClickListener(onClickListener: OnClickListener) {
binding.btn.setOnClickListener(onClickListener)
}
}

View File

@@ -1,81 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.custom.layouts.button
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
import com.aurora.extensions.runOnUiThread
import com.aurora.store.R
import com.aurora.store.data.model.DownloadStatus
import com.aurora.store.databinding.ViewUpdateButtonBinding
class UpdateButton : RelativeLayout {
private lateinit var binding: ViewUpdateButtonBinding
constructor(context: Context) : super(context) {
init(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context)
}
private fun init(context: Context) {
val view = inflate(context, R.layout.view_update_button, this)
binding = ViewUpdateButtonBinding.bind(view)
}
fun updateState(downloadStatus: DownloadStatus) {
val displayChild = when (downloadStatus) {
DownloadStatus.QUEUED,
DownloadStatus.DOWNLOADING,
DownloadStatus.VERIFYING -> 1
else -> 0
}
if (binding.viewFlipper.displayedChild != displayChild) {
runOnUiThread {
binding.viewFlipper.displayedChild = displayChild
}
}
// Not allowed to cancel installation at this point
binding.btnNegative.isEnabled = downloadStatus != DownloadStatus.VERIFYING
}
fun addPositiveOnClickListener(onClickListener: OnClickListener?) {
binding.btnPositive.setOnClickListener(onClickListener)
}
fun addNegativeOnClickListener(onClickListener: OnClickListener?) {
binding.btnNegative.setOnClickListener(onClickListener)
}
}

View File

@@ -1,50 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.custom.preference
import android.content.Context
import android.util.AttributeSet
import androidx.preference.ListPreference
class AuroraListPreference : ListPreference {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
override fun getPersistedString(defaultReturnValue: String?): String =
getPersistedInt(defaultReturnValue?.toInt() ?: -1).toString()
override fun persistString(value: String?): Boolean =
if (value != null) persistInt(Integer.valueOf(value)) else false
}

View File

@@ -1,46 +0,0 @@
package com.aurora.store.view.custom.preference
import android.app.Dialog
import android.os.Bundle
import android.view.WindowManager
import androidx.preference.EditTextPreferenceDialogFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class M3EditTextPreference : EditTextPreferenceDialogFragmentCompat() {
companion object {
const val PREFERENCE_DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG"
fun newInstance(key: String?): M3EditTextPreference {
val fragment = M3EditTextPreference()
val bundle = Bundle(1)
bundle.putString(ARG_KEY, key)
fragment.arguments = bundle
return fragment
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = MaterialAlertDialogBuilder(requireContext())
.setTitle(preference.dialogTitle)
.setIcon(preference.dialogIcon)
.setPositiveButton(preference.positiveButtonText, this)
.setNegativeButton(preference.negativeButtonText, this)
val contentView = onCreateDialogView(requireContext())
if (contentView != null) {
onBindDialogView(contentView)
builder.setView(contentView)
} else {
builder.setMessage(preference.dialogMessage)
}
onPrepareDialogBuilder(builder)
return builder.create()
}
override fun onResume() {
super.onResume()
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
}

View File

@@ -1,40 +0,0 @@
package com.aurora.store.view.custom.preference
import android.app.Dialog
import android.os.Bundle
import androidx.preference.ListPreferenceDialogFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class M3ListPreference : ListPreferenceDialogFragmentCompat() {
companion object {
const val PREFERENCE_DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG"
fun newInstance(key: String?): M3ListPreference {
val fragment = M3ListPreference()
val bundle = Bundle(1)
bundle.putString(ARG_KEY, key)
fragment.arguments = bundle
return fragment
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = MaterialAlertDialogBuilder(requireContext())
.setTitle(preference.dialogTitle)
.setIcon(preference.dialogIcon)
.setPositiveButton(preference.positiveButtonText, this)
.setNegativeButton(preference.negativeButtonText, this)
val contentView = onCreateDialogView(requireContext())
if (contentView != null) {
onBindDialogView(contentView)
builder.setView(contentView)
} else {
builder.setMessage(preference.dialogMessage)
}
onPrepareDialogBuilder(builder)
return builder.create()
}
}

View File

@@ -1,173 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.custom.recycler
import android.view.View
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
abstract class EndlessRecyclerOnScrollListener : RecyclerView.OnScrollListener {
private var enabled = true
private var previousTotal = 0
private var isLoading = true
private var visibleThreshold = RecyclerView.NO_POSITION
var firstVisibleItem: Int = 0
private set
var visibleItemCount: Int = 0
private set
var totalItemCount: Int = 0
private set
private var isOrientationHelperVertical: Boolean = false
private var orientationHelper: OrientationHelper? = null
var currentPage = 0
private set
lateinit var layoutManager: RecyclerView.LayoutManager
private set
constructor()
constructor(visibleThreshold: Int) {
this.visibleThreshold = visibleThreshold
}
private fun findFirstVisibleItemPosition(recyclerView: RecyclerView): Int {
val child = findOneVisibleChild(0, layoutManager.childCount, true, false)
return if (child == null) {
RecyclerView.NO_POSITION
} else {
recyclerView.getChildAdapterPosition(child)
}
}
private fun findLastVisibleItemPosition(recyclerView: RecyclerView): Int {
val child = findOneVisibleChild(recyclerView.childCount - 1, -1, false, true)
return if (child == null) {
RecyclerView.NO_POSITION
} else {
recyclerView.getChildAdapterPosition(child)
}
}
private fun findOneVisibleChild(
fromIndex: Int,
toIndex: Int,
completelyVisible: Boolean,
acceptPartiallyVisible: Boolean
): View? {
if (layoutManager.canScrollVertically() != isOrientationHelperVertical ||
orientationHelper == null
) {
isOrientationHelperVertical = layoutManager.canScrollVertically()
orientationHelper = if (isOrientationHelperVertical) {
OrientationHelper.createVerticalHelper(layoutManager)
} else {
OrientationHelper.createHorizontalHelper(layoutManager)
}
}
val mOrientationHelper = this.orientationHelper ?: return null
val start = mOrientationHelper.startAfterPadding
val end = mOrientationHelper.endAfterPadding
val next = if (toIndex > fromIndex) 1 else -1
var partiallyVisible: View? = null
var i = fromIndex
while (i != toIndex) {
val child = layoutManager.getChildAt(i)
if (child != null) {
val childStart = mOrientationHelper.getDecoratedStart(child)
val childEnd = mOrientationHelper.getDecoratedEnd(child)
if (childStart < end && childEnd > start) {
if (completelyVisible) {
if (childStart >= start && childEnd <= end) {
return child
} else if (acceptPartiallyVisible && partiallyVisible == null) {
partiallyVisible = child
}
} else {
return child
}
}
}
i += next
}
return partiallyVisible
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (enabled) {
if (!::layoutManager.isInitialized) {
layoutManager = recyclerView.layoutManager
?: throw RuntimeException("A LayoutManager is required")
}
if (visibleThreshold == RecyclerView.NO_POSITION) {
visibleThreshold = findLastVisibleItemPosition(recyclerView) -
findFirstVisibleItemPosition(recyclerView)
}
visibleItemCount = recyclerView.childCount
totalItemCount = layoutManager.itemCount
firstVisibleItem = findFirstVisibleItemPosition(recyclerView)
if (isLoading) {
if (totalItemCount > previousTotal) {
isLoading = false
previousTotal = totalItemCount
}
}
if (!isLoading &&
totalItemCount - visibleItemCount <= firstVisibleItem + visibleThreshold
) {
currentPage++
onLoadMore(currentPage)
isLoading = true
}
}
}
fun enable(): EndlessRecyclerOnScrollListener {
enabled = true
return this
}
fun disable(): EndlessRecyclerOnScrollListener {
enabled = false
return this
}
@JvmOverloads
fun resetPageCount(page: Int = 0) {
previousTotal = 0
isLoading = true
currentPage = page
onLoadMore(currentPage)
}
abstract fun onLoadMore(currentPage: Int)
}

View File

@@ -1,29 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.controller
import com.aurora.gplayapi.data.models.StreamCluster
class CategoryCarouselController(callbacks: Callbacks) : GenericCarouselController(callbacks) {
override fun applyFilter(streamBundle: StreamCluster): Boolean {
return streamBundle.clusterAppList.isNotEmpty() // Filter empty clusters
}
}

View File

@@ -1,102 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.controller
import com.airbnb.epoxy.TypedEpoxyController
import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.StreamBundle
import com.aurora.gplayapi.data.models.StreamCluster
import com.aurora.store.R
import com.aurora.store.view.epoxy.groups.CarouselModelGroup
import com.aurora.store.view.epoxy.groups.CarouselShimmerGroup
import com.aurora.store.view.epoxy.views.app.AppListViewModel_
import com.aurora.store.view.epoxy.views.app.NoAppViewModel_
open class GenericCarouselController(private val callbacks: Callbacks) :
TypedEpoxyController<StreamBundle?>() {
interface Callbacks {
fun onHeaderClicked(streamCluster: StreamCluster)
fun onClusterScrolled(streamCluster: StreamCluster)
fun onAppClick(app: App)
fun onAppLongClick(app: App)
}
open fun applyFilter(streamBundle: StreamCluster): Boolean {
return streamBundle.clusterTitle.isNotBlank() &&
// Filter noisy cluster
streamBundle.clusterAppList.isNotEmpty() &&
// Filter empty clusters
streamBundle.clusterAppList.count() > 1 // Filter clusters with single apps (promotions)
}
override fun buildModels(streamBundle: StreamBundle?) {
setFilterDuplicates(true)
if (streamBundle == null) {
for (i in 1..4) {
add(
CarouselShimmerGroup()
.id(i)
)
}
} else {
if (streamBundle.streamClusters.isEmpty()) {
add(
NoAppViewModel_()
.id("no_app")
.icon(R.drawable.ic_apps)
.message(R.string.no_apps_available)
)
} else {
if (streamBundle.streamClusters.size == 1) {
streamBundle
.streamClusters
.values
.filter { applyFilter(it) }
.forEach { streamCluster ->
streamCluster.clusterAppList.forEach {
add(
AppListViewModel_()
.id(it.id)
.app(it)
.click { _ -> callbacks.onAppClick(it) }
)
}
}
} else {
streamBundle
.streamClusters
.values
.filter { applyFilter(it) }
.forEach { streamCluster ->
add(CarouselModelGroup(streamCluster, callbacks))
}
}
if (streamBundle.hasNext()) {
add(
CarouselShimmerGroup()
.id("progress")
)
}
}
}
}
}

View File

@@ -1,35 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.groups
import android.content.Context
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.airbnb.epoxy.Carousel
import com.airbnb.epoxy.ModelView
@ModelView(saveViewState = true, autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
class CarouselHorizontal(context: Context?) : Carousel(context) {
override fun createLayoutManager(): LayoutManager =
LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
override fun getSnapHelperFactory(): Nothing? = null
}

View File

@@ -1,105 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.groups
import android.util.Log
import com.airbnb.epoxy.EpoxyModel
import com.airbnb.epoxy.EpoxyModelGroup
import com.aurora.gplayapi.data.models.StreamCluster
import com.aurora.store.R
import com.aurora.store.view.epoxy.controller.GenericCarouselController
import com.aurora.store.view.epoxy.views.HeaderViewModel_
import com.aurora.store.view.epoxy.views.app.AppViewModel_
import com.aurora.store.view.epoxy.views.shimmer.AppViewShimmerModel_
class CarouselModelGroup(
streamCluster: StreamCluster,
callbacks: GenericCarouselController.Callbacks
) :
EpoxyModelGroup(
R.layout.model_carousel_group,
buildModels(
streamCluster,
callbacks
)
) {
companion object {
private const val TAG = "CarouselModelGroup"
private fun buildModels(
streamCluster: StreamCluster,
callbacks: GenericCarouselController.Callbacks
): List<EpoxyModel<*>> {
val models = ArrayList<EpoxyModel<*>>()
val clusterViewModels = mutableListOf<EpoxyModel<*>>()
val idPrefix = streamCluster.clusterTitle.hashCode()
models.add(
HeaderViewModel_()
.id("${idPrefix}_header")
.title(streamCluster.clusterTitle)
.browseUrl(streamCluster.clusterBrowseUrl)
.click { _ ->
callbacks.onHeaderClicked(streamCluster)
}
)
for (app in streamCluster.clusterAppList) {
clusterViewModels.add(
AppViewModel_()
.id(app.id)
.app(app)
.click { _ ->
callbacks.onAppClick(app)
}
.longClick { _ ->
callbacks.onAppLongClick(app)
false
}
.onBind { _, _, position ->
val itemCount = clusterViewModels.count()
if (itemCount >= 2) {
if (position == clusterViewModels.count() - 2) {
callbacks.onClusterScrolled(streamCluster)
Log.i(TAG, "Cluster ${streamCluster.clusterTitle} Scrolled")
}
}
}
)
}
if (streamCluster.hasNext()) {
clusterViewModels.add(
AppViewShimmerModel_()
.id("${idPrefix}_progress")
)
}
models.add(
CarouselHorizontalModel_()
.id("${idPrefix}_cluster")
.models(clusterViewModels)
)
return models
}
}
}

View File

@@ -1,60 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.groups
import com.airbnb.epoxy.EpoxyModel
import com.airbnb.epoxy.EpoxyModelGroup
import com.aurora.store.R
import com.aurora.store.view.epoxy.views.shimmer.AppViewShimmerModel_
import com.aurora.store.view.epoxy.views.shimmer.HeaderViewShimmerModel_
import java.util.UUID
class CarouselShimmerGroup :
EpoxyModelGroup(
R.layout.model_carousel_group,
buildModels()
) {
companion object {
private fun buildModels(): List<EpoxyModel<*>> {
val models = ArrayList<EpoxyModel<*>>()
val clusterViewModels = mutableListOf<EpoxyModel<*>>()
val idPrefix = UUID.randomUUID()
for (i in 1..8) {
clusterViewModels.add(
AppViewShimmerModel_()
.id(i)
)
}
models.add(
HeaderViewShimmerModel_()
.id("shimmer_header")
)
models.add(
CarouselHorizontalModel_()
.id("cluster_$idPrefix")
.models(clusterViewModels)
)
return models
}
}
}

View File

@@ -1,32 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.ModelView
import com.aurora.store.databinding.ViewAppProgressBinding
@ModelView(autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT)
class AppProgressView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppProgressBinding>(context, attrs, defStyleAttr)

View File

@@ -1,50 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views
import android.view.View
import android.view.animation.AnimationUtils
import com.airbnb.epoxy.EpoxyModel
import com.aurora.store.view.epoxy.views.app.AppListView
abstract class BaseModel<T : View> : EpoxyModel<T>() {
override fun bind(view: T) {
super.bind(view)
when (view) {
is AppListView -> {
view.startAnimation(
AnimationUtils.loadAnimation(
view.context,
android.R.anim.fade_in
)
)
}
}
}
override fun unbind(view: T) {
when (view) {
is AppListView -> {
view.clearAnimation()
}
}
}
}

View File

@@ -1,51 +0,0 @@
package com.aurora.store.view.epoxy.views
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType
abstract class BaseView<ViewBindingType : ViewBinding> : RelativeLayout {
private lateinit var _binding: ViewBindingType
protected val binding get() = _binding
constructor(context: Context?) : super(context) {
init(context)
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
init(context)
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context)
}
private fun init(context: Context?) {
if (context != null) {
_binding = inflateViewBinding(LayoutInflater.from(context))
addView(_binding.root)
}
}
@Suppress("UNCHECKED_CAST")
private fun inflateViewBinding(inflater: LayoutInflater): ViewBindingType {
val type = (javaClass.genericSuperclass as ParameterizedType)
.actualTypeArguments[0] as Class<ViewBindingType>
val method = type.getMethod(
"inflate",
LayoutInflater::class.java,
ViewGroup::class.java,
Boolean::class.java
)
return method.invoke(null, inflater, this, false) as ViewBindingType
}
}

View File

@@ -1,51 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views
import android.content.Context
import android.util.AttributeSet
import coil3.load
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.aurora.gplayapi.data.models.Category
import com.aurora.store.databinding.ViewCategoryBinding
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class CategoryView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewCategoryBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun category(category: Category) {
binding.txtName.text = category.title
binding.imgBackground.load(category.imageUrl)
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.root.setOnClickListener(onClickListener)
}
}

View File

@@ -1,62 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.epoxy.OnViewRecycled
import com.aurora.store.databinding.ViewHeaderBinding
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class HeaderView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewHeaderBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun title(title: String) {
binding.txtTitle.text = title
}
@JvmOverloads
@ModelProp
fun browseUrl(browseUrl: String? = String()) {
if (browseUrl.isNullOrEmpty()) {
binding.imgAction.visibility = INVISIBLE
}
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.root.setOnClickListener(onClickListener)
}
@OnViewRecycled
fun clear() {
binding.imgAction.visibility = VISIBLE
}
}

View File

@@ -1,59 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.epoxy.OnViewRecycled
import com.aurora.store.databinding.ViewHeaderUpdateBinding
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class UpdateHeaderView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewHeaderUpdateBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun title(title: String) {
binding.txtTitle.text = title
}
@ModelProp
fun action(action: String) {
binding.btnAction.text = action
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.btnAction.setOnClickListener(onClickListener)
}
@OnViewRecycled
fun clear() {
binding.btnAction.isEnabled = true
}
}

View File

@@ -1,90 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.app
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.ContextCompat
import coil3.load
import coil3.request.placeholder
import coil3.request.transformations
import coil3.transform.RoundedCornersTransformation
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.aurora.gplayapi.data.models.App
import com.aurora.store.R
import com.aurora.store.databinding.ViewAppListBinding
import com.aurora.store.util.CommonUtil
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class AppListView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppListBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun app(app: App) {
binding.imgIcon.load(app.iconArtwork.url) {
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(25F))
}
binding.txtLine1.text = app.displayName
binding.txtLine2.text = app.developerName
val extras: MutableList<String> = mutableListOf()
extras.add(if (app.size > 0) CommonUtil.addSiPrefix(app.size) else app.downloadString)
extras.add("${app.labeledRating}")
extras.add(
if (app.isFree) {
ContextCompat.getString(context, R.string.details_free)
} else {
ContextCompat.getString(context, R.string.details_paid)
}
)
if (app.containsAds) {
extras.add(ContextCompat.getString(context, R.string.details_contains_ads))
}
if (app.dependencies.dependentPackages.isNotEmpty()) {
extras.add(ContextCompat.getString(context, R.string.details_gsf_dependent))
}
binding.txtLine3.text = extras.joinToString(separator = "")
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.root.setOnClickListener(onClickListener)
}
@CallbackProp
fun longClick(onClickListener: OnLongClickListener?) {
binding.root.setOnLongClickListener(onClickListener)
}
}

View File

@@ -1,205 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.app
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.core.view.isVisible
import coil3.asDrawable
import coil3.load
import coil3.request.placeholder
import coil3.request.transformations
import coil3.transform.CircleCropTransformation
import coil3.transform.RoundedCornersTransformation
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.epoxy.OnViewRecycled
import com.aurora.extensions.invisible
import com.aurora.extensions.px
import com.aurora.store.R
import com.aurora.store.data.model.DownloadStatus
import com.aurora.store.data.room.download.Download
import com.aurora.store.data.room.update.Update
import com.aurora.store.databinding.ViewAppUpdateBinding
import com.aurora.store.util.CommonUtil
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class AppUpdateView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppUpdateBinding>(context, attrs, defStyleAttr) {
private var iconDrawable: Drawable? = null
private val cornersTransformation = RoundedCornersTransformation(8.px.toFloat())
@ModelProp
fun update(update: Update) {
/*Inflate App details*/
with(update) {
binding.txtLine1.text = displayName
binding.imgIcon.load(iconURL) {
placeholder(R.drawable.bg_placeholder)
transformations(cornersTransformation)
listener { _, result ->
result.image.asDrawable(resources).let { iconDrawable = it }
}
}
binding.txtLine2.text = developerName
binding.txtLine3.text = ("${CommonUtil.addSiPrefix(size)}$updatedOn")
binding.txtLine4.text = ("$versionName ($versionCode)")
binding.txtChangelog.text = if (changelog.isNotEmpty()) {
HtmlCompat.fromHtml(
changelog,
HtmlCompat.FROM_HTML_OPTION_USE_CSS_COLORS
)
} else {
context.getString(R.string.details_changelog_unavailable)
}
binding.headerIndicator.setOnClickListener {
if (binding.cardChangelog.isVisible) {
binding.headerIndicator.icon =
ContextCompat.getDrawable(context, R.drawable.ic_arrow_down)
binding.cardChangelog.visibility = View.GONE
} else {
binding.headerIndicator.icon =
ContextCompat.getDrawable(context, R.drawable.ic_arrow_up)
binding.cardChangelog.visibility = View.VISIBLE
}
}
}
}
@ModelProp
fun download(download: Download?) {
if (download != null) {
binding.btnAction.updateState(download.status)
when (download.status) {
DownloadStatus.VERIFYING,
DownloadStatus.QUEUED -> {
binding.progressDownload.isIndeterminate = true
animateImageView(scaleFactor = 0.75f)
}
DownloadStatus.DOWNLOADING -> {
binding.progressDownload.isIndeterminate = false
binding.progressDownload.progress = download.progress
animateImageView(scaleFactor = 0.75f)
}
else -> {
binding.progressDownload.isIndeterminate = true
animateImageView(scaleFactor = 1f)
}
}
}
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.layoutContent.setOnClickListener(onClickListener)
}
@CallbackProp
fun positiveAction(onClickListener: OnClickListener?) {
binding.btnAction.addPositiveOnClickListener(onClickListener)
}
@CallbackProp
fun negativeAction(onClickListener: OnClickListener?) {
binding.btnAction.addNegativeOnClickListener(onClickListener)
}
@CallbackProp
fun longClick(onClickListener: OnLongClickListener?) {
binding.layoutContent.setOnLongClickListener(onClickListener)
}
@OnViewRecycled
fun clear() {
iconDrawable = null
binding.apply {
headerIndicator.removeCallbacks {}
progressDownload.invisible()
btnAction.apply {
removeCallbacks { }
updateState(DownloadStatus.UNAVAILABLE)
}
}
}
private fun animateImageView(scaleFactor: Float = 1f) {
val isDownloadVisible = binding.progressDownload.isShown
// Avoids flickering when the download is in progress
if (isDownloadVisible && scaleFactor != 1f) {
return
}
if (!isDownloadVisible && scaleFactor == 1f) {
return
}
if (scaleFactor == 1f) {
binding.progressDownload.invisible()
} else {
binding.progressDownload.show()
}
val scale = listOf(
ObjectAnimator.ofFloat(binding.imgIcon, "scaleX", scaleFactor),
ObjectAnimator.ofFloat(binding.imgIcon, "scaleY", scaleFactor)
)
scale.forEach { animation ->
animation.apply {
interpolator = AccelerateDecelerateInterpolator()
duration = 250
start()
}
}
iconDrawable?.let {
binding.imgIcon.load(it) {
transformations(
if (scaleFactor == 1f) {
cornersTransformation
} else {
CircleCropTransformation()
}
)
}
}
}
}

View File

@@ -1,72 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.app
import android.content.Context
import android.util.AttributeSet
import coil3.load
import coil3.request.placeholder
import coil3.request.transformations
import coil3.transform.RoundedCornersTransformation
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.aurora.gplayapi.data.models.App
import com.aurora.store.R
import com.aurora.store.databinding.ViewAppBinding
import com.aurora.store.util.CommonUtil
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class AppView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun app(app: App) {
binding.txtName.text = app.displayName
binding.imgIcon.load(app.iconArtwork.url) {
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(32F))
}
if (app.size > 0) {
binding.txtSize.text = CommonUtil.addSiPrefix(app.size)
} else {
binding.txtSize.text = app.downloadString
}
}
@CallbackProp
fun click(onClickListener: OnClickListener?) {
binding.root.setOnClickListener(onClickListener)
}
@CallbackProp
fun longClick(onClickListener: OnLongClickListener?) {
binding.root.setOnLongClickListener(onClickListener)
}
}

View File

@@ -1,72 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.app
import android.content.Context
import android.util.AttributeSet
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import coil3.load
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.aurora.store.databinding.ViewNoAppBinding
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.MATCH_WIDTH_MATCH_HEIGHT,
baseModelClass = BaseModel::class
)
class NoAppView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewNoAppBinding>(context, attrs, defStyleAttr) {
@ModelProp
fun message(@StringRes message: Int) {
binding.txt.text = context.getString(message)
}
@ModelProp
fun icon(@DrawableRes icon: Int) {
binding.img.load(icon)
}
@JvmOverloads
@ModelProp
fun showAction(visibility: Boolean = false) {
binding.button.isVisible = visibility
}
@JvmOverloads
@ModelProp
fun actionMessage(@StringRes message: Int? = null) {
message?.let { binding.button.text = context.getString(message) }
}
@JvmOverloads
@CallbackProp
fun actionCallback(viewOnClickListener: OnClickListener? = null) {
binding.button.setOnClickListener(viewOnClickListener)
}
}

View File

@@ -1,37 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.shimmer
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.ModelView
import com.aurora.store.databinding.ViewAppListShimmerBinding
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class AppListViewShimmer @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppListShimmerBinding>(context, attrs, defStyleAttr)

View File

@@ -1,37 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.shimmer
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.ModelView
import com.aurora.store.databinding.ViewAppShimmerBinding
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class AppViewShimmer @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewAppShimmerBinding>(context, attrs, defStyleAttr)

View File

@@ -1,37 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.view.epoxy.views.shimmer
import android.content.Context
import android.util.AttributeSet
import com.airbnb.epoxy.ModelView
import com.aurora.store.databinding.ViewHeaderShimmerBinding
import com.aurora.store.view.epoxy.views.BaseModel
import com.aurora.store.view.epoxy.views.BaseView
@ModelView(
autoLayout = ModelView.Size.WRAP_WIDTH_WRAP_HEIGHT,
baseModelClass = BaseModel::class
)
class HeaderViewShimmer @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseView<ViewHeaderShimmerBinding>(context, attrs, defStyleAttr)