From 9d4ee65f43ea1be3dd40761b38666ed26d85ed5e Mon Sep 17 00:00:00 2001 From: akliuxingyuan Date: Wed, 27 Sep 2023 20:43:04 +0800 Subject: [PATCH] update AddonsProvider --- ...nProvider.kt => PagedAMOAddonsProvider.kt} | 65 ++++++++++++++++--- .../PagedAddonInstallationDialogFragment.kt | 8 +-- .../components/PagedAddonsManagerAdapter.kt | 7 +- .../fenix/addons/AddonsManagementFragment.kt | 2 +- .../mozilla/fenix/components/Components.kt | 8 +-- 5 files changed, 68 insertions(+), 22 deletions(-) rename app/src/main/java/io/github/forkmaintainers/iceraven/components/{PagedAddonCollectionProvider.kt => PagedAMOAddonsProvider.kt} (89%) diff --git a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonCollectionProvider.kt b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAMOAddonsProvider.kt similarity index 89% rename from app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonCollectionProvider.kt rename to app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAMOAddonsProvider.kt index 4e227151e..9a5ff26f6 100644 --- a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonCollectionProvider.kt +++ b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAMOAddonsProvider.kt @@ -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, + readTimeoutInSeconds: Long?, + language: String?, + ): List { + 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 { +internal fun JSONObject.getAddonsFromSearchResults(language: String? = null): List { + val addonsJson = getJSONArray("results") + return (0 until addonsJson.length()).map { index -> + addonsJson.getJSONObject(index).toAddon(language) + } +} + +internal fun JSONObject.getAddonsFromCollection(language: String? = null): List { 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) diff --git a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonInstallationDialogFragment.kt b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonInstallationDialogFragment.kt index 07d57abc6..059d5eec3 100644 --- a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonInstallationDialogFragment.kt +++ b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonInstallationDialogFragment.kt @@ -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 } } diff --git a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonsManagerAdapter.kt b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonsManagerAdapter.kt index 9596eed04..7362710e0 100644 --- a/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonsManagerAdapter.kt +++ b/app/src/main/java/io/github/forkmaintainers/iceraven/components/PagedAddonsManagerAdapter.kt @@ -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, 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) { diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index 08700ae73..78e3c4a2b 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -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()), diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt index f36ad9c0f..e21d9e2c6 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -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")