From 17d43d0c2719cd93e3e7b39427639493020d4396 Mon Sep 17 00:00:00 2001 From: Yuichiro Kinoshita Date: Mon, 26 Jun 2023 12:56:32 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20fallback=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../milktea/common_android_ui/MFMDecorator.kt | 35 ++++++++-- .../common_android_ui/ReactionViewHelper.kt | 6 +- .../image/ImageCacheRepositoryImpl.kt | 67 +++++++++---------- .../note/reaction/NoteReactionViewHelper.kt | 12 +++- .../reaction/choices/EmojiListItemsAdapter.kt | 12 +++- 5 files changed, 90 insertions(+), 42 deletions(-) diff --git a/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/MFMDecorator.kt b/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/MFMDecorator.kt index 64647745b8..dfcb9d6513 100644 --- a/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/MFMDecorator.kt +++ b/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/MFMDecorator.kt @@ -6,16 +6,36 @@ import android.content.Intent import android.graphics.Color import android.graphics.Typeface import android.net.Uri -import android.text.* -import android.text.style.* +import android.text.Layout +import android.text.SpannableString +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.SpannedString +import android.text.style.AlignmentSpan +import android.text.style.BackgroundColorSpan +import android.text.style.ClickableSpan +import android.text.style.ForegroundColorSpan +import android.text.style.QuoteSpan +import android.text.style.RelativeSizeSpan +import android.text.style.StrikethroughSpan +import android.text.style.StyleSpan import android.util.Log import android.view.View import android.widget.TextView import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.internal.managers.FragmentComponentManager -import jp.panta.misskeyandroidclient.mfm.* +import jp.panta.misskeyandroidclient.mfm.EmojiElement +import jp.panta.misskeyandroidclient.mfm.HashTag +import jp.panta.misskeyandroidclient.mfm.Mention +import jp.panta.misskeyandroidclient.mfm.Node +import jp.panta.misskeyandroidclient.mfm.Search +import jp.panta.misskeyandroidclient.mfm.Text import net.pantasystem.milktea.common.glide.GlideApp -import net.pantasystem.milktea.common_android.mfm.* +import net.pantasystem.milktea.common_android.mfm.Element +import net.pantasystem.milktea.common_android.mfm.ElementType +import net.pantasystem.milktea.common_android.mfm.Leaf +import net.pantasystem.milktea.common_android.mfm.Link +import net.pantasystem.milktea.common_android.mfm.Root import net.pantasystem.milktea.common_android.ui.Activities import net.pantasystem.milktea.common_android.ui.putActivity import net.pantasystem.milktea.common_android.ui.text.DrawableEmojiSpan @@ -321,7 +341,12 @@ object MFMDecorator { else -> height * aspectRatio } GlideApp.with(textView) - .load(emojiElement.emoji.getLoadUrl()) + .load(emojiElement.emoji.cachePath) + .error( + GlideApp.with(textView) + .load(emojiElement.emoji.url ?: emojiElement.emoji.uri) + .override((width * customEmojiScale).toInt(), (height * customEmojiScale).toInt()) + ) .override((width * customEmojiScale).toInt(), (height * customEmojiScale).toInt()) .into(emojiSpan.target) } diff --git a/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/ReactionViewHelper.kt b/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/ReactionViewHelper.kt index d5d1ae432e..eab7797abc 100644 --- a/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/ReactionViewHelper.kt +++ b/modules/common_android_ui/src/main/java/net/pantasystem/milktea/common_android_ui/ReactionViewHelper.kt @@ -84,7 +84,11 @@ object ReactionViewHelper { if (emoji != null) { //Log.d("ReactionViewHelper", "カスタム絵文字を発見した: ${emoji}") GlideApp.with(reactionImageView.context) - .load(emoji.getLoadUrl()) + .load(emoji.cachePath) + .error( + GlideApp.with(reactionImageView.context) + .load(emoji.url ?: emoji.uri) + ) .into(reactionImageView) reactionImageView.setMemoVisibility(View.VISIBLE) reactionStringView.setMemoVisibility(View.GONE) diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/image/ImageCacheRepositoryImpl.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/image/ImageCacheRepositoryImpl.kt index 0e7fa36195..18424e3140 100644 --- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/image/ImageCacheRepositoryImpl.kt +++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/image/ImageCacheRepositoryImpl.kt @@ -7,6 +7,7 @@ import android.net.Uri import dagger.hilt.android.qualifiers.ApplicationContext import io.objectbox.BoxStore import io.objectbox.kotlin.awaitCallInTx +import io.objectbox.kotlin.inValues import io.objectbox.query.QueryBuilder import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext @@ -34,7 +35,7 @@ class ImageCacheRepositoryImpl @Inject constructor( companion object { const val cacheDir = "milktea_image_caches" -// val cacheExpireDuration = 7.days + val cacheExpireDuration = 7.days val cacheIgnoreUpdateDuration = 3.days } @@ -76,22 +77,21 @@ class ImageCacheRepositoryImpl @Inject constructor( } override suspend fun findBySourceUrl(url: String): ImageCache? { -// return withContext(coroutineDispatcher) { -// val now = Clock.System.now() -// val record = imageCacheStore.query().equal( -// ImageCacheRecord_.sourceUrl, -// url, -// QueryBuilder.StringOrder.CASE_SENSITIVE -// ).build().findFirst() -// val model = record?.toModel() -// if (model != null && now - model.cachedAt > cacheExpireDuration) { -// imageCacheStore.remove(record) -// null -// } else { -// model -// } -// } - return null + return withContext(coroutineDispatcher) { + val now = Clock.System.now() + val record = imageCacheStore.query().equal( + ImageCacheRecord_.sourceUrl, + url, + QueryBuilder.StringOrder.CASE_SENSITIVE + ).build().findFirst() + val model = record?.toModel() + if (model != null && now - model.cachedAt > cacheExpireDuration) { + imageCacheStore.remove(record) + null + } else { + model + } + } } override suspend fun deleteExpiredCaches() { @@ -112,23 +112,22 @@ class ImageCacheRepositoryImpl @Inject constructor( } override suspend fun findBySourceUrls(urls: List): List { -// return withContext(coroutineDispatcher) { -// val now = Clock.System.now() -// val records = imageCacheStore.query().inValues( -// ImageCacheRecord_.sourceUrl, -// urls.toTypedArray(), -// QueryBuilder.StringOrder.CASE_SENSITIVE -// ).build().find() -// records.mapNotNull { record -> -// val model = record.toModel() -// if (now - model.cachedAt > cacheExpireDuration) { -// null -// } else { -// model -// } -// } -// } - return emptyList() + return withContext(coroutineDispatcher) { + val now = Clock.System.now() + val records = imageCacheStore.query().inValues( + ImageCacheRecord_.sourceUrl, + urls.toTypedArray(), + QueryBuilder.StringOrder.CASE_SENSITIVE + ).build().find() + records.mapNotNull { record -> + val model = record.toModel() + if (now - model.cachedAt > cacheExpireDuration) { + null + } else { + model + } + } + } } private suspend fun upInsert(cache: ImageCache) { diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/NoteReactionViewHelper.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/NoteReactionViewHelper.kt index cb501d1871..14c0478a78 100644 --- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/NoteReactionViewHelper.kt +++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/NoteReactionViewHelper.kt @@ -58,7 +58,13 @@ object NoteReactionViewHelper { GlideApp.with(reactionImageTypeView.context) - .load(emoji.getLoadUrl()) + .load(emoji.cachePath) + .error( + GlideApp.with(reactionImageTypeView.context) + .load(emoji.url ?: emoji.uri) + .override(imageViewWidthPx.toInt(), imageViewHeightPx.toInt()) + .addListener(SaveImageAspectRequestListener(emoji, context)) + ) .override(imageViewWidthPx.toInt(), imageViewHeightPx.toInt()) .addListener(SaveImageAspectRequestListener(emoji, context)) .into(reactionImageTypeView) @@ -98,6 +104,10 @@ object NoteReactionViewHelper { GlideApp.with(reactionImageTypeView.context) .load(emoji.getLoadUrl()) + .error( + GlideApp.with(reactionImageTypeView.context) + .load(emoji.url ?: emoji.uri) + ) .into(reactionImageTypeView) } diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/choices/EmojiListItemsAdapter.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/choices/EmojiListItemsAdapter.kt index d4a2aa28c3..d659dbd6ba 100644 --- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/choices/EmojiListItemsAdapter.kt +++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/reaction/choices/EmojiListItemsAdapter.kt @@ -76,7 +76,7 @@ class EmojiListItemsAdapter( ) } GlideApp.with(binding.reactionImagePreview.context) - .load(item.emoji.getLoadUrl()) + .load(item.emoji.cachePath) // FIXME: webpの場合うまく表示できなくなる // .centerCrop() .addListener( @@ -85,6 +85,16 @@ class EmojiListItemsAdapter( binding.root.context ) ) + .error( + GlideApp.with(binding.reactionImagePreview.context) + .load(item.emoji.url ?: item.emoji.uri) + .addListener( + SaveImageAspectRequestListener( + item.emoji, + binding.root.context + ) + ) + ) .into(binding.reactionImagePreview)