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
@@ -108,4 +108,4 @@ private val AppBarHorizontalPadding = 4.dp
private val TitleInsetWithoutIcon = Modifier.width(16.dp - AppBarHorizontalPadding) private val TitleInsetWithoutIcon = Modifier.width(16.dp - AppBarHorizontalPadding)
// Start inset for the title when there is a navigation icon provided // 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)
@@ -31,7 +31,6 @@ import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
import com.vitorpamplona.amethyst.model.Account 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.MediaCompressor
import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator import com.vitorpamplona.amethyst.service.uploads.MultiOrchestrator
import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator import com.vitorpamplona.amethyst.service.uploads.UploadOrchestrator
@@ -59,7 +58,6 @@ open class ChatFileUploadModel : ViewModel() {
// Images and Videos // Images and Videos
var multiOrchestrator by mutableStateOf<MultiOrchestrator?>(null) var multiOrchestrator by mutableStateOf<MultiOrchestrator?>(null)
var onceUploaded: () -> Unit = {}
// 0 = Low, 1 = Medium, 2 = High, 3=UNCOMPRESSED // 0 = Low, 1 = Medium, 2 = High, 3=UNCOMPRESSED
var mediaQualitySlider by mutableIntStateOf(1) var mediaQualitySlider by mutableIntStateOf(1)
@@ -84,6 +82,7 @@ open class ChatFileUploadModel : ViewModel() {
fun upload( fun upload(
onError: (title: String, message: String) -> Unit, onError: (title: String, message: String) -> Unit,
context: Context, context: Context,
onceUploaded: () -> Unit,
) { ) {
val myAccount = account ?: return val myAccount = account ?: return
val mySelectedServer = selectedServer ?: return val mySelectedServer = selectedServer ?: return
@@ -157,8 +156,4 @@ open class ChatFileUploadModel : ViewModel() {
fun canPost(): Boolean = !isUploadingImage && multiOrchestrator != null && selectedServer != null fun canPost(): Boolean = !isUploadingImage && multiOrchestrator != null && selectedServer != null
fun defaultServer() = account?.settings?.defaultFileServer ?: DEFAULT_MEDIA_SERVERS[0] fun defaultServer() = account?.settings?.defaultFileServer ?: DEFAULT_MEDIA_SERVERS[0]
fun onceUploaded(onceUploaded: () -> Unit) {
this.onceUploaded = onceUploaded
}
} }
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth 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.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@@ -51,6 +52,7 @@ 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.platform.LocalContext 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.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow 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.actions.uploads.ShowImageUploadGallery
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
import com.vitorpamplona.amethyst.ui.navigation.INav 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.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.SettingSwitchItem
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
import com.vitorpamplona.amethyst.ui.stringRes 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.Size5dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@@ -101,52 +105,61 @@ fun ChatFileUploadView(
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(
scrollBehavior = rememberHeightDecreaser(),
modifier = Modifier,
title = { title = {
Row( val room = postViewModel.chatroom
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = StdHorzSpacer)
if (room == null) {
Text( Text(
text = stringRes(R.string.dm_upload), text = stringRes(R.string.dm_upload),
modifier = Modifier.weight(1f),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
) )
} else {
Row(verticalAlignment = Alignment.CenterVertically) {
NonClickableUserPictures(
room = room,
accountViewModel = accountViewModel,
size = Size34dp,
)
PostButton( RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp), FontWeight.Normal, accountViewModel)
}
}
},
navigationIcon = {
IconButton(
modifier = TitleIconModifier,
onClick = {
postViewModel.cancelModel()
onClose()
},
) {
ArrowBackIcon()
}
},
actions = {
SendButton(
modifier = Modifier.padding(end = 5.dp),
onPost = { onPost = {
postViewModel.upload( postViewModel.upload(
onError = accountViewModel::toast, onError = accountViewModel::toast,
context = context, context = context,
) ) {
onClose
}
postViewModel.selectedServer?.let { postViewModel.selectedServer?.let {
if (it.type != ServerType.NIP95) { if (it.type != ServerType.NIP95) {
account.settings.changeDefaultFileServer(it) account.settings.changeDefaultFileServer(it)
} }
} }
onClose()
}, },
isActive = postViewModel.canPost(), isActive = postViewModel.canPost(),
) )
}
},
navigationIcon = {
Row {
Spacer(modifier = StdHorzSpacer)
CloseButton(
onPress = {
postViewModel.cancelModel()
onClose()
},
)
}
}, },
colors = colors =
TopAppBarDefaults.topAppBarColors( TopAppBarDefaults.topAppBarColors(
@@ -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))
}
}
@@ -79,6 +79,7 @@ import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map import androidx.lifecycle.map
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Chatroom
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
@@ -205,20 +206,15 @@ private fun RenderRoomTopBar(
} else { } else {
TopBarExtensibleWithBackButton( TopBarExtensibleWithBackButton(
title = { title = {
Row(verticalAlignment = Alignment.CenterVertically) {
NonClickableUserPictures( NonClickableUserPictures(
room = room, room = room,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
size = Size34dp, size = Size34dp,
) )
RoomNameOnlyDisplay( RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp).weight(1f), FontWeight.Normal, accountViewModel)
room, }
Modifier
.padding(start = 10.dp)
.weight(1f),
fontWeight = FontWeight.Normal,
accountViewModel,
)
}, },
extendableRow = { extendableRow = {
LongRoomHeader(room = room, accountViewModel = accountViewModel, nav = nav) LongRoomHeader(room = room, accountViewModel = accountViewModel, nav = nav)
@@ -787,10 +783,7 @@ fun GroupChatroomHeader(
size = Size34dp, size = Size34dp,
) )
Column(modifier = Modifier.padding(start = 10.dp)) { RoomNameOnlyDisplay(room, Modifier.padding(start = 10.dp), FontWeight.Bold, accountViewModel)
RoomNameOnlyDisplay(room, Modifier, FontWeight.Bold, accountViewModel)
DisplayUserSetAsSubject(room, accountViewModel, FontWeight.Normal)
}
} }
} }
} }
@@ -989,8 +982,10 @@ fun RoomNameOnlyDisplay(
.observeAsState(accountViewModel.userProfile().privateChatrooms[room]?.subject) .observeAsState(accountViewModel.userProfile().privateChatrooms[room]?.subject)
CrossfadeIfEnabled(targetState = roomSubject, modifier, accountViewModel = accountViewModel) { CrossfadeIfEnabled(targetState = roomSubject, modifier, accountViewModel = accountViewModel) {
if (it != null && it.isNotBlank()) { if (!it.isNullOrBlank()) {
DisplayRoomSubject(it, fontWeight) DisplayRoomSubject(it, fontWeight)
} else {
DisplayUserSetAsSubject(room, accountViewModel, FontWeight.Normal)
} }
} }
} }