Skip to content
Snippets Groups Projects
Verified Commit 567bb3d5 authored by Mikolai Gütschow's avatar Mikolai Gütschow
Browse files

fix visual bug with long names in contact list

parent 1f9c3bd6
No related branches found
No related tags found
1 merge request!266Fix visual bug with long names in contact list
Pipeline #12784 passed
...@@ -21,7 +21,7 @@ package androidx.compose.material ...@@ -21,7 +21,7 @@ package androidx.compose.material
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.interaction.Interaction import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.requiredSize
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
...@@ -74,7 +74,7 @@ fun IconButton( ...@@ -74,7 +74,7 @@ fun IconButton(
Icon( Icon(
icon, icon,
contentDescription, contentDescription,
Modifier.size(iconSize), Modifier.requiredSize(iconSize),
iconTint iconTint
) )
extraContent?.invoke() extraContent?.invoke()
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
package org.briarproject.briar.desktop.contact package org.briarproject.briar.desktop.contact
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
...@@ -28,7 +27,7 @@ import androidx.compose.foundation.layout.defaultMinSize ...@@ -28,7 +27,7 @@ import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
...@@ -115,7 +114,8 @@ fun ContactCard( ...@@ -115,7 +114,8 @@ fun ContactCard(
) { ) {
val bgColor = if (selected) MaterialTheme.colors.selectedCard else Color.Transparent val bgColor = if (selected) MaterialTheme.colors.selectedCard else Color.Transparent
Column( Box(
contentAlignment = Alignment.Center,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.defaultMinSize(minHeight = HEADER_SIZE) .defaultMinSize(minHeight = HEADER_SIZE)
...@@ -127,148 +127,150 @@ fun ContactCard( ...@@ -127,148 +127,150 @@ fun ContactCard(
} }
.selectable(selected, onClick = onSel, role = Role.Button) .selectable(selected, onClick = onSel, role = Role.Button)
.background(bgColor), .background(bgColor),
verticalArrangement = Arrangement.Center
) { ) {
when (contactItem) { when (contactItem) {
is ContactItem -> { is ContactItem -> {
RealContactRow(contactItem) RealContactRow(contactItem)
} }
is PendingContactItem -> { is PendingContactItem -> {
PendingContactRow(contactItem, onRemovePending) PendingContactRow(contactItem, onRemovePending)
} }
} }
HorizontalDivider(Modifier.align(Alignment.BottomStart))
} }
HorizontalDivider()
} }
@Composable @Composable
private fun RealContactRow(contactItem: ContactItem) { private fun RealContactRow(contactItem: ContactItem) = Row(
horizontalArrangement = spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
// makes sure that ConnectionIndicator is aligned with AddContact button
.padding(start = 16.dp, end = 20.dp)
.semantics {
text = getRealContactRowDescription(contactItem)
}
) {
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier horizontalArrangement = spacedBy(12.dp),
.fillMaxWidth() modifier = Modifier.weight(1f, fill = true),
.semantics {
text = buildBlankAnnotatedString {
append(i18nF("access.contact.with_name", contactItem.displayName))
appendCommaSeparated(
if (contactItem.isConnected) i18n("access.contact.connected.yes")
else i18n("access.contact.connected.no")
)
if (contactItem.unread > 0)
appendCommaSeparated(i18nP("access.contact.unread_count", contactItem.unread))
if (contactItem.isEmpty)
appendCommaSeparated(i18n("contacts.card.nothing"))
else
appendCommaSeparated(
i18nF(
"access.contact.last_message_timestamp",
getFormattedTimestamp(contactItem.timestamp)
)
)
append('.')
}
}
) { ) {
Row( Box {
verticalAlignment = Alignment.CenterVertically, ProfileCircle(36.dp, contactItem)
modifier = Modifier.padding(start = 16.dp, end = 8.dp).padding(vertical = 8.dp), NumberBadge(
) { num = contactItem.unread,
Box { modifier = Modifier.align(Alignment.TopEnd).offset(6.dp, (-6).dp)
ProfileCircle(36.dp, contactItem)
NumberBadge(
num = contactItem.unread,
modifier = Modifier.align(Alignment.TopEnd).offset(6.dp, (-6).dp)
)
}
RealContactInfo(
contactItem = contactItem,
) )
} }
ConnectionIndicator( RealContactInfo(
modifier = Modifier.padding(end = (16 + 4).dp).size(16.dp), contactItem = contactItem,
isConnected = contactItem.isConnected
) )
} }
ConnectionIndicator(
modifier = Modifier.requiredSize(16.dp),
isConnected = contactItem.isConnected
)
} }
@Composable fun getRealContactRowDescription(contactItem: ContactItem) = buildBlankAnnotatedString {
private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> Unit) { append(i18nF("access.contact.with_name", contactItem.displayName))
Row( appendCommaSeparated(
horizontalArrangement = Arrangement.SpaceBetween, if (contactItem.isConnected) i18n("access.contact.connected.yes")
modifier = Modifier else i18n("access.contact.connected.no")
.fillMaxWidth() )
.semantics { if (contactItem.unread > 0)
text = buildBlankAnnotatedString { appendCommaSeparated(i18nP("access.contact.unread_count", contactItem.unread))
append(i18nF("access.contact.pending.with_name", contactItem.displayName)) if (contactItem.isEmpty)
// todo: include pending status appendCommaSeparated(i18n("contacts.card.nothing"))
appendCommaSeparated( else
i18nF( appendCommaSeparated(
"access.contact.pending.added_timestamp", i18nF(
getFormattedTimestamp(contactItem.timestamp) "access.contact.last_message_timestamp",
) getFormattedTimestamp(contactItem.timestamp)
)
}
},
verticalAlignment = Alignment.CenterVertically
) {
Row(
modifier = Modifier.padding(start = 16.dp, end = 8.dp).padding(vertical = 8.dp)
) {
ProfileCircle(36.dp)
PendingContactInfo(
contactItem = contactItem,
) )
}
IconButton(
icon = Icons.Filled.Delete,
contentDescription = i18n("access.contacts.pending.remove"),
onClick = onRemove,
modifier = Modifier.padding(end = 4.dp)
) )
} append('.')
} }
@Composable @Composable
private fun RealContactInfo(contactItem: ContactItem, modifier: Modifier = Modifier) { private fun PendingContactRow(contactItem: PendingContactItem, onRemove: () -> Unit) = Row(
Column( horizontalArrangement = spacedBy(8.dp),
horizontalAlignment = Alignment.Start, verticalAlignment = Alignment.CenterVertically,
verticalArrangement = spacedBy(2.dp), modifier = Modifier
modifier = modifier.padding(start = 12.dp), .fillMaxWidth()
.padding(vertical = 8.dp)
// makes sure that Delete button is aligned with AddContact button
.padding(start = 16.dp, end = 4.dp)
.semantics {
text = getPendingContactRowDescription(contactItem)
},
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = spacedBy(12.dp),
modifier = Modifier.weight(1f, fill = true),
) { ) {
Text( ProfileCircle(36.dp)
text = contactItem.displayName, PendingContactInfo(
style = MaterialTheme.typography.body1, contactItem = contactItem,
maxLines = 3,
overflow = Ellipsis,
)
ProvideTextStyle(MaterialTheme.typography.caption) {
TrustIndicatorLong(contactItem.trustLevel)
}
Text(
if (contactItem.isEmpty) i18n("contacts.card.nothing") else getFormattedTimestamp(
contactItem.timestamp
),
style = MaterialTheme.typography.caption,
modifier = Modifier.align(Alignment.Start)
) )
} }
IconButton(
icon = Icons.Filled.Delete,
contentDescription = i18n("access.contacts.pending.remove"),
onClick = onRemove,
)
} }
@Composable fun getPendingContactRowDescription(contactItem: PendingContactItem) = buildBlankAnnotatedString {
private fun PendingContactInfo(contactItem: PendingContactItem, modifier: Modifier = Modifier) { append(i18nF("access.contact.pending.with_name", contactItem.displayName))
Column(modifier = modifier.padding(start = 12.dp)) { // todo: include pending status
Text( appendCommaSeparated(
contactItem.displayName, i18nF(
style = MaterialTheme.typography.body1, "access.contact.pending.added_timestamp",
maxLines = 3, getFormattedTimestamp(contactItem.timestamp)
overflow = Ellipsis,
modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp)
)
Text(
getFormattedTimestamp(contactItem.timestamp),
modifier = Modifier.align(Alignment.Start),
style = MaterialTheme.typography.caption,
) )
)
}
@Composable
private fun RealContactInfo(contactItem: ContactItem) = Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = spacedBy(2.dp),
) {
Text(
text = contactItem.displayName,
style = MaterialTheme.typography.body1,
maxLines = 3,
overflow = Ellipsis,
)
ProvideTextStyle(MaterialTheme.typography.caption) {
TrustIndicatorLong(contactItem.trustLevel)
} }
Text(
text = if (contactItem.isEmpty) i18n("contacts.card.nothing")
else getFormattedTimestamp(contactItem.timestamp),
style = MaterialTheme.typography.caption,
)
}
@Composable
private fun PendingContactInfo(contactItem: PendingContactItem) = Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = spacedBy(2.dp),
) {
Text(
text = contactItem.displayName,
style = MaterialTheme.typography.body1,
maxLines = 3,
overflow = Ellipsis,
)
Text(
text = getFormattedTimestamp(contactItem.timestamp),
style = MaterialTheme.typography.caption,
)
} }
...@@ -29,7 +29,6 @@ import androidx.compose.runtime.mutableStateOf ...@@ -29,7 +29,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.toAwtImage import androidx.compose.ui.graphics.toAwtImage
...@@ -111,7 +110,6 @@ constructor( ...@@ -111,7 +110,6 @@ constructor(
} }
} }
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
override fun start(onClose: () -> Unit) { override fun start(onClose: () -> Unit) {
val title = i18n("main.title") val title = i18n("main.title")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment