feat(media_downloader): better preview of chat messages

- set media resolver url to web api
This commit is contained in:
rhunk 2023-09-13 19:26:59 +02:00
parent bf73babf0d
commit 2e4b161eeb
3 changed files with 78 additions and 23 deletions

View File

@ -9,7 +9,7 @@ import java.io.InputStream
import java.util.Base64
object RemoteMediaResolver {
private const val BOLT_HTTP_RESOLVER_URL = "https://aws.api.snapchat.com/bolt-http"
private const val BOLT_HTTP_RESOLVER_URL = "https://web.snapchat.com/bolt-http"
const val CF_ST_CDN_D = "https://cf-st.sc-cdn.net/d/"
private val urlCache = mutableMapOf<String, String>()

View File

@ -32,4 +32,8 @@ abstract class Feature(
protected fun findClass(name: String): Class<*> {
return context.androidContext.classLoader.loadClass(name)
}
protected fun runOnUiThread(block: () -> Unit) {
context.runOnUiThread(block)
}
}

View File

@ -1,10 +1,18 @@
package me.rhunk.snapenhance.features.impl.downloader
import android.content.DialogInterface
import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.view.Gravity
import android.view.ViewGroup.MarginLayoutParams
import android.view.Window
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import me.rhunk.snapenhance.bridge.DownloadCallback
import me.rhunk.snapenhance.core.database.objects.FriendInfo
@ -475,6 +483,8 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp
}
}
@SuppressLint("SetTextI18n")
@OptIn(ExperimentalCoroutinesApi::class)
fun downloadMessageId(messageId: Long, isPreview: Boolean = false) {
val messageLogger = context.feature(MessageLogger::class)
val message = context.database.getConversationMessageFromId(messageId) ?: throw Exception("Message not found in database")
@ -557,35 +567,76 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp
return
}
runBlocking {
val previewCoroutine = async {
val downloadedMediaList = MediaDownloaderHelper.downloadMediaFromReference(urlProto) {
EncryptionHelper.decryptInputStream(it, contentType, messageReader, isArroyo = isArroyoMessage)
}
runCatching {
val originalMedia = downloadedMediaList[SplitMediaAssetType.ORIGINAL] ?: return
val originalMedia = downloadedMediaList[SplitMediaAssetType.ORIGINAL] ?: return@async null
val overlay = downloadedMediaList[SplitMediaAssetType.OVERLAY]
var bitmap: Bitmap? = PreviewUtils.createPreview(originalMedia, isVideo = FileType.fromByteArray(originalMedia).isVideo)
if (bitmap == null) {
context.shortToast(translations["failed_to_create_preview_toast"])
return
return@async null
}
overlay?.let {
overlay?.also {
bitmap = PreviewUtils.mergeBitmapOverlay(bitmap!!, BitmapFactory.decodeByteArray(it, 0, it.size))
}
with(ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity)) {
setView(ImageView(context).apply {
setImageBitmap(bitmap)
})
setPositiveButton("Close") { dialog: DialogInterface, _: Int -> dialog.dismiss() }
this@MediaDownloader.context.runOnUiThread { show()}
bitmap
}
with(ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity)) {
val viewGroup = LinearLayout(context).apply {
layoutParams = MarginLayoutParams(MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.MATCH_PARENT)
gravity = Gravity.CENTER_HORIZONTAL or Gravity.CENTER_VERTICAL
addView(ProgressBar(context).apply {
isIndeterminate = true
})
}
setOnDismissListener {
previewCoroutine.cancel()
}
previewCoroutine.invokeOnCompletion { cause ->
runOnUiThread {
viewGroup.removeAllViews()
if (cause != null) {
viewGroup.addView(TextView(context).apply {
text = translations["failed_to_create_preview_toast"] + "\n" + cause.message
setPadding(30, 30, 30, 30)
})
return@runOnUiThread
}
viewGroup.addView(ImageView(context).apply {
setImageBitmap(previewCoroutine.getCompleted())
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
adjustViewBounds = true
})
}
}
runOnUiThread {
show().apply {
setContentView(viewGroup)
requestWindowFeature(Window.FEATURE_NO_TITLE)
window?.setLayout(
context.resources.displayMetrics.widthPixels,
context.resources.displayMetrics.heightPixels
)
}
previewCoroutine.start()
}
}
}.onFailure {
context.shortToast(translations["failed_to_create_preview_toast"])
context.log.error("Failed to create preview", it)
}
}.onFailure {
context.longToast(translations["failed_generic_toast"])