mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-06-14 11:29:18 +00:00
Add: More info on top of the screen
Fix: Show real size of apk
This commit is contained in:
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PermissionGroupInfo
|
||||
import android.content.pm.PermissionInfo
|
||||
import android.content.res.Resources
|
||||
@ -24,11 +25,17 @@ import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.text.util.LinkifyCompat
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.divider.MaterialDivider
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||
import com.google.android.material.textview.MaterialTextView
|
||||
import com.looker.droidify.R
|
||||
import com.looker.droidify.content.Preferences
|
||||
import com.looker.droidify.content.ProductPreferences
|
||||
@ -79,7 +86,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
data class Downloading(val read: Long, val total: Long?) : Status()
|
||||
}
|
||||
|
||||
enum class ViewType { HEADER, SWITCH, SECTION, EXPAND, TEXT, LINK, PERMISSIONS, SCREENSHOT, RELEASE, EMPTY }
|
||||
enum class ViewType { HEADER, RELEASE_INFO, SWITCH, SECTION, EXPAND, TEXT, LINK, PERMISSIONS, SCREENSHOT, RELEASE, EMPTY }
|
||||
|
||||
private enum class SwitchType(val titleResId: Int) {
|
||||
IGNORE_ALL_UPDATES(R.string.ignore_all_updates),
|
||||
@ -129,6 +136,14 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
get() = ViewType.HEADER
|
||||
}
|
||||
|
||||
object ReleaseInfoItem : Item() {
|
||||
override val descriptor: String
|
||||
get() = "release_item"
|
||||
override val viewType: ViewType
|
||||
get() = ViewType.RELEASE_INFO
|
||||
|
||||
}
|
||||
|
||||
class SwitchItem(
|
||||
val switchType: SwitchType,
|
||||
val packageName: String,
|
||||
@ -309,7 +324,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
private class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val icon = itemView.findViewById<ShapeableImageView>(R.id.icon)!!
|
||||
val name = itemView.findViewById<TextView>(R.id.name)!!
|
||||
val version = itemView.findViewById<TextView>(R.id.version)!!
|
||||
val packageName = itemView.findViewById<TextView>(R.id.package_name)!!
|
||||
val action = itemView.findViewById<Button>(R.id.action)!!
|
||||
val statusLayout = itemView.findViewById<View>(R.id.status_layout)!!
|
||||
@ -334,6 +348,17 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
}
|
||||
}
|
||||
|
||||
private class ReleaseInfoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val targetBlock = itemView.findViewById<LinearLayout>(R.id.sdk_block)!!
|
||||
val divider1 = itemView.findViewById<MaterialDivider>(R.id.divider1)!!
|
||||
val targetSdk = itemView.findViewById<MaterialTextView>(R.id.sdk)!!
|
||||
val version = itemView.findViewById<MaterialTextView>(R.id.version)!!
|
||||
val size = itemView.findViewById<MaterialTextView>(R.id.size)!!
|
||||
val devName = itemView.findViewById<MaterialTextView>(R.id.dev)!!
|
||||
val devIcon = itemView.findViewById<ShapeableImageView>(R.id.dev_icon)!!
|
||||
val dev = itemView.findViewById<MaterialCardView>(R.id.dev_block)!!
|
||||
}
|
||||
|
||||
private class SwitchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val enabled = itemView.findViewById<SwitchMaterial>(R.id.enabled)!!
|
||||
|
||||
@ -699,6 +724,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
return if (length >= 0) subSequence(0, length) else null
|
||||
}
|
||||
|
||||
items.add(Item.ReleaseInfoItem)
|
||||
val screenshotItems = productRepository.first.screenshots
|
||||
.map { Item.ScreenshotItem(productRepository.second, packageName, it) }
|
||||
if (screenshotItems.isNotEmpty()) {
|
||||
@ -994,6 +1020,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
ViewType.HEADER -> HeaderViewHolder(parent.inflate(R.layout.product_header_item)).apply {
|
||||
action.setOnClickListener { this@ProductAdapter.action?.let(callbacks::onActionClick) }
|
||||
}
|
||||
ViewType.RELEASE_INFO -> ReleaseInfoViewHolder(parent.inflate(R.layout.release_info))
|
||||
ViewType.SWITCH -> SwitchViewHolder(parent.inflate(R.layout.switch_item)).apply {
|
||||
itemView.setOnClickListener {
|
||||
val switchItem = items[adapterPosition] as Item.SwitchItem
|
||||
@ -1145,12 +1172,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
holder.name.text = item.product.name
|
||||
val canUpdate = item.product.canUpdate(installedItem) &&
|
||||
!ProductPreferences[item.product.packageName].shouldIgnoreUpdate(item.product.versionCode)
|
||||
val version =
|
||||
(if (canUpdate) item.product.version else installedItem?.version)?.nullIfEmpty()
|
||||
?: item.product.version.nullIfEmpty()
|
||||
holder.version.text =
|
||||
version?.let { context.getString(R.string.version_FORMAT, it) }
|
||||
?: context.getString(R.string.unknown)
|
||||
holder.packageName.apply {
|
||||
text = item.product.packageName
|
||||
setTextSizeScaled(15)
|
||||
@ -1196,6 +1217,31 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
}
|
||||
Unit
|
||||
}
|
||||
ViewType.RELEASE_INFO -> {
|
||||
holder as ReleaseInfoViewHolder
|
||||
item as Item.ReleaseInfoItem
|
||||
|
||||
val imageSource = product?.source?.trimAfter('/', 4).plus(".png")
|
||||
val sdk = product?.displayRelease?.targetSdkVersion
|
||||
|
||||
holder.version.doOnPreDraw {
|
||||
if (it.measuredWidth > 70 || sdk == 0) {
|
||||
holder.targetBlock.visibility = View.GONE
|
||||
holder.divider1.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
holder.targetSdk.text = sdk.toString()
|
||||
holder.version.text = product?.displayRelease?.version
|
||||
holder.size.text = product?.displayRelease?.size?.formatSize()
|
||||
holder.devName.text = product?.author?.name?.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
|
||||
}
|
||||
holder.devIcon.load(imageSource)
|
||||
holder.dev.setOnClickListener {
|
||||
context.startActivity(Intent(Intent.ACTION_VIEW, product?.source?.toUri()))
|
||||
}
|
||||
}
|
||||
ViewType.SWITCH -> {
|
||||
holder as SwitchViewHolder
|
||||
item as Item.SwitchItem
|
||||
|
@ -108,7 +108,6 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
||||
|
||||
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)!!
|
||||
screenActivity.onToolbarCreated(toolbar)
|
||||
toolbar.title = getString(R.string.application)
|
||||
this.toolbar = toolbar
|
||||
|
||||
toolbar.menu.apply {
|
||||
@ -190,7 +189,6 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
||||
layoutManagerState = null
|
||||
if (firstChanged || productChanged) {
|
||||
this.products = products
|
||||
toolbar.title = products[0].first.name
|
||||
}
|
||||
if (firstChanged || installedItemChanged) {
|
||||
installed = installedItem.value?.let {
|
||||
@ -342,6 +340,15 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
||||
updateToolbarButtons()
|
||||
}
|
||||
|
||||
private fun updateToolbarTitle() {
|
||||
val showPackageName = recyclerView?.let {
|
||||
(it.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() != 0
|
||||
} == true
|
||||
|
||||
if (showPackageName) toolbar?.title = products[0].first.name
|
||||
else toolbar?.title = getString(R.string.application)
|
||||
}
|
||||
|
||||
private fun updateToolbarButtons() {
|
||||
val (actions, primaryAction) = actions
|
||||
val showPrimaryAction = recyclerView
|
||||
@ -394,6 +401,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
||||
val lastPosition = lastPosition
|
||||
this.lastPosition = position
|
||||
if ((lastPosition == 0) != (position == 0)) {
|
||||
updateToolbarTitle()
|
||||
updateToolbarButtons()
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,23 @@ private val sizeFormats = listOf("%.0f B", "%.0f kB", "%.1f MB", "%.2f GB")
|
||||
|
||||
fun Long.formatSize(): String {
|
||||
val (size, index) = generateSequence(Pair(this.toFloat(), 0)) { (size, index) ->
|
||||
if (size >= 1000f)
|
||||
Pair(size / 1000f, index + 1) else null
|
||||
if (size >= 1024f)
|
||||
Pair(size / 1024f, index + 1) else null
|
||||
}.take(sizeFormats.size).last()
|
||||
return sizeFormats[index].format(Locale.US, size)
|
||||
}
|
||||
|
||||
fun String?.trimAfter(char: Char, repeated: Int): String? {
|
||||
var count = 0
|
||||
this?.let {
|
||||
for (i in it.indices) {
|
||||
if (it[i] == char) count++
|
||||
if (repeated == count) return it.substring(0, i)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun Char.halfByte(): Int {
|
||||
return when (this) {
|
||||
in '0'..'9' -> this - '0'
|
||||
|
Reference in New Issue
Block a user