Skip to content

Commit

Permalink
Improving the UI of the Custom Emoji page.
Browse files Browse the repository at this point in the history
  • Loading branch information
vitorpamplona committed Mar 5, 2025
1 parent 987d8fa commit 8722f37
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
Expand All @@ -44,10 +45,13 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
Expand Down Expand Up @@ -77,6 +81,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.service.firstFullChar
import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.navigation.routeFor
import com.vitorpamplona.amethyst.ui.note.types.RenderEmojiPack
Expand All @@ -85,9 +90,9 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
Expand Down Expand Up @@ -157,7 +162,7 @@ fun UpdateReactionTypeDialog(
UpdateReactionTypeDialog(postViewModel, onClose, accountViewModel, nav)
}

@OptIn(ExperimentalLayoutApi::class)
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
@Composable
fun UpdateReactionTypeDialog(
postViewModel: UpdateReactionTypeViewModel,
Expand All @@ -174,98 +179,112 @@ fun UpdateReactionTypeDialog(
decorFitsSystemWindows = false,
),
) {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
Column(
modifier = Modifier.padding(10.dp).imePadding(),
SetDialogToEdgeToEdge()

Scaffold(
topBar = {
TopAppBar(
actions = {
SaveButton(
onPost = {
postViewModel.sendPost()
onClose()
},
isActive = postViewModel.hasChanged(),
)
Spacer(modifier = StdHorzSpacer)
},
title = {},
navigationIcon = {
Row {
Spacer(modifier = StdHorzSpacer)
CloseButton(
onPress = {
postViewModel.cancel()
onClose()
},
)
}
},
)
},
) { pad ->
Surface(
modifier =
Modifier
.padding(pad)
.consumeWindowInsets(pad)
.imePadding(),
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
Column(
modifier = Modifier.padding(10.dp),
) {
CloseButton(
onPress = {
postViewModel.cancel()
onClose()
},
)

SaveButton(
onPost = {
postViewModel.sendPost()
onClose()
},
isActive = postViewModel.hasChanged(),
)
}

Spacer(modifier = Modifier.height(10.dp))

Row(
modifier = Modifier.fillMaxWidth(),
) {
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
Row(
modifier = Modifier.fillMaxWidth(),
) {
Row(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.animateContentSize()) {
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
postViewModel.reactionSet.forEach { reactionType ->
RenderReactionOption(reactionType, postViewModel)
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
) {
Row(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.animateContentSize()) {
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
postViewModel.reactionSet.forEach { reactionType ->
RenderReactionOption(reactionType, postViewModel)
}
}
}
}
}

Spacer(modifier = Modifier.height(10.dp))
Spacer(modifier = Modifier.height(10.dp))

Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 5.dp),
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
label = { Text(text = stringRes(R.string.new_reaction_symbol)) },
value = postViewModel.nextChoice,
onValueChange = { postViewModel.nextChoice = it },
keyboardOptions =
KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.None,
keyboardType = KeyboardType.Text,
),
placeholder = {
Text(
text = "\uD83D\uDCAF, \uD83C\uDF89, \uD83D\uDC4E",
color = MaterialTheme.colorScheme.placeholderText,
)
},
singleLine = true,
modifier = Modifier.padding(end = 10.dp).weight(1f),
)

Button(
onClick = { postViewModel.addChoice() },
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 5.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = stringRes(R.string.add), color = Color.White)
OutlinedTextField(
label = { Text(text = stringRes(R.string.new_reaction_symbol)) },
value = postViewModel.nextChoice,
onValueChange = { postViewModel.nextChoice = it },
keyboardOptions =
KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.None,
keyboardType = KeyboardType.Text,
),
placeholder = {
Text(
text = "\uD83D\uDCAF, \uD83C\uDF89, \uD83D\uDC4E",
color = MaterialTheme.colorScheme.placeholderText,
)
},
singleLine = true,
modifier = Modifier.padding(end = 10.dp).weight(1f),
)

Button(
onClick = { postViewModel.addChoice() },
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
Text(text = stringRes(R.string.add), color = Color.White)
}
}
}
}
}

EmojiSelector(
accountViewModel = accountViewModel,
nav = nav,
) {
postViewModel.addChoice(it)
Spacer(StdVertSpacer)

EmojiSelector(
accountViewModel = accountViewModel,
nav = nav,
) {
postViewModel.addChoice(it)
}
}
}
}
Expand Down Expand Up @@ -348,11 +367,11 @@ private fun EmojiSelector(
usersEmojiList
.live()
.metadata
.map { (it.note.event as? EmojiPackSelectionEvent)?.taggedAddresses()?.toImmutableList() }
.map { (it.note.event as? EmojiPackSelectionEvent)?.emojiPackIds()?.toImmutableList() }
.distinctUntilChanged()
.observeAsState(
(usersEmojiList.event as? EmojiPackSelectionEvent)
?.taggedAddresses()
?.emojiPackIds()
?.toImmutableList(),
)

Expand All @@ -363,7 +382,7 @@ private fun EmojiSelector(

@Composable
fun EmojiCollectionGallery(
emojiCollections: ImmutableList<Address>,
emojiCollections: ImmutableList<String>,
accountViewModel: AccountViewModel,
nav: INav,
onClick: ((EmojiUrlTag) -> Unit)? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
package com.vitorpamplona.amethyst.ui.note.types

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
Expand All @@ -40,6 +41,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
Expand Down Expand Up @@ -112,7 +114,7 @@ public fun RenderEmojiPack(
allEmojis.take(60)
}

Row(verticalAlignment = Alignment.CenterVertically) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(top = 10.dp)) {
Text(
text = remember(noteEvent) { "#${noteEvent.dTag()}" },
fontWeight = FontWeight.Bold,
Expand All @@ -131,16 +133,19 @@ public fun RenderEmojiPack(
}

Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.TopCenter) {
FlowRow(modifier = Modifier.padding(top = 5.dp)) {
FlowRow(
modifier = Modifier.padding(top = 5.dp),
verticalArrangement = spacedBy(1.dp),
horizontalArrangement = spacedBy(1.dp),
) {
emojisToShow.forEach { emoji ->
if (onClick != null) {
IconButton(onClick = { onClick(emoji) }, modifier = Size35Modifier) {
AsyncImage(
model = emoji.url,
contentDescription = emoji.code,
modifier = Size35Modifier,
)
}
AsyncImage(
model = emoji.url,
contentDescription = emoji.code,
modifier = Size35Modifier.clickable { onClick(emoji) },
contentScale = ContentScale.Crop,
)
} else {
Box(
modifier = Size35Modifier,
Expand All @@ -150,6 +155,7 @@ public fun RenderEmojiPack(
model = emoji.url,
contentDescription = emoji.code,
modifier = Size35Modifier,
contentScale = ContentScale.Crop,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
import com.vitorpamplona.quartz.nip31Alts.alt
import com.vitorpamplona.quartz.utils.TimeUtils
Expand All @@ -47,7 +46,9 @@ class EmojiPackSelectionEvent(
AddressHintProvider {
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)

fun emojiPacks() = taggedATags()
fun emojiPacks() = tags.mapNotNull(ATag::parseAddress)

fun emojiPackIds() = tags.mapNotNull(ATag::parseAddressId)

companion object {
const val KIND = 10030
Expand Down

0 comments on commit 8722f37

Please sign in to comment.