From 9777c709a14a9c67c921bfcdddbc69c3191ccb5e Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 21 Aug 2023 15:42:45 -0400 Subject: [PATCH] - Fixes some of the TopBar padding issues. - Adds more info tap on single-user chat rooms - Moves creation date to a new line. --- .../amethyst/ui/navigation/AppTopBar.kt | 32 ++++++-- .../amethyst/ui/note/NoteCompose.kt | 67 +++++++++------- .../amethyst/ui/note/UserCompose.kt | 11 +-- .../ui/screen/loggedIn/ChannelScreen.kt | 78 ++++++++++++------- .../ui/screen/loggedIn/ChatroomScreen.kt | 26 ++++--- app/src/main/res/values/strings.xml | 2 + 6 files changed, 133 insertions(+), 83 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt index 89c4e19eb..6691b02ea 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt @@ -91,6 +91,7 @@ import com.vitorpamplona.amethyst.ui.note.LongCommunityHeader import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.note.SearchIcon import com.vitorpamplona.amethyst.ui.note.ShortCommunityHeader +import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.screen.equalImmutableLists import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -108,7 +109,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.SpinnerSelectionDialog import com.vitorpamplona.amethyst.ui.theme.BottomTopHeight import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.ui.theme.HeaderPictureModifier -import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.ui.theme.Size34dp import com.vitorpamplona.amethyst.ui.theme.Size40dp @@ -231,7 +231,7 @@ private fun CommunityTopBar( ShortCommunityHeader(baseNote, fontWeight = FontWeight.Medium, accountViewModel, nav) }, extendableRow = { - LongCommunityHeader(baseNote, accountViewModel, nav) + LongCommunityHeader(baseNote = baseNote, accountViewModel = accountViewModel, nav = nav) }, popBack = navPopBack ) @@ -297,6 +297,17 @@ private fun RenderRoomTopBar( } } }, + extendableRow = { + LoadUser(baseUserHex = room.users.first()) { + if (it != null) { + UserCompose( + baseUser = it, + accountViewModel = accountViewModel, + nav = nav + ) + } + } + }, popBack = navPopBack ) } else { @@ -308,10 +319,17 @@ private fun RenderRoomTopBar( size = Size34dp ) - RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp).weight(1f), fontWeight = FontWeight.Medium, accountViewModel.userProfile()) + RoomNameOnlyDisplay( + room, + Modifier + .padding(start = 10.dp) + .weight(1f), + fontWeight = FontWeight.Medium, + accountViewModel.userProfile() + ) }, extendableRow = { - LongRoomHeader(room, accountViewModel, nav) + LongRoomHeader(room = room, accountViewModel = accountViewModel, nav = nav) }, popBack = navPopBack ) @@ -342,7 +360,7 @@ private fun ChannelTopBar( ) }, extendableRow = { - LongChannelHeader(baseChannel, accountViewModel, nav) + LongChannelHeader(baseChannel = baseChannel, accountViewModel = accountViewModel, nav = nav) }, popBack = navPopBack ) @@ -861,9 +879,7 @@ fun MyExtensibleTopAppBar( if (expanded.value && extendableRow != null) { Row( - Modifier - .fillMaxWidth() - .padding(bottom = Size10dp), + Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 2a0179820..6ef5f5c5d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -113,6 +113,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader import com.vitorpamplona.amethyst.ui.screen.loggedIn.JoinCommunityButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.LeaveCommunityButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.LiveFlag +import com.vitorpamplona.amethyst.ui.screen.loggedIn.NormalTimeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.ScheduledFlag import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.DividerThickness @@ -124,6 +125,7 @@ import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding import com.vitorpamplona.amethyst.ui.theme.HalfVertSpacer import com.vitorpamplona.amethyst.ui.theme.HeaderPictureModifier import com.vitorpamplona.amethyst.ui.theme.QuoteBorder +import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size15Modifier import com.vitorpamplona.amethyst.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier @@ -517,7 +519,7 @@ fun CommunityHeader( Column(Modifier.fillMaxWidth()) { Column( verticalArrangement = Arrangement.Center, - modifier = modifier.clickable { + modifier = Modifier.clickable { if (sendToCommunity) { routeFor(baseNote, accountViewModel.userProfile())?.let { nav(it) @@ -534,7 +536,7 @@ fun CommunityHeader( ) if (expanded.value) { - LongCommunityHeader(baseNote, accountViewModel, nav) + LongCommunityHeader(baseNote = baseNote, lineModifier = modifier, accountViewModel = accountViewModel, nav = nav) } } @@ -547,23 +549,24 @@ fun CommunityHeader( } @Composable -fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountViewModel, nav: (String) -> Unit) { +fun LongCommunityHeader( + baseNote: AddressableNote, + lineModifier: Modifier = Modifier.padding(horizontal = Size10dp, vertical = Size5dp), + accountViewModel: AccountViewModel, + nav: (String) -> Unit +) { val noteState by baseNote.live().metadata.observeAsState() val noteEvent = remember(noteState) { noteState?.note?.event as? CommunityDefinitionEvent } ?: return Row( - Modifier - .fillMaxWidth() - .padding(top = 10.dp) + lineModifier ) { val summary = remember(noteState) { noteEvent.description()?.ifBlank { null } } Column( - Modifier - .weight(1f) - .padding(start = 10.dp) + Modifier.weight(1f) ) { Row(verticalAlignment = Alignment.CenterVertically) { val defaultBackground = MaterialTheme.colors.background @@ -598,17 +601,14 @@ fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountView } rules?.let { - Spacer(DoubleVertSpacer) Row( - Modifier - .fillMaxWidth() - .padding(start = 10.dp) + lineModifier ) { val defaultBackground = MaterialTheme.colors.background val background = remember { mutableStateOf(defaultBackground) } - val tags = remember(noteEvent) { noteEvent?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() } + val tags = remember(noteEvent) { noteEvent.tags().toImmutableListOfLists() } TranslatableRichTextViewer( content = it, @@ -621,12 +621,8 @@ fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountView } } - Spacer(DoubleVertSpacer) - Row( - Modifier - .fillMaxWidth() - .padding(start = 10.dp), + lineModifier, verticalAlignment = Alignment.CenterVertically ) { Text( @@ -639,8 +635,6 @@ fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountView NoteAuthorPicture(baseNote, nav, accountViewModel, Size25dp) Spacer(DoubleHorzSpacer) NoteUsernameDisplay(baseNote, remember { Modifier.weight(1f) }) - TimeAgo(baseNote) - MoreOptionsButton(baseNote, accountViewModel) } var participantUsers by remember(baseNote) { @@ -664,12 +658,9 @@ fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountView participantUsers.forEach { Row( - Modifier - .fillMaxWidth() - .padding(start = 10.dp, top = 10.dp) - .clickable { - nav("User/${it.second.pubkeyHex}") - }, + lineModifier.clickable { + nav("User/${it.second.pubkeyHex}") + }, verticalAlignment = Alignment.CenterVertically ) { it.first.role?.let { it1 -> @@ -686,6 +677,21 @@ fun LongCommunityHeader(baseNote: AddressableNote, accountViewModel: AccountView UsernameDisplay(it.second, remember { Modifier.weight(1f) }) } } + + Row( + lineModifier, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(id = R.string.created_at), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.width(75.dp) + ) + Spacer(DoubleHorzSpacer) + NormalTimeAgo(baseNote = baseNote, Modifier.weight(1f)) + MoreOptionsButton(baseNote, accountViewModel) + } } @Composable @@ -3424,7 +3430,12 @@ fun AudioHeader(noteEvent: AudioHeaderEvent, note: Note, accountViewModel: Accou } content?.let { - Row(verticalAlignment = CenterVertically, modifier = Modifier.fillMaxWidth().padding(top = 5.dp)) { + Row( + verticalAlignment = CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(top = 5.dp) + ) { TranslatableRichTextViewer( content = it, canPreview = true, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt index 620d6c5af..32b53d4ba 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt @@ -13,18 +13,12 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size55dp +import com.vitorpamplona.amethyst.ui.theme.StdPadding @Composable fun UserCompose( baseUser: User, - overallModifier: Modifier = remember { - Modifier - .padding( - start = 12.dp, - end = 12.dp, - top = 10.dp - ) - }, + overallModifier: Modifier = StdPadding, showDiviser: Boolean = true, accountViewModel: AccountViewModel, nav: (String) -> Unit @@ -56,7 +50,6 @@ fun UserCompose( if (showDiviser) { Divider( - modifier = Modifier.padding(top = 10.dp), thickness = 0.25.dp ) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt index a653717cd..00ad2cc63 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt @@ -105,12 +105,12 @@ import com.vitorpamplona.amethyst.ui.note.LoadChannel import com.vitorpamplona.amethyst.ui.note.MoreOptionsButton import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay -import com.vitorpamplona.amethyst.ui.note.TimeAgo import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.ZapReaction import com.vitorpamplona.amethyst.ui.note.routeFor import com.vitorpamplona.amethyst.ui.note.timeAgo +import com.vitorpamplona.amethyst.ui.note.timeAgoShort import com.vitorpamplona.amethyst.ui.screen.NostrChannelFeedViewModel import com.vitorpamplona.amethyst.ui.screen.RefreshingChatroomFeedView import com.vitorpamplona.amethyst.ui.screen.equalImmutableLists @@ -580,7 +580,7 @@ fun ChannelHeader( ) if (expanded.value) { - LongChannelHeader(baseChannel, accountViewModel, nav) + LongChannelHeader(baseChannel = baseChannel, accountViewModel = accountViewModel, nav = nav) } } @@ -722,6 +722,7 @@ fun ShortChannelHeader( @Composable fun LongChannelHeader( baseChannel: Channel, + lineModifier: Modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp), accountViewModel: AccountViewModel, nav: (String) -> Unit ) { @@ -731,18 +732,14 @@ fun LongChannelHeader( } ?: return Row( - Modifier - .fillMaxWidth() - .padding(top = 10.dp) + lineModifier ) { val summary = remember(channelState) { channel.summary()?.ifBlank { null } } Column( - Modifier - .weight(1f) - .padding(start = 10.dp) + Modifier.weight(1f) ) { Row(verticalAlignment = Alignment.CenterVertically) { val defaultBackground = MaterialTheme.colors.background @@ -769,7 +766,9 @@ fun LongChannelHeader( } if (baseChannel is LiveActivitiesChannel) { - val hashtags = remember(baseChannel.info) { baseChannel.info?.hashtags()?.toImmutableList() ?: persistentListOf() } + val hashtags = remember(baseChannel.info) { + baseChannel.info?.hashtags()?.toImmutableList() ?: persistentListOf() + } DisplayUncitedHashtags(hashtags, summary ?: "", nav) } } @@ -784,28 +783,37 @@ fun LongChannelHeader( } } - Spacer(DoubleVertSpacer) - - Row( - Modifier - .fillMaxWidth() - .padding(start = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - LoadNote(baseNoteHex = channel.idHex) { - it?.let { + LoadNote(baseNoteHex = channel.idHex) { loadingNote -> + loadingNote?.let { note -> + Row( + lineModifier, + verticalAlignment = Alignment.CenterVertically + ) { Text( text = stringResource(id = R.string.owner), maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.width(55.dp) + modifier = Modifier.width(75.dp) ) Spacer(DoubleHorzSpacer) - NoteAuthorPicture(it, nav, accountViewModel, Size25dp) + NoteAuthorPicture(note, nav, accountViewModel, Size25dp) Spacer(DoubleHorzSpacer) - NoteUsernameDisplay(it, remember { Modifier.weight(1f) }) - TimeAgo(it) - MoreOptionsButton(it, accountViewModel) + NoteUsernameDisplay(note, remember { Modifier.weight(1f) }) + } + + Row( + lineModifier, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(id = R.string.created_at), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.width(75.dp) + ) + Spacer(DoubleHorzSpacer) + NormalTimeAgo(note, remember { Modifier.weight(1f) }) + MoreOptionsButton(note, accountViewModel) } } } @@ -831,9 +839,7 @@ fun LongChannelHeader( participantUsers.forEach { Row( - Modifier - .fillMaxWidth() - .padding(start = 10.dp, top = 10.dp) + lineModifier .clickable { nav("User/${it.second.pubkeyHex}") }, @@ -856,6 +862,24 @@ fun LongChannelHeader( } } +@Composable +fun NormalTimeAgo(baseNote: Note, modifier: Modifier) { + val nowStr = stringResource(id = R.string.now) + + val time by remember(baseNote) { + derivedStateOf { + timeAgoShort(baseNote.createdAt() ?: 0, nowStr) + } + } + + Text( + text = time, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = modifier + ) +} + @Composable private fun ShortChannelActionOptions( channel: PublicChatChannel, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index d25c3197e..17c3f4758 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -5,7 +5,6 @@ import androidx.compose.animation.Crossfade import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight @@ -550,7 +549,7 @@ fun GroupChatroomHeader( } if (expanded.value) { - LongRoomHeader(room, accountViewModel, nav) + LongRoomHeader(room = room, accountViewModel = accountViewModel, nav = nav) } } @@ -687,15 +686,18 @@ fun NewSubjectView(onClose: () -> Unit, accountViewModel: AccountViewModel, room } @Composable -fun LongRoomHeader(room: ChatroomKey, accountViewModel: AccountViewModel, nav: (String) -> Unit) { +fun LongRoomHeader( + room: ChatroomKey, + lineModifier: Modifier = StdPadding, + accountViewModel: AccountViewModel, + nav: (String) -> Unit +) { val list = remember(room) { room.users.toPersistentList() } Row( - modifier = Modifier - .padding(top = 10.dp) - .fillMaxWidth(), + modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { @@ -712,16 +714,18 @@ fun LongRoomHeader(room: ChatroomKey, accountViewModel: AccountViewModel, nav: ( } LazyColumn( - modifier = Modifier.fillMaxHeight(), - contentPadding = PaddingValues( - bottom = 10.dp - ), + modifier = Modifier, state = rememberLazyListState() ) { itemsIndexed(list, key = { _, item -> item }) { _, item -> LoadUser(baseUserHex = item) { if (it != null) { - UserCompose(baseUser = it, accountViewModel = accountViewModel, nav = nav) + UserCompose( + baseUser = it, + overallModifier = lineModifier, + accountViewModel = accountViewModel, + nav = nav + ) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9558dbd7f..834c4a682 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -546,4 +546,6 @@ Copy URL to clipboard Copy Note ID to clipboard + + Created at