chore: improve line break handling (#39)

Reviewed-on: #39
This commit was merged in pull request #39.
This commit is contained in:
2026-07-09 03:48:42 +00:00
parent 7a44e836a9
commit c7a646ae73
4 changed files with 19 additions and 9 deletions

View File

@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@@ -23,6 +24,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coop.composeapp.generated.resources.Res import coop.composeapp.generated.resources.Res
import coop.composeapp.generated.resources.ic_add_circle import coop.composeapp.generated.resources.ic_add_circle
@@ -52,6 +55,11 @@ fun ChatInput(
value = value, value = value,
onValueChange = onValueChange, onValueChange = onValueChange,
placeholder = { Text("Message") }, placeholder = { Text("Message") },
maxLines = 5,
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Sentences,
imeAction = ImeAction.Default
),
leadingIcon = { leadingIcon = {
IconButton(onClick = onUpload) { IconButton(onClick = onUpload) {
Icon( Icon(

View File

@@ -10,17 +10,17 @@ fun PublicKey.short(): String {
val URL_REGEX = Regex("(https?://\\S+)", RegexOption.IGNORE_CASE) val URL_REGEX = Regex("(https?://\\S+)", RegexOption.IGNORE_CASE)
private val imageExtensions = setOf("jpg", "jpeg", "png", "gif", "webp", "bmp") private val imageExtensions = setOf("jpg", "jpeg", "png", "gif", "webp", "bmp")
fun String.extractUrls(): List<String> {
return URL_REGEX.findAll(this).map { it.value }.toList()
}
fun String.removeImageUrls(): String { fun String.removeImageUrls(): String {
return URL_REGEX.replace(this) { result -> return URL_REGEX.replace(this) { result ->
if (result.value.isImageUrl()) "" else result.value if (result.value.isImageUrl()) "" else result.value
}.replace(Regex("\\s+"), " ").trim() }.trim()
} }
fun String.isImageUrl(): Boolean { fun String.isImageUrl(): Boolean {
val extension = this.substringAfterLast('.', "").lowercase() val extension = this.substringAfterLast('.', "").lowercase()
return extension in imageExtensions return extension in imageExtensions
} }
fun String.sanitizeName(): String {
return this.replace("\n", " ").replace("\r", " ").trim()
}

View File

@@ -10,8 +10,8 @@ data class Profile(
private val record by lazy { metadata.asRecord() } private val record by lazy { metadata.asRecord() }
val name: String val name: String
get() = record.displayName ?: record.name ?: publicKey.short() get() = record.displayName?.sanitizeName() ?: record.name ?: publicKey.short()
val picture: String? val picture: String?
get() = record.picture get() = record.picture

View File

@@ -99,11 +99,13 @@ fun Room.uiStateFlow(
val displayMembers = if (isGroup()) members.take(2) else members.take(1) val displayMembers = if (isGroup()) members.take(2) else members.take(1)
if (!subject.isNullOrBlank()) { if (!subject.isNullOrBlank()) {
return flowOf(RoomUiState(name = subject, isGroup = isGroup())) return flowOf(RoomUiState(name = subject.sanitizeName(), isGroup = isGroup()))
} }
return combine(displayMembers.map { nostrViewModel.getMetadata(it) }) { profiles -> return combine(displayMembers.map { nostrViewModel.getMetadata(it) }) { profiles ->
val names = profiles.mapIndexed { i, profile -> profile?.name ?: displayMembers[i].short() } val names = profiles.mapIndexed { i, profile ->
profile?.name?.sanitizeName() ?: displayMembers[i].short()
}
val name = when { val name = when {
isGroup() -> { isGroup() -> {