commit 39769f8940c1b14f87c1473b5a7089599d2a24b3
parent fe0b82c75b81c0048cf89a1b19b16113108415a1
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Sun, 4 Jun 2023 20:57:32 +0200
add: status dialogs
Diffstat:
3 files changed, 64 insertions(+), 18 deletions(-)
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt b/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt
@@ -11,6 +11,8 @@ import me.rhunk.snapenhance.bridge.client.ServiceBridgeClient
import me.rhunk.snapenhance.data.SnapClassCache
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
+import kotlin.time.ExperimentalTime
+import kotlin.time.measureTime
class SnapEnhance {
companion object {
@@ -22,7 +24,6 @@ class SnapEnhance {
private val appContext = ModContext()
init {
-
Hooker.hook(Application::class.java, "attach", HookStage.BEFORE) { param ->
appContext.androidContext = param.arg<Context>(0).also {
classLoader = it.classLoader
@@ -51,7 +52,7 @@ class SnapEnhance {
if (!activity.packageName.equals(Constants.SNAPCHAT_PACKAGE_NAME)) return@hook
val isMainActivityNotNull = appContext.mainActivity != null
appContext.mainActivity = activity
- if (isMainActivityNotNull) return@hook
+ if (isMainActivityNotNull || !appContext.mappings.areMappingsLoaded) return@hook
onActivityCreate()
}
}
@@ -65,15 +66,20 @@ class SnapEnhance {
return ServiceBridgeClient()
}
+ @OptIn(ExperimentalTime::class)
private fun init() {
- val time = System.currentTimeMillis()
- with(appContext) {
- translation.init()
- config.init()
- mappings.init()
- features.init()
+ measureTime {
+ with(appContext) {
+ translation.init()
+ config.init()
+ mappings.init()
+ //if mappings aren't loaded, we can't initialize features
+ if (!mappings.areMappingsLoaded) return
+ features.init()
+ }
+ }.also { time ->
+ Logger.debug("initialized in $time")
}
- Logger.debug("initialized in ${System.currentTimeMillis() - time} ms")
}
private fun onActivityCreate() {
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/GalleryMediaSendOverride.kt b/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/GalleryMediaSendOverride.kt
@@ -1,5 +1,6 @@
package me.rhunk.snapenhance.features.impl.tweaks
+import android.app.AlertDialog
import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.MessageSender
@@ -11,7 +12,6 @@ import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.util.protobuf.ProtoReader
class GalleryMediaSendOverride : Feature("Gallery Media Send Override", loadParams = FeatureLoadParams.INIT_SYNC) {
-
override fun init() {
Hooker.hook(context.classCache.conversationManager, "sendMessageWithContent", HookStage.BEFORE) { param ->
val localMessageContent = MessageContent(param.arg(1))
@@ -20,8 +20,20 @@ class GalleryMediaSendOverride : Feature("Gallery Media Send Override", loadPara
//story replies
val messageProtoReader = ProtoReader(localMessageContent.content)
if (messageProtoReader.exists(7)) return@hook
+ val overrideType = context.config.state(ConfigProperty.GALLERY_MEDIA_SEND_OVERRIDE)
+
+ if (overrideType != "OFF" && messageProtoReader.readPath(3)?.getCount(3) != 1) {
+ context.runOnUiThread {
+ AlertDialog.Builder(context.mainActivity!!)
+ .setMessage("You can only send one media at a time")
+ .setPositiveButton("OK", null)
+ .show()
+ }
+ param.setResult(null)
+ return@hook
+ }
- when (val overrideType = context.config.state(ConfigProperty.GALLERY_MEDIA_SEND_OVERRIDE)) {
+ when (overrideType) {
"SNAP", "LIVE_SNAP" -> {
localMessageContent.contentType = ContentType.SNAP
localMessageContent.content = MessageSender.redSnapProto(overrideType == "LIVE_SNAP")
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/MappingManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/MappingManager.kt
@@ -1,9 +1,11 @@
package me.rhunk.snapenhance.manager.impl
+import android.app.AlertDialog
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import kotlinx.coroutines.Job
+import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import me.rhunk.snapenhance.Constants
@@ -22,6 +24,7 @@ import me.rhunk.snapenhance.mapping.impl.PlusSubscriptionMapper
import me.rhunk.snapenhance.util.getObjectField
import java.nio.charset.StandardCharsets
import java.util.concurrent.ConcurrentHashMap
+import kotlin.concurrent.thread
@Suppress("UNCHECKED_CAST")
class MappingManager(private val context: ModContext) : Manager {
@@ -36,6 +39,8 @@ class MappingManager(private val context: ModContext) : Manager {
}
private val mappings = ConcurrentHashMap<String, Any>()
+ val areMappingsLoaded: Boolean
+ get() = mappings.isNotEmpty()
private var snapBuildNumber = 0
@Suppress("deprecation")
@@ -59,12 +64,35 @@ class MappingManager(private val context: ModContext) : Manager {
}
return
}
- runCatching {
- refresh()
- }.onSuccess {
- context.shortToast("Generated mappings for build $snapBuildNumber")
- }.onFailure {
- context.crash("Failed to generate mappings ${it.message}", it)
+ context.runOnUiThread {
+ val statusDialogBuilder = AlertDialog.Builder(context.mainActivity)
+ .setMessage("Generating mappings, please wait...")
+ .setCancelable(false)
+ .setView(android.widget.ProgressBar(context.mainActivity).apply {
+ setPadding(0, 20, 0, 20)
+ })
+
+ val loadingDialog = statusDialogBuilder.show()
+
+ thread(start = true) {
+ runCatching {
+ refresh()
+ }.onSuccess {
+ context.shortToast("Generated mappings for build $snapBuildNumber")
+ context.softRestartApp()
+ }.onFailure {
+ Logger.error("Failed to generate mappings", it)
+ context.runOnUiThread {
+ loadingDialog.dismiss()
+ statusDialogBuilder.setView(null)
+ statusDialogBuilder.setMessage("Failed to generate mappings: $it")
+ statusDialogBuilder.setNegativeButton("Close") { _, _ ->
+ context.mainActivity!!.finish()
+ }
+ statusDialogBuilder.show()
+ }
+ }
+ }
}
}
@@ -107,7 +135,7 @@ class MappingManager(private val context: ModContext) : Manager {
}
}.also { jobs.add(it) }
}
- jobs.forEach { it.join() }
+ jobs.joinAll()
}
@Suppress("UNCHECKED_CAST", "DEPRECATION")