From da543f14e921dcb66f93e43e27ca648a681617ec Mon Sep 17 00:00:00 2001 From: rhunk <101876869+rhunk@users.noreply.github.com> Date: Sun, 2 Jul 2023 17:27:53 +0200 Subject: [PATCH] feat: startup page override (#115) * feat: startup page override * feat(conversation_info): total messages * fix: translation key --- app/src/main/assets/lang/en_US.json | 14 +++++ .../me/rhunk/snapenhance/SnapEnhance.kt | 2 - .../snapenhance/config/ConfigProperty.kt | 16 +++++ .../features/impl/ui/StartupPageOverride.kt | 60 +++++++++++++++++++ .../manager/impl/FeatureManager.kt | 2 + .../ui/menu/impl/FriendFeedInfoMenu.kt | 13 +++- 6 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 app/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/StartupPageOverride.kt diff --git a/app/src/main/assets/lang/en_US.json b/app/src/main/assets/lang/en_US.json index 1521fa5a..5a2a50af 100644 --- a/app/src/main/assets/lang/en_US.json +++ b/app/src/main/assets/lang/en_US.json @@ -160,6 +160,10 @@ "name": "Enable App Appearance Settings", "description": "Enables the hidden app appearance settings" }, + "startup_page_override": { + "name": "Override Startup Page", + "description": "Overrides the startup page" + }, "auto_updater": { "name": "Auto Updater", @@ -286,6 +290,15 @@ "hide_friends": "Hide friends section", "hide_following": "Hide following section", "hide_for_you": "Hide For You section" + }, + "startup_page_override": { + "OFF": "Off", + "ngs_map_icon_container": "Map", + "ngs_chat_icon_container": "Chat", + "ngs_camera_icon_container": "Camera", + "ngs_community_icon_container": "Community / Stories", + "ngs_spotlight_icon_container": "Spotlight", + "ngs_search_icon_container": "Search" } } }, @@ -319,6 +332,7 @@ "conversation_preview": { "streak_expiration": "expires in {day} days {hour} hours {minute} minutes", + "total_messages": "Total sent/received messages: {count}", "title": "Preview", "unknown_user": "Unknown User" }, diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt b/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt index bd192eae..7b6b3523 100644 --- a/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt +++ b/app/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt @@ -4,11 +4,9 @@ import android.annotation.SuppressLint import android.app.Activity import android.app.Application import android.content.Context -import android.os.Build import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import me.rhunk.snapenhance.bridge.AbstractBridgeClient -import me.rhunk.snapenhance.bridge.client.RootBridgeClient import me.rhunk.snapenhance.bridge.client.ServiceBridgeClient import me.rhunk.snapenhance.data.SnapClassCache import me.rhunk.snapenhance.hook.HookStage diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt b/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt index 029e353d..50c40d4f 100644 --- a/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt +++ b/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt @@ -278,6 +278,22 @@ enum class ConfigProperty( ConfigCategory.UI_TWEAKS, ConfigStateValue(false) ), + STARTUP_PAGE_OVERRIDE( + "startup_page_override", + ConfigCategory.UI_TWEAKS, + ConfigStateSelection( + listOf( + "OFF", + "ngs_map_icon_container", + "ngs_chat_icon_container", + "ngs_camera_icon_container", + "ngs_community_icon_container", + "ngs_spotlight_icon_container", + "ngs_search_icon_container" + ), + "OFF" + ) + ), //CAMERA diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/StartupPageOverride.kt b/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/StartupPageOverride.kt new file mode 100644 index 00000000..5bf968a8 --- /dev/null +++ b/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/StartupPageOverride.kt @@ -0,0 +1,60 @@ +package me.rhunk.snapenhance.features.impl.ui + +import android.annotation.SuppressLint +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import me.rhunk.snapenhance.Constants +import me.rhunk.snapenhance.config.ConfigProperty +import me.rhunk.snapenhance.features.Feature +import me.rhunk.snapenhance.features.FeatureLoadParams +import me.rhunk.snapenhance.hook.HookStage +import me.rhunk.snapenhance.hook.hook + +@SuppressLint("DiscouragedApi") +class StartupPageOverride : Feature("StartupPageOverride", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) { + private var ngsIcon: View? = null + /* + navbar icons: + ngs_map_icon_container + ngs_chat_icon_container + ngs_camera_icon_container + ngs_community_icon_container + ngs_spotlight_icon_container + ngs_search_icon_container + */ + + override fun onActivityCreate() { + val ngsIconName = context.config.state(ConfigProperty.STARTUP_PAGE_OVERRIDE).also { + if (it == "OFF") return + } + + context.androidContext.classLoader.loadClass("com.snap.mushroom.MainActivity").apply { + hook("onPostCreate", HookStage.AFTER) { + ngsIcon?.callOnClick() + } + + hook("onResume", HookStage.AFTER) { + ngsIcon?.callOnClick() + } + } + + val ngsIconId = context.androidContext.resources.getIdentifier(ngsIconName, "id", Constants.SNAPCHAT_PACKAGE_NAME) + val unhooks = mutableListOf<() -> Unit>() + + ViewGroup::class.java.getMethod( + "addView", + View::class.java, + Int::class.javaPrimitiveType, + ViewGroup.LayoutParams::class.java + ).hook(HookStage.AFTER) { param -> + if (param.thisObject() !is LinearLayout) return@hook + with(param.arg(0)) { + if (id == ngsIconId) { + ngsIcon = this + unhooks.forEach { it() } + } + } + }.also { unhooks.add(it::unhook) } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt index d57cb850..862e484a 100644 --- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt +++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt @@ -31,6 +31,7 @@ import me.rhunk.snapenhance.features.impl.spying.PreventReadReceipts import me.rhunk.snapenhance.features.impl.spying.StealthMode import me.rhunk.snapenhance.features.impl.tweaks.CameraTweaks import me.rhunk.snapenhance.features.impl.ui.PinConversations +import me.rhunk.snapenhance.features.impl.ui.StartupPageOverride import me.rhunk.snapenhance.features.impl.ui.UITweaks import me.rhunk.snapenhance.ui.menu.impl.MenuViewInjector import me.rhunk.snapenhance.manager.Manager @@ -87,6 +88,7 @@ class FeatureManager(private val context: ModContext) : Manager { register(AmoledDarkMode::class) register(PinConversations::class) register(UnlimitedMultiSnap::class) + register(StartupPageOverride::class) initializeFeatures() } diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt index 135cfd1d..beff9ada 100644 --- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt +++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt @@ -91,8 +91,7 @@ class FriendFeedInfoMenu : AbstractMenu() { context.translation.format("profile_info.birthday", "month" to it, "day" to profile.birthday.toInt().toString()) - } - } + }} """.trimIndent() builder.setMessage(message) builder.setPositiveButton( @@ -150,7 +149,7 @@ class FriendFeedInfoMenu : AbstractMenu() { targetPerson?.streakExpirationTimestamp?.takeIf { it > 0 }?.let { val timeSecondDiff = ((it - System.currentTimeMillis()) / 1000 / 60).toInt() - messageBuilder.append("\n\n") + messageBuilder.append("\n") .append("\uD83D\uDD25 ") //fire emoji .append( context.translation.format("conversation_preview.streak_expiration", @@ -160,6 +159,14 @@ class FriendFeedInfoMenu : AbstractMenu() { )) } + messages.lastOrNull()?.let { + messageBuilder + .append("\n\n") + .append(context.translation.format("conversation_preview.total_messages", "count" to it.server_message_id.toString())) + .append("\n") + } + + //alert dialog val builder = AlertDialog.Builder(context.mainActivity) builder.setTitle(context.translation["conversation_preview.title"])