Adjusts the top bar when uploading media to DMs to match the chat top bar

This commit is contained in:
Vitor Pamplona 2025-01-02 18:53:44 -05:00
parent 577ef6437f
commit d29e90fe8f
4 changed files with 79 additions and 61 deletions

View File

@ -108,4 +108,4 @@ private val AppBarHorizontalPadding = 4.dp
private val TitleInsetWithoutIcon = Modifier.width(16.dp - AppBarHorizontalPadding)
// Start inset for the title when there is a navigation icon provided
private val TitleIconModifier = Modifier.width(48.dp - AppBarHorizontalPadding)
val TitleIconModifier = Modifier.width(48.dp - AppBarHorizontalPadding)

View File

@ -31,7 +31,6 @@ import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache.users
import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
@ -59,7 +58,6 @@ open class ChatFileUploadModel : ViewModel() {
// Images and Videos
var multiOrchestrator by mutableStateOf<MultiOrchestrator?>(null)
var onceUploaded: () -> Unit = {}
// 0 = Low, 1 = Medium, 2 = High, 3=UNCOMPRESSED
var mediaQualitySlider by mutableIntStateOf(1)
@ -84,6 +82,7 @@ open class ChatFileUploadModel : ViewModel() {
fun upload(
onError: (title: String, message: String) -> Unit,
context: Context,
onceUploaded: () -> Unit,
) {
val myAccount = account ?: return
val mySelectedServer = selectedServer ?: return
@ -157,8 +156,4 @@ open class ChatFileUploadModel : ViewModel() {
fun canPost(): Boolean = !isUploadingImage && multiOrchestrator != null && selectedServer != null
fun defaultServer() = account?.settings?.defaultFileServer ?: DEFAULT_MEDIA_SERVERS[0]
fun onceUploaded(onceUploaded: () -> Unit) {
this.onceUploaded = onceUploaded
}
}

View File

@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -34,7 +33,9 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
@ -51,6 +52,7 @@ 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.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@ -62,16 +64,18 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
import com.vitorpamplona.amethyst.ui.actions.uploads.ShowImageUploadGallery
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.navigation.TitleIconModifier
import com.vitorpamplona.amethyst.ui.navigation.rememberHeightDecreaser
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SettingSwitchItem
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size34dp
import com.vitorpamplona.amethyst.ui.theme.Size5dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.collections.immutable.toImmutableList
@ -101,53 +105,62 @@ fun ChatFileUploadView(
Scaffold(
topBar = {
TopAppBar(
scrollBehavior = rememberHeightDecreaser(),
modifier = Modifier,
title = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = StdHorzSpacer)
val room = postViewModel.chatroom
if (room == null) {
Text(
text = stringRes(R.string.dm_upload),
modifier = Modifier.weight(1f),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
)
} else {
Row(verticalAlignment = Alignment.CenterVertically) {
NonClickableUserPictures(
room = room,
accountViewModel = accountViewModel,
size = Size34dp,
)
PostButton(
onPost = {
postViewModel.upload(
onError = accountViewModel::toast,
context = context,
)
postViewModel.selectedServer?.let {
if (it.type != ServerType.NIP95) {
account.settings.changeDefaultFileServer(it)
}
}
onClose()
},
isActive = postViewModel.canPost(),
)
RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp), FontWeight.Normal, accountViewModel)
}
}
},
navigationIcon = {
Row {
Spacer(modifier = StdHorzSpacer)
CloseButton(
onPress = {
postViewModel.cancelModel()
onClose()
},
)
IconButton(
modifier = TitleIconModifier,
onClick = {
postViewModel.cancelModel()
onClose()
},
) {
ArrowBackIcon()
}
},
actions = {
SendButton(
modifier = Modifier.padding(end = 5.dp),
onPost = {
postViewModel.upload(
onError = accountViewModel::toast,
context = context,
) {
onClose
}
postViewModel.selectedServer?.let {
if (it.type != ServerType.NIP95) {
account.settings.changeDefaultFileServer(it)
}
}
},
isActive = postViewModel.canPost(),
)
},
colors =
TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
@ -279,3 +292,18 @@ private fun ImageVideoPostChat(
)
}
}
@Composable
fun SendButton(
onPost: () -> Unit = {},
isActive: Boolean,
modifier: Modifier = Modifier,
) {
Button(
modifier = modifier,
enabled = isActive,
onClick = onPost,
) {
Text(text = stringRes(R.string.accessibility_send))
}
}

View File

@ -79,6 +79,7 @@ import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Chatroom
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
@ -205,20 +206,15 @@ private fun RenderRoomTopBar(
} else {
TopBarExtensibleWithBackButton(
title = {
NonClickableUserPictures(
room = room,
accountViewModel = accountViewModel,
size = Size34dp,
)
Row(verticalAlignment = Alignment.CenterVertically) {
NonClickableUserPictures(
room = room,
accountViewModel = accountViewModel,
size = Size34dp,
)
RoomNameOnlyDisplay(
room,
Modifier
.padding(start = 10.dp)
.weight(1f),
fontWeight = FontWeight.Normal,
accountViewModel,
)
RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp).weight(1f), FontWeight.Normal, accountViewModel)
}
},
extendableRow = {
LongRoomHeader(room = room, accountViewModel = accountViewModel, nav = nav)
@ -787,10 +783,7 @@ fun GroupChatroomHeader(
size = Size34dp,
)
Column(modifier = Modifier.padding(start = 10.dp)) {
RoomNameOnlyDisplay(room, Modifier, FontWeight.Bold, accountViewModel)
DisplayUserSetAsSubject(room, accountViewModel, FontWeight.Normal)
}
RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp), FontWeight.Bold, accountViewModel)
}
}
}
@ -989,8 +982,10 @@ fun RoomNameOnlyDisplay(
.observeAsState(accountViewModel.userProfile().privateChatrooms[room]?.subject)
CrossfadeIfEnabled(targetState = roomSubject, modifier, accountViewModel = accountViewModel) {
if (it != null && it.isNotBlank()) {
if (!it.isNullOrBlank()) {
DisplayRoomSubject(it, fontWeight)
} else {
DisplayUserSetAsSubject(room, accountViewModel, FontWeight.Normal)
}
}
}