geist mono

This commit is contained in:
callebtc 2026-07-27 13:27:15 +02:00
parent 7b03863eaa
commit a85ba40637
42 changed files with 590 additions and 346 deletions

View File

@ -10,10 +10,10 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.CompositionLocalProvider
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.core.ui.component.button.CloseButton
@OptIn(ExperimentalMaterial3Api::class)
@ -83,7 +83,7 @@ fun BitchatSheetTitle(text: String) {
text = text,
style = MaterialTheme.typography.titleMedium.copy(
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
)
}

View File

@ -30,12 +30,12 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.BitchatTheme
import com.bitchat.android.util.UniversalApkManager
import com.google.accompanist.permissions.ExperimentalPermissionsApi
@ -112,7 +112,7 @@ fun HotspotScreen(
title = {
Text(
text = "Share BitChat",
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
},
navigationIcon = {
@ -398,7 +398,7 @@ fun ActiveHotspotScreen(state: HotspotViewModel.HotspotState.Active) {
text = {
Text(
text = title,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = if (selectedTab == index) FontWeight.Bold else FontWeight.Normal
)
}
@ -615,7 +615,7 @@ fun CredentialCard(
Text(
text = value,
style = MaterialTheme.typography.bodyLarge,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSecondaryContainer
)

View File

@ -28,11 +28,11 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -99,7 +99,7 @@ fun BackgroundLocationPermissionScreen(
Text(
text = stringResource(R.string.background_location_settings_tip),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = colorScheme.onBackground.copy(alpha = 0.8f)
)
@ -140,14 +140,14 @@ fun BackgroundLocationPermissionScreen(
Text(
text = stringResource(R.string.background_location_needs_bullets),
style = MaterialTheme.typography.bodySmall,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.8f)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(R.string.background_location_privacy_note),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium
),
color = colorScheme.onBackground
@ -183,7 +183,7 @@ fun BackgroundLocationPermissionScreen(
Text(
text = stringResource(R.string.grant_background_location),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(vertical = 4.dp)
@ -201,7 +201,7 @@ fun BackgroundLocationPermissionScreen(
Text(
text = stringResource(R.string.check_again),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
)
}
@ -213,7 +213,7 @@ fun BackgroundLocationPermissionScreen(
Text(
text = stringResource(R.string.battery_optimization_skip),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
)
}
@ -234,7 +234,7 @@ private fun HeaderSection(colorScheme: ColorScheme) {
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
@ -244,7 +244,7 @@ private fun HeaderSection(colorScheme: ColorScheme) {
Text(
text = stringResource(R.string.background_location_required_subtitle),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.7f)
)
}

View File

@ -15,11 +15,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -105,7 +105,7 @@ private fun BatteryOptimizationEnabledContent(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
@ -115,7 +115,7 @@ private fun BatteryOptimizationEnabledContent(
Text(
text = stringResource(R.string.battery_optimization_detected_title),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.7f)
)
}
@ -225,7 +225,7 @@ private fun BatteryOptimizationEnabledContent(
Text(
text = stringResource(R.string.disable_battery_optimization),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
)
)
@ -243,7 +243,7 @@ private fun BatteryOptimizationEnabledContent(
Text(
text = stringResource(R.string.check_again),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
)
}
@ -259,7 +259,7 @@ private fun BatteryOptimizationEnabledContent(
Text(
text = stringResource(R.string.battery_optimization_skip),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
)
}
@ -284,7 +284,7 @@ private fun BatteryOptimizationCheckingContent(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
@ -294,7 +294,7 @@ private fun BatteryOptimizationCheckingContent(
Text(
text = stringResource(R.string.battery_optimization_disabled_title),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.7f)
)
}
@ -322,7 +322,7 @@ private fun BatteryOptimizationCheckingContent(
Text(
text = stringResource(R.string.battery_optimization_success_message),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.8f)
),
textAlign = TextAlign.Center
@ -347,7 +347,7 @@ private fun BatteryOptimizationNotSupportedContent(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
@ -357,7 +357,7 @@ private fun BatteryOptimizationNotSupportedContent(
Text(
text = stringResource(R.string.battery_optimization_not_required),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.7f)
)
}
@ -372,7 +372,7 @@ private fun BatteryOptimizationNotSupportedContent(
Text(
text = stringResource(R.string.battery_optimization_not_supported_message),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.8f)
),
textAlign = TextAlign.Center
@ -388,7 +388,7 @@ private fun BatteryOptimizationNotSupportedContent(
Text(
text = stringResource(R.string.continue_btn),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
)
)

View File

@ -10,11 +10,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -83,7 +83,7 @@ private fun BluetoothDisabledContent(
Text(
text = stringResource(R.string.bluetooth_recommended),
style = MaterialTheme.typography.headlineSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.primary
),
@ -114,7 +114,7 @@ private fun BluetoothDisabledContent(
Text(
text = stringResource(R.string.bluetooth_needs_bullets),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.8f)
)
)
@ -138,7 +138,7 @@ private fun BluetoothDisabledContent(
Text(
text = stringResource(R.string.enable_bluetooth),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(vertical = 4.dp)
@ -187,7 +187,7 @@ private fun BluetoothNotSupportedContent(
Text(
text = stringResource(R.string.bluetooth_not_supported),
style = MaterialTheme.typography.headlineSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.error
),
@ -204,7 +204,7 @@ private fun BluetoothNotSupportedContent(
Text(
text = stringResource(R.string.bluetooth_unsupported_explanation),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface
),
modifier = Modifier.padding(16.dp),
@ -235,7 +235,7 @@ private fun BluetoothCheckingContent(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.primary
),
@ -247,7 +247,7 @@ private fun BluetoothCheckingContent(
Text(
text = stringResource(R.string.checking_bluetooth_status),
style = MaterialTheme.typography.bodyLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
)

View File

@ -8,11 +8,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -63,7 +63,7 @@ fun InitializingScreen(modifier: Modifier) {
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.primary
),
@ -92,7 +92,7 @@ fun InitializingScreen(modifier: Modifier) {
Text(
text = stringResource(R.string.initializing_mesh_network),
style = MaterialTheme.typography.bodyLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
)
@ -102,7 +102,7 @@ fun InitializingScreen(modifier: Modifier) {
Text(
text = stringResource(R.string.dot),
style = MaterialTheme.typography.bodyLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = alpha)
)
)
@ -127,7 +127,7 @@ fun InitializingScreen(modifier: Modifier) {
Text(
text = stringResource(R.string.setting_up_bluetooth),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.8f)
),
textAlign = TextAlign.Center
@ -136,7 +136,7 @@ fun InitializingScreen(modifier: Modifier) {
Text(
text = stringResource(R.string.should_take_seconds),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.6f)
),
textAlign = TextAlign.Center
@ -184,7 +184,7 @@ fun InitializationErrorScreen(
Text(
text = stringResource(R.string.setup_not_complete),
style = MaterialTheme.typography.headlineSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.error
),
@ -201,7 +201,7 @@ fun InitializationErrorScreen(
Text(
text = errorMessage,
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface
),
modifier = Modifier.padding(16.dp),
@ -220,7 +220,7 @@ fun InitializationErrorScreen(
Text(
text = stringResource(R.string.try_again),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(vertical = 4.dp)
@ -234,7 +234,7 @@ fun InitializationErrorScreen(
Text(
text = stringResource(R.string.open_settings),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
modifier = Modifier.padding(vertical = 4.dp)
)

View File

@ -11,11 +11,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -80,7 +80,7 @@ private fun LocationDisabledContent(
Text(
text = stringResource(R.string.location_services_required),
style = MaterialTheme.typography.headlineSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.primary
),
@ -122,7 +122,7 @@ private fun LocationDisabledContent(
Text(
text = stringResource(R.string.location_explanation),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.8f)
)
)
@ -142,7 +142,7 @@ private fun LocationDisabledContent(
Text(
text = stringResource(R.string.location_needs_bullets),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.8f)
)
)
@ -166,7 +166,7 @@ private fun LocationDisabledContent(
Text(
text = stringResource(R.string.open_location_settings),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(vertical = 4.dp)
@ -180,7 +180,7 @@ private fun LocationDisabledContent(
Text(
text = stringResource(R.string.check_again),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
modifier = Modifier.padding(vertical = 4.dp)
)
@ -209,7 +209,7 @@ private fun LocationNotAvailableContent(
Text(
text = stringResource(R.string.location_services_unavailable),
style = MaterialTheme.typography.headlineSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.error
),
@ -226,7 +226,7 @@ private fun LocationNotAvailableContent(
Text(
text = stringResource(R.string.location_unavailable_explanation),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface
),
modifier = Modifier.padding(16.dp),
@ -247,7 +247,7 @@ private fun LocationCheckingContent(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = colorScheme.primary
),
@ -259,7 +259,7 @@ private fun LocationCheckingContent(
Text(
text = stringResource(R.string.checking_location_services),
style = MaterialTheme.typography.bodyLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
)

View File

@ -18,12 +18,12 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
/**
@ -68,7 +68,7 @@ fun PermissionExplanationScreen(
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 32.sp
),
@ -79,7 +79,7 @@ fun PermissionExplanationScreen(
Text(
text = stringResource(R.string.about_tagline),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.7f)
)
}
@ -117,7 +117,7 @@ fun PermissionExplanationScreen(
Text(
text = stringResource(R.string.privacy_bullets),
style = MaterialTheme.typography.bodySmall,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.onBackground.copy(alpha = 0.8f)
)
}
@ -164,7 +164,7 @@ fun PermissionExplanationScreen(
Text(
text = stringResource(R.string.grant_permissions),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
modifier = Modifier.padding(vertical = 4.dp)

View File

@ -46,10 +46,10 @@ import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.icon.BitChatIcon
import com.bitchat.android.ui.theme.BitchatMotion
@ -108,7 +108,7 @@ internal fun AboutSectionLabel(
val palette = LocalBitchatPalette.current
Text(
text = text.uppercase(),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.8.sp,
@ -149,7 +149,7 @@ internal fun SheetIconSectionHeader(
Text(
text = title,
fontSize = 17.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.SemiBold,
color = colorScheme.primary
)
@ -159,7 +159,7 @@ internal fun SheetIconSectionHeader(
text = subtitle,
fontSize = 12.sp,
lineHeight = 17.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textSecondary
)
}
@ -205,7 +205,7 @@ internal fun AboutHero(
Text(
text = stringResource(R.string.app_name),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 40.sp,
// Monospace at display size leaves too much air between glyphs; pull it in slightly
@ -218,7 +218,7 @@ internal fun AboutHero(
Text(
text = stringResource(R.string.about_tagline),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 16.sp,
color = palette.textSecondary
)
@ -227,7 +227,7 @@ internal fun AboutHero(
Text(
text = stringResource(R.string.version_prefix, versionName),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = palette.textTertiary
)
@ -320,7 +320,7 @@ private fun AboutTabLabel(
) {
Text(
text = text.uppercase(),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.8.sp,
@ -355,7 +355,7 @@ private fun AboutInstructionRow(
)
Text(
text = text,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
lineHeight = 20.sp,
color = palette.textPrimary
@ -373,7 +373,7 @@ internal fun AboutHowToUseSection(modifier: Modifier = Modifier) {
Column(modifier = modifier.fillMaxWidth()) {
Text(
text = stringResource(R.string.about_how_to_use_heading),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.Medium,
color = colorScheme.primary,
@ -481,7 +481,7 @@ private fun AboutFeatureRow(
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
Text(
text = title,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
lineHeight = 20.sp,
@ -489,7 +489,7 @@ private fun AboutFeatureRow(
)
Text(
text = subtitle,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
lineHeight = 17.sp,
color = palette.textSecondary
@ -514,7 +514,7 @@ internal fun BitchatBadge(
) {
Text(
text = text.uppercase(),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 10.sp,
fontWeight = FontWeight.Bold,
letterSpacing = 0.5.sp,
@ -539,7 +539,7 @@ internal fun SheetSectionLabel(
val palette = LocalBitchatPalette.current
Text(
text = text.uppercase(),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.8.sp,
@ -608,7 +608,7 @@ internal fun SheetDestructiveButton(
Box(contentAlignment = Alignment.Center) {
Text(
text = text.uppercase(),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.8.sp,

View File

@ -52,12 +52,12 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.button.CloseButton
import com.bitchat.android.core.ui.component.sheet.LocalSheetDismiss
@ -111,7 +111,7 @@ private fun ThemeChip(
) {
Text(
text = label,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 13.sp,
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Normal,
color = labelColor
@ -188,7 +188,7 @@ private fun SettingsToggleRow(
) {
Text(
text = title,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = titleColor
@ -197,7 +197,7 @@ private fun SettingsToggleRow(
}
Text(
text = subtitle,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = subtitleColor,
lineHeight = 17.sp
@ -789,7 +789,7 @@ fun AboutSheet(
Text(
text = stringResource(R.string.tor_not_available_in_this_build),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary,
modifier = Modifier.padding(
start = AboutHorizontalPadding + 16.dp,
@ -825,7 +825,7 @@ fun AboutSheet(
) {
Text(
text = stringResource(R.string.about_difficulty),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = palette.textPrimary
@ -837,7 +837,7 @@ fun AboutSheet(
powDifficulty,
NostrProofOfWork.estimateMiningTime(powDifficulty)
),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = palette.textSecondary
)
@ -867,7 +867,7 @@ fun AboutSheet(
else -> stringResource(R.string.about_pow_desc_extreme)
},
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary
)
}
@ -911,7 +911,7 @@ fun AboutSheet(
} else {
stringResource(R.string.about_tor_disconnected)
},
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = palette.textPrimary
@ -921,7 +921,7 @@ fun AboutSheet(
Text(
text = torStatus.lastLogLine.take(120),
fontSize = 11.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary,
maxLines = 2
)
@ -952,7 +952,7 @@ fun AboutSheet(
Text(
text = stringResource(R.string.about_debug_settings),
fontSize = 13.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.primary
)
}
@ -960,7 +960,7 @@ fun AboutSheet(
Text(
text = stringResource(R.string.about_footer),
fontSize = 11.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary
)
Spacer(modifier = Modifier.height(20.dp))
@ -1028,7 +1028,7 @@ fun PasswordPromptDialog(
onValueChange = onPasswordChange,
label = { Text(stringResource(R.string.pwd_label), style = MaterialTheme.typography.bodyMedium) },
textStyle = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = colorScheme.primary,

View File

@ -1,6 +1,5 @@
package com.bitchat.android.ui
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.*
@ -35,12 +34,12 @@ import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
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.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.button.BitChatBrandButton
import com.bitchat.android.net.ArtiTorManager
@ -277,7 +276,7 @@ fun NicknameEditor(
onValueChange = onValueChange,
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = colorScheme.primary,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = HeaderTextSize
),
cursorBrush = SolidColor(colorScheme.primary),

View File

@ -1,4 +1,7 @@
package com.bitchat.android.ui
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.BitchatFontFamily
// [Goose] Bridge file share events to ViewModel via dispatcher is installed in ChatScreen composition
// [Goose] Installing FileShareDispatcher handler in ChatScreen to forward file sends to ViewModel
@ -24,7 +27,6 @@ import androidx.compose.material3.IconButton
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
@ -535,7 +537,7 @@ private fun NearbyNotesStrip(
},
modifier = Modifier.weight(1f),
color = MaterialTheme.colorScheme.primary,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
)
Text(

View File

@ -9,6 +9,7 @@ import androidx.compose.ui.unit.sp
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.ui.theme.BASE_FONT_SIZE
import com.bitchat.android.ui.theme.BitchatPalette
import com.bitchat.android.ui.theme.ChatVisualTokens
import java.text.SimpleDateFormat
import java.util.*
@ -18,13 +19,13 @@ import java.util.*
*/
/** Opacity applied to the `#abcd` disambiguation suffix so the readable name dominates. */
internal const val SUFFIX_ALPHA = 0.55f
internal const val SUFFIX_ALPHA = ChatVisualTokens.SenderSuffixAlpha
/** Background opacity for a mention chip referring to somebody else. */
internal const val MENTION_CHIP_ALPHA = 0.18f
internal const val MENTION_CHIP_ALPHA = ChatVisualTokens.HighlightAlpha
/** Background opacity for a mention chip referring to you. Slightly stronger to catch the eye. */
internal const val MENTION_CHIP_ALPHA_SELF = 0.22f
internal const val MENTION_CHIP_ALPHA_SELF = ChatVisualTokens.HighlightAlpha
/**
* Get RSSI-based color for signal strength visualization
@ -54,13 +55,13 @@ fun formatTextMessageSender(
val builder = AnnotatedString.Builder()
val isSelf = message.isFromSelf(currentUserNickname, myPeerID)
val senderColor = if (isSelf) palette.accentOrange else getPeerColor(message, palette.isDark)
val senderWeight = if (isSelf) FontWeight.Bold else FontWeight.SemiBold
val senderWeight = FontWeight.SemiBold
val (baseName, suffix) = splitSuffix(message.sender)
builder.pushStyle(
SpanStyle(
color = senderColor,
fontSize = BASE_FONT_SIZE.sp,
fontSize = ChatVisualTokens.SenderFontSize,
fontWeight = senderWeight
)
)
@ -82,8 +83,8 @@ fun formatTextMessageSender(
builder.pushStyle(
SpanStyle(
color = senderColor.copy(alpha = SUFFIX_ALPHA),
fontSize = BASE_FONT_SIZE.sp,
fontWeight = senderWeight
fontSize = ChatVisualTokens.SenderFontSize,
fontWeight = FontWeight.Normal
)
)
builder.append(suffix)
@ -97,7 +98,7 @@ fun formatTextMessageSender(
* Build the compact timestamp and optional proof-of-work label.
*
* Used standalone by media rows; text messages get the same span appended inline to the end of
* their body via [appendTrailingTimestamp].
* their body via [appendBodyTimestamp].
*/
fun formatTextMessageMetadata(
message: BitchatMessage,
@ -125,24 +126,49 @@ fun formatTextMessageMetadata(
* Deliberately carries no click annotation: the timestamp is decoration, and making it
* tappable would create dead zones inside the message body.
*/
private fun appendTrailingTimestamp(
private fun appendTimestampText(
builder: AnnotatedString.Builder,
message: BitchatMessage,
palette: BitchatPalette,
timeFormatter: SimpleDateFormat
) {
builder.pushStyle(
SpanStyle(
color = palette.textTertiary,
fontSize = (BASE_FONT_SIZE - 4).sp,
fontWeight = FontWeight.Normal
)
)
builder.append(" ")
builder.append(timeFormatter.format(message.timestamp))
message.powDifficulty?.takeIf { it > 0 }?.let { bits ->
builder.append("${bits}b")
}
}
private fun appendBodyTimestamp(
builder: AnnotatedString.Builder,
message: BitchatMessage,
palette: BitchatPalette,
timeFormatter: SimpleDateFormat,
) {
builder.pushStyle(
SpanStyle(
color = palette.textTertiary,
fontSize = ChatVisualTokens.SystemTimeFontSize,
fontWeight = FontWeight.Normal,
)
)
appendTimestampText(builder, message, timeFormatter)
builder.pop()
}
private fun appendMutedTimestamp(
builder: AnnotatedString.Builder,
message: BitchatMessage,
palette: BitchatPalette,
timeFormatter: SimpleDateFormat,
) {
builder.pushStyle(
SpanStyle(
color = palette.textPrimary.copy(alpha = ChatVisualTokens.MutedTextAlpha),
fontSize = ChatVisualTokens.SystemTimeFontSize,
fontWeight = FontWeight.Normal,
)
)
appendTimestampText(builder, message, timeFormatter)
builder.pop()
}
@ -170,7 +196,7 @@ fun formatTextMessageBody(
)
if (includeTimestamp) {
appendTrailingTimestamp(builder, message, palette, timeFormatter)
appendBodyTimestamp(builder, message, palette, timeFormatter)
}
return builder.toAnnotatedString()
}
@ -189,16 +215,16 @@ fun formatSystemMessage(
val builder = AnnotatedString.Builder()
builder.pushStyle(
SpanStyle(
color = palette.textSecondary,
fontSize = (BASE_FONT_SIZE - 2).sp,
fontWeight = FontWeight.Normal
color = palette.textPrimary.copy(alpha = ChatVisualTokens.MutedTextAlpha),
fontSize = ChatVisualTokens.SystemActionFontSize,
fontWeight = FontWeight.Medium,
)
)
builder.append("// ")
builder.append(message.content)
builder.pop()
appendTrailingTimestamp(builder, message, palette, timeFormatter)
appendMutedTimestamp(builder, message, palette, timeFormatter)
return builder.toAnnotatedString()
}
@ -226,14 +252,13 @@ fun formatMessageHeaderAnnotatedString(
if (includeSender) {
val baseColor = if (isSelf) palette.accentOrange else getPeerColor(message, palette.isDark)
val weight = if (isSelf) FontWeight.Bold else FontWeight.SemiBold
val (baseName, suffix) = splitSuffix(message.sender)
builder.pushStyle(
SpanStyle(
color = baseColor,
fontSize = BASE_FONT_SIZE.sp,
fontWeight = weight
fontSize = ChatVisualTokens.SenderFontSize,
fontWeight = FontWeight.SemiBold,
)
)
builder.append("@")
@ -254,8 +279,8 @@ fun formatMessageHeaderAnnotatedString(
builder.pushStyle(
SpanStyle(
color = baseColor.copy(alpha = SUFFIX_ALPHA),
fontSize = BASE_FONT_SIZE.sp,
fontWeight = weight
fontSize = ChatVisualTokens.SenderFontSize,
fontWeight = FontWeight.Normal,
)
)
builder.append(suffix)
@ -263,7 +288,7 @@ fun formatMessageHeaderAnnotatedString(
}
}
appendTrailingTimestamp(builder, message, palette, timeFormatter)
appendMutedTimestamp(builder, message, palette, timeFormatter)
return builder.toAnnotatedString()
}
@ -318,8 +343,8 @@ fun colorForPeerSeed(seed: String, isDark: Boolean): Color {
hue = (hue + 0.12) % 1.0
}
val saturation = if (isDark) 0.62 else 0.85
val brightness = if (isDark) 0.92 else 0.45
val saturation = if (isDark) 1.0 else 0.85
val brightness = if (isDark) 1.0 else 0.45
return Color.hsv(
hue = (hue * 360).toFloat(),

View File

@ -6,10 +6,10 @@ import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.BASE_FONT_SIZE
import androidx.compose.ui.res.stringResource
import com.bitchat.android.R
@ -59,7 +59,7 @@ fun ChatUserSheet(
Text(
text = stringResource(R.string.at_nickname, targetNickname),
fontSize = 18.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
@ -67,7 +67,7 @@ fun ChatUserSheet(
Text(
text = if (selectedMessage != null) stringResource(R.string.choose_action_message_or_user) else stringResource(R.string.choose_action_user),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
)
@ -183,7 +183,7 @@ fun ChatUserSheet(
Text(
text = stringResource(R.string.cancel_lower),
fontSize = BASE_FONT_SIZE.sp,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
}
}
@ -214,7 +214,7 @@ private fun UserActionRow(
Text(
text = title,
fontSize = BASE_FONT_SIZE.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
color = titleColor
)
@ -222,7 +222,7 @@ private fun UserActionRow(
Text(
text = subtitle,
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
}

View File

@ -19,13 +19,13 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.ui.theme.BitchatMotion
import com.bitchat.android.ui.theme.LocalBitchatPalette
@ -73,7 +73,7 @@ fun GeohashPeopleList(
) {
Text(
text = stringResource(R.string.nobody_around),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = palette.textTertiary,
modifier = Modifier.padding(
@ -272,7 +272,7 @@ private fun PeopleCard(
AnimatedCountLabel(
count = hiddenCount,
text = stringResource(R.string.people_n_more, hiddenCount),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = palette.textTertiary,
modifier = Modifier.padding(
@ -357,7 +357,7 @@ private fun GeohashPersonItem(
) {
Text(
text = baseName,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = if (isMe) FontWeight.Bold else FontWeight.Medium,
color = baseColor,
@ -368,7 +368,7 @@ private fun GeohashPersonItem(
if (suffix.isNotEmpty()) {
Text(
text = suffix,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = if (isMe) FontWeight.Bold else FontWeight.Medium,
color = baseColor.copy(alpha = SUFFIX_ALPHA)
@ -378,7 +378,7 @@ private fun GeohashPersonItem(
if (isMe) {
Text(
text = stringResource(R.string.you_suffix),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
color = baseColor
)

View File

@ -31,13 +31,13 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import androidx.core.view.updateLayoutParams
import com.bitchat.android.geohash.Geohash
@ -186,7 +186,7 @@ class GeohashPickerActivity : OrientationAwareActivity() {
text = stringResource(R.string.pan_zoom_instruction),
fontSize = 12.sp,
textAlign = TextAlign.Center,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.padding(horizontal = 14.dp, vertical = 10.dp)
@ -211,7 +211,7 @@ class GeohashPickerActivity : OrientationAwareActivity() {
Text(
text = if (currentGeohash.isNotEmpty()) "#${currentGeohash}" else "select location",
fontSize = BASE_FONT_SIZE.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
@ -277,7 +277,7 @@ class GeohashPickerActivity : OrientationAwareActivity() {
Text(
text = stringResource(R.string.select),
fontSize = (BASE_FONT_SIZE - 2).sp,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
}
}

View File

@ -1,4 +1,7 @@
package com.bitchat.android.ui
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.BitchatFontFamily
// [Goose] TODO: Replace inline file attachment stub with FilePickerButton abstraction that dispatches via FileShareDispatcher
@ -45,7 +48,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
@ -98,7 +100,7 @@ class SlashCommandVisualTransformation(
withStyle(
style = SpanStyle(
color = commandColor,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
background = commandBackground
)
@ -145,7 +147,7 @@ class MentionVisualTransformation(
withStyle(
style = SpanStyle(
color = mentionColor,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.SemiBold,
// Mirrors the mention chip used in rendered messages, so what you type
// looks like what everyone will see.
@ -367,7 +369,7 @@ fun MessageInput(
// type into.
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = palette.textPrimary,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
cursorBrush = SolidColor(
if (isRecording) Color.Transparent else palette.textPrimary
@ -411,7 +413,7 @@ fun MessageInput(
Text(
text = stringResource(R.string.type_a_message_placeholder),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = palette.textTertiary,
maxLines = 1,
@ -446,7 +448,7 @@ fun MessageInput(
"%02d:%02d / %02d:%02d",
secs / 60, secs % 60, maxSecs / 60, maxSecs % 60
),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.accentRed,
fontSize = (BASE_FONT_SIZE - 4).sp
)
@ -664,7 +666,7 @@ fun CommandSuggestionItem(
Text(
text = allCommands.joinToString(", "),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium
),
color = colorScheme.primary,
@ -676,7 +678,7 @@ fun CommandSuggestionItem(
Text(
text = syntax,
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = palette.textSecondary,
fontSize = (BASE_FONT_SIZE - 4).sp
@ -687,7 +689,7 @@ fun CommandSuggestionItem(
Text(
text = suggestion.description,
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = palette.textTertiary,
fontSize = (BASE_FONT_SIZE - 4).sp,
@ -737,7 +739,7 @@ fun MentionSuggestionItem(
Text(
text = stringResource(R.string.mention_suggestion_at, suggestion),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.SemiBold
),
color = palette.accentOrange,
@ -749,7 +751,7 @@ fun MentionSuggestionItem(
Text(
text = stringResource(R.string.mention),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = palette.textTertiary,
fontSize = (BASE_FONT_SIZE - 4).sp

View File

@ -17,11 +17,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.BASE_FONT_SIZE
import java.net.URL
@ -110,7 +110,7 @@ fun LinkPreviewPill(
// Title - matches iOS styling
Text(
text = displayTitle,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = BASE_FONT_SIZE.sp,
fontWeight = FontWeight.SemiBold,
color = textColor,
@ -121,7 +121,7 @@ fun LinkPreviewPill(
// Host - matches iOS styling
Text(
text = displayHost,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = textColor.copy(alpha = 0.6f),
maxLines = 1,

View File

@ -42,12 +42,12 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.nostr.NearbyNotesController
import com.bitchat.android.nostr.geohashesForSampling
import com.bitchat.android.ui.theme.BASE_FONT_SIZE
@ -351,7 +351,7 @@ fun LocationChannelsSheet(
Text(
text = stringResource(R.string.location_permission_denied),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.accentRed
)
TextButton(
@ -371,7 +371,7 @@ fun LocationChannelsSheet(
Text(
text = stringResource(R.string.open_settings),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
}
}
@ -495,7 +495,7 @@ fun LocationChannelsSheet(
Text(
text = shownError,
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.accentRed,
modifier = Modifier.padding(
start = AboutHorizontalPadding + ChannelRowHorizontal,
@ -541,7 +541,7 @@ fun LocationChannelsSheet(
Text(
text = stringResource(R.string.tor_not_available_in_this_build),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary,
modifier = Modifier.padding(
start = AboutHorizontalPadding + ChannelRowHorizontal,
@ -683,7 +683,7 @@ private fun ChannelOptionRow(
Text(
text = baseTitle,
fontSize = 14.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = if (titleBold) FontWeight.SemiBold else FontWeight.Medium,
color = titleColor ?: palette.textPrimary
)
@ -692,7 +692,7 @@ private fun ChannelOptionRow(
count = participantCount,
text = count,
fontSize = 11.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textSecondary
)
}
@ -700,7 +700,7 @@ private fun ChannelOptionRow(
Text(
text = subtitle,
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
lineHeight = 17.sp,
color = palette.textSecondary
)
@ -759,7 +759,7 @@ private fun ChannelLoadingRow() {
Text(
text = stringResource(R.string.finding_nearby_channels),
fontSize = 12.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textSecondary
)
}
@ -822,7 +822,7 @@ private fun CustomGeohashRow(
Text(
text = stringResource(R.string.hash_symbol),
fontSize = 14.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary
)
@ -833,7 +833,7 @@ private fun CustomGeohashRow(
onValueChange = onGeohashChange,
textStyle = TextStyle(
fontSize = 14.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = colorScheme.primary
),
cursorBrush = SolidColor(colorScheme.primary),
@ -846,7 +846,7 @@ private fun CustomGeohashRow(
Text(
text = stringResource(R.string.geohash_placeholder),
fontSize = 14.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary
)
}
@ -882,7 +882,7 @@ private fun CustomGeohashRow(
fontSize = 11.sp,
letterSpacing = 0.8.sp,
fontWeight = FontWeight.Medium,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = teleportColor,
modifier = Modifier.padding(horizontal = 10.dp, vertical = 8.dp)
)
@ -927,7 +927,7 @@ private fun ChannelSettingsToggleRow(
) {
Text(
text = title,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = if (enabled) palette.textPrimary else palette.textTertiary
@ -936,7 +936,7 @@ private fun ChannelSettingsToggleRow(
}
Text(
text = subtitle,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
lineHeight = 17.sp,
color = if (enabled) palette.textSecondary else palette.textTertiary

View File

@ -18,9 +18,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.pluralStringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@ -251,7 +251,7 @@ private fun LocationNotesHeader(
if (name.isNotEmpty()) {
Text(
text = name,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = accentGreen
)
@ -262,7 +262,7 @@ private fun LocationNotesHeader(
// Description
Text(
text = stringResource(R.string.location_notes_description),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -272,7 +272,7 @@ private fun LocationNotesHeader(
Spacer(modifier = Modifier.height(4.dp))
Text(
text = stringResource(R.string.location_notes_relays_unavailable),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -303,7 +303,7 @@ private fun NoteRow(note: LocationNotesManager.Note) {
) {
Text(
text = "@$baseName",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onSurface
@ -312,7 +312,7 @@ private fun NoteRow(note: LocationNotesManager.Note) {
Spacer(modifier = Modifier.width(6.dp))
Text(
text = ts,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -324,7 +324,7 @@ private fun NoteRow(note: LocationNotesManager.Note) {
// Second row: content
Text(
text = note.content,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurface
)
@ -343,7 +343,7 @@ private fun NoRelaysRow(onRetry: () -> Unit) {
) {
Text(
text = stringResource(R.string.location_notes_no_relays_title),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onSurface
@ -351,14 +351,14 @@ private fun NoRelaysRow(onRetry: () -> Unit) {
Spacer(modifier = Modifier.height(4.dp))
Text(
text = stringResource(R.string.location_notes_no_relays_desc),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = stringResource(R.string.retry),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.clickable(onClick = onRetry)
@ -385,7 +385,7 @@ private fun LoadingRow() {
Spacer(modifier = Modifier.width(10.dp))
Text(
text = stringResource(R.string.loading_location_notes),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -404,7 +404,7 @@ private fun EmptyRow() {
) {
Text(
text = stringResource(R.string.location_notes_empty_title),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onSurface
@ -412,7 +412,7 @@ private fun EmptyRow() {
Spacer(modifier = Modifier.height(4.dp))
Text(
text = stringResource(R.string.location_notes_empty_desc),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -440,7 +440,7 @@ private fun ErrorRow(message: String, onDismiss: () -> Unit) {
Spacer(modifier = Modifier.width(6.dp))
Text(
text = message,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurface
)
@ -448,7 +448,7 @@ private fun ErrorRow(message: String, onDismiss: () -> Unit) {
Spacer(modifier = Modifier.height(4.dp))
Text(
text = stringResource(R.string.dismiss),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.clickable(onClick = onDismiss)
@ -482,7 +482,7 @@ private fun LocationNotesInputSection(
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = "@$baseName",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold,
color = colorScheme.onSurface
@ -506,7 +506,7 @@ private fun LocationNotesInputSection(
onValueChange = onDraftChange,
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = colorScheme.primary,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
cursorBrush = androidx.compose.ui.graphics.SolidColor(colorScheme.primary),
keyboardOptions = androidx.compose.foundation.text.KeyboardOptions(
@ -523,7 +523,7 @@ private fun LocationNotesInputSection(
Text(
text = stringResource(R.string.location_notes_input_placeholder),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = colorScheme.onSurface.copy(alpha = 0.5f),
modifier = Modifier.fillMaxWidth()

View File

@ -4,6 +4,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import android.util.Log
import androidx.compose.animation.AnimatedVisibility
@ -28,7 +29,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -271,7 +271,7 @@ private fun ChannelRow(
} else {
Text(
text = "#",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = palette.textTertiary
@ -283,7 +283,7 @@ private fun ChannelRow(
Text(
text = channel,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
color = if (isSelected) colorScheme.primary else palette.textPrimary,
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Medium,
@ -337,7 +337,7 @@ fun PeopleSection(
if (connectedPeers.isEmpty()) {
Text(
text = stringResource(id = R.string.no_one_connected),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = palette.textTertiary,
modifier = Modifier
@ -655,7 +655,7 @@ private fun PeerItem(
) {
Text(
text = baseName,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = if (isMe) FontWeight.Bold else FontWeight.Medium,
color = baseColor,
@ -666,7 +666,7 @@ private fun PeerItem(
if (suffix.isNotEmpty()) {
Text(
text = suffix,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = if (isMe) FontWeight.Bold else FontWeight.Medium,
color = baseColor.copy(alpha = SUFFIX_ALPHA)
@ -741,7 +741,7 @@ private fun UnreadBadge(
style = MaterialTheme.typography.labelSmall,
fontSize = 10.sp,
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = Color.Black
)
}
@ -1007,7 +1007,7 @@ fun PrivateChatSheet(
text = titleText,
style = MaterialTheme.typography.titleMedium.copy(
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = if (isNostrPeer || isNostrReachableFavorite) Color(0xFFFF9500) else colorScheme.onSurface
)

View File

@ -1,6 +1,5 @@
package com.bitchat.android.ui
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.animation.AnimatedContent
@ -54,13 +53,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.text.AnnotatedClickableText
import com.bitchat.android.mesh.MeshService
@ -70,6 +69,7 @@ import com.bitchat.android.model.DeliveryStatus
import com.bitchat.android.ui.media.FileMessageItem
import com.bitchat.android.ui.theme.BASE_FONT_SIZE
import com.bitchat.android.ui.theme.BitchatMotion
import com.bitchat.android.ui.theme.ChatVisualTokens
import com.bitchat.android.ui.theme.LocalBitchatPalette
import com.bitchat.android.ui.theme.MessageBodyTextStyle
import com.bitchat.android.ui.theme.MessageSenderTextStyle
@ -290,8 +290,8 @@ fun MessagesList(
top = 8.dp + contentPadding.calculateTopPadding(),
bottom = 12.dp + contentPadding.calculateBottomPadding()
),
// Spacing is owned by each item so that a continuation of the same author can sit
// tighter than the start of a new speaker's run.
// Spacing is owned by each item. The exported transcript uses a consistent 8.dp rhythm;
// a new speaker gets additional separation from the visible sender row's top inset.
verticalArrangement = Arrangement.spacedBy(0.dp),
modifier = modifier,
reverseLayout = true
@ -515,7 +515,7 @@ fun MessageItem(
}
},
onLongPress = { onMessageLongPress?.invoke(message) },
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textPrimary,
)
@ -579,7 +579,7 @@ fun MessageItem(
} else {
Text(
text = stringResource(R.string.file_unavailable),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textTertiary
)
}
@ -610,13 +610,11 @@ fun MessageItem(
}
)
},
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
softWrap = true,
overflow = TextOverflow.Visible,
style = MessageBodyTextStyle.copy(
fontSize = (BASE_FONT_SIZE - 2).sp,
lineHeight = (BASE_FONT_SIZE + 3).sp,
color = palette.textSecondary
style = ChatVisualTokens.SystemActionStyle.copy(
color = palette.textPrimary.copy(alpha = ChatVisualTokens.MutedTextAlpha),
)
)
} else {
@ -696,8 +694,10 @@ internal fun TextMessageLayout(
}
},
onLongPress = handleLongPress,
modifier = Modifier.fillMaxWidth(),
fontFamily = FontFamily.Monospace,
modifier = Modifier
.fillMaxWidth()
.padding(top = MessageGrouping.SENDER_TOP_PADDING),
fontFamily = BitchatFontFamily,
softWrap = false,
overflow = TextOverflow.Ellipsis,
style = MessageSenderTextStyle,
@ -725,7 +725,7 @@ internal fun TextMessageLayout(
}
},
onLongPress = handleLongPress,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
softWrap = true,
overflow = TextOverflow.Visible,
style = MessageBodyTextStyle.copy(color = palette.textPrimary),

View File

@ -3,24 +3,29 @@ package com.bitchat.android.ui
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.ui.theme.ChatVisualTokens
/**
* Consecutive-message grouping for the chat surface.
*
* The redesign suppresses the `@sender` label on runs of messages from the same author so the
* eye only has to register a name when the speaker actually changes. Grouped messages sit
* closer together; a new group gets extra breathing room above it.
* eye only has to register a name when the speaker actually changes. The transcript uses one
* consistent item rhythm; new groups get their additional separation from the visible sender
* row's own top padding.
*/
object MessageGrouping {
/** Space above the first message of a group (i.e. one that renders its sender label). */
val NEW_GROUP_SPACING: Dp = 10.dp
val NEW_GROUP_SPACING: Dp = ChatVisualTokens.MessageItemSpacing
/** Space above a continuation message inside an existing group. */
val GROUPED_SPACING: Dp = 4.dp
val GROUPED_SPACING: Dp = ChatVisualTokens.MessageItemSpacing
/** Gap between the sender label and the first line of the body. */
val SENDER_TO_BODY_SPACING: Dp = 2.dp
val SENDER_TO_BODY_SPACING: Dp = ChatVisualTokens.SenderToBodySpacing
/** Top inset inside a visible sender row. */
val SENDER_TOP_PADDING: Dp = ChatVisualTokens.SenderTopPadding
/**
* Messages further apart than this always start a new group, even from the same sender:

View File

@ -39,12 +39,12 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.button.CloseButton
import com.bitchat.android.core.ui.component.sheet.LocalSheetDismiss
@ -93,7 +93,7 @@ fun SecurityVerificationSheet(
if (peerID == null) {
Text(
text = stringResource(R.string.fingerprint_no_peer),
style = MaterialTheme.typography.bodyMedium.copy(fontFamily = FontFamily.Monospace),
style = MaterialTheme.typography.bodyMedium.copy(fontFamily = BitchatFontFamily),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
)
} else {
@ -156,7 +156,7 @@ private fun SecurityVerificationHeader(
Text(
text = stringResource(R.string.security_verification_title),
style = MaterialTheme.typography.titleSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
color = accent
@ -221,7 +221,7 @@ private fun SecurityStatusCard(
Text(
text = displayName,
style = MaterialTheme.typography.titleMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
color = accent
@ -229,7 +229,7 @@ private fun SecurityStatusCard(
Text(
text = statusInfo.text,
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = accent.copy(alpha = 0.8f)
)
@ -259,7 +259,7 @@ private fun SecurityVerificationActions(
) {
Text(
text = stringResource(R.string.fingerprint_start_handshake),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp
)
}
@ -275,7 +275,7 @@ private fun SecurityVerificationActions(
Text(
text = stringResource(R.string.fingerprint_verified_message),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = accent.copy(alpha = 0.7f),
modifier = Modifier.fillMaxWidth(),
@ -291,7 +291,7 @@ private fun SecurityVerificationActions(
) {
Text(
text = stringResource(R.string.verify_remove),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp
)
}
@ -305,7 +305,7 @@ private fun SecurityVerificationActions(
Text(
text = stringResource(R.string.fingerprint_not_verified_message_fmt, displayName),
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
),
color = accent.copy(alpha = 0.7f),
modifier = Modifier.fillMaxWidth(),
@ -322,7 +322,7 @@ private fun SecurityVerificationActions(
) {
Text(
text = stringResource(R.string.fingerprint_mark_verified),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp
)
}
@ -351,7 +351,7 @@ private fun VerificationStatusRow(
Text(
text = text,
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
color = textTint
@ -377,7 +377,7 @@ private fun FingerprintBlock(
Text(
text = title,
style = MaterialTheme.typography.labelSmall.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold
),
color = accent.copy(alpha = 0.8f)
@ -387,7 +387,7 @@ private fun FingerprintBlock(
Text(
text = formatFingerprint(fingerprint),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp
),
color = accent,
@ -419,7 +419,7 @@ private fun FingerprintBlock(
} else {
Text(
text = stringResource(R.string.fingerprint_pending),
style = MaterialTheme.typography.bodyMedium.copy(fontFamily = FontFamily.Monospace),
style = MaterialTheme.typography.bodyMedium.copy(fontFamily = BitchatFontFamily),
color = Color(0xFFFF9500),
modifier = Modifier.padding(16.dp)
)

View File

@ -60,7 +60,6 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -70,6 +69,7 @@ import androidx.core.graphics.createBitmap
import androidx.core.graphics.set
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.button.CloseButton
import com.bitchat.android.core.ui.component.sheet.LocalSheetDismiss
@ -145,7 +145,7 @@ fun VerificationSheet(
text = {
Text(
text = "My QR",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp
)
}
@ -156,7 +156,7 @@ fun VerificationSheet(
text = {
Text(
text = "Scan",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp
)
}
@ -209,7 +209,7 @@ fun VerificationSheet(
) {
Text(
text = stringResource(R.string.verify_remove),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp
)
}
@ -233,7 +233,7 @@ private fun VerificationHeader(
Text(
text = stringResource(R.string.verify_title).uppercase(),
fontSize = 14.sp,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = accent
)
val dismiss = LocalSheetDismiss.current
@ -260,7 +260,7 @@ private fun MyQrTabContent(
Text(
text = stringResource(R.string.verify_my_qr_title),
style = MaterialTheme.typography.titleMedium,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = accent
)
@ -285,7 +285,7 @@ private fun MyQrTabContent(
) {
Text(
text = stringResource(R.string.verify_qr_unavailable),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = Color.Black.copy(alpha = 0.6f)
)
@ -298,7 +298,7 @@ private fun MyQrTabContent(
Text(
text = nickname,
style = MaterialTheme.typography.headlineSmall,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = MaterialTheme.colorScheme.onSurface,
textAlign = TextAlign.Center
)
@ -309,7 +309,7 @@ private fun MyQrTabContent(
Text(
text = stringResource(R.string.app_name).lowercase(),
style = MaterialTheme.typography.bodyMedium,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
textAlign = TextAlign.Center
)
@ -357,7 +357,7 @@ private fun ScanTabContent(
Text(
text = stringResource(R.string.verify_scan_prompt_friend),
color = Color.White,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
modifier = Modifier
.align(Alignment.BottomCenter)
@ -388,7 +388,7 @@ private fun ScanTabContent(
Spacer(modifier = Modifier.height(24.dp))
Text(
text = stringResource(R.string.verify_camera_permission),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurface
)
@ -399,7 +399,7 @@ private fun ScanTabContent(
) {
Text(
text = stringResource(R.string.verify_request_camera),
fontFamily = FontFamily.Monospace
fontFamily = BitchatFontFamily
)
}
}

View File

@ -26,11 +26,11 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.draw.rotate
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.mesh.BluetoothMeshService
import com.bitchat.android.services.meshgraph.MeshGraphService
import kotlinx.coroutines.launch
@ -67,13 +67,13 @@ fun MeshTopologySection(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.SettingsEthernet, contentDescription = null, tint = Color(0xFF8E8E93))
Text("Mesh topology", fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text("Mesh topology", fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
val nodes = snapshot.nodes
val edges = snapshot.edges
val empty = nodes.isEmpty()
if (empty) {
Text("No gossip yet", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
Text("No gossip yet", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
} else {
ForceDirectedMeshGraph(
nodes = nodes,
@ -97,7 +97,7 @@ fun MeshTopologySection(
val label = "${node.peerID.take(8)}${node.nickname ?: "Unknown"}"
Text(
text = label,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.85f)
)
@ -128,7 +128,7 @@ private fun DistributionInfoSection(info: DistributionInfoProvider.DistributionI
Icon(Icons.Filled.Devices, contentDescription = null, tint = Color(0xFF5856D6))
Text(
"Distribution info",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
@ -137,7 +137,7 @@ private fun DistributionInfoSection(info: DistributionInfoProvider.DistributionI
if (info == null) {
Text(
"Inspecting installed package…",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -170,7 +170,7 @@ private fun DistributionInfoSection(info: DistributionInfoProvider.DistributionI
},
contentPadding = PaddingValues(horizontal = 0.dp)
) {
Text("Copy certificate fingerprint", fontFamily = FontFamily.Monospace)
Text("Copy certificate fingerprint", fontFamily = BitchatFontFamily)
}
}
}
@ -184,13 +184,13 @@ private fun DistributionInfoRow(label: String, value: String) {
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
Text(
label,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 10.sp,
color = colorScheme.onSurface.copy(alpha = 0.55f)
)
Text(
value,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.9f)
)
@ -347,7 +347,7 @@ fun DebugSettingsSheet(
item {
Text(
text = stringResource(R.string.debug_tools_desc),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 12.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
@ -361,13 +361,13 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.SettingsEthernet, contentDescription = null, tint = Color(0xFF00C851))
Text(stringResource(R.string.debug_verbose_logging), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_verbose_logging), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Spacer(Modifier.weight(1f))
Switch(checked = verboseLogging, onCheckedChange = { manager.setVerboseLoggingEnabled(it) })
}
Text(
stringResource(R.string.debug_verbose_hint),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
@ -392,10 +392,10 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.Bluetooth, contentDescription = null, tint = Color(0xFF007AFF))
Text(stringResource(R.string.debug_bluetooth_roles), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_bluetooth_roles), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.debug_gatt_server), fontFamily = FontFamily.Monospace, modifier = Modifier.weight(1f))
Text(stringResource(R.string.debug_gatt_server), fontFamily = BitchatFontFamily, modifier = Modifier.weight(1f))
Switch(checked = gattServerEnabled, onCheckedChange = {
manager.setGattServerEnabled(it)
scope.launch {
@ -404,9 +404,9 @@ fun DebugSettingsSheet(
})
}
val serverCount = connectedDevices.count { it.connectionType == ConnectionType.GATT_SERVER }
Text(stringResource(R.string.debug_connections_fmt, serverCount, maxServer), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_connections_fmt, serverCount, maxServer), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Row(verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.debug_max_server), fontFamily = FontFamily.Monospace, modifier = Modifier.width(90.dp))
Text(stringResource(R.string.debug_max_server), fontFamily = BitchatFontFamily, modifier = Modifier.width(90.dp))
Slider(
value = maxServer.toFloat(),
onValueChange = { manager.setMaxServerConnections(it.toInt().coerceAtLeast(1)) },
@ -415,7 +415,7 @@ fun DebugSettingsSheet(
)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.debug_gatt_client), fontFamily = FontFamily.Monospace, modifier = Modifier.weight(1f))
Text(stringResource(R.string.debug_gatt_client), fontFamily = BitchatFontFamily, modifier = Modifier.weight(1f))
Switch(checked = gattClientEnabled, onCheckedChange = {
manager.setGattClientEnabled(it)
scope.launch {
@ -424,9 +424,9 @@ fun DebugSettingsSheet(
})
}
val clientCount = connectedDevices.count { it.connectionType == ConnectionType.GATT_CLIENT }
Text(stringResource(R.string.debug_connections_fmt, clientCount, maxClient), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_connections_fmt, clientCount, maxClient), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Row(verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.debug_max_client), fontFamily = FontFamily.Monospace, modifier = Modifier.width(90.dp))
Text(stringResource(R.string.debug_max_client), fontFamily = BitchatFontFamily, modifier = Modifier.width(90.dp))
Slider(
value = maxClient.toFloat(),
onValueChange = { manager.setMaxClientConnections(it.toInt().coerceAtLeast(1)) },
@ -435,9 +435,9 @@ fun DebugSettingsSheet(
)
}
val overallCount = connectedDevices.size
Text(stringResource(R.string.debug_overall_connections_fmt, overallCount, maxOverall), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_overall_connections_fmt, overallCount, maxOverall), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Row(verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.debug_max_overall), fontFamily = FontFamily.Monospace, modifier = Modifier.width(90.dp))
Text(stringResource(R.string.debug_max_overall), fontFamily = BitchatFontFamily, modifier = Modifier.width(90.dp))
Slider(
value = maxOverall.toFloat(),
onValueChange = { manager.setMaxConnectionsOverall(it.toInt().coerceAtLeast(1)) },
@ -447,7 +447,7 @@ fun DebugSettingsSheet(
}
Text(
stringResource(R.string.debug_roles_hint),
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f)
)
@ -461,12 +461,12 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.Devices, contentDescription = null, tint = Color(0xFF4CAF50))
Text("Transports", fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text("Transports", fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(Icons.Filled.Bluetooth, contentDescription = null, tint = Color(0xFF007AFF))
Spacer(Modifier.width(8.dp))
Text("BLE", fontFamily = FontFamily.Monospace, modifier = Modifier.weight(1f))
Text("BLE", fontFamily = BitchatFontFamily, modifier = Modifier.weight(1f))
Switch(checked = bleEnabled, onCheckedChange = {
manager.setBleEnabled(it)
})
@ -474,7 +474,7 @@ fun DebugSettingsSheet(
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(Icons.Filled.Wifi, contentDescription = null, tint = Color(0xFF9C27B0))
Spacer(Modifier.width(8.dp))
Text("WiFi Aware", fontFamily = FontFamily.Monospace, modifier = Modifier.weight(1f))
Text("WiFi Aware", fontFamily = BitchatFontFamily, modifier = Modifier.weight(1f))
val wifiSwitchEnabled = wifiAwareSupported
Text(
when {
@ -482,7 +482,7 @@ fun DebugSettingsSheet(
wifiAwareAvailable -> "available"
else -> "unavailable"
},
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -497,7 +497,7 @@ fun DebugSettingsSheet(
}
Row(verticalAlignment = Alignment.CenterVertically) {
Spacer(Modifier.width(24.dp))
Text("WiFi Aware verbose logging", fontFamily = FontFamily.Monospace, modifier = Modifier.weight(1f))
Text("WiFi Aware verbose logging", fontFamily = BitchatFontFamily, modifier = Modifier.weight(1f))
Switch(checked = wifiAwareVerbose, onCheckedChange = { manager.setWifiAwareVerbose(it) })
}
}
@ -512,7 +512,7 @@ fun DebugSettingsSheet(
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.PowerSettingsNew, contentDescription = null, tint = Color(0xFFFF9500))
Text(stringResource(R.string.debug_packet_relay), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_packet_relay), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Spacer(Modifier.weight(1f))
Switch(checked = packetRelayed, onCheckedChange = { manager.setPacketRelayEnabled(it) })
}
@ -648,10 +648,10 @@ fun DebugSettingsSheet(
// Helper functions moved to top-level composable below to avoid scope issues
// Render two blocks: Incoming and Outgoing
Text("Incoming", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text("Incoming", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(
"${relayStats.lastSecondIncoming}/s • ${relayStats.lastMinuteIncoming}/m • ${relayStats.last15MinuteIncoming}/15m • total ${relayStats.totalIncomingCount}",
fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = colorScheme.onSurface.copy(alpha = 0.6f)
fontFamily = BitchatFontFamily, fontSize = 10.sp, color = colorScheme.onSurface.copy(alpha = 0.6f)
)
DrawGraphBlock(
title = "Incoming",
@ -704,10 +704,10 @@ fun DebugSettingsSheet(
if (graphMode != GraphMode.OVERALL && stackedKeysIncoming.isNotEmpty()) { /* legend printed inside DrawGraphBlock */ }
Spacer(Modifier.height(8.dp))
Text("Outgoing", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text("Outgoing", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(
"${relayStats.lastSecondOutgoing}/s • ${relayStats.lastMinuteOutgoing}/m • ${relayStats.last15MinuteOutgoing}/15m • total ${relayStats.totalOutgoingCount}",
fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = colorScheme.onSurface.copy(alpha = 0.6f)
fontFamily = BitchatFontFamily, fontSize = 10.sp, color = colorScheme.onSurface.copy(alpha = 0.6f)
)
DrawGraphBlock(
title = "Outgoing",
@ -770,7 +770,7 @@ fun DebugSettingsSheet(
val running by com.bitchat.android.wifiaware.WifiAwareController.running.collectAsState()
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.WifiTethering, contentDescription = null, tint = Color(0xFF9C27B0))
Text("WiFi Aware", fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text("WiFi Aware", fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Spacer(Modifier.weight(1f))
val wifiStatusText = when {
!wifiAwareSupported -> "unsupported"
@ -778,12 +778,12 @@ fun DebugSettingsSheet(
!wifiAwareAvailable -> "unavailable"
else -> "stopped"
}
Text(wifiStatusText, fontFamily = FontFamily.Monospace, fontSize = 12.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(wifiStatusText, fontFamily = BitchatFontFamily, fontSize = 12.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
}
if (!wifiAwareSupported) {
Text(
wifiAwareSupportStatus?.reason ?: "Wi-Fi Aware is not supported on this device",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 11.sp,
color = colorScheme.onSurface.copy(alpha = 0.6f)
)
@ -801,21 +801,21 @@ fun DebugSettingsSheet(
label = { Text("Announce") }
)
}
Text("Discovered: ${wifiAwareDiscovered.size}", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text("Discovered: ${wifiAwareDiscovered.size}", fontFamily = BitchatFontFamily, fontSize = 12.sp)
if (wifiAwareDiscovered.isEmpty()) {
Text("No discoveries yet", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
Text("No discoveries yet", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
} else {
wifiAwareDiscovered.entries.take(50).forEach { (peer, nick) ->
Text("${if (nick.isBlank()) peer.take(8) + "…" else nick} (${peer.take(8)}…) ", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text("${if (nick.isBlank()) peer.take(8) + "…" else nick} (${peer.take(8)}…) ", fontFamily = BitchatFontFamily, fontSize = 12.sp)
}
}
Divider()
Text("Connected: ${wifiAwareConnected.size}", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text("Connected: ${wifiAwareConnected.size}", fontFamily = BitchatFontFamily, fontSize = 12.sp)
if (wifiAwareConnected.isEmpty()) {
Text("No active sockets", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
Text("No active sockets", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
} else {
wifiAwareConnected.entries.take(50).forEach { (peer, ip) ->
Text("${peer.take(8)}… @ $ip", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text("${peer.take(8)}… @ $ip", fontFamily = BitchatFontFamily, fontSize = 12.sp)
}
}
}
@ -828,17 +828,17 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.SettingsEthernet, contentDescription = null, tint = Color(0xFF9C27B0))
Text("Sync settings", fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text("Sync settings", fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
Text(stringResource(R.string.debug_max_packets_per_sync_fmt, seenCapacity), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_max_packets_per_sync_fmt, seenCapacity), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Slider(value = seenCapacity.toFloat(), onValueChange = { manager.setSeenPacketCapacity(it.toInt()) }, valueRange = 10f..1000f, steps = 99)
Text(stringResource(R.string.debug_max_gcs_filter_size_fmt, gcsMaxBytes), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_max_gcs_filter_size_fmt, gcsMaxBytes), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Slider(value = gcsMaxBytes.toFloat(), onValueChange = { manager.setGcsMaxBytes(it.toInt()) }, valueRange = 128f..1024f, steps = 0)
Text(stringResource(R.string.debug_target_fpr_fmt, gcsFpr), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_target_fpr_fmt, gcsFpr), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Slider(value = gcsFpr.toFloat(), onValueChange = { manager.setGcsFprPercent(it.toDouble()) }, valueRange = 0.1f..5.0f, steps = 49)
val p = remember(gcsFpr) { com.bitchat.android.sync.GCSFilter.deriveP(gcsFpr / 100.0) }
val nmax = remember(gcsFpr, gcsMaxBytes) { com.bitchat.android.sync.GCSFilter.estimateMaxElementsForSize(gcsMaxBytes, p) }
Text(stringResource(R.string.debug_derived_p_fmt, p.toString(), nmax.toString()), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_derived_p_fmt, p.toString(), nmax.toString()), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
}
}
}
@ -849,22 +849,22 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.Devices, contentDescription = null, tint = Color(0xFF4CAF50))
Text(stringResource(R.string.debug_connected_devices), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_connected_devices), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
val localAddr = remember { meshService.connectionManager.getLocalAdapterAddress() }
Text(stringResource(R.string.debug_our_device_id_fmt, localAddr ?: stringResource(R.string.unknown)), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text(stringResource(R.string.debug_our_device_id_fmt, localAddr ?: stringResource(R.string.unknown)), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
if (connectedDevices.isEmpty()) {
Text("None", fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
Text("None", fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
} else {
connectedDevices.forEach { dev ->
Surface(shape = RoundedCornerShape(8.dp), color = colorScheme.surface.copy(alpha = 0.6f)) {
Row(Modifier.fillMaxWidth().padding(10.dp), verticalAlignment = Alignment.CenterVertically) {
Column(Modifier.weight(1f)) {
Text((dev.peerID ?: stringResource(R.string.unknown)) + "${dev.deviceAddress}", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text((dev.peerID ?: stringResource(R.string.unknown)) + "${dev.deviceAddress}", fontFamily = BitchatFontFamily, fontSize = 12.sp)
val roleLabel = if (dev.connectionType == ConnectionType.GATT_SERVER) stringResource(R.string.debug_role_server) else stringResource(R.string.debug_role_client)
Text("${dev.nickname ?: ""}" + stringResource(R.string.debug_rssi_fmt, dev.rssi ?: stringResource(R.string.debug_question_mark)) + "$roleLabel" + (if (dev.isDirectConnection) stringResource(R.string.debug_direct_suffix) else ""), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text("${dev.nickname ?: ""}" + stringResource(R.string.debug_rssi_fmt, dev.rssi ?: stringResource(R.string.debug_question_mark)) + "$roleLabel" + (if (dev.isDirectConnection) stringResource(R.string.debug_direct_suffix) else ""), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
}
Text(stringResource(R.string.debug_disconnect), color = Color(0xFFBF1A1A), fontFamily = FontFamily.Monospace, modifier = Modifier.clickable {
Text(stringResource(R.string.debug_disconnect), color = Color(0xFFBF1A1A), fontFamily = BitchatFontFamily, modifier = Modifier.clickable {
meshService.connectionManager.disconnectAddress(dev.deviceAddress)
})
}
@ -881,19 +881,19 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.Bluetooth, contentDescription = null, tint = Color(0xFF007AFF))
Text(stringResource(R.string.debug_recent_scan_results), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_recent_scan_results), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
}
if (scanResults.isEmpty()) {
Text(stringResource(R.string.debug_none), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
Text(stringResource(R.string.debug_none), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.6f))
} else {
scanResults.forEach { res ->
Surface(shape = RoundedCornerShape(8.dp), color = colorScheme.surface.copy(alpha = 0.6f)) {
Row(Modifier.fillMaxWidth().padding(10.dp), verticalAlignment = Alignment.CenterVertically) {
Column(Modifier.weight(1f)) {
Text((res.peerID ?: stringResource(R.string.unknown)) + "${res.deviceAddress}", fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text(stringResource(R.string.debug_rssi_fmt, res.rssi.toString()), fontFamily = FontFamily.Monospace, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
Text((res.peerID ?: stringResource(R.string.unknown)) + "${res.deviceAddress}", fontFamily = BitchatFontFamily, fontSize = 12.sp)
Text(stringResource(R.string.debug_rssi_fmt, res.rssi.toString()), fontFamily = BitchatFontFamily, fontSize = 11.sp, color = colorScheme.onSurface.copy(alpha = 0.7f))
}
Text(stringResource(R.string.debug_connect), color = Color(0xFF00C851), fontFamily = FontFamily.Monospace, modifier = Modifier.clickable {
Text(stringResource(R.string.debug_connect), color = Color(0xFF00C851), fontFamily = BitchatFontFamily, modifier = Modifier.clickable {
meshService.connectionManager.connectToAddress(res.deviceAddress)
})
}
@ -910,15 +910,15 @@ fun DebugSettingsSheet(
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Icon(Icons.Filled.BugReport, contentDescription = null, tint = Color(0xFFFF9500))
Text(stringResource(R.string.debug_debug_console), fontFamily = FontFamily.Monospace, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Text(stringResource(R.string.debug_debug_console), fontFamily = BitchatFontFamily, fontSize = 14.sp, fontWeight = FontWeight.Medium)
Spacer(Modifier.weight(1f))
Text(stringResource(R.string.debug_clear), color = Color(0xFFBF1A1A), fontFamily = FontFamily.Monospace, modifier = Modifier.clickable {
Text(stringResource(R.string.debug_clear), color = Color(0xFFBF1A1A), fontFamily = BitchatFontFamily, modifier = Modifier.clickable {
manager.clearDebugMessages()
})
}
Column(Modifier.heightIn(max = 260.dp).background(colorScheme.surface.copy(alpha = 0.5f)).padding(8.dp)) {
debugMessages.takeLast(100).reversed().forEach { msg ->
Text("${msg.content}", fontFamily = FontFamily.Monospace, fontSize = 11.sp)
Text("${msg.content}", fontFamily = BitchatFontFamily, fontSize = 11.sp)
}
}
}
@ -1039,7 +1039,7 @@ private fun DrawGraphBlock(
Box(Modifier.width(leftGutter).fillMaxHeight()) {
Text(
"p/s",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 10.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f),
modifier = Modifier.align(Alignment.CenterStart).padding(start = 2.dp).rotate(-90f)
@ -1053,14 +1053,14 @@ private fun DrawGraphBlock(
}
Text(
topLabel,
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 10.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f),
modifier = Modifier.align(Alignment.TopEnd).padding(end = 4.dp)
)
Text(
"0",
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontSize = 10.sp,
color = colorScheme.onSurface.copy(alpha = 0.7f),
modifier = Modifier.align(Alignment.BottomEnd).padding(end = 4.dp)
@ -1085,8 +1085,8 @@ private fun DrawGraphBlock(
) {
Box(Modifier.size(10.dp).background(swatchColor, RoundedCornerShape(2.dp)))
Column {
Text(legendTitleFor(key), fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (dimmed) 0.6f else 0.95f))
Text(legendMetricsFor(key), fontFamily = FontFamily.Monospace, fontSize = 9.sp, color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (dimmed) 0.45f else 0.75f))
Text(legendTitleFor(key), fontFamily = BitchatFontFamily, fontSize = 10.sp, color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (dimmed) 0.6f else 0.95f))
Text(legendMetricsFor(key), fontFamily = BitchatFontFamily, fontSize = 9.sp, color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (dimmed) 0.45f else 0.75f))
}
}
}

View File

@ -13,9 +13,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import com.bitchat.android.core.ui.component.text.AnnotatedClickableText
import com.bitchat.android.mesh.MeshService
@ -72,7 +72,7 @@ fun AudioMessageItem(
}
},
onLongPress = { onMessageLongPress?.invoke(message) },
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textPrimary,
)

View File

@ -30,6 +30,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.dp
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import kotlinx.coroutines.delay
@ -96,7 +97,7 @@ fun FileSendingAnimation(
androidx.compose.material3.Text(
text = revealedText,
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = Color.White
),
modifier = Modifier.padding(end = 2.dp)
@ -107,7 +108,7 @@ fun FileSendingAnimation(
androidx.compose.material3.Text(
text = stringResource(R.string.underscore),
style = MaterialTheme.typography.bodyMedium.copy(
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = Color.White
)
)
@ -149,7 +150,7 @@ private fun FileProgressBars(
androidx.compose.material3.Text(
text = progressString,
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = Color(0xFF00FF7F) // Matrix green
),
modifier = modifier

View File

@ -33,6 +33,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.res.stringResource
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.R
import java.io.File
@ -101,7 +102,7 @@ fun FullScreenImageViewer(imagePaths: List<String>, initialIndex: Int = 0, onClo
text = stringResource(R.string.image_counter, (pagerState.currentPage ?: 0) + 1, imagePaths.size),
color = Color.White,
fontSize = 14.sp,
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
fontFamily = BitchatFontFamily
)
}
}

View File

@ -21,7 +21,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.unit.dp
import androidx.compose.ui.text.font.FontFamily
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.mesh.MeshService
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.model.BitchatMessageType
@ -70,7 +70,7 @@ fun ImageMessageItem(
}
},
onLongPress = { onMessageLongPress?.invoke(message) },
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
color = palette.textPrimary,
)
@ -142,7 +142,7 @@ fun ImageMessageItem(
}
}
} else {
Text(text = stringResource(com.bitchat.android.R.string.image_unavailable), fontFamily = FontFamily.Monospace, color = Color.Gray)
Text(text = stringResource(com.bitchat.android.R.string.image_unavailable), fontFamily = BitchatFontFamily, color = Color.Gray)
}
}
}

View File

@ -1,5 +1,6 @@
package com.bitchat.android.ui.media
import com.bitchat.android.ui.theme.BitchatFontFamily
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
@ -18,7 +19,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.font.FontFamily
@Composable
fun VoiceNotePlayer(
@ -110,7 +110,7 @@ fun VoiceNotePlayer(
onSeek = seekTo
)
val durText = if (durationMs > 0) String.format("%02d:%02d", (durationMs / 1000) / 60, (durationMs / 1000) % 60) else "--:--"
Text(text = durText, fontFamily = FontFamily.Monospace, fontSize = 12.sp)
Text(text = durText, fontFamily = BitchatFontFamily, fontSize = 12.sp)
}
}

View File

@ -90,7 +90,7 @@ val DarkBitchatPalette = BitchatPalette(
inputSurface = Color(0xFF0B0B0B),
inputSurfaceFocused = Color(0xFF151515),
inputButton = Color(0xFF1E1E1E),
textPrimary = Color(0xFFE8EDE8),
textPrimary = Color(0xFFF5F5F5),
textSecondary = Color(0xFF9AA69A),
textTertiary = Color(0xFF6B776B),
accentGreen = Color(0xFF32D74B),

View File

@ -0,0 +1,64 @@
package com.bitchat.android.ui.theme
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bitchat.android.R
/**
* The bundled Geist Mono family used throughout the app.
*
* Keeping the fonts in the APK preserves offline behavior and guarantees that the design-spec
* metrics do not depend on which monospace family a device happens to provide.
*/
internal val BitchatFontFamily = FontFamily(
Font(R.font.geist_mono_regular, FontWeight.Normal),
Font(R.font.geist_mono_medium, FontWeight.Medium),
Font(R.font.geist_mono_semibold, FontWeight.SemiBold),
Font(R.font.geist_mono_bold, FontWeight.Bold),
)
/** Exact typography, spacing, and opacity values exported for the chat transcript. */
internal object ChatVisualTokens {
val MessageBodyFontSize: TextUnit = 14.sp
val MessageBodyLineHeight: TextUnit = 20.sp
val SenderFontSize: TextUnit = 14.sp
val SenderLineHeight: TextUnit = 16.sp
val SystemActionFontSize: TextUnit = 12.sp
val SystemActionLineHeight: TextUnit = 16.sp
val SystemTimeFontSize: TextUnit = 10.sp
val MessageItemSpacing: Dp = 8.dp
val SenderTopPadding: Dp = 8.dp
val SenderToBodySpacing: Dp = 4.dp
const val SenderSuffixAlpha: Float = 0.60f
const val HighlightAlpha: Float = 0.20f
const val MutedTextAlpha: Float = 0.50f
val MessageBodyStyle = TextStyle(
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Normal,
fontSize = MessageBodyFontSize,
lineHeight = MessageBodyLineHeight,
)
val SenderStyle = TextStyle(
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = SenderFontSize,
lineHeight = SenderLineHeight,
)
val SystemActionStyle = TextStyle(
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = SystemActionFontSize,
lineHeight = SystemActionLineHeight,
)
}

View File

@ -2,92 +2,81 @@ package com.bitchat.android.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Base font size for consistent scaling across the app
internal const val BASE_FONT_SIZE = com.bitchat.android.util.AppConstants.UI.BASE_FONT_SIZE_SP // sp - increased from 14sp for better readability
internal const val BASE_FONT_SIZE = com.bitchat.android.util.AppConstants.UI.BASE_FONT_SIZE_SP
/**
* Message body style. The generous leading (1.4x) is what gives the redesigned chat surface
* its readable rhythm; without an explicit lineHeight, Compose falls back to the font's own
* metrics and lines sit too tightly for long paragraphs.
*/
val MessageBodyTextStyle = TextStyle(
fontFamily = FontFamily.Monospace,
fontWeight = FontWeight.Normal,
fontSize = BASE_FONT_SIZE.sp,
lineHeight = (BASE_FONT_SIZE + 6).sp
)
val MessageBodyTextStyle = ChatVisualTokens.MessageBodyStyle
/** Sender label above a message group. Single line, never wraps. */
val MessageSenderTextStyle = TextStyle(
fontFamily = FontFamily.Monospace,
fontWeight = FontWeight.SemiBold,
fontSize = BASE_FONT_SIZE.sp,
lineHeight = (BASE_FONT_SIZE + 5).sp
)
val MessageSenderTextStyle = ChatVisualTokens.SenderStyle
// Typography matching the iOS monospace design - using BASE_FONT_SIZE for consistency
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Normal,
fontSize = (BASE_FONT_SIZE + 1).sp,
lineHeight = (BASE_FONT_SIZE + 7).sp
),
bodyMedium = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Normal,
fontSize = BASE_FONT_SIZE.sp,
lineHeight = (BASE_FONT_SIZE + 6).sp
),
bodySmall = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Normal,
fontSize = (BASE_FONT_SIZE - 3).sp,
lineHeight = (BASE_FONT_SIZE + 1).sp
),
headlineSmall = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = (BASE_FONT_SIZE + 3).sp,
lineHeight = (BASE_FONT_SIZE + 9).sp
),
// Previously unset, which leaked the Roboto default into onboarding + sheet titles.
headlineLarge = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Bold,
fontSize = (BASE_FONT_SIZE + 13).sp,
lineHeight = (BASE_FONT_SIZE + 21).sp
),
titleLarge = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = (BASE_FONT_SIZE + 5).sp,
lineHeight = (BASE_FONT_SIZE + 13).sp
),
titleMedium = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = (BASE_FONT_SIZE + 1).sp,
lineHeight = (BASE_FONT_SIZE + 7).sp
),
labelLarge = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = (BASE_FONT_SIZE - 1).sp,
lineHeight = (BASE_FONT_SIZE + 5).sp
),
labelMedium = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Medium,
fontSize = (BASE_FONT_SIZE - 2).sp,
lineHeight = (BASE_FONT_SIZE + 3).sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Monospace,
fontFamily = BitchatFontFamily,
fontWeight = FontWeight.Normal,
fontSize = (BASE_FONT_SIZE - 4).sp,
lineHeight = (BASE_FONT_SIZE + 1).sp

View File

@ -120,7 +120,7 @@ object AppConstants {
object UI {
const val MAX_NICKNAME_LENGTH: Int = 15
const val BASE_FONT_SIZE_SP: Int = 15
const val BASE_FONT_SIZE_SP: Int = 14
const val MESSAGE_DEDUP_TIMEOUT_MS: Long = 30_000L
const val SYSTEM_EVENT_DEDUP_TIMEOUT_MS: Long = 5_000L
const val ACTIVE_PEERS_NOTIFICATION_INTERVAL_MS: Long = 300_000L

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,93 @@
Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@ -1,9 +1,16 @@
package com.bitchat.android.ui
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.ui.theme.BitchatFontFamily
import com.bitchat.android.ui.theme.ChatVisualTokens
import com.bitchat.android.ui.theme.DarkBitchatPalette
import com.bitchat.android.ui.theme.LightBitchatPalette
import com.bitchat.android.ui.theme.MessageBodyTextStyle
import com.bitchat.android.ui.theme.MessageSenderTextStyle
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@ -68,6 +75,12 @@ class ChatUIUtilsTest {
)
assertEquals("hello there 00:00:00", body.text)
val timestamp = body.spanStyles.first {
body.text.substring(it.start, it.end) == " 00:00:00"
}.item
assertEquals(10.sp, timestamp.fontSize)
assertEquals(FontWeight.Normal, timestamp.fontWeight)
assertEquals(palette.textTertiary, timestamp.color)
}
@Test
@ -80,6 +93,11 @@ class ChatUIUtilsTest {
)
assertEquals("mined 00:00:00 ⛨8b", body.text)
val timestampAndPow = body.spanStyles.first {
body.text.substring(it.start, it.end) == " 00:00:00 ⛨8b"
}.item
assertEquals(10.sp, timestampAndPow.fontSize)
assertEquals(palette.textTertiary, timestampAndPow.color)
}
@Test
@ -109,6 +127,17 @@ class ChatUIUtilsTest {
assertEquals(palette.textPrimary, textStyle.item.color)
}
@Test
fun `chat text styles match the exported type scale`() {
assertEquals(14.sp, MessageBodyTextStyle.fontSize)
assertEquals(20.sp, MessageBodyTextStyle.lineHeight)
assertEquals(FontWeight.Normal, MessageBodyTextStyle.fontWeight)
assertEquals(BitchatFontFamily, MessageBodyTextStyle.fontFamily)
assertEquals(14.sp, MessageSenderTextStyle.fontSize)
assertEquals(16.sp, MessageSenderTextStyle.lineHeight)
assertEquals(FontWeight.SemiBold, MessageSenderTextStyle.fontWeight)
}
@Test
fun `body does not bold plain text for the sender's own messages`() {
// Regression guard: the old renderer bolded the entire body when the message was yours,
@ -165,6 +194,7 @@ class ChatUIUtilsTest {
val chip = mentionChipSpans(body).single()
assertEquals(palette.accentOrange.copy(alpha = MENTION_CHIP_ALPHA_SELF), chip.item.background)
assertEquals(0.2f, chip.item.background.alpha)
val nameStyle: SpanStyle = body.spanStyles
.first { it.start == chip.start && it.item.color == palette.accentOrange }
@ -226,6 +256,29 @@ class ChatUIUtilsTest {
assertTrue(annotated.spanStyles.all { it.item.fontStyle == null })
}
@Test
fun `system action and timestamp use their exported weights sizes and opacity`() {
val annotated = formatSystemMessage(
message = message("tor restarting", sender = "system"),
palette = palette,
timeFormatter = timeFormatter,
)
val action = annotated.spanStyles.first {
annotated.text.substring(it.start, it.end) == "// tor restarting"
}.item
val time = annotated.spanStyles.first {
annotated.text.substring(it.start, it.end) == " 00:00:00"
}.item
assertEquals(12.sp, action.fontSize)
assertEquals(FontWeight.Medium, action.fontWeight)
assertEquals(palette.textPrimary.copy(alpha = 0.5f), action.color)
assertEquals(10.sp, time.fontSize)
assertEquals(FontWeight.Normal, time.fontWeight)
assertEquals(palette.textPrimary.copy(alpha = 0.5f), time.color)
}
// MARK: - Sender label
@Test
@ -242,6 +295,11 @@ class ChatUIUtilsTest {
val suffixSpan = sender.spanStyles.first { sender.text.substring(it.start, it.end) == "#04af" }
val nameSpan = sender.spanStyles.first { sender.text.substring(it.start, it.end) == "@carol" }
assertNotNull(suffixSpan.item.color)
assertEquals(14.sp, nameSpan.item.fontSize)
assertEquals(FontWeight.SemiBold, nameSpan.item.fontWeight)
assertEquals(14.sp, suffixSpan.item.fontSize)
assertEquals(FontWeight.Normal, suffixSpan.item.fontWeight)
assertEquals(ChatVisualTokens.SenderSuffixAlpha, suffixSpan.item.color.alpha)
assertTrue(
"suffix must be dimmer than the name",
suffixSpan.item.color.alpha < nameSpan.item.color.alpha
@ -282,6 +340,8 @@ class ChatUIUtilsTest {
rgbToHsv(light.red, light.green, light.blue, lightHsv)
assertEquals(darkHsv[0].toDouble(), lightHsv[0].toDouble(), 1.0)
assertEquals(1.0, darkHsv[1].toDouble(), 0.01)
assertEquals(1.0, darkHsv[2].toDouble(), 0.01)
}
@Test
@ -302,6 +362,7 @@ class ChatUIUtilsTest {
@Test
fun `light palette is not the dark palette`() {
assertNull(null)
assertEquals(Color(0xFFF5F5F5), DarkBitchatPalette.textPrimary)
assertTrue(LightBitchatPalette.textPrimary != DarkBitchatPalette.textPrimary)
assertTrue(LightBitchatPalette.isDark != DarkBitchatPalette.isDark)
}

View File

@ -138,13 +138,15 @@ class MessageGroupingTest {
}
@Test
fun `grouped rows sit tighter than the start of a new group`() {
fun `all transcript rows use the exported eight dp rhythm`() {
val grouped = MessageGrouping.topSpacingFor(isGrouped = true, isFirstInList = false)
val newGroup = MessageGrouping.topSpacingFor(isGrouped = false, isFirstInList = false)
assertEquals(MessageGrouping.GROUPED_SPACING, grouped)
assertEquals(MessageGrouping.NEW_GROUP_SPACING, newGroup)
assertTrue("a new speaker needs more air than a continuation", newGroup > grouped)
assertEquals(8.dp, grouped)
assertEquals(8.dp, newGroup)
assertEquals(grouped, newGroup)
assertEquals(8.dp, MessageGrouping.SENDER_TOP_PADDING)
assertEquals(4.dp, MessageGrouping.SENDER_TO_BODY_SPACING)
}
private fun BitchatMessage.copyWithOffset(offsetMs: Long) =