pull/749/head
greenart7c3 2024-03-18 17:47:15 -03:00
rodzic f6e5af3e98
commit 940fa2ee8d
5 zmienionych plików z 72 dodań i 12 usunięć

Wyświetl plik

@ -171,13 +171,18 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.lang.Math.round import java.lang.Math.round
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
@Composable @Composable
fun NewPostView( fun NewPostView(
onClose: () -> Unit, onClose: () -> Unit,
@ -201,6 +206,14 @@ fun NewPostView(
var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() } var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
launch(Dispatchers.IO) {
postViewModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
postViewModel.sendPost(relayList = relayList, localDraft = postViewModel.draftTag)
}
}
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
postViewModel.load(accountViewModel, baseReplyTo, quote, fork, version, draft) postViewModel.load(accountViewModel, baseReplyTo, quote, fork, version, draft)

Wyświetl plik

@ -69,6 +69,7 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
@ -83,7 +84,7 @@ enum class UserSuggestionAnchor {
@Stable @Stable
open class NewPostViewModel() : ViewModel() { open class NewPostViewModel() : ViewModel() {
private var draftTag: String = UUID.randomUUID().toString() var draftTag: String = UUID.randomUUID().toString()
var accountViewModel: AccountViewModel? = null var accountViewModel: AccountViewModel? = null
var account: Account? = null var account: Account? = null
var requiresNIP24: Boolean = false var requiresNIP24: Boolean = false
@ -166,6 +167,8 @@ open class NewPostViewModel() : ViewModel() {
// NIP24 Wrapped DMs / Group messages // NIP24 Wrapped DMs / Group messages
var nip24 by mutableStateOf(false) var nip24 by mutableStateOf(false)
val draftTextChanges = Channel<String>(Channel.CONFLATED)
fun lnAddress(): String? { fun lnAddress(): String? {
return account?.userProfile()?.info?.lnAddress() return account?.userProfile()?.info?.lnAddress()
} }
@ -190,7 +193,7 @@ open class NewPostViewModel() : ViewModel() {
this.account = accountViewModel.account this.account = accountViewModel.account
if (draft != null) { if (draft != null) {
loadfromDraft(draft, accountViewModel) loadFromDraft(draft, accountViewModel)
} else { } else {
originalNote = replyingTo originalNote = replyingTo
replyingTo?.let { replyNote -> replyingTo?.let { replyNote ->
@ -305,7 +308,7 @@ open class NewPostViewModel() : ViewModel() {
} }
} }
private fun loadfromDraft( private fun loadFromDraft(
draft: Note, draft: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
@ -798,9 +801,8 @@ open class NewPostViewModel() : ViewModel() {
pTags = pTags?.filter { it != userToRemove } pTags = pTags?.filter { it != userToRemove }
} }
open fun saveDraft() { open suspend fun saveDraft() {
// TODO: find a way to send only the last modification so we dont get rate limited draftTextChanges.send("")
sendPost(localDraft = draftTag)
} }
open fun updateMessage(it: TextFieldValue) { open fun updateMessage(it: TextFieldValue) {
@ -1010,7 +1012,9 @@ open class NewPostViewModel() : ViewModel() {
message = message.insertUrlAtCursor(imageUrl) message = message.insertUrlAtCursor(imageUrl)
urlPreview = findUrlInMessage() urlPreview = findUrlInMessage()
saveDraft() viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
}, },
onError = { onError = {
@ -1055,7 +1059,9 @@ open class NewPostViewModel() : ViewModel() {
} }
urlPreview = findUrlInMessage() urlPreview = findUrlInMessage()
saveDraft() viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
}, },
onError = { onError = {
@ -1076,7 +1082,7 @@ open class NewPostViewModel() : ViewModel() {
locUtil?.let { locUtil?.let {
location = location =
it.locationStateFlow.mapLatest { it.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString() } it.locationStateFlow.mapLatest { it.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString() }
saveDraft() viewModelScope.launch(Dispatchers.IO) { saveDraft() }
} }
viewModelScope.launch(Dispatchers.IO) { locUtil?.start() } viewModelScope.launch(Dispatchers.IO) { locUtil?.start() }
} }

Wyświetl plik

@ -40,11 +40,14 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable @Composable
fun ZapRaiserRequest( fun ZapRaiserRequest(
@ -97,7 +100,9 @@ fun ZapRaiserRequest(
} else { } else {
newPostViewModel.zapRaiserAmount = it.toLongOrNull() newPostViewModel.zapRaiserAmount = it.toLongOrNull()
} }
newPostViewModel.saveDraft() newPostViewModel.viewModelScope.launch(Dispatchers.IO) {
newPostViewModel.saveDraft()
}
} }
}, },
placeholder = { placeholder = {

Wyświetl plik

@ -165,6 +165,10 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.text.DateFormat import java.text.DateFormat
@ -189,6 +193,7 @@ fun ChannelScreen(
} }
} }
@OptIn(FlowPreview::class)
@Composable @Composable
fun PrepareChannelViewModels( fun PrepareChannelViewModels(
baseChannel: Channel, baseChannel: Channel,
@ -206,6 +211,18 @@ fun PrepareChannelViewModels(
) )
val channelScreenModel: NewPostViewModel = viewModel() val channelScreenModel: NewPostViewModel = viewModel()
LaunchedEffect(Unit) {
launch(Dispatchers.IO) {
channelScreenModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
channelScreenModel.sendPost(localDraft = channelScreenModel.draftTag)
}
}
}
channelScreenModel.accountViewModel = accountViewModel channelScreenModel.accountViewModel = accountViewModel
channelScreenModel.account = accountViewModel.account channelScreenModel.account = accountViewModel.account
channelScreenModel.originalNote = LocalCache.getNoteIfExists(baseChannel.idHex) channelScreenModel.originalNote = LocalCache.getNoteIfExists(baseChannel.idHex)
@ -680,7 +697,12 @@ fun ShowVideoStreaming(
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
modifier = remember { Modifier.fillMaxWidth().heightIn(min = 50.dp, max = 300.dp) }, modifier =
remember {
Modifier
.fillMaxWidth()
.heightIn(min = 50.dp, max = 300.dp)
},
) { ) {
val zoomableUrlVideo = val zoomableUrlVideo =
remember(streamingInfo) { remember(streamingInfo) {

Wyświetl plik

@ -124,6 +124,10 @@ import com.vitorpamplona.quartz.events.findURLs
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -208,6 +212,7 @@ fun LoadRoomByAuthor(
content(room) content(room)
} }
@OptIn(FlowPreview::class)
@Composable @Composable
fun PrepareChatroomViewModels( fun PrepareChatroomViewModels(
room: ChatroomKey, room: ChatroomKey,
@ -237,6 +242,15 @@ fun PrepareChatroomViewModels(
} }
LaunchedEffect(key1 = newPostModel) { LaunchedEffect(key1 = newPostModel) {
launch(Dispatchers.IO) {
newPostModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
newPostModel.sendPost(localDraft = newPostModel.draftTag)
}
}
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
val hasNIP24 = val hasNIP24 =
accountViewModel.userProfile().privateChatrooms[room]?.roomMessages?.any { accountViewModel.userProfile().privateChatrooms[room]?.roomMessages?.any {