Loading app/src/main/java/org/mozilla/fenix/ext/String.kt +21 −0 Original line number Diff line number Diff line Loading @@ -5,15 +5,20 @@ package org.mozilla.fenix.ext import android.content.Context import android.graphics.BitmapFactory import android.net.Uri import android.util.Patterns import android.webkit.URLUtil import androidx.core.graphics.drawable.RoundedBitmapDrawable import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import androidx.core.net.toUri import kotlinx.coroutines.runBlocking import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.lib.publicsuffixlist.ext.urlToTrimmedHost import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes import java.net.IDN import java.net.MalformedURLException import java.net.URL import java.util.Locale const val FILE_PREFIX = "file://" Loading Loading @@ -106,3 +111,19 @@ fun String.simplifiedUrl(): String { } return afterScheme } /** * Gets a rounded drawable from a URL if possible, else null. Must be called off main thread. */ fun String.decodeUrlToRoundedDrawable(context: Context): RoundedBitmapDrawable? { val avatarUrl = try { URL(this) } catch (e: MalformedURLException) { return null } val bitmap = BitmapFactory.decodeStream(avatarUrl.openConnection().getInputStream()) val roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(context.resources, bitmap) roundedBitmapDrawable.isCircular = true roundedBitmapDrawable.setAntiAlias(true) return roundedBitmapDrawable } app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +18 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.appcompat.content.res.AppCompatResources import androidx.lifecycle.lifecycleScope import androidx.navigation.NavDirections import androidx.navigation.findNavController Loading @@ -17,7 +18,10 @@ import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount Loading @@ -30,6 +34,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.application import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.decodeUrlToRoundedDrawable import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.requireComponents Loading Loading @@ -320,6 +325,19 @@ class SettingsFragment : PreferenceFragmentCompat() { // Signed-in, no problems. if (account != null && !accountManager.accountNeedsReauth()) { preferenceSignIn?.isVisible = false profile?.avatar?.url?.let { lifecycleScope.launch(IO) { val roundedDrawable = it.decodeUrlToRoundedDrawable(context) withContext(Main) { preferenceFirefoxAccount?.icon = roundedDrawable ?: AppCompatResources.getDrawable( context, R.drawable.ic_account ) } } } preferenceSignIn?.onPreferenceClickListener = null preferenceFirefoxAccountAuthError?.isVisible = false preferenceFirefoxAccount?.isVisible = true Loading app/src/main/res/layout/account_preference.xml +9 −16 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- This Source Code Form is subject to the terms of the Mozilla Public <?xml version="1.0" encoding="utf-8"?><!-- 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/. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/account_preference_background" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> <FrameLayout android:id="@+id/icon_frame" android:layout_width="wrap_content" android:layout_height="wrap_content"> <androidx.preference.internal.PreferenceImageView <ImageView android:id="@android:id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" app:maxHeight="48dp" app:maxWidth="48dp" /> </FrameLayout> android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center" android:scaleType="fitCenter" /> <RelativeLayout android:layout_width="0dp" Loading @@ -32,8 +25,8 @@ android:layout_marginEnd="6dp" android:layout_weight="1" android:paddingStart="16dp" android:paddingEnd="0dp" android:paddingTop="16dp" android:paddingEnd="0dp" android:paddingBottom="16dp"> <TextView Loading Loading
app/src/main/java/org/mozilla/fenix/ext/String.kt +21 −0 Original line number Diff line number Diff line Loading @@ -5,15 +5,20 @@ package org.mozilla.fenix.ext import android.content.Context import android.graphics.BitmapFactory import android.net.Uri import android.util.Patterns import android.webkit.URLUtil import androidx.core.graphics.drawable.RoundedBitmapDrawable import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import androidx.core.net.toUri import kotlinx.coroutines.runBlocking import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.lib.publicsuffixlist.ext.urlToTrimmedHost import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes import java.net.IDN import java.net.MalformedURLException import java.net.URL import java.util.Locale const val FILE_PREFIX = "file://" Loading Loading @@ -106,3 +111,19 @@ fun String.simplifiedUrl(): String { } return afterScheme } /** * Gets a rounded drawable from a URL if possible, else null. Must be called off main thread. */ fun String.decodeUrlToRoundedDrawable(context: Context): RoundedBitmapDrawable? { val avatarUrl = try { URL(this) } catch (e: MalformedURLException) { return null } val bitmap = BitmapFactory.decodeStream(avatarUrl.openConnection().getInputStream()) val roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(context.resources, bitmap) roundedBitmapDrawable.isCircular = true roundedBitmapDrawable.setAntiAlias(true) return roundedBitmapDrawable }
app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +18 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.appcompat.content.res.AppCompatResources import androidx.lifecycle.lifecycleScope import androidx.navigation.NavDirections import androidx.navigation.findNavController Loading @@ -17,7 +18,10 @@ import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount Loading @@ -30,6 +34,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.application import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.decodeUrlToRoundedDrawable import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.requireComponents Loading Loading @@ -320,6 +325,19 @@ class SettingsFragment : PreferenceFragmentCompat() { // Signed-in, no problems. if (account != null && !accountManager.accountNeedsReauth()) { preferenceSignIn?.isVisible = false profile?.avatar?.url?.let { lifecycleScope.launch(IO) { val roundedDrawable = it.decodeUrlToRoundedDrawable(context) withContext(Main) { preferenceFirefoxAccount?.icon = roundedDrawable ?: AppCompatResources.getDrawable( context, R.drawable.ic_account ) } } } preferenceSignIn?.onPreferenceClickListener = null preferenceFirefoxAccountAuthError?.isVisible = false preferenceFirefoxAccount?.isVisible = true Loading
app/src/main/res/layout/account_preference.xml +9 −16 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- This Source Code Form is subject to the terms of the Mozilla Public <?xml version="1.0" encoding="utf-8"?><!-- 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/. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/account_preference_background" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> <FrameLayout android:id="@+id/icon_frame" android:layout_width="wrap_content" android:layout_height="wrap_content"> <androidx.preference.internal.PreferenceImageView <ImageView android:id="@android:id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" app:maxHeight="48dp" app:maxWidth="48dp" /> </FrameLayout> android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center" android:scaleType="fitCenter" /> <RelativeLayout android:layout_width="0dp" Loading @@ -32,8 +25,8 @@ android:layout_marginEnd="6dp" android:layout_weight="1" android:paddingStart="16dp" android:paddingEnd="0dp" android:paddingTop="16dp" android:paddingEnd="0dp" android:paddingBottom="16dp"> <TextView Loading