update AddonsProvider

pull/700/head iceraven-2.10.0
akliuxingyuan 9 months ago
parent faaa23a167
commit 9d4ee65f43

@ -58,7 +58,7 @@ internal const val DEFAULT_READ_TIMEOUT_IN_SECONDS = 20L
* cache is being used by default
*/
@Suppress("LongParameterList")
class PagedAddonCollectionProvider(
class PagedAMOAddonProvider(
private val context: Context,
private val client: Client,
private val serverURL: String = DEFAULT_SERVER_URL,
@ -117,8 +117,9 @@ class PagedAddonCollectionProvider(
* @throws IOException if the request failed, or could not be executed due to cancellation,
* a connectivity problem or a timeout.
*/
@Throws(IOException::class)
override suspend fun getAvailableAddons(
override suspend fun getFeaturedAddons(
allowCache: Boolean,
readTimeoutInSeconds: Long?,
language: String?,
@ -164,8 +165,46 @@ class PagedAddonCollectionProvider(
writeToDiskCache(it.toString(), language)
}
deleteUnusedCacheFiles(language)
}.getAddons(language)
}.getAddonsFromCollection(language)
}
}
override suspend fun getAddonsByGUIDs(
guids: List<String>,
readTimeoutInSeconds: Long?,
language: String?,
): List<Addon> {
if (guids.isEmpty()) {
logger.warn("Attempted to retrieve add-ons with an empty list of GUIDs")
return emptyList()
}
val langParam = if (!language.isNullOrEmpty()) {
"&lang=$language"
} else {
""
}
client.fetch(
Request(
url = "$serverURL/${API_VERSION}/addons/search/?guid=${guids.joinToString(",")}" + langParam,
readTimeout = Pair(readTimeoutInSeconds ?: DEFAULT_READ_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS),
),
)
.use { response ->
if (response.isSuccess) {
val responseBody = response.body.string(Charsets.UTF_8)
return try {
JSONObject(responseBody).getAddonsFromSearchResults(language)
} catch (e: JSONException) {
throw IOException(e)
}
} else {
val errorMessage = "Failed to get add-ons by GUIDs. Status code: ${response.status}"
logger.error(errorMessage)
throw IOException(errorMessage)
}
}
}
/**
@ -225,7 +264,7 @@ class PagedAddonCollectionProvider(
* a connectivity problem or a timeout.
*/
@Throws(IOException::class)
suspend fun getAddonIconBitmap(addon: Addon): Bitmap? {
override suspend fun getAddonIconBitmap(addon: Addon): Bitmap? {
var bitmap: Bitmap? = null
if (addon.iconUrl != "") {
client.fetch(
@ -259,7 +298,7 @@ class PagedAddonCollectionProvider(
logger.info("Loading cache file")
synchronized(diskCacheLock) {
return getCacheFile(context, language, useFallbackFile).readAndDeserialize {
JSONObject(it).getAddons(language)
JSONObject(it).getAddonsFromCollection(language)
}
}
}
@ -363,15 +402,23 @@ class PagedAddonCollectionProvider(
}
}
internal fun JSONObject.getAddons(language: String? = null): List<Addon> {
internal fun JSONObject.getAddonsFromSearchResults(language: String? = null): List<Addon> {
val addonsJson = getJSONArray("results")
return (0 until addonsJson.length()).map { index ->
addonsJson.getJSONObject(index).toAddon(language)
}
}
internal fun JSONObject.getAddonsFromCollection(language: String? = null): List<Addon> {
val addonsJson = getJSONArray("results")
// Each result in a collection response has an `addon` key and some (optional) notes.
return (0 until addonsJson.length()).map { index ->
addonsJson.getJSONObject(index).toAddons(language)
addonsJson.getJSONObject(index).getJSONObject("addon").toAddon(language)
}
}
internal fun JSONObject.toAddons(language: String? = null): Addon {
return with(getJSONObject("addon")) {
internal fun JSONObject.toAddon(language: String? = null): Addon {
return with(this) {
val download = getDownload()
val safeLanguage = language?.lowercase(Locale.getDefault())
val summary = getSafeTranslations("summary", safeLanguage)

@ -77,7 +77,7 @@ class PagedAddonInstallationDialogFragment : AppCompatDialogFragment() {
/**
* Reference to the application's [PagedAddonInstallationDialogFragment] to fetch add-on icons.
*/
var addonCollectionProvider: PagedAddonCollectionProvider? = null
var addonsProvider: PagedAMOAddonProvider? = null
private val safeArguments get() = requireNotNull(arguments)
@ -229,7 +229,7 @@ class PagedAddonInstallationDialogFragment : AppCompatDialogFragment() {
internal fun fetchIcon(addon: Addon, iconView: ImageView, scope: CoroutineScope = this.scope): Job {
return scope.launch {
try {
val iconBitmap = addonCollectionProvider?.getAddonIconBitmap(addon)
val iconBitmap = addonsProvider?.getAddonIconBitmap(addon)
iconBitmap?.let {
scope.launch(Dispatchers.Main) {
safeArguments.putParcelable(KEY_ICON, it)
@ -273,7 +273,7 @@ class PagedAddonInstallationDialogFragment : AppCompatDialogFragment() {
*/
fun newInstance(
addon: Addon,
addonCollectionProvider: PagedAddonCollectionProvider,
addonsProvider: PagedAMOAddonProvider,
promptsStyling: PromptsStyling? = PromptsStyling(
gravity = Gravity.BOTTOM,
shouldWidthMatchParent = true,
@ -304,7 +304,7 @@ class PagedAddonInstallationDialogFragment : AppCompatDialogFragment() {
fragment.onConfirmButtonClicked = onConfirmButtonClicked
fragment.onDismissed = onDismissed
fragment.arguments = arguments
fragment.addonCollectionProvider = addonCollectionProvider
fragment.addonsProvider = addonsProvider
return fragment
}
}

@ -55,15 +55,14 @@ private const val VIEW_HOLDER_TYPE_ADDON = 2
* an add-on such as recommended, unsupported or installed. In addition, it will perform actions
* such as installing an add-on.
*
* @property addonCollectionProvider Provider of AMO collection API.
* @property addonsProvider Provider of AMO collection API.
* @property addonsManagerDelegate Delegate that will provides method for handling the add-on items.
* @param addons The list of add-on based on the AMO store.
* @property style Indicates how items should look like.
* @property excludedAddonIDs The list of add-on IDs to be excluded from the recommended section.
*/
@Suppress("LargeClass")
class PagedAddonsManagerAdapter(
private val addonCollectionProvider: PagedAddonCollectionProvider,
private val addonsProvider: PagedAMOAddonProvider,
private val addonsManagerDelegate: AddonsManagerAdapterDelegate,
addons: List<Addon>,
private val style: Style? = null,
@ -257,7 +256,7 @@ class PagedAddonsManagerAdapter(
// if takes less than a second, we assume it comes
// from a cache and we don't show any transition animation.
val startTime = System.currentTimeMillis()
val iconBitmap = addonCollectionProvider.getAddonIconBitmap(addon)
val iconBitmap = addonsProvider.getAddonIconBitmap(addon)
val timeToFetch: Double = (System.currentTimeMillis() - startTime) / 1000.0
val isFromCache = timeToFetch < 1
if (iconBitmap != null) {

@ -233,7 +233,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
runIfFragmentIsAttached {
if (!shouldRefresh) {
adapter = PagedAddonsManagerAdapter(
requireContext().components.addonCollectionProvider,
requireContext().components.addonsProvider,
managementView,
addons!!,
style = createAddonStyle(requireContext()),

@ -9,7 +9,7 @@ import android.app.Application
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import io.github.forkmaintainers.iceraven.components.PagedAddonCollectionProvider
import io.github.forkmaintainers.iceraven.components.PagedAMOAddonProvider
import androidx.core.app.NotificationManagerCompat
import mozilla.components.feature.addons.AddonManager
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
@ -109,8 +109,8 @@ class Components(private val context: Context) {
)
}
val addonCollectionProvider by lazyMonitored {
PagedAddonCollectionProvider(
val addonsProvider by lazyMonitored {
PagedAMOAddonProvider(
context,
core.client,
serverURL = BuildConfig.AMO_SERVER_URL,
@ -119,7 +119,7 @@ class Components(private val context: Context) {
}
fun clearAddonCache() {
addonCollectionProvider.deleteCacheFile()
addonsProvider.deleteCacheFile()
}
@Suppress("MagicNumber")

Loading…
Cancel
Save