mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-21 00:27:09 +02:00
feat(media_downloader): better preview of chat messages
- set media resolver url to web api
This commit is contained in:
parent
bf73babf0d
commit
2e4b161eeb
@ -9,7 +9,7 @@ import java.io.InputStream
|
|||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
|
|
||||||
object RemoteMediaResolver {
|
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/"
|
const val CF_ST_CDN_D = "https://cf-st.sc-cdn.net/d/"
|
||||||
|
|
||||||
private val urlCache = mutableMapOf<String, String>()
|
private val urlCache = mutableMapOf<String, String>()
|
||||||
|
@ -32,4 +32,8 @@ abstract class Feature(
|
|||||||
protected fun findClass(name: String): Class<*> {
|
protected fun findClass(name: String): Class<*> {
|
||||||
return context.androidContext.classLoader.loadClass(name)
|
return context.androidContext.classLoader.loadClass(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun runOnUiThread(block: () -> Unit) {
|
||||||
|
context.runOnUiThread(block)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,10 +1,18 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.downloader
|
package me.rhunk.snapenhance.features.impl.downloader
|
||||||
|
|
||||||
import android.content.DialogInterface
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
|
import android.view.Window
|
||||||
import android.widget.ImageView
|
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 kotlinx.coroutines.runBlocking
|
||||||
import me.rhunk.snapenhance.bridge.DownloadCallback
|
import me.rhunk.snapenhance.bridge.DownloadCallback
|
||||||
import me.rhunk.snapenhance.core.database.objects.FriendInfo
|
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) {
|
fun downloadMessageId(messageId: Long, isPreview: Boolean = false) {
|
||||||
val messageLogger = context.feature(MessageLogger::class)
|
val messageLogger = context.feature(MessageLogger::class)
|
||||||
val message = context.database.getConversationMessageFromId(messageId) ?: throw Exception("Message not found in database")
|
val message = context.database.getConversationMessageFromId(messageId) ?: throw Exception("Message not found in database")
|
||||||
@ -557,35 +567,76 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
val previewCoroutine = async {
|
||||||
val downloadedMediaList = MediaDownloaderHelper.downloadMediaFromReference(urlProto) {
|
val downloadedMediaList = MediaDownloaderHelper.downloadMediaFromReference(urlProto) {
|
||||||
EncryptionHelper.decryptInputStream(it, contentType, messageReader, isArroyo = isArroyoMessage)
|
EncryptionHelper.decryptInputStream(it, contentType, messageReader, isArroyo = isArroyoMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
runCatching {
|
val originalMedia = downloadedMediaList[SplitMediaAssetType.ORIGINAL] ?: return@async null
|
||||||
val originalMedia = downloadedMediaList[SplitMediaAssetType.ORIGINAL] ?: return
|
|
||||||
val overlay = downloadedMediaList[SplitMediaAssetType.OVERLAY]
|
val overlay = downloadedMediaList[SplitMediaAssetType.OVERLAY]
|
||||||
|
|
||||||
var bitmap: Bitmap? = PreviewUtils.createPreview(originalMedia, isVideo = FileType.fromByteArray(originalMedia).isVideo)
|
var bitmap: Bitmap? = PreviewUtils.createPreview(originalMedia, isVideo = FileType.fromByteArray(originalMedia).isVideo)
|
||||||
|
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
context.shortToast(translations["failed_to_create_preview_toast"])
|
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))
|
bitmap = PreviewUtils.mergeBitmapOverlay(bitmap!!, BitmapFactory.decodeByteArray(it, 0, it.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
with(ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity)) {
|
bitmap
|
||||||
setView(ImageView(context).apply {
|
}
|
||||||
setImageBitmap(bitmap)
|
|
||||||
})
|
with(ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity)) {
|
||||||
setPositiveButton("Close") { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
val viewGroup = LinearLayout(context).apply {
|
||||||
this@MediaDownloader.context.runOnUiThread { show()}
|
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 {
|
}.onFailure {
|
||||||
context.longToast(translations["failed_generic_toast"])
|
context.longToast(translations["failed_generic_toast"])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user