commit e0f6d05676cb54a59fb5319c7d16be9a304b3d65
parent 72b03085060d58d028a2e90972db72b84559587a
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Sun, 8 Oct 2023 21:03:39 +0200
feat: better ff message preview
Diffstat:
3 files changed, 69 insertions(+), 35 deletions(-)
diff --git a/core/src/main/assets/lang/en_US.json b/core/src/main/assets/lang/en_US.json
@@ -220,9 +220,15 @@
"name": "AMOLED Dark Mode",
"description": "Enables AMOLED dark mode\nMake sure Snapchats Dark mode is enabled"
},
- "conversation_preview_in_friend_feed": {
- "name": "Preview in FF",
- "description": "Shows a preview of the last messages in the Friend Feed"
+ "friend_feed_message_preview": {
+ "name": "Friend Feed Message Preview",
+ "description": "Shows a preview of the last messages in the Friend Feed",
+ "properties": {
+ "amount": {
+ "name": "Amount",
+ "description": "The amount of messages to get previewed"
+ }
+ }
},
"bootstrap_override": {
"name": "Bootstrap Override",
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/UserInterfaceTweaks.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/UserInterfaceTweaks.kt
@@ -11,14 +11,18 @@ class UserInterfaceTweaks : ConfigContainer() {
val homeTab = unique("home_tab", *ClientBootstrapOverride.tabs) { addNotices(FeatureNotice.UNSTABLE) }
}
+ inner class FriendFeedMessagePreview : ConfigContainer(hasGlobalState = true) {
+ val amount = integer("amount", defaultValue = 1)
+ }
+
val friendFeedMenuButtons = multiple(
- "friend_feed_menu_buttons","conversation_info", *MessagingRuleType.values().toList().filter { it.showInFriendMenu }.map { it.key }.toTypedArray()
+ "friend_feed_menu_buttons","conversation_info", *MessagingRuleType.entries.filter { it.showInFriendMenu }.map { it.key }.toTypedArray()
).apply {
set(mutableListOf("conversation_info", MessagingRuleType.STEALTH.key))
}
val friendFeedMenuPosition = integer("friend_feed_menu_position", defaultValue = 1)
val amoledDarkMode = boolean("amoled_dark_mode") { addNotices(FeatureNotice.UNSTABLE); requireRestart() }
- val conversationPreviewInFriendFeed = boolean("conversation_preview_in_friend_feed") { requireRestart() }
+ val friendFeedMessagePreview = container("friend_feed_message_preview", FriendFeedMessagePreview()) { requireRestart() }
val bootstrapOverride = container("bootstrap_override", BootstrapOverride()) { requireRestart() }
val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() }
val streakExpirationInfo = boolean("streak_expiration_info") { requireRestart() }
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/FriendFeedMessagePreview.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/FriendFeedMessagePreview.kt
@@ -3,11 +3,12 @@ package me.rhunk.snapenhance.features.impl.ui
import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.Paint
+import android.graphics.Rect
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.Shape
+import android.text.TextPaint
import android.view.View
import android.view.ViewGroup
-import android.widget.FrameLayout
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.core.event.events.impl.BindViewEvent
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
@@ -16,64 +17,87 @@ import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.ui.addForegroundDrawable
import me.rhunk.snapenhance.ui.removeForegroundDrawable
+import kotlin.math.absoluteValue
+@SuppressLint("DiscouragedApi")
class FriendFeedMessagePreview : Feature("FriendFeedMessagePreview", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
- @SuppressLint("SetTextI18n", "DiscouragedApi")
+ private val sigColorTextPrimary by lazy {
+ context.mainActivity!!.theme.obtainStyledAttributes(
+ intArrayOf(context.resources.getIdentifier("sigColorTextPrimary", "attr", Constants.SNAPCHAT_PACKAGE_NAME))
+ ).getColor(0, 0)
+ }
+
+ private fun getDimens(name: String) = context.resources.getDimensionPixelSize(context.resources.getIdentifier(name, "dimen", Constants.SNAPCHAT_PACKAGE_NAME))
+
override fun onActivityCreate() {
- if (!context.config.userInterface.conversationPreviewInFriendFeed.get()) return
+ val setting = context.config.userInterface.friendFeedMessagePreview
+ if (setting.globalState != true) return
val ffItemId = context.resources.getIdentifier("ff_item", "id", Constants.SNAPCHAT_PACKAGE_NAME)
- val sigColorTextPrimary by lazy {
- context.mainActivity!!.theme.obtainStyledAttributes(
- intArrayOf(context.resources.getIdentifier("sigColorTextPrimary", "attr", Constants.SNAPCHAT_PACKAGE_NAME))
- ).getColor(0, 0)
- }
+ val secondaryTextSize = getDimens("ff_feed_cell_secondary_text_size").toFloat()
+ val ffSdlAvatarMargin = getDimens("ff_sdl_avatar_margin")
+ val ffSdlAvatarSize = getDimens("ff_sdl_avatar_size")
+ val ffSdlAvatarStartMargin = getDimens("ff_sdl_avatar_start_margin")
+ val ffSdlPrimaryTextStartMargin = getDimens("ff_sdl_primary_text_start_margin").toFloat()
- val ffSdlAvatarMargin = context.resources.getDimensionPixelSize(context.resources.getIdentifier("ff_sdl_avatar_margin", "dimen", Constants.SNAPCHAT_PACKAGE_NAME))
- val ffSdlAvatarSize = context.resources.getDimensionPixelSize(context.resources.getIdentifier("ff_sdl_avatar_size", "dimen", Constants.SNAPCHAT_PACKAGE_NAME))
- val ffSdlAvatarStartMargin = context.resources.getDimensionPixelSize(context.resources.getIdentifier("ff_sdl_avatar_start_margin", "dimen", Constants.SNAPCHAT_PACKAGE_NAME))
- val ffSdlPrimaryTextStartMargin = context.resources.getDimensionPixelSize(context.resources.getIdentifier("ff_sdl_primary_text_start_margin", "dimen", Constants.SNAPCHAT_PACKAGE_NAME))
+ val feedEntryHeight = ffSdlAvatarSize + ffSdlAvatarMargin * 2 + ffSdlAvatarStartMargin
+ val separatorHeight = (context.resources.displayMetrics.density * 2).toInt()
+ val textPaint = TextPaint().apply {
+ textSize = secondaryTextSize
+ }
context.event.subscribe(BindViewEvent::class) { param ->
param.friendFeedItem { conversationId ->
- val frameLayout = param.view as FrameLayout
+ val frameLayout = param.view as ViewGroup
val ffItem = frameLayout.findViewById<View>(ffItemId)
- context.log.verbose("updated $conversationId")
-
ffItem.layoutParams = ffItem.layoutParams.apply {
height = ViewGroup.LayoutParams.MATCH_PARENT
}
-
frameLayout.removeForegroundDrawable("ffItem")
- val stringMessages = context.database.getMessagesFromConversationId(conversationId, 5)?.mapNotNull { message ->
- message.messageContent
+ val stringMessages = context.database.getMessagesFromConversationId(conversationId, setting.amount.get().absoluteValue)?.mapNotNull { message ->
+ val messageContainer = message.messageContent
?.let { ProtoReader(it) }
?.followPath(4, 4)
- ?.let { messageContainer ->
- messageContainer.getString(2, 1) ?: ContentType.fromMessageContainer(messageContainer)?.name ?: return@mapNotNull null
- }
- } ?: return@friendFeedItem
+ ?: return@mapNotNull null
+
+ val messageString = messageContainer.getString(2, 1)
+ ?: ContentType.fromMessageContainer(messageContainer)?.name
+ ?: return@mapNotNull null
+
+ val friendName = context.database.getFriendInfo(message.senderId ?: return@mapNotNull null)?.let { it.displayName?: it.mutableUsername } ?: "Unknown"
+
+ "$friendName: $messageString"
+ }?.reversed() ?: return@friendFeedItem
+
+ var maxTextHeight = 0
+ val previewContainerHeight = stringMessages.sumOf { msg ->
+ val rect = Rect()
+ textPaint.getTextBounds(msg, 0, msg.length, rect)
+ rect.height().also {
+ if (it > maxTextHeight) maxTextHeight = it
+ }.plus(separatorHeight)
+ }
+
+ ffItem.layoutParams = ffItem.layoutParams.apply {
+ height = feedEntryHeight + previewContainerHeight + separatorHeight
+ }
frameLayout.addForegroundDrawable("ffItem", ShapeDrawable(object: Shape() {
override fun draw(canvas: Canvas, paint: Paint) {
- val offsetY = canvas.height.toFloat() - (stringMessages.size * 30f)
+ val offsetY = canvas.height.toFloat() - previewContainerHeight
stringMessages.forEachIndexed { index, messageString ->
- paint.textSize = 30f
+ paint.textSize = secondaryTextSize
paint.color = sigColorTextPrimary
canvas.drawText(messageString,
- ffSdlAvatarStartMargin.toFloat() + ffSdlAvatarMargin * 2 + ffSdlAvatarSize + ffSdlPrimaryTextStartMargin,
- offsetY + (index * 30f),
+ feedEntryHeight + ffSdlPrimaryTextStartMargin,
+ offsetY + index * maxTextHeight,
paint
)
}
-
- ffItem.layoutParams = ffItem.layoutParams.apply {
- height = ffSdlAvatarSize + ffSdlAvatarMargin * 2 + ffSdlAvatarStartMargin + (stringMessages.size * 30)
- }
}
}))
}