mirror of
https://github.com/whyorean/AuroraStore.git
synced 2026-06-11 09:16:06 -04:00
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:
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user