mirror of
https://github.com/Michatec/michas-droid.git
synced 2026-05-31 02:12:42 +02:00
Search in description, rank search results
This commit is contained in:
@@ -75,6 +75,7 @@ object Database {
|
|||||||
const val ROW_PACKAGE_NAME = "package_name"
|
const val ROW_PACKAGE_NAME = "package_name"
|
||||||
const val ROW_NAME = "name"
|
const val ROW_NAME = "name"
|
||||||
const val ROW_SUMMARY = "summary"
|
const val ROW_SUMMARY = "summary"
|
||||||
|
const val ROW_DESCRIPTION = "description"
|
||||||
const val ROW_ADDED = "added"
|
const val ROW_ADDED = "added"
|
||||||
const val ROW_UPDATED = "updated"
|
const val ROW_UPDATED = "updated"
|
||||||
const val ROW_VERSION_CODE = "version_code"
|
const val ROW_VERSION_CODE = "version_code"
|
||||||
@@ -90,6 +91,7 @@ object Database {
|
|||||||
$ROW_PACKAGE_NAME TEXT NOT NULL,
|
$ROW_PACKAGE_NAME TEXT NOT NULL,
|
||||||
$ROW_NAME TEXT NOT NULL,
|
$ROW_NAME TEXT NOT NULL,
|
||||||
$ROW_SUMMARY TEXT NOT NULL,
|
$ROW_SUMMARY TEXT NOT NULL,
|
||||||
|
$ROW_DESCRIPTION TEXT NOT NULL,
|
||||||
$ROW_ADDED INTEGER NOT NULL,
|
$ROW_ADDED INTEGER NOT NULL,
|
||||||
$ROW_UPDATED INTEGER NOT NULL,
|
$ROW_UPDATED INTEGER NOT NULL,
|
||||||
$ROW_VERSION_CODE INTEGER NOT NULL,
|
$ROW_VERSION_CODE INTEGER NOT NULL,
|
||||||
@@ -148,6 +150,7 @@ object Database {
|
|||||||
|
|
||||||
object Synthetic {
|
object Synthetic {
|
||||||
const val ROW_CAN_UPDATE = "can_update"
|
const val ROW_CAN_UPDATE = "can_update"
|
||||||
|
const val ROW_MATCH_RANK = "match_rank"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +194,7 @@ object Database {
|
|||||||
db.execSQL(it.formatCreateTable(it.name))
|
db.execSQL(it.formatCreateTable(it.name))
|
||||||
!it.memory
|
!it.memory
|
||||||
}
|
}
|
||||||
if (shouldVacuum.any { it }) {
|
if (shouldVacuum.any { it } && !db.inTransaction()) {
|
||||||
db.execSQL("VACUUM")
|
db.execSQL("VACUUM")
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -215,7 +218,7 @@ object Database {
|
|||||||
!it.memory
|
!it.memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldVacuum.any { it }) {
|
if (shouldVacuum.any { it } && !db.inTransaction()) {
|
||||||
db.execSQL("VACUUM")
|
db.execSQL("VACUUM")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +233,9 @@ object Database {
|
|||||||
for (table in tables) {
|
for (table in tables) {
|
||||||
db.execSQL("DROP TABLE IF EXISTS $table")
|
db.execSQL("DROP TABLE IF EXISTS $table")
|
||||||
}
|
}
|
||||||
db.execSQL("VACUUM")
|
if (!db.inTransaction()) {
|
||||||
|
db.execSQL("VACUUM")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +383,7 @@ object Database {
|
|||||||
object ProductAdapter {
|
object ProductAdapter {
|
||||||
fun get(packageName: String, signal: CancellationSignal?): List<Product> {
|
fun get(packageName: String, signal: CancellationSignal?): List<Product> {
|
||||||
return db.query(Schema.Product.name,
|
return db.query(Schema.Product.name,
|
||||||
columns = arrayOf(Schema.Product.ROW_REPOSITORY_ID, Schema.Product.ROW_DATA),
|
columns = arrayOf(Schema.Product.ROW_REPOSITORY_ID, Schema.Product.ROW_DESCRIPTION, Schema.Product.ROW_DATA),
|
||||||
selection = Pair("${Schema.Product.ROW_PACKAGE_NAME} = ?", arrayOf(packageName)),
|
selection = Pair("${Schema.Product.ROW_PACKAGE_NAME} = ?", arrayOf(packageName)),
|
||||||
signal = signal).use { it.asSequence().map(::transform).toList() }
|
signal = signal).use { it.asSequence().map(::transform).toList() }
|
||||||
}
|
}
|
||||||
@@ -404,7 +409,19 @@ object Database {
|
|||||||
product.${Schema.Product.ROW_COMPATIBLE} != 0 AND product.${Schema.Product.ROW_VERSION_CODE} >
|
product.${Schema.Product.ROW_COMPATIBLE} != 0 AND product.${Schema.Product.ROW_VERSION_CODE} >
|
||||||
COALESCE(installed.${Schema.Installed.ROW_VERSION_CODE}, 0xffffffff) AND $signatureMatches)
|
COALESCE(installed.${Schema.Installed.ROW_VERSION_CODE}, 0xffffffff) AND $signatureMatches)
|
||||||
AS ${Schema.Synthetic.ROW_CAN_UPDATE}, product.${Schema.Product.ROW_COMPATIBLE},
|
AS ${Schema.Synthetic.ROW_CAN_UPDATE}, product.${Schema.Product.ROW_COMPATIBLE},
|
||||||
product.${Schema.Product.ROW_DATA_ITEM}, MAX((product.${Schema.Product.ROW_COMPATIBLE} AND
|
product.${Schema.Product.ROW_DATA_ITEM},"""
|
||||||
|
|
||||||
|
if (searchQuery.isNotEmpty()) {
|
||||||
|
builder += """(((product.${Schema.Product.ROW_NAME} LIKE ? OR
|
||||||
|
product.${Schema.Product.ROW_SUMMARY} LIKE ?) * 7) |
|
||||||
|
((product.${Schema.Product.ROW_PACKAGE_NAME} LIKE ?) * 3) |
|
||||||
|
(product.${Schema.Product.ROW_DESCRIPTION} LIKE ?)) AS ${Schema.Synthetic.ROW_MATCH_RANK},"""
|
||||||
|
builder %= List(4) { "%$searchQuery%" }
|
||||||
|
} else {
|
||||||
|
builder += "0 AS ${Schema.Synthetic.ROW_MATCH_RANK},"
|
||||||
|
}
|
||||||
|
|
||||||
|
builder += """MAX((product.${Schema.Product.ROW_COMPATIBLE} AND
|
||||||
(installed.${Schema.Installed.ROW_SIGNATURE} IS NULL OR $signatureMatches)) ||
|
(installed.${Schema.Installed.ROW_SIGNATURE} IS NULL OR $signatureMatches)) ||
|
||||||
PRINTF('%016X', product.${Schema.Product.ROW_VERSION_CODE})) FROM ${Schema.Product.name} AS product"""
|
PRINTF('%016X', product.${Schema.Product.ROW_VERSION_CODE})) FROM ${Schema.Product.name} AS product"""
|
||||||
|
|
||||||
@@ -429,10 +446,7 @@ object Database {
|
|||||||
builder %= category
|
builder %= category
|
||||||
}
|
}
|
||||||
if (searchQuery.isNotEmpty()) {
|
if (searchQuery.isNotEmpty()) {
|
||||||
builder += """AND (product.${Schema.Product.ROW_PACKAGE_NAME} LIKE ? OR
|
builder += """AND ${Schema.Synthetic.ROW_MATCH_RANK} > 0"""
|
||||||
product.${Schema.Product.ROW_NAME} LIKE ? OR
|
|
||||||
product.${Schema.Product.ROW_SUMMARY} LIKE ?)"""
|
|
||||||
builder %= List(3) { "%$searchQuery%" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
builder += "GROUP BY product.${Schema.Product.ROW_PACKAGE_NAME} HAVING 1"
|
builder += "GROUP BY product.${Schema.Product.ROW_PACKAGE_NAME} HAVING 1"
|
||||||
@@ -440,6 +454,9 @@ object Database {
|
|||||||
builder += "AND ${Schema.Synthetic.ROW_CAN_UPDATE}"
|
builder += "AND ${Schema.Synthetic.ROW_CAN_UPDATE}"
|
||||||
}
|
}
|
||||||
builder += "ORDER BY"
|
builder += "ORDER BY"
|
||||||
|
if (searchQuery.isNotEmpty()) {
|
||||||
|
builder += """${Schema.Synthetic.ROW_MATCH_RANK} DESC,"""
|
||||||
|
}
|
||||||
when (order) {
|
when (order) {
|
||||||
ProductItem.Order.NAME -> Unit
|
ProductItem.Order.NAME -> Unit
|
||||||
ProductItem.Order.DATE_ADDED -> builder += "product.${Schema.Product.ROW_ADDED} DESC,"
|
ProductItem.Order.DATE_ADDED -> builder += "product.${Schema.Product.ROW_ADDED} DESC,"
|
||||||
@@ -452,7 +469,8 @@ object Database {
|
|||||||
|
|
||||||
private fun transform(cursor: Cursor): Product {
|
private fun transform(cursor: Cursor): Product {
|
||||||
return cursor.getBlob(cursor.getColumnIndex(Schema.Product.ROW_DATA))
|
return cursor.getBlob(cursor.getColumnIndex(Schema.Product.ROW_DATA))
|
||||||
.jsonParse { Product.deserialize(cursor.getLong(cursor.getColumnIndex(Schema.Product.ROW_REPOSITORY_ID)), it) }
|
.jsonParse { Product.deserialize(cursor.getLong(cursor.getColumnIndex(Schema.Product.ROW_REPOSITORY_ID)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(Schema.Product.ROW_DESCRIPTION)), it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformItem(cursor: Cursor): ProductItem {
|
fun transformItem(cursor: Cursor): ProductItem {
|
||||||
@@ -463,7 +481,8 @@ object Database {
|
|||||||
cursor.getString(cursor.getColumnIndex(Schema.Product.ROW_SUMMARY)),
|
cursor.getString(cursor.getColumnIndex(Schema.Product.ROW_SUMMARY)),
|
||||||
cursor.getString(cursor.getColumnIndex(Schema.Installed.ROW_VERSION)).orEmpty(),
|
cursor.getString(cursor.getColumnIndex(Schema.Installed.ROW_VERSION)).orEmpty(),
|
||||||
cursor.getInt(cursor.getColumnIndex(Schema.Product.ROW_COMPATIBLE)) != 0,
|
cursor.getInt(cursor.getColumnIndex(Schema.Product.ROW_COMPATIBLE)) != 0,
|
||||||
cursor.getInt(cursor.getColumnIndex(Schema.Synthetic.ROW_CAN_UPDATE)) != 0, it) }
|
cursor.getInt(cursor.getColumnIndex(Schema.Synthetic.ROW_CAN_UPDATE)) != 0,
|
||||||
|
cursor.getInt(cursor.getColumnIndex(Schema.Synthetic.ROW_MATCH_RANK)), it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,6 +604,7 @@ object Database {
|
|||||||
put(Schema.Product.ROW_PACKAGE_NAME, product.packageName)
|
put(Schema.Product.ROW_PACKAGE_NAME, product.packageName)
|
||||||
put(Schema.Product.ROW_NAME, product.name)
|
put(Schema.Product.ROW_NAME, product.name)
|
||||||
put(Schema.Product.ROW_SUMMARY, product.summary)
|
put(Schema.Product.ROW_SUMMARY, product.summary)
|
||||||
|
put(Schema.Product.ROW_DESCRIPTION, product.description)
|
||||||
put(Schema.Product.ROW_ADDED, product.added)
|
put(Schema.Product.ROW_ADDED, product.added)
|
||||||
put(Schema.Product.ROW_UPDATED, product.updated)
|
put(Schema.Product.ROW_UPDATED, product.updated)
|
||||||
put(Schema.Product.ROW_VERSION_CODE, product.versionCode)
|
put(Schema.Product.ROW_VERSION_CODE, product.versionCode)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ data class Product(val repositoryId: Long, val packageName: String, val name: St
|
|||||||
get() = selectedReleases.mapNotNull { it.signature.nullIfEmpty() }.distinct().toList()
|
get() = selectedReleases.mapNotNull { it.signature.nullIfEmpty() }.distinct().toList()
|
||||||
|
|
||||||
fun item(): ProductItem {
|
fun item(): ProductItem {
|
||||||
return ProductItem(repositoryId, packageName, name, summary, icon, version, "", compatible, false)
|
return ProductItem(repositoryId, packageName, name, summary, icon, version, "", compatible, false, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canUpdate(installedItem: InstalledItem?): Boolean {
|
fun canUpdate(installedItem: InstalledItem?): Boolean {
|
||||||
@@ -67,7 +67,6 @@ data class Product(val repositoryId: Long, val packageName: String, val name: St
|
|||||||
generator.writeStringField("packageName", packageName)
|
generator.writeStringField("packageName", packageName)
|
||||||
generator.writeStringField("name", name)
|
generator.writeStringField("name", name)
|
||||||
generator.writeStringField("summary", summary)
|
generator.writeStringField("summary", summary)
|
||||||
generator.writeStringField("description", description)
|
|
||||||
generator.writeStringField("whatsNew", whatsNew)
|
generator.writeStringField("whatsNew", whatsNew)
|
||||||
generator.writeStringField("icon", icon)
|
generator.writeStringField("icon", icon)
|
||||||
generator.writeStringField("authorName", author.name)
|
generator.writeStringField("authorName", author.name)
|
||||||
@@ -133,11 +132,10 @@ data class Product(val repositoryId: Long, val packageName: String, val name: St
|
|||||||
(installedItem == null || installedItem.signature in extract(it).signatures) }, { extract(it).versionCode }))
|
(installedItem == null || installedItem.signature in extract(it).signatures) }, { extract(it).versionCode }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserialize(repositoryId: Long, parser: JsonParser): Product {
|
fun deserialize(repositoryId: Long, description: String, parser: JsonParser): Product {
|
||||||
var packageName = ""
|
var packageName = ""
|
||||||
var name = ""
|
var name = ""
|
||||||
var summary = ""
|
var summary = ""
|
||||||
var description = ""
|
|
||||||
var whatsNew = ""
|
var whatsNew = ""
|
||||||
var icon = ""
|
var icon = ""
|
||||||
var authorName = ""
|
var authorName = ""
|
||||||
@@ -161,7 +159,6 @@ data class Product(val repositoryId: Long, val packageName: String, val name: St
|
|||||||
it.string("packageName") -> packageName = valueAsString
|
it.string("packageName") -> packageName = valueAsString
|
||||||
it.string("name") -> name = valueAsString
|
it.string("name") -> name = valueAsString
|
||||||
it.string("summary") -> summary = valueAsString
|
it.string("summary") -> summary = valueAsString
|
||||||
it.string("description") -> description = valueAsString
|
|
||||||
it.string("whatsNew") -> whatsNew = valueAsString
|
it.string("whatsNew") -> whatsNew = valueAsString
|
||||||
it.string("icon") -> icon = valueAsString
|
it.string("icon") -> icon = valueAsString
|
||||||
it.string("authorName") -> authorName = valueAsString
|
it.string("authorName") -> authorName = valueAsString
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import nya.kitsunyan.foxydroid.utility.extension.json.*
|
|||||||
|
|
||||||
data class ProductItem(val repositoryId: Long, val packageName: String,
|
data class ProductItem(val repositoryId: Long, val packageName: String,
|
||||||
val name: String, val summary: String, val icon: String, val version: String, val installedVersion: String,
|
val name: String, val summary: String, val icon: String, val version: String, val installedVersion: String,
|
||||||
val compatible: Boolean, val canUpdate: Boolean) {
|
val compatible: Boolean, val canUpdate: Boolean, val matchRank: Int) {
|
||||||
enum class Order(val titleResId: Int) {
|
enum class Order(val titleResId: Int) {
|
||||||
NAME(R.string.name),
|
NAME(R.string.name),
|
||||||
DATE_ADDED(R.string.date_added),
|
DATE_ADDED(R.string.date_added),
|
||||||
@@ -22,7 +22,8 @@ data class ProductItem(val repositoryId: Long, val packageName: String,
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun deserialize(repositoryId: Long, packageName: String, name: String, summary: String,
|
fun deserialize(repositoryId: Long, packageName: String, name: String, summary: String,
|
||||||
installedVersion: String, compatible: Boolean, canUpdate: Boolean, parser: JsonParser): ProductItem {
|
installedVersion: String, compatible: Boolean, canUpdate: Boolean, matchRank: Int,
|
||||||
|
parser: JsonParser): ProductItem {
|
||||||
var icon = ""
|
var icon = ""
|
||||||
var version = ""
|
var version = ""
|
||||||
parser.forEachKey {
|
parser.forEachKey {
|
||||||
@@ -33,7 +34,7 @@ data class ProductItem(val repositoryId: Long, val packageName: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ProductItem(repositoryId, packageName, name, summary, icon,
|
return ProductItem(repositoryId, packageName, name, summary, icon,
|
||||||
version, installedVersion, compatible, canUpdate)
|
version, installedVersion, compatible, canUpdate, matchRank)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class IndexMerger(file: File): Closeable {
|
|||||||
init {
|
init {
|
||||||
db.execWithResult("PRAGMA synchronous = OFF")
|
db.execWithResult("PRAGMA synchronous = OFF")
|
||||||
db.execWithResult("PRAGMA journal_mode = OFF")
|
db.execWithResult("PRAGMA journal_mode = OFF")
|
||||||
db.execSQL("CREATE TABLE product (package_name TEXT PRIMARY KEY, data BLOB NOT NULL)")
|
db.execSQL("CREATE TABLE product (package_name TEXT PRIMARY KEY, description TEXT NOT NULL, data BLOB NOT NULL)")
|
||||||
db.execSQL("CREATE TABLE releases (package_name TEXT PRIMARY KEY, data BLOB NOT NULL)")
|
db.execSQL("CREATE TABLE releases (package_name TEXT PRIMARY KEY, data BLOB NOT NULL)")
|
||||||
db.beginTransaction()
|
db.beginTransaction()
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@ class IndexMerger(file: File): Closeable {
|
|||||||
Json.factory.createGenerator(outputStream).use { it.writeDictionary(product::serialize) }
|
Json.factory.createGenerator(outputStream).use { it.writeDictionary(product::serialize) }
|
||||||
db.insert("product", null, ContentValues().apply {
|
db.insert("product", null, ContentValues().apply {
|
||||||
put("package_name", product.packageName)
|
put("package_name", product.packageName)
|
||||||
|
put("description", product.description)
|
||||||
put("data", outputStream.toByteArray())
|
put("data", outputStream.toByteArray())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -60,14 +61,15 @@ class IndexMerger(file: File): Closeable {
|
|||||||
|
|
||||||
fun forEach(repositoryId: Long, windowSize: Int, callback: (List<Product>, Int) -> Unit) {
|
fun forEach(repositoryId: Long, windowSize: Int, callback: (List<Product>, Int) -> Unit) {
|
||||||
closeTransaction()
|
closeTransaction()
|
||||||
db.rawQuery("""SELECT product.data AS p, releases.data AS d FROM product
|
db.rawQuery("""SELECT product.description, product.data AS pd, releases.data AS rd FROM product
|
||||||
LEFT JOIN releases ON product.package_name = releases.package_name""", null)
|
LEFT JOIN releases ON product.package_name = releases.package_name""", null)
|
||||||
?.use { it.asSequence().map {
|
?.use { it.asSequence().map {
|
||||||
val product = Json.factory.createParser(it.getBlob(0)).use {
|
val description = it.getString(0)
|
||||||
|
val product = Json.factory.createParser(it.getBlob(1)).use {
|
||||||
it.nextToken()
|
it.nextToken()
|
||||||
Product.deserialize(repositoryId, it)
|
Product.deserialize(repositoryId, description, it)
|
||||||
}
|
}
|
||||||
val releases = it.getBlob(1)?.let { Json.factory.createParser(it).use {
|
val releases = it.getBlob(2)?.let { Json.factory.createParser(it).use {
|
||||||
it.nextToken()
|
it.nextToken()
|
||||||
it.collectNotNull(JsonToken.START_OBJECT, Release.Companion::deserialize)
|
it.collectNotNull(JsonToken.START_OBJECT, Release.Companion::deserialize)
|
||||||
} }.orEmpty()
|
} }.orEmpty()
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.text.Html
|
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.text.style.BulletSpan
|
import android.text.style.BulletSpan
|
||||||
@@ -37,6 +36,7 @@ import android.widget.Switch
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.core.text.util.LinkifyCompat
|
import androidx.core.text.util.LinkifyCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import nya.kitsunyan.foxydroid.R
|
import nya.kitsunyan.foxydroid.R
|
||||||
@@ -1207,8 +1207,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun formatHtml(text: String): SpannableStringBuilder {
|
private fun formatHtml(text: String): SpannableStringBuilder {
|
||||||
val html = if (Android.sdk(24)) Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY) else
|
val html = HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||||
@Suppress("DEPRECATION") Html.fromHtml(text)
|
|
||||||
val builder = run {
|
val builder = run {
|
||||||
val builder = SpannableStringBuilder(html)
|
val builder = SpannableStringBuilder(html)
|
||||||
val last = builder.indexOfLast { it != '\n' }
|
val last = builder.indexOfLast { it != '\n' }
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import nya.kitsunyan.foxydroid.utility.Utils
|
|||||||
import nya.kitsunyan.foxydroid.utility.extension.resources.*
|
import nya.kitsunyan.foxydroid.utility.extension.resources.*
|
||||||
import nya.kitsunyan.foxydroid.utility.extension.text.*
|
import nya.kitsunyan.foxydroid.utility.extension.text.*
|
||||||
import nya.kitsunyan.foxydroid.widget.CursorRecyclerAdapter
|
import nya.kitsunyan.foxydroid.widget.CursorRecyclerAdapter
|
||||||
|
import nya.kitsunyan.foxydroid.widget.DividerItemDecoration
|
||||||
|
|
||||||
class ProductsAdapter(private val onClick: (ProductItem) -> Unit):
|
class ProductsAdapter(private val onClick: (ProductItem) -> Unit):
|
||||||
CursorRecyclerAdapter<ProductsAdapter.ViewType, RecyclerView.ViewHolder>() {
|
CursorRecyclerAdapter<ProductsAdapter.ViewType, RecyclerView.ViewHolder>() {
|
||||||
@@ -68,6 +69,20 @@ class ProductsAdapter(private val onClick: (ProductItem) -> Unit):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun configureDivider(context: Context, position: Int, configuration: DividerItemDecoration.Configuration) {
|
||||||
|
val currentItem = if (getItemEnumViewType(position) == ViewType.PRODUCT) getProductItem(position) else null
|
||||||
|
val nextItem = if (position + 1 < itemCount && getItemEnumViewType(position + 1) == ViewType.PRODUCT)
|
||||||
|
getProductItem(position + 1) else null
|
||||||
|
when {
|
||||||
|
currentItem != null && nextItem != null && currentItem.matchRank != nextItem.matchRank -> {
|
||||||
|
configuration.set(true, false, 0, 0)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
configuration.set(true, false, context.resources.sizeScaled(72), 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var repositories: Map<Long, Repository> = emptyMap()
|
var repositories: Map<Long, Repository> = emptyMap()
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import nya.kitsunyan.foxydroid.database.CursorOwner
|
|||||||
import nya.kitsunyan.foxydroid.database.Database
|
import nya.kitsunyan.foxydroid.database.Database
|
||||||
import nya.kitsunyan.foxydroid.entity.ProductItem
|
import nya.kitsunyan.foxydroid.entity.ProductItem
|
||||||
import nya.kitsunyan.foxydroid.utility.RxUtils
|
import nya.kitsunyan.foxydroid.utility.RxUtils
|
||||||
import nya.kitsunyan.foxydroid.utility.extension.resources.*
|
|
||||||
import nya.kitsunyan.foxydroid.widget.DividerItemDecoration
|
import nya.kitsunyan.foxydroid.widget.DividerItemDecoration
|
||||||
import nya.kitsunyan.foxydroid.widget.RecyclerFastScroller
|
import nya.kitsunyan.foxydroid.widget.RecyclerFastScroller
|
||||||
|
|
||||||
@@ -79,9 +78,9 @@ class ProductsFragment(): ScreenFragment(), CursorOwner.Callback {
|
|||||||
isVerticalScrollBarEnabled = false
|
isVerticalScrollBarEnabled = false
|
||||||
setHasFixedSize(true)
|
setHasFixedSize(true)
|
||||||
recycledViewPool.setMaxRecycledViews(ProductsAdapter.ViewType.PRODUCT.ordinal, 30)
|
recycledViewPool.setMaxRecycledViews(ProductsAdapter.ViewType.PRODUCT.ordinal, 30)
|
||||||
adapter = ProductsAdapter { screenActivity.navigateProduct(it.packageName) }
|
val adapter = ProductsAdapter { screenActivity.navigateProduct(it.packageName) }
|
||||||
addItemDecoration(DividerItemDecoration(context,
|
this.adapter = adapter
|
||||||
DividerItemDecoration.fixed(context.resources.sizeScaled(72), 0)))
|
addItemDecoration(DividerItemDecoration(context, adapter::configureDivider))
|
||||||
RecyclerFastScroller(this)
|
RecyclerFastScroller(this)
|
||||||
recyclerView = this
|
recyclerView = this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ import kotlin.math.*
|
|||||||
|
|
||||||
class DividerItemDecoration(context: Context, private val configure: (context: Context,
|
class DividerItemDecoration(context: Context, private val configure: (context: Context,
|
||||||
position: Int, configuration: Configuration) -> Unit): RecyclerView.ItemDecoration() {
|
position: Int, configuration: Configuration) -> Unit): RecyclerView.ItemDecoration() {
|
||||||
companion object {
|
|
||||||
fun fixed(start: Int, end: Int): (Context, Int, Configuration) -> Unit = { _, _, configuration ->
|
|
||||||
configuration.set(true, false, start, end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Configuration {
|
interface Configuration {
|
||||||
fun set(needDivider: Boolean, toTop: Boolean, paddingStart: Int, paddingEnd: Int)
|
fun set(needDivider: Boolean, toTop: Boolean, paddingStart: Int, paddingEnd: Int)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user