Update: Extract Author, Screenshot and Donate into a file

This commit is contained in:
machiav3lli 2022-02-20 02:19:06 +01:00
parent b56da3679c
commit 3f490c2487
10 changed files with 175 additions and 95 deletions

View File

@ -32,28 +32,6 @@ data class Product(
val screenshots: List<Screenshot>,
val releases: List<Release>,
) {
data class Author(val name: String, val email: String, val web: String)
sealed class Donate {
data class Regular(val url: String) : Donate()
data class Bitcoin(val address: String) : Donate()
data class Litecoin(val address: String) : Donate()
data class Flattr(val id: String) : Donate()
data class Liberapay(val id: String) : Donate()
data class OpenCollective(val id: String) : Donate()
}
class Screenshot(val locale: String, val type: Type, val path: String) {
enum class Type(val jsonName: String) {
PHONE("phone"),
SMALL_TABLET("smallTablet"),
LARGE_TABLET("largeTablet")
}
val identifier: String
get() = "$locale.${type.name}.$path"
}
// Same releases with different signatures
val selectedReleases: List<Release>
get() = releases.filter { it.selected }

View File

@ -0,0 +1,106 @@
package com.looker.droidify.entity
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.looker.droidify.utility.extension.json.forEachKey
data class Author(val name: String, val email: String, val web: String)
sealed class Donate {
data class Regular(val url: String) : Donate()
data class Bitcoin(val address: String) : Donate()
data class Litecoin(val address: String) : Donate()
data class Flattr(val id: String) : Donate()
data class Liberapay(val id: String) : Donate()
data class OpenCollective(val id: String) : Donate()
fun serialize(generator: JsonGenerator) {
when (this) {
is Regular -> {
generator.writeStringField("type", "")
generator.writeStringField("url", url)
}
is Bitcoin -> {
generator.writeStringField("type", "bitcoin")
generator.writeStringField("address", address)
}
is Litecoin -> {
generator.writeStringField("type", "litecoin")
generator.writeStringField("address", address)
}
is Flattr -> {
generator.writeStringField("type", "flattr")
generator.writeStringField("id", id)
}
is Liberapay -> {
generator.writeStringField("type", "liberapay")
generator.writeStringField("id", id)
}
is OpenCollective -> {
generator.writeStringField("type", "openCollective")
generator.writeStringField("id", id)
}
}::class
}
companion object {
fun deserialize(parser: JsonParser): Donate? {
var type = ""
var url = ""
var address = ""
var id = ""
parser.forEachKey {
when {
it.string("type") -> type = valueAsString
it.string("url") -> url = valueAsString
it.string("address") -> address = valueAsString
it.string("id") -> id = valueAsString
else -> skipChildren()
}
}
return when (type) {
"" -> Regular(url)
"bitcoin" -> Bitcoin(address)
"litecoin" -> Litecoin(address)
"flattr" -> Flattr(id)
"liberapay" -> Liberapay(id)
"openCollective" -> OpenCollective(id)
else -> null
}
}
}
}
class Screenshot(val locale: String, val type: Type, val path: String) {
enum class Type(val jsonName: String) {
PHONE("phone"),
SMALL_TABLET("smallTablet"),
LARGE_TABLET("largeTablet")
}
val identifier: String
get() = "$locale.${type.name}.$path"
fun serialize(generator: JsonGenerator) {
generator.writeStringField("locale", locale)
generator.writeStringField("type", type.jsonName)
generator.writeStringField("path", path)
}
companion object {
fun deserialize(parser: JsonParser): Screenshot? {
var locale = ""
var type = ""
var path = ""
parser.forEachKey {
when {
it.string("locale") -> locale = valueAsString
it.string("type") -> type = valueAsString
it.string("path") -> path = valueAsString
else -> skipChildren()
}
}
return Type.values().find { it.jsonName == type }?.let { Screenshot(locale, it, path) }
}
}
}

View File

@ -1,6 +1,8 @@
package com.looker.droidify.index
import com.looker.droidify.database.entity.Release
import com.looker.droidify.entity.Author
import com.looker.droidify.entity.Donate
import com.looker.droidify.entity.Product
import com.looker.droidify.utility.extension.android.Android
import org.xml.sax.Attributes
@ -36,17 +38,17 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
fun onProduct(product: Product)
}
internal object DonateComparator : Comparator<Product.Donate> {
internal object DonateComparator : Comparator<Donate> {
private val classes = listOf(
Product.Donate.Regular::class,
Product.Donate.Bitcoin::class,
Product.Donate.Litecoin::class,
Product.Donate.Flattr::class,
Product.Donate.Liberapay::class,
Product.Donate.OpenCollective::class
Donate.Regular::class,
Donate.Bitcoin::class,
Donate.Litecoin::class,
Donate.Flattr::class,
Donate.Liberapay::class,
Donate.OpenCollective::class
)
override fun compare(donate1: Product.Donate, donate2: Product.Donate): Int {
override fun compare(donate1: Donate, donate2: Donate): Int {
val index1 = classes.indexOf(donate1::class)
val index2 = classes.indexOf(donate2::class)
return when {
@ -84,7 +86,7 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
val categories = linkedSetOf<String>()
val antiFeatures = linkedSetOf<String>()
val licenses = mutableListOf<String>()
val donates = mutableListOf<Product.Donate>()
val donates = mutableListOf<Donate>()
val releases = mutableListOf<Release>()
fun build(): Product {
@ -97,7 +99,7 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
"",
icon,
"",
Product.Author(authorName, authorEmail, ""),
Author(authorName, authorEmail, ""),
source,
changelog,
web,
@ -318,12 +320,12 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
.filter { it.isNotEmpty() }
"license" -> productBuilder.licenses += content.split(',')
.filter { it.isNotEmpty() }
"donate" -> productBuilder.donates += Product.Donate.Regular(content)
"bitcoin" -> productBuilder.donates += Product.Donate.Bitcoin(content)
"litecoin" -> productBuilder.donates += Product.Donate.Litecoin(content)
"flattr" -> productBuilder.donates += Product.Donate.Flattr(content)
"liberapay" -> productBuilder.donates += Product.Donate.Liberapay(content)
"openCollective" -> productBuilder.donates += Product.Donate.OpenCollective(
"donate" -> productBuilder.donates += Donate.Regular(content)
"bitcoin" -> productBuilder.donates += Donate.Bitcoin(content)
"litecoin" -> productBuilder.donates += Donate.Litecoin(content)
"flattr" -> productBuilder.donates += Donate.Flattr(content)
"liberapay" -> productBuilder.donates += Donate.Liberapay(content)
"openCollective" -> productBuilder.donates += Donate.OpenCollective(
content
)
}

View File

@ -3,7 +3,10 @@ package com.looker.droidify.index
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.core.JsonToken
import com.looker.droidify.database.entity.Release
import com.looker.droidify.entity.Author
import com.looker.droidify.entity.Donate
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.utility.extension.android.Android
import com.looker.droidify.utility.extension.json.*
import com.looker.droidify.utility.extension.text.nullIfEmpty
@ -123,7 +126,7 @@ object IndexV1Parser {
var categories = emptyList<String>()
var antiFeatures = emptyList<String>()
val licenses = mutableListOf<String>()
val donates = mutableListOf<Product.Donate>()
val donates = mutableListOf<Donate>()
val localizedMap = mutableMapOf<String, Localized>()
forEachKey { it ->
when {
@ -147,11 +150,11 @@ object IndexV1Parser {
it.array("antiFeatures") -> antiFeatures = collectDistinctNotEmptyStrings()
it.string("license") -> licenses += valueAsString.split(',')
.filter { it.isNotEmpty() }
it.string("donate") -> donates += Product.Donate.Regular(valueAsString)
it.string("bitcoin") -> donates += Product.Donate.Bitcoin(valueAsString)
it.string("flattrID") -> donates += Product.Donate.Flattr(valueAsString)
it.string("liberapayID") -> donates += Product.Donate.Liberapay(valueAsString)
it.string("openCollective") -> donates += Product.Donate.OpenCollective(
it.string("donate") -> donates += Donate.Regular(valueAsString)
it.string("bitcoin") -> donates += Donate.Bitcoin(valueAsString)
it.string("flattrID") -> donates += Donate.Flattr(valueAsString)
it.string("liberapayID") -> donates += Donate.Liberapay(valueAsString)
it.string("openCollective") -> donates += Donate.OpenCollective(
valueAsString
)
it.dictionary("localized") -> forEachKey { keyToken ->
@ -206,23 +209,11 @@ object IndexV1Parser {
val screenshots = screenshotPairs
?.let { (key, screenshots) ->
screenshots.phone.asSequence()
.map { Product.Screenshot(key, Product.Screenshot.Type.PHONE, it) } +
.map { Screenshot(key, Screenshot.Type.PHONE, it) } +
screenshots.smallTablet.asSequence()
.map {
Product.Screenshot(
key,
Product.Screenshot.Type.SMALL_TABLET,
it
)
} +
.map { Screenshot(key, Screenshot.Type.SMALL_TABLET, it) } +
screenshots.largeTablet.asSequence()
.map {
Product.Screenshot(
key,
Product.Screenshot.Type.LARGE_TABLET,
it
)
}
.map { Screenshot(key, Screenshot.Type.LARGE_TABLET, it) }
}
.orEmpty().toList()
return Product(
@ -234,7 +225,7 @@ object IndexV1Parser {
whatsNew,
icon,
metadataIcon,
Product.Author(authorName, authorEmail, authorWeb),
Author(authorName, authorEmail, authorWeb),
source,
changelog,
web,

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.net.Uri
import android.view.View
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.utility.extension.text.nullIfEmpty
import okhttp3.Cache
import okhttp3.Call
@ -92,7 +92,7 @@ object CoilDownloader {
fun createScreenshotUri(
repository: Repository,
packageName: String,
screenshot: Product.Screenshot,
screenshot: Screenshot,
): Uri {
return Uri.Builder().scheme("https").authority(HOST_SCREENSHOT)
.appendQueryParameter(QUERY_ADDRESS, repository.address)
@ -101,9 +101,9 @@ object CoilDownloader {
.appendQueryParameter(QUERY_LOCALE, screenshot.locale)
.appendQueryParameter(
QUERY_DEVICE, when (screenshot.type) {
Product.Screenshot.Type.PHONE -> "phoneScreenshots"
Product.Screenshot.Type.SMALL_TABLET -> "sevenInchScreenshots"
Product.Screenshot.Type.LARGE_TABLET -> "tenInchScreenshots"
Screenshot.Type.PHONE -> "phoneScreenshots"
Screenshot.Type.SMALL_TABLET -> "sevenInchScreenshots"
Screenshot.Type.LARGE_TABLET -> "tenInchScreenshots"
}
)
.appendQueryParameter(QUERY_SCREENSHOT, screenshot.path)

View File

@ -11,7 +11,7 @@ import com.google.android.material.card.MaterialCardView
import com.google.android.material.imageview.ShapeableImageView
import com.looker.droidify.R
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.graphics.PaddingDrawable
import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.utility.extension.resources.getColorFromAttr
@ -19,7 +19,7 @@ import com.looker.droidify.utility.extension.resources.getDrawableCompat
import com.looker.droidify.utility.extension.resources.sizeScaled
import com.looker.droidify.widget.StableRecyclerAdapter
class ScreenshotsAdapter(private val onClick: (Product.Screenshot) -> Unit) :
class ScreenshotsAdapter(private val onClick: (Screenshot) -> Unit) :
StableRecyclerAdapter<ScreenshotsAdapter.ViewType, RecyclerView.ViewHolder>() {
enum class ViewType { SCREENSHOT }
@ -68,7 +68,7 @@ class ScreenshotsAdapter(private val onClick: (Product.Screenshot) -> Unit) :
fun setScreenshots(
repository: Repository,
packageName: String,
screenshots: List<Product.Screenshot>
screenshots: List<Screenshot>
) {
items.clear()
items += screenshots.map { Item.ScreenshotItem(repository, packageName, it) }
@ -132,7 +132,7 @@ class ScreenshotsAdapter(private val onClick: (Product.Screenshot) -> Unit) :
class ScreenshotItem(
val repository: Repository,
val packageName: String,
val screenshot: Product.Screenshot,
val screenshot: Screenshot,
) : Item() {
override val descriptor: String
get() = "screenshot.${repository.id}.${screenshot.identifier}"

View File

@ -21,7 +21,7 @@ import com.google.android.material.imageview.ShapeableImageView
import com.looker.droidify.R
import com.looker.droidify.database.DatabaseX
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.graphics.PaddingDrawable
import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.utility.RxUtils
@ -211,12 +211,12 @@ class ScreenshotsFragment() : DialogFragment() {
}
private var repository: Repository? = null
private var screenshots = emptyList<Product.Screenshot>()
private var screenshots = emptyList<Screenshot>()
fun update(
viewPager: ViewPager2,
repository: Repository?,
screenshots: List<Product.Screenshot>,
screenshots: List<Screenshot>,
) {
this.repository = repository
this.screenshots = screenshots

View File

@ -48,6 +48,7 @@ import com.looker.droidify.database.entity.Release
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.ProductPreference
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.network.CoilDownloader
import com.looker.droidify.screen.ScreenshotsAdapter
import com.looker.droidify.utility.KParcelable
@ -76,7 +77,7 @@ class AppDetailAdapter(private val callbacks: Callbacks) :
fun onActionClick(action: Action)
fun onPreferenceChanged(preference: ProductPreference)
fun onPermissionsClick(group: String?, permissions: List<String>)
fun onScreenshotClick(screenshot: Product.Screenshot)
fun onScreenshotClick(screenshot: Screenshot)
fun onReleaseClick(release: Release)
fun onUriClick(uri: Uri, shouldConfirm: Boolean): Boolean
}
@ -150,7 +151,7 @@ class AppDetailAdapter(private val callbacks: Callbacks) :
}
class ScreenshotItem(
val screenshots: List<Product.Screenshot>,
val screenshots: List<Screenshot>,
val packageName: String,
val repository: Repository,
) : Item() {
@ -234,36 +235,36 @@ class AppDetailAdapter(private val callbacks: Callbacks) :
}
}
class Donate(val donate: Product.Donate) : LinkItem() {
class Donate(val donate: com.looker.droidify.entity.Donate) : LinkItem() {
override val descriptor: String
get() = "link.donate.$donate"
override val iconResId: Int
get() = when (donate) {
is Product.Donate.Regular -> R.drawable.ic_donate_regular
is Product.Donate.Bitcoin -> R.drawable.ic_donate_bitcoin
is Product.Donate.Litecoin -> R.drawable.ic_donate_litecoin
is Product.Donate.Flattr -> R.drawable.ic_donate_flattr
is Product.Donate.Liberapay -> R.drawable.ic_donate_liberapay
is Product.Donate.OpenCollective -> R.drawable.ic_donate_opencollective
is com.looker.droidify.entity.Donate.Regular -> R.drawable.ic_donate_regular
is com.looker.droidify.entity.Donate.Bitcoin -> R.drawable.ic_donate_bitcoin
is com.looker.droidify.entity.Donate.Litecoin -> R.drawable.ic_donate_litecoin
is com.looker.droidify.entity.Donate.Flattr -> R.drawable.ic_donate_flattr
is com.looker.droidify.entity.Donate.Liberapay -> R.drawable.ic_donate_liberapay
is com.looker.droidify.entity.Donate.OpenCollective -> R.drawable.ic_donate_opencollective
}
override fun getTitle(context: Context): String = when (donate) {
is Product.Donate.Regular -> context.getString(R.string.website)
is Product.Donate.Bitcoin -> "Bitcoin"
is Product.Donate.Litecoin -> "Litecoin"
is Product.Donate.Flattr -> "Flattr"
is Product.Donate.Liberapay -> "Liberapay"
is Product.Donate.OpenCollective -> "Open Collective"
is com.looker.droidify.entity.Donate.Regular -> context.getString(R.string.website)
is com.looker.droidify.entity.Donate.Bitcoin -> "Bitcoin"
is com.looker.droidify.entity.Donate.Litecoin -> "Litecoin"
is com.looker.droidify.entity.Donate.Flattr -> "Flattr"
is com.looker.droidify.entity.Donate.Liberapay -> "Liberapay"
is com.looker.droidify.entity.Donate.OpenCollective -> "Open Collective"
}
override val uri: Uri? = when (donate) {
is Product.Donate.Regular -> Uri.parse(donate.url)
is Product.Donate.Bitcoin -> Uri.parse("bitcoin:${donate.address}")
is Product.Donate.Litecoin -> Uri.parse("litecoin:${donate.address}")
is Product.Donate.Flattr -> Uri.parse("https://flattr.com/thing/${donate.id}")
is Product.Donate.Liberapay -> Uri.parse("https://liberapay.com/~${donate.id}")
is Product.Donate.OpenCollective -> Uri.parse("https://opencollective.com/${donate.id}")
is com.looker.droidify.entity.Donate.Regular -> Uri.parse(donate.url)
is com.looker.droidify.entity.Donate.Bitcoin -> Uri.parse("bitcoin:${donate.address}")
is com.looker.droidify.entity.Donate.Litecoin -> Uri.parse("litecoin:${donate.address}")
is com.looker.droidify.entity.Donate.Flattr -> Uri.parse("https://flattr.com/thing/${donate.id}")
is com.looker.droidify.entity.Donate.Liberapay -> Uri.parse("https://liberapay.com/~${donate.id}")
is com.looker.droidify.entity.Donate.OpenCollective -> Uri.parse("https://opencollective.com/${donate.id}")
}
}
}

View File

@ -21,6 +21,7 @@ import com.looker.droidify.database.entity.Release
import com.looker.droidify.database.entity.Repository
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.ProductPreference
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.installer.AppInstaller
import com.looker.droidify.screen.MessageDialog
import com.looker.droidify.screen.ScreenFragment
@ -507,7 +508,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks {
)
}
override fun onScreenshotClick(screenshot: Product.Screenshot) {
override fun onScreenshotClick(screenshot: Screenshot) {
val pair = products.asSequence()
.map { it ->
Pair(

View File

@ -23,6 +23,7 @@ import com.looker.droidify.database.entity.Repository
import com.looker.droidify.databinding.SheetAppXBinding
import com.looker.droidify.entity.Product
import com.looker.droidify.entity.ProductPreference
import com.looker.droidify.entity.Screenshot
import com.looker.droidify.installer.AppInstaller
import com.looker.droidify.screen.MessageDialog
import com.looker.droidify.screen.ScreenshotsFragment
@ -385,7 +386,7 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), AppDetailAdapter.Call
)
}
override fun onScreenshotClick(screenshot: Product.Screenshot) {
override fun onScreenshotClick(screenshot: Screenshot) {
val pair = productRepos.asSequence()
.map { it ->
Pair(