Merge pull request #273 from believethehype/main

Image upload button in Chats
This commit is contained in:
Vitor Pamplona
2023-03-14 12:19:17 -04:00
committed by GitHub
3 changed files with 45 additions and 14 deletions

View File

@@ -319,7 +319,7 @@ class Account(
LocalCache.consume(signedEvent, null) LocalCache.consume(signedEvent, null)
} }
fun sendPrivateMeesage(message: String, toUser: String, replyingTo: Note? = null) { fun sendPrivateMessage(message: String, toUser: String, replyingTo: Note? = null) {
if (!isWriteable()) return if (!isWriteable()) return
val user = LocalCache.users[toUser] ?: return val user = LocalCache.users[toUser] ?: return

View File

@@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.widget.Toast
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -65,7 +66,9 @@ import com.vitorpamplona.amethyst.model.Channel
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.NostrChannelDataSource import com.vitorpamplona.amethyst.service.NostrChannelDataSource
import com.vitorpamplona.amethyst.ui.actions.NewChannelView import com.vitorpamplona.amethyst.ui.actions.NewChannelView
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.actions.PostButton import com.vitorpamplona.amethyst.ui.actions.PostButton
import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery
import com.vitorpamplona.amethyst.ui.components.ResizeImage import com.vitorpamplona.amethyst.ui.components.ResizeImage
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.dal.ChannelFeedFilter import com.vitorpamplona.amethyst.ui.dal.ChannelFeedFilter
@@ -82,9 +85,10 @@ fun ChannelScreen(
) { ) {
val accountState by accountViewModel.accountLiveData.observeAsState() val accountState by accountViewModel.accountLiveData.observeAsState()
val account = accountState?.account val account = accountState?.account
val context = LocalContext.current
val channelScreenModel: NewPostViewModel = viewModel()
if (account != null && channelId != null) { if (account != null && channelId != null) {
val newPost = remember { mutableStateOf(TextFieldValue("")) }
val replyTo = remember { mutableStateOf<Note?>(null) } val replyTo = remember { mutableStateOf<Note?>(null) }
ChannelFeedFilter.loadMessagesBetween(account, channelId) ChannelFeedFilter.loadMessagesBetween(account, channelId)
@@ -98,6 +102,9 @@ fun ChannelScreen(
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
feedViewModel.invalidateData() feedViewModel.invalidateData()
channelScreenModel.imageUploadingError.collect { error ->
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
}
} }
DisposableEffect(channelId) { DisposableEffect(channelId) {
@@ -171,6 +178,13 @@ fun ChannelScreen(
} }
} }
Row(modifier = Modifier.fillMaxWidth()) {
UploadFromGallery(
isUploading = channelScreenModel.isUploadingImage
) {
channelScreenModel.upload(it, context)
}
}
// LAST ROW // LAST ROW
Row( Row(
modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp).fillMaxWidth(), modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp).fillMaxWidth(),
@@ -178,8 +192,10 @@ fun ChannelScreen(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
TextField( TextField(
value = newPost.value, value = channelScreenModel.message,
onValueChange = { newPost.value = it }, onValueChange = {
channelScreenModel.updateMessage(it)
},
keyboardOptions = KeyboardOptions.Default.copy( keyboardOptions = KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.Sentences capitalization = KeyboardCapitalization.Sentences
), ),
@@ -195,12 +211,12 @@ fun ChannelScreen(
trailingIcon = { trailingIcon = {
PostButton( PostButton(
onPost = { onPost = {
account.sendChannelMessage(newPost.value.text, channel.idHex, replyTo.value, null) account.sendChannelMessage(channelScreenModel.message.text, channel.idHex, replyTo.value, null)
newPost.value = TextFieldValue("") channelScreenModel.message = TextFieldValue("")
replyTo.value = null replyTo.value = null
feedViewModel.refresh() // Don't wait a full second before updating feedViewModel.refresh() // Don't wait a full second before updating
}, },
newPost.value.text.isNotBlank(), isActive = channelScreenModel.message.text.isNotBlank() && !channelScreenModel.isUploadingImage,
modifier = Modifier.padding(end = 10.dp) modifier = Modifier.padding(end = 10.dp)
) )
}, },

View File

@@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.widget.Toast
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -36,6 +37,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
@@ -50,7 +52,9 @@ import com.vitorpamplona.amethyst.R
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
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.actions.PostButton import com.vitorpamplona.amethyst.ui.actions.PostButton
import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
import com.vitorpamplona.amethyst.ui.components.ResizeImage import com.vitorpamplona.amethyst.ui.components.ResizeImage
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
@@ -64,9 +68,10 @@ import com.vitorpamplona.amethyst.ui.screen.NostrChatRoomFeedViewModel
fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) { fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) {
val accountState by accountViewModel.accountLiveData.observeAsState() val accountState by accountViewModel.accountLiveData.observeAsState()
val account = accountState?.account val account = accountState?.account
val context = LocalContext.current
val chatRoomScreenModel: NewPostViewModel = viewModel()
if (account != null && userId != null) { if (account != null && userId != null) {
val newPost = remember { mutableStateOf(TextFieldValue("")) }
val replyTo = remember { mutableStateOf<Note?>(null) } val replyTo = remember { mutableStateOf<Note?>(null) }
ChatroomFeedFilter.loadMessagesBetween(account, userId) ChatroomFeedFilter.loadMessagesBetween(account, userId)
@@ -77,6 +82,9 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
LaunchedEffect(userId) { LaunchedEffect(userId) {
feedViewModel.refresh() feedViewModel.refresh()
chatRoomScreenModel.imageUploadingError.collect { error ->
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
}
} }
DisposableEffect(userId) { DisposableEffect(userId) {
@@ -148,6 +156,13 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
} }
} }
Row(modifier = Modifier.fillMaxWidth()) {
UploadFromGallery(
isUploading = chatRoomScreenModel.isUploadingImage
) {
chatRoomScreenModel.upload(it, context)
}
}
// LAST ROW // LAST ROW
Row( Row(
modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp) modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp, top = 5.dp)
@@ -156,8 +171,8 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
TextField( TextField(
value = newPost.value, value = chatRoomScreenModel.message,
onValueChange = { newPost.value = it }, onValueChange = { chatRoomScreenModel.updateMessage(it) },
keyboardOptions = KeyboardOptions.Default.copy( keyboardOptions = KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.Sentences capitalization = KeyboardCapitalization.Sentences
), ),
@@ -173,13 +188,13 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
trailingIcon = { trailingIcon = {
PostButton( PostButton(
onPost = { onPost = {
account.sendPrivateMeesage(newPost.value.text, userId, replyTo.value) account.sendPrivateMessage(chatRoomScreenModel.message.text, userId, replyTo.value)
newPost.value = TextFieldValue("") chatRoomScreenModel.message = TextFieldValue("")
replyTo.value = null replyTo.value = null
feedViewModel.refresh() // Don't wait a full second before updating feedViewModel.refresh() // Don't wait a full second before updating
}, },
newPost.value.text.isNotBlank(), isActive = chatRoomScreenModel.message.text.isNotBlank() && !chatRoomScreenModel.isUploadingImage,
modifier = Modifier.padding(end = 10.dp) modifier = Modifier.padding(end = 10.dp),
) )
}, },
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.textFieldColors(