diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cd57cc67..431397483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ ### Significant bug fixes +## v25.1 + +### Significant bug fixes + +- Fixed two crashes at startup introduced in 25.0 [PR#4415](https://github.com/tuskyapp/Tusky/pull/4415) [PR#4417](https://github.com/tuskyapp/Tusky/pull/4417) + ## v25.0 ### New features and other improvements diff --git a/app/build.gradle b/app/build.gradle index 97e604233..b6c224555 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { namespace "com.keylesspalace.tusky" minSdk 24 targetSdk 34 - versionCode 119 - versionName "25.0" + versionCode 120 + versionName "25.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/com/keylesspalace/tusky/util/GlideExtensions.kt b/app/src/main/java/com/keylesspalace/tusky/util/GlideExtensions.kt index bbad02f5f..bc5ad2b3a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/GlideExtensions.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/GlideExtensions.kt @@ -8,7 +8,6 @@ import com.bumptech.glide.request.target.Target import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException import kotlinx.coroutines.suspendCancellableCoroutine -import okio.IOException /** * Allows waiting for a Glide request to complete without blocking a background thread. @@ -26,7 +25,7 @@ suspend fun RequestBuilder.submitAsync( target: Target, isFirstResource: Boolean ): Boolean { - continuation.resumeWithException(e ?: IOException("Image loading failed")) + continuation.resumeWithException(e ?: GlideException("Image loading failed")) return false } diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt b/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt index 03c5d5848..fafb007be 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt @@ -21,11 +21,15 @@ import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.graphics.Canvas +import android.util.Log +import androidx.appcompat.content.res.AppCompatResources import androidx.core.app.Person import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat +import androidx.core.graphics.drawable.toBitmap import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.GlideException import com.keylesspalace.tusky.MainActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.db.AccountManager @@ -49,14 +53,20 @@ class ShareShortcutHelper @Inject constructor( val maxNumberOfShortcuts = ShortcutManagerCompat.getMaxShortcutCountPerActivity(context) - val shortcuts = accountManager.accounts.take(maxNumberOfShortcuts).map { account -> + val shortcuts = accountManager.accounts.take(maxNumberOfShortcuts).mapNotNull { account -> - val bmp = Glide.with(context) - .asBitmap() - .load(account.profilePictureUrl) - .placeholder(R.drawable.avatar_default) - .error(R.drawable.avatar_default) - .submitAsync(innerSize, innerSize) + val bmp = try { + Glide.with(context) + .asBitmap() + .load(account.profilePictureUrl) + .placeholder(R.drawable.avatar_default) + .error(R.drawable.avatar_default) + .submitAsync(innerSize, innerSize) + } catch (e: GlideException) { + // https://github.com/bumptech/glide/issues/4672 :/ + Log.w(TAG, "failed to load avatar ${account.profilePictureUrl}", e) + AppCompatResources.getDrawable(context, R.drawable.avatar_default)?.toBitmap(innerSize, innerSize) ?: return@mapNotNull null + } // inset the loaded bitmap inside a 108dp transparent canvas so it looks good as adaptive icon val outBmp = Bitmap.createBitmap(outerSize, outerSize, Bitmap.Config.ARGB_8888) @@ -89,16 +99,19 @@ class ShareShortcutHelper @Inject constructor( .setCategories(setOf("com.keylesspalace.tusky.Share")) .setShortLabel(account.displayName) .setPerson(person) - .setLongLived(true) .setIcon(icon) .build() } - ShortcutManagerCompat.addDynamicShortcuts(context, shortcuts) + ShortcutManagerCompat.setDynamicShortcuts(context, shortcuts) } } fun removeShortcut(account: AccountEntity) { ShortcutManagerCompat.removeDynamicShortcuts(context, listOf(account.id.toString())) } + + companion object { + private const val TAG = "ShareShortcutHelper" + } }