[fenix] For https://github.com/mozilla-mobile/fenix/issues/23432 - Use the imageUrl as the favicon for a provided top site

pull/600/head
Gabriel Luong 2 years ago committed by mergify[bot]
parent 4cc353c6fb
commit 60d9bcec18

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ext
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import mozilla.components.concept.fetch.Client
import mozilla.components.concept.fetch.Request
import java.io.IOException
/**
* Given an image [url], fetches and returns a [Bitmap] if possible, otherwise null.
*
* @param url The image URL to fetch from.
*/
suspend fun Client.bitmapForUrl(url: String): Bitmap? = withContext(Dispatchers.IO) {
// Code below will cache it in Gecko's cache, which ensures that as long as we've fetched it once,
// we will be able to display this avatar as long as the cache isn't purged (e.g. via 'clear user data').
val body = try {
fetch(Request(url, useCaches = true)).body
} catch (e: IOException) {
return@withContext null
}
body.useStream { BitmapFactory.decodeStream(it) }
}

@ -4,20 +4,13 @@
package org.mozilla.fenix.ext
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.text.Editable
import android.util.Patterns
import android.webkit.URLUtil
import androidx.core.net.toUri
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import mozilla.components.concept.fetch.Client
import mozilla.components.concept.fetch.Request
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
import java.io.IOException
import java.net.IDN
import java.util.Locale
@ -110,14 +103,3 @@ fun String.simplifiedUrl(): String {
* Returns an [Editable] for the provided string.
*/
fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)
suspend fun bitmapForUrl(url: String, client: Client): Bitmap? = withContext(Dispatchers.IO) {
// Code below will cache it in Gecko's cache, which ensures that as long as we've fetched it once,
// we will be able to display this avatar as long as the cache isn't purged (e.g. via 'clear user data').
val body = try {
client.fetch(Request(url, useCaches = true)).body
} catch (e: IOException) {
return@withContext null
}
body.useStream { BitmapFactory.decodeStream(it) }
}

@ -10,12 +10,18 @@ import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
import androidx.appcompat.content.res.AppCompatResources.getDrawable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.databinding.TopSiteItemBinding
import org.mozilla.fenix.ext.bitmapForUrl
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
@ -72,27 +78,37 @@ class TopSiteItemViewHolder(
binding.topSiteTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
}
when (topSite.url) {
SupportUtils.POCKET_TRENDING_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_pocket))
}
SupportUtils.BAIDU_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_baidu))
}
SupportUtils.JD_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_jd))
}
SupportUtils.PDD_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_pdd))
}
SupportUtils.TC_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_tc))
}
SupportUtils.MEITUAN_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_meituan))
if (topSite is TopSite.Provided) {
CoroutineScope(IO).launch {
itemView.context.components.core.client.bitmapForUrl(topSite.imageUrl)?.let { bitmap ->
withContext(Main) {
binding.faviconImage.setImageBitmap(bitmap)
}
}
}
else -> {
itemView.context.components.core.icons.loadIntoView(binding.faviconImage, topSite.url)
} else {
when (topSite.url) {
SupportUtils.POCKET_TRENDING_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_pocket))
}
SupportUtils.BAIDU_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_baidu))
}
SupportUtils.JD_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_jd))
}
SupportUtils.PDD_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_pdd))
}
SupportUtils.TC_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_tc))
}
SupportUtils.MEITUAN_URL -> {
binding.faviconImage.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_meituan))
}
else -> {
itemView.context.components.core.icons.loadIntoView(binding.faviconImage, topSite.url)
}
}
}

@ -114,7 +114,7 @@ class AccountUiView(
private suspend fun toRoundedDrawable(
url: String,
context: Context
) = bitmapForUrl(url, httpClient)?.let { bitmap ->
) = httpClient.bitmapForUrl(url)?.let { bitmap ->
RoundedBitmapDrawableFactory.create(context.resources, bitmap).apply {
isCircular = true
setAntiAlias(true)

Loading…
Cancel
Save