feat: gigamoji

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2024-08-15 21:48:23 +02:00
parent f1683ad385
commit 01452bed52
4 changed files with 77 additions and 19 deletions

View File

@ -78,6 +78,7 @@ import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.UserAvatarWidthPlaceholder
import chat.revolt.components.markdown.LocalMarkdownTreeConfig
import chat.revolt.components.markdown.RichMarkdown
import chat.revolt.internals.text.Gigamoji
import kotlinx.coroutines.launch
import chat.revolt.api.schemas.Message as MessageSchema
@ -362,7 +363,11 @@ fun Message(
CompositionLocalProvider(
LocalMarkdownTreeConfig provides LocalMarkdownTreeConfig.current.copy(
currentServer = RevoltAPI.channelCache[message.channel]?.server
currentServer = RevoltAPI.channelCache[message.channel]?.server,
fontSizeMultiplier = Gigamoji.useGigamojiForMessage(message.content)
.let {
if (it) 2f else 1f
}
)
) {
Spacer(modifier = Modifier.height(2.dp))

View File

@ -28,7 +28,8 @@ import chat.revolt.ndk.AstNode
data class MarkdownTreeConfig(
val linksClickable: Boolean = true,
val currentServer: String? = null
val currentServer: String? = null,
val fontSizeMultiplier: Float = 1f
)
val LocalMarkdownTreeConfig =
@ -47,12 +48,12 @@ fun MarkdownTree(node: AstNode) {
LocalTextStyle provides LocalTextStyle.current.copy(
fontWeight = FontWeight.Bold,
fontSize = when (node.level) {
1 -> 32.sp
2 -> 24.sp
3 -> 20.sp
4 -> 16.sp
5 -> 14.sp
else -> 12.sp
1 -> 32.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
2 -> 24.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
3 -> 20.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
4 -> 16.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
5 -> 14.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
else -> 12.sp * LocalMarkdownTreeConfig.current.fontSizeMultiplier
}
)
) {
@ -67,17 +68,23 @@ fun MarkdownTree(node: AstNode) {
}
"paragraph" -> {
MarkdownText(
node,
modifier = Modifier
.then(
if (node.startLine != 1) {
Modifier.padding(top = 8.dp)
} else {
Modifier
}
)
)
CompositionLocalProvider(
LocalTextStyle provides LocalTextStyle.current.copy(
fontSize = LocalTextStyle.current.fontSize * LocalMarkdownTreeConfig.current.fontSizeMultiplier
)
) {
MarkdownText(
node,
modifier = Modifier
.then(
if (node.startLine != 1) {
Modifier.padding(top = 8.dp)
} else {
Modifier
}
)
)
}
}
"document" -> {

View File

@ -279,6 +279,16 @@ class EmojiImpl {
}
}
fun codepointIsEmoji(codepoint: Int): Boolean {
return metadata.any { group ->
group.emoji.any { emoji ->
emoji.base.contains(codepoint.toLong()) || emoji.alternates.any { alternate ->
alternate.contains(codepoint.toLong())
}
}
}
}
init {
metadata = initMetadata(RevoltApplication.instance.applicationContext)
}

View File

@ -0,0 +1,36 @@
package chat.revolt.internals.text
private val STRING_IS_CUSTOM_EMOTES_REGEX = Regex("(?::[0-9A-HJKMNP-TV-Z]{26}:|\\s)+")
object Gigamoji {
private fun stringIsEntirelyCustomEmotes(content: String): Boolean {
return STRING_IS_CUSTOM_EMOTES_REGEX.matches(content)
}
private fun stringIsEntirelyUnicodeEmojis(unfilteredContent: String): Boolean {
// Remove all custom emotes
val content = unfilteredContent.replace(STRING_IS_CUSTOM_EMOTES_REGEX, "")
// the message is solely custom emotes
if (content.isBlank()) return true
if ("[0-9A-Za-z#*]".toRegex()
.containsMatchIn(content)
) { // reject common non-emoji characters
return false
}
for (codepoint in content.codePoints()) {
if (MessageProcessor.emoji.codepointIsEmoji(codepoint)) {
return true
}
}
return false
}
fun useGigamojiForMessage(content: String): Boolean {
if (content.isBlank()) return false
return stringIsEntirelyCustomEmotes(content) || stringIsEntirelyUnicodeEmojis(content)
}
}