mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2024-09-29 16:30:49 +00:00
add debouncer
This commit is contained in:
parent
f6e5af3e98
commit
940fa2ee8d
@ -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)
|
||||||
|
|
||||||
|
@ -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() }
|
||||||
}
|
}
|
||||||
|
@ -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 = {
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user