Header: improve location control accessibility and crowding

This commit is contained in:
caly 2026-07-29 14:20:17 +03:00
parent 3b53b9bdcc
commit ad05bc5ed5
34 changed files with 162 additions and 83 deletions

View File

@ -40,6 +40,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@ -83,6 +84,18 @@ private val HeaderTextSize = 17.sp
/** Minimum tap target for every interactive element in the header. */
private val HeaderTapTarget = 44.dp
internal enum class HeaderCrowdingMode {
Full,
HideJoinedChannelCount,
IconOnlyLocationChannel,
}
internal fun headerCrowdingMode(availableWidth: Dp): HeaderCrowdingMode = when {
availableWidth < 360.dp -> HeaderCrowdingMode.IconOnlyLocationChannel
availableWidth < 400.dp -> HeaderCrowdingMode.HideJoinedChannelCount
else -> HeaderCrowdingMode.Full
}
/** Corner radius for the header's tappable label+icon clusters. */
private val HeaderClusterShape = RoundedCornerShape(8.dp)
@ -518,6 +531,7 @@ fun NicknameEditor(
}
),
modifier = Modifier
.weight(1f)
.widthIn(max = 150.dp)
.horizontalScroll(scrollState)
)
@ -533,7 +547,8 @@ fun PeerCounter(
selectedLocationChannel: com.bitchat.android.geohash.ChannelID?,
geohashPeople: List<GeoPerson>,
onClick: () -> Unit,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
showJoinedChannelCount: Boolean = true
) {
val palette = LocalBitchatPalette.current
val colorScheme = MaterialTheme.colorScheme
@ -590,7 +605,7 @@ fun PeerCounter(
fontWeight = FontWeight.Medium
)
if (joinedChannels.isNotEmpty()) {
if (showJoinedChannelCount && joinedChannels.isNotEmpty()) {
AnimatedCount(
count = joinedChannels.size,
prefix = stringResource(R.string.channel_count_prefix),
@ -690,22 +705,17 @@ private fun MainHeader(
val selectedLocationChannel by viewModel.selectedLocationChannel.collectAsStateWithLifecycle()
val geohashPeople by viewModel.geohashPeople.collectAsStateWithLifecycle()
Row(
modifier = Modifier
.fillMaxWidth()
.height(ChatHeaderHeight)
.padding(start = HeaderInsetStart, end = HeaderInsetEnd),
verticalAlignment = Alignment.CenterVertically
) {
// MARK: - Identity cluster.
//
// Weighted so it yields space to the status cluster rather than pushing it off screen.
// Compose measures unweighted children first, so the icons on the right always get the
// width they need and a long nickname simply scrolls within what is left.
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
val crowdingMode = headerCrowdingMode(maxWidth)
Row(
modifier = Modifier.weight(1f),
modifier = Modifier
.fillMaxWidth()
.height(ChatHeaderHeight)
.padding(start = HeaderInsetStart, end = HeaderInsetEnd),
verticalAlignment = Alignment.CenterVertically
) {
// Keep the brand and trailing actions fixed. Only the nickname yields under pressure.
BitChatBrandButton(
onClick = onTitleClick,
onTripleClick = onTripleTitleClick,
@ -713,11 +723,13 @@ private fun MainHeader(
modifier = Modifier.size(HeaderTapTarget),
)
// Nudge toward the brand glyph: the 44.dp tap target leaves more optical gap than
// spacing between the mark and the path label.
// Nudge toward the brand glyph: the 44.dp tap target leaves more optical gap than the
// spacing between the mark and path label.
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.offset(x = (-6).dp)
modifier = Modifier
.weight(1f)
.offset(x = (-6).dp)
) {
Text(
text = "/",
@ -731,66 +743,58 @@ private fun MainHeader(
NicknameEditor(
value = nickname,
onValueChange = onNicknameChange
onValueChange = onNicknameChange,
modifier = Modifier.weight(1f)
)
}
}
// MARK: - Status cluster.
//
// Order, left to right: unread DMs, notes, channel, people.
// Tor health is read from the location channel / notes icon colour rather than a
// dedicated status dot.
Row(
verticalAlignment = Alignment.CenterVertically,
// Tight, because every child below is its own >=44.dp tap target.
horizontalArrangement = Arrangement.spacedBy(2.dp)
) {
// Unread private messages badge (click to open most recent DM)
if (hasUnreadPrivateMessages.isNotEmpty()) {
HeaderIconButton(
onClick = { viewModel.openLatestUnreadPrivateChat() },
contentDescription = stringResource(R.string.cd_unread_private_messages)
) {
Icon(
painter = painterResource(R.drawable.ic_spec_envelope),
contentDescription = stringResource(R.string.cd_unread_private_messages),
modifier = Modifier.size(HeaderIconSize),
tint = palette.accentOrange
)
}
}
// Location notes + channel badge: one tight unit so the document glyph and the
// bluetooth/globe glyph sit at the same visual pitch as other header pairings.
// Order, left to right: unread DMs, notes, channel, people. This cluster is measured
// before the weighted nickname, so actions cannot be pushed off-screen by identity.
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(0.dp)
horizontalArrangement = Arrangement.spacedBy(2.dp)
) {
LocationNotesButton(
viewModel = viewModel,
onClick = onLocationNotesClick
)
if (hasUnreadPrivateMessages.isNotEmpty()) {
HeaderIconButton(
onClick = { viewModel.openLatestUnreadPrivateChat() },
contentDescription = stringResource(R.string.cd_unread_private_messages)
) {
Icon(
painter = painterResource(R.drawable.ic_spec_envelope),
contentDescription = stringResource(R.string.cd_unread_private_messages),
modifier = Modifier.size(HeaderIconSize),
tint = palette.accentOrange
)
}
}
// Bookmarking lives in the Location Channels sheet, one tap away via the channel
// button. Duplicating it here bought a shortcut for a rare action at the cost
// of a slot in the app's most crowded row.
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(0.dp)
) {
LocationNotesButton(
viewModel = viewModel,
onClick = onLocationNotesClick
)
LocationChannelsButton(
viewModel = viewModel,
onClick = onLocationChannelsClick
LocationChannelsButton(
viewModel = viewModel,
onClick = onLocationChannelsClick,
showLabel = crowdingMode != HeaderCrowdingMode.IconOnlyLocationChannel
)
}
PeerCounter(
connectedPeers = connectedPeers.filter { it != viewModel.myPeerID },
joinedChannels = joinedChannels,
hasUnreadChannels = hasUnreadChannels,
isConnected = isConnected,
selectedLocationChannel = selectedLocationChannel,
geohashPeople = geohashPeople,
onClick = onSidebarClick,
showJoinedChannelCount = crowdingMode == HeaderCrowdingMode.Full
)
}
PeerCounter(
connectedPeers = connectedPeers.filter { it != viewModel.myPeerID },
joinedChannels = joinedChannels,
hasUnreadChannels = hasUnreadChannels,
isConnected = isConnected,
selectedLocationChannel = selectedLocationChannel,
geohashPeople = geohashPeople,
onClick = onSidebarClick
)
}
}
}
@ -805,7 +809,8 @@ private fun MainHeader(
@Composable
private fun LocationChannelsButton(
viewModel: ChatViewModel,
onClick: () -> Unit
onClick: () -> Unit,
showLabel: Boolean
) {
val colorScheme = MaterialTheme.colorScheme
@ -832,35 +837,39 @@ private fun LocationChannelsButton(
} else {
R.drawable.ic_spec_range
}
val contentDescription = stringResource(R.string.cd_open_location_channels)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(6.dp),
horizontalArrangement = if (showLabel) Arrangement.spacedBy(6.dp) else Arrangement.Center,
modifier = Modifier
.clip(HeaderClusterShape)
.pressScaleClickable(
onClick = onClick,
onClickLabel = stringResource(R.string.location_channels_title)
onClickLabel = contentDescription
)
.height(HeaderTapTarget)
// No start padding: the notes icon is paired directly to the left; keep end
// padding so the gap to PeerCounter matches other cluster separations.
.padding(start = 0.dp, end = 6.dp)
.widthIn(min = HeaderTapTarget)
.padding(end = if (showLabel) 6.dp else 0.dp)
) {
TorAwareHeaderIcon(
painter = painterResource(badgeIconRes),
tint = torVisual.tint,
isProgress = torVisual.isProgress,
contentDescription = stringResource(R.string.cd_tor_status)
contentDescription = contentDescription
)
Text(
text = badgeText,
style = MaterialTheme.typography.bodyMedium,
fontSize = HeaderTextSize,
fontWeight = FontWeight.Medium,
color = channelColor,
maxLines = 1
)
if (showLabel) {
Text(
text = badgeText,
style = MaterialTheme.typography.bodyMedium,
fontSize = HeaderTextSize,
fontWeight = FontWeight.Medium,
color = channelColor,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.widthIn(max = 88.dp)
)
}
}
}

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">رسائل خاصة غير مقروءة</string>
<string name="cd_teleported">تم الانتقال</string>
<string name="cd_tor_status">حالة Tor</string>
<string name="cd_open_location_channels">فتح إعدادات الموقع والقنوات</string>
<string name="cd_connected_peers">الأقران المتصلون</string>
<string name="cd_geohash_participants">مشاركو geohash</string>
<string name="cd_ready_for_handshake">جاهز للمصافحة</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">অপঠিত ব্যক্তিগত বার্তা</string>
<string name="cd_teleported">টেলিপোর্ট করা হয়েছে</string>
<string name="cd_tor_status">Tor অবস্থা</string>
<string name="cd_open_location_channels">অবস্থান ও চ্যানেল সেটিংস খুলুন</string>
<string name="cd_connected_peers">সংযুক্ত পিয়ার</string>
<string name="cd_geohash_participants">জিওহ্যাশ অংশগ্রহণকারী</string>
<string name="cd_ready_for_handshake">হ্যান্ডশেকের জন্য প্রস্তুত</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Ungelesene private Nachrichten</string>
<string name="cd_teleported">Teleportiert</string>
<string name="cd_tor_status">TorStatus</string>
<string name="cd_open_location_channels">Standort- und Kanaleinstellungen öffnen</string>
<string name="cd_connected_peers">Verbundenen Peers</string>
<string name="cd_geohash_participants">GeohashTeilnehmer</string>
<string name="cd_ready_for_handshake">Bereit für Handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Mensajes privados sin leer</string>
<string name="cd_teleported">Teletransportado</string>
<string name="cd_tor_status">Estado de Tor</string>
<string name="cd_open_location_channels">Abrir ajustes de ubicación y canales</string>
<string name="cd_connected_peers">Pares conectados</string>
<string name="cd_geohash_participants">Participantes geohash</string>
<string name="cd_ready_for_handshake">Listo para handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">پیام‌های خصوصی خوانده‌نشده</string>
<string name="cd_teleported">انتقال مکانی</string>
<string name="cd_tor_status">وضعیت Tor</string>
<string name="cd_open_location_channels">باز کردن تنظیمات مکان و کانال‌ها</string>
<string name="cd_connected_peers">همتایان متصل</string>
<string name="cd_geohash_participants">شرکت‌کنندگان geohash</string>
<string name="cd_ready_for_handshake">آمادهٔ دست‌دهی</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Hindi nabasang pribadong mensahe</string>
<string name="cd_teleported">Naiteleport</string>
<string name="cd_tor_status">Katayuan ng Tor</string>
<string name="cd_open_location_channels">Buksan ang mga setting ng lokasyon at channel</string>
<string name="cd_connected_peers">Nakakonektang peers</string>
<string name="cd_geohash_participants">Mga kalahok sa geohash</string>
<string name="cd_ready_for_handshake">Handa para sa handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Messages privés non lus</string>
<string name="cd_teleported">Téléporté</string>
<string name="cd_tor_status">Statut Tor</string>
<string name="cd_open_location_channels">Ouvrir les réglages de localisation et des canaux</string>
<string name="cd_connected_peers">Pairs connectés</string>
<string name="cd_geohash_participants">Participants geohash</string>
<string name="cd_ready_for_handshake">Prêt pour léchange de clés</string>

View File

@ -54,6 +54,7 @@
<string name="verify_success_body">You verified %1$s</string>
<string name="verify_success_system_message">verified %1$s</string>
<string name="cd_open_about">פתיחת אודות</string>
<string name="cd_open_location_channels">פתיחת הגדרות מיקום וערוצים</string>
<string name="nearby_notes_reveal">בדיקה אם הושארו כאן פתקים</string>
<string name="nearby_notes_one">פתק אחד הושאר כאן — הקש לקריאה</string>
<string name="nearby_notes_many">%d פתקים הושארו כאן — הקש לקריאה</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">अपठित निजी संदेश</string>
<string name="cd_teleported">टेलीपोर्ट हुआ</string>
<string name="cd_tor_status">Tor स्थिति</string>
<string name="cd_open_location_channels">स्थान और चैनल सेटिंग खोलें</string>
<string name="cd_connected_peers">कनेक्टेड पीयर्स</string>
<string name="cd_geohash_participants">geohash प्रतिभागी</string>
<string name="cd_ready_for_handshake">हैंडशेक के लिए तैयार</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Pesan pribadi yang belum dibaca</string>
<string name="cd_teleported">Diteleportasi</string>
<string name="cd_tor_status">Status Tor</string>
<string name="cd_open_location_channels">Buka pengaturan lokasi dan channel</string>
<string name="cd_connected_peers">Peer yang terhubung</string>
<string name="cd_geohash_participants">Peserta geohash</string>
<string name="cd_ready_for_handshake">Siap untuk handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Messaggi privati non letti</string>
<string name="cd_teleported">Teletrasportato</string>
<string name="cd_tor_status">Stato Tor</string>
<string name="cd_open_location_channels">Apri le impostazioni di posizione e canali</string>
<string name="cd_connected_peers">Peer connessi</string>
<string name="cd_geohash_participants">Partecipanti geohash</string>
<string name="cd_ready_for_handshake">Pronto per l\'handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">未読のプライベートメッセージ</string>
<string name="cd_teleported">テレポート済み</string>
<string name="cd_tor_status">Tor ステータス</string>
<string name="cd_open_location_channels">位置情報とチャンネルの設定を開く</string>
<string name="cd_connected_peers">接続中のピア</string>
<string name="cd_geohash_participants">Geohash 参加者</string>
<string name="cd_ready_for_handshake">ハンドシェイク準備完了</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">წაუკითხავი პირადი შეტყობინებები</string>
<string name="cd_teleported">ტელეპორტირებული</string>
<string name="cd_tor_status">Tor-ის სტატუსი</string>
<string name="cd_open_location_channels">მდებარეობისა და არხების პარამეტრების გახსნა</string>
<string name="cd_connected_peers">დაკავშირებული პირები</string>
<string name="cd_geohash_participants">geohash მონაწილეები</string>
<string name="cd_ready_for_handshake">მზადაა ხელის ჩამოსართმევად</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">읽지 않은 개인 메시지</string>
<string name="cd_teleported">텔레포트됨</string>
<string name="cd_tor_status">Tor 상태</string>
<string name="cd_open_location_channels">위치 및 채널 설정 열기</string>
<string name="cd_connected_peers">연결된 피어</string>
<string name="cd_geohash_participants">geohash 참여자</string>
<string name="cd_ready_for_handshake">핸드셰이크 준비됨</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Hafatra manokana tsy voavaky</string>
<string name="cd_teleported">Nafindra toerana</string>
<string name="cd_tor_status">Toe-javatra Tor</string>
<string name="cd_open_location_channels">Sokafy ny fikirana toerana sy fantsona</string>
<string name="cd_connected_peers">Mpiara-miasa mifandray</string>
<string name="cd_geohash_participants">Mpandray anjara Geohash</string>
<string name="cd_ready_for_handshake">Vonona ho amin\'ny fifampiraharahana</string>

View File

@ -41,6 +41,7 @@
<string name="verify_success_body">You verified %1$s</string>
<string name="verify_success_system_message">verified %1$s</string>
<string name="cd_open_about">Buka Perihal</string>
<string name="cd_open_location_channels">Buka tetapan lokasi dan saluran</string>
<string name="nearby_notes_reveal">semak nota yang ditinggalkan di sini</string>
<string name="nearby_notes_one">1 nota ditinggalkan di sini — ketik untuk baca</string>
<string name="nearby_notes_many">%d nota ditinggalkan di sini — ketik untuk baca</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">नपढिएका निजी सन्देश</string>
<string name="cd_teleported">टेलिपोर्ट भयो</string>
<string name="cd_tor_status">Tor स्थिति</string>
<string name="cd_open_location_channels">स्थान र च्यानल सेटिङ खोल्नुहोस्</string>
<string name="cd_connected_peers">जडान भएका साथीहरू</string>
<string name="cd_geohash_participants">Geohash सहभागिहरू</string>
<string name="cd_ready_for_handshake">ह्यान्डशेकका लागि तयार</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Ongelezen privéberichten</string>
<string name="cd_teleported">Geteleporteerd</string>
<string name="cd_tor_status">Tor-status</string>
<string name="cd_open_location_channels">Locatie- en kanaalinstellingen openen</string>
<string name="cd_connected_peers">Verbonden peers</string>
<string name="cd_geohash_participants">Geohash-deelnemers</string>
<string name="cd_ready_for_handshake">Klaar voor handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">انہ پڑھیا ذاتی پیغام</string>
<string name="cd_teleported">ٹیلپورٹ کیتا گیا</string>
<string name="cd_tor_status">Tor حالت</string>
<string name="cd_open_location_channels">مقام تے چینل دیاں ترتیباں کھولو</string>
<string name="cd_connected_peers">جُڑے پیئر</string>
<string name="cd_geohash_participants">geohash شریک</string>
<string name="cd_ready_for_handshake">ہینڈشیک لئی تیار</string>

View File

@ -54,6 +54,7 @@
<string name="verify_success_body">You verified %1$s</string>
<string name="verify_success_system_message">verified %1$s</string>
<string name="cd_open_about">Otwórz informacje</string>
<string name="cd_open_location_channels">Otwórz ustawienia lokalizacji i kanałów</string>
<string name="nearby_notes_reveal">sprawdź, czy zostawiono tutaj notatki</string>
<string name="nearby_notes_one">1 notatka zostawiona tutaj — stuknij, aby przeczytać</string>
<string name="nearby_notes_many">%d notatek zostawionych tutaj — stuknij, aby przeczytać</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Mensagens privadas não lidas</string>
<string name="cd_teleported">Teletransportado</string>
<string name="cd_tor_status">Status do Tor</string>
<string name="cd_open_location_channels">Abrir configurações de localização e canais</string>
<string name="cd_connected_peers">Peers conectados</string>
<string name="cd_geohash_participants">Participantes geohash</string>
<string name="cd_ready_for_handshake">Pronto para handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Mensagens privadas não lidas</string>
<string name="cd_teleported">Teletransportado</string>
<string name="cd_tor_status">Estado do Tor</string>
<string name="cd_open_location_channels">Abrir definições de localização e canais</string>
<string name="cd_connected_peers">Pares ligados</string>
<string name="cd_geohash_participants">Participantes geohash</string>
<string name="cd_ready_for_handshake">Pronto para handshake</string>

View File

@ -67,6 +67,7 @@
<string name="cd_unread_private_messages">Непрочитанные личные</string>
<string name="cd_teleported">Телепортировано</string>
<string name="cd_tor_status">Статус Tor</string>
<string name="cd_open_location_channels">Открыть настройки местоположения и каналов</string>
<string name="cd_connected_peers">Подключённые узлы</string>
<string name="cd_geohash_participants">Участники geohash</string>
<string name="cd_ready_for_handshake">Готов к рукопожатию</string>

View File

@ -67,6 +67,7 @@
<string name="cd_unread_private_messages">Olästa privata meddelanden</string>
<string name="cd_teleported">Teleporterad</string>
<string name="cd_tor_status">Torstatus</string>
<string name="cd_open_location_channels">Öppna plats- och kanalinställningar</string>
<string name="cd_connected_peers">Anslutna noder</string>
<string name="cd_geohash_participants">Geohashdeltagare</string>
<string name="cd_ready_for_handshake">Redo för handshake</string>

View File

@ -41,6 +41,7 @@
<string name="verify_success_body">You verified %1$s</string>
<string name="verify_success_system_message">verified %1$s</string>
<string name="cd_open_about">அறிமுகத்தைத் திற</string>
<string name="cd_open_location_channels">இருப்பிடம் மற்றும் சேனல் அமைப்புகளைத் திற</string>
<string name="nearby_notes_reveal">இங்கே விடப்பட்ட குறிப்புகள் உள்ளதா எனப் பார்க்கவும்</string>
<string name="nearby_notes_one">இங்கே 1 குறிப்பு விடப்பட்டுள்ளது — படிக்க தட்டவும்</string>
<string name="nearby_notes_many">இங்கே %d குறிப்புகள் விடப்பட்டுள்ளன — படிக்க தட்டவும்</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">ข้อความส่วนตัวยังไม่ได้อ่าน</string>
<string name="cd_teleported">เทเลพอร์ตแล้ว</string>
<string name="cd_tor_status">สถานะ Tor</string>
<string name="cd_open_location_channels">เปิดการตั้งค่าตำแหน่งและช่อง</string>
<string name="cd_connected_peers">เพียร์ที่เชื่อมต่อ</string>
<string name="cd_geohash_participants">ผู้เข้าร่วม geohash</string>
<string name="cd_ready_for_handshake">พร้อมสำหรับการจับมือ</string>

View File

@ -67,6 +67,7 @@
<string name="cd_unread_private_messages">Okunmamış özel mesaj</string>
<string name="cd_teleported">Teleport edildi</string>
<string name="cd_tor_status">Tor durumu</string>
<string name="cd_open_location_channels">Konum ve kanal ayarlarını</string>
<string name="cd_connected_peers">Bağlı eşler</string>
<string name="cd_geohash_participants">Geohash katılımcıları</string>
<string name="cd_ready_for_handshake">El sıkışmaya hazır</string>

View File

@ -41,6 +41,7 @@
<string name="verify_success_body">You verified %1$s</string>
<string name="verify_success_system_message">verified %1$s</string>
<string name="cd_open_about">Відкрити розділ «Про застосунок»</string>
<string name="cd_open_location_channels">Відкрити налаштування розташування та каналів</string>
<string name="nearby_notes_reveal">перевірити, чи залишено тут нотатки</string>
<string name="nearby_notes_one">тут залишено 1 нотатку — торкніться, щоб прочитати</string>
<string name="nearby_notes_many">тут залишено %d нотаток — торкніться, щоб прочитати</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">غیر پڑھے ہوئے نجی پیغامات</string>
<string name="cd_teleported">ٹیلی پورٹ</string>
<string name="cd_tor_status">Tor کی کیفیت</string>
<string name="cd_open_location_channels">مقام اور چینل کی ترتیبات کھولیں</string>
<string name="cd_connected_peers">منسلک پیئرز</string>
<string name="cd_geohash_participants">geohash شرکاء</string>
<string name="cd_ready_for_handshake">ہینڈ شیک کے لیے تیار</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">Tin nhắn riêng chưa đọc</string>
<string name="cd_teleported">Đã dịch chuyển</string>
<string name="cd_tor_status">Trạng thái Tor</string>
<string name="cd_open_location_channels">Mở cài đặt vị trí và kênh</string>
<string name="cd_connected_peers">Peers đã kết nối</string>
<string name="cd_geohash_participants">Người tham gia geohash</string>
<string name="cd_ready_for_handshake">Sẵn sàng cho handshake</string>

View File

@ -75,6 +75,7 @@
<string name="cd_unread_private_messages">未读私信</string>
<string name="cd_teleported">已传送</string>
<string name="cd_tor_status">Tor 状态</string>
<string name="cd_open_location_channels">打开位置和频道设置</string>
<string name="cd_connected_peers">已连接节点</string>
<string name="cd_geohash_participants">Geohash 参与者</string>
<string name="cd_ready_for_handshake">准备握手</string>

View File

@ -77,6 +77,7 @@
<string name="cd_location_notes">Location notes</string>
<string name="cd_teleported">Teleported</string>
<string name="cd_tor_status">Tor status</string>
<string name="cd_open_location_channels">Open location and channel settings</string>
<string name="cd_connected_peers">Connected peers</string>
<string name="cd_geohash_participants">Geohash participants</string>
<string name="cd_ready_for_handshake">Ready for handshake</string>

View File

@ -0,0 +1,38 @@
package com.bitchat.android.ui
import androidx.compose.ui.unit.dp
import org.junit.Assert.assertEquals
import org.junit.Test
class ChatHeaderCrowdingTest {
@Test
fun `full header is used at four hundred dp and above`() {
assertEquals(HeaderCrowdingMode.Full, headerCrowdingMode(400.dp))
assertEquals(HeaderCrowdingMode.Full, headerCrowdingMode(500.dp))
}
@Test
fun `joined channel count yields before the location label`() {
assertEquals(
HeaderCrowdingMode.HideJoinedChannelCount,
headerCrowdingMode(399.dp)
)
assertEquals(
HeaderCrowdingMode.HideJoinedChannelCount,
headerCrowdingMode(360.dp)
)
}
@Test
fun `location action becomes icon only on narrow headers`() {
assertEquals(
HeaderCrowdingMode.IconOnlyLocationChannel,
headerCrowdingMode(359.dp)
)
assertEquals(
HeaderCrowdingMode.IconOnlyLocationChannel,
headerCrowdingMode(320.dp)
)
}
}