Modify the models to support creating a new list with several profiles. Use IO dispatcher in FollowSetState. Introduce follow set copying/cloning, with custom names/descriptions for the clones.

This commit is contained in:
KotlinGeekDev
2025-10-03 16:02:15 +01:00
parent 88fbee84dc
commit 2df575d4af
3 changed files with 55 additions and 22 deletions
@@ -25,20 +25,16 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
import com.vitorpamplona.quartz.utils.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class FollowSetState(
@@ -50,7 +46,7 @@ class FollowSetState(
private val isActive = MutableStateFlow(false)
suspend fun getFollowSetNotes() =
withContext(Dispatchers.Default) {
withContext(Dispatchers.IO) {
val followSetNotes = LocalCache.getFollowSetNotesFor(user)
return@withContext followSetNotes
}
@@ -63,7 +59,7 @@ class FollowSetState(
emit(followSets)
delay(2000)
}
}.flowOn(Dispatchers.Default)
}.flowOn(Dispatchers.IO)
val profilesFlow =
getFollowSetNotesFlow()
@@ -82,14 +78,5 @@ class FollowSetState(
init {
isActive.update { true }
scope.launch(Dispatchers.Default) {
getFollowSetNotesFlow()
.onCompletion {
isActive.update { false }
}.catch {
Log.e(this@FollowSetState.javaClass.simpleName, "Error on flow collection: ${it.message}")
isActive.update { false }
}.collect {}
}
}
}
@@ -129,7 +129,8 @@ class FollowSetFeedViewModel(
title = setName,
description = setDescription,
isPrivate = firstMemberShouldBePrivate,
firstMemberHex = optionalFirstMemberHex,
firstPublicMembers = if (optionalFirstMemberHex != null) listOf(optionalFirstMemberHex) else emptyList(),
firstPrivateMembers = if (optionalFirstMemberHex != null) listOf(optionalFirstMemberHex) else emptyList(),
signer = account.signer,
) {
account.sendMyPublicAndPrivateOutbox(it)
@@ -159,6 +160,31 @@ class FollowSetFeedViewModel(
}
}
fun cloneFollowSet(
currentFollowSet: FollowSet,
customCloneName: String?,
customCloneDescription: String?,
account: Account,
) {
if (!account.settings.isWriteable()) {
println("You are in read-only mode. Please login to make modifications.")
} else {
viewModelScope.launch(Dispatchers.IO) {
PeopleListEvent.createListWithDescription(
dTag = UUID.randomUUID().toString(),
title = customCloneName ?: currentFollowSet.title,
description = customCloneDescription ?: currentFollowSet.description,
isPrivate = false,
firstPublicMembers = currentFollowSet.publicProfiles.toList(),
firstPrivateMembers = currentFollowSet.privateProfiles.toList(),
signer = account.signer,
) {
account.sendMyPublicAndPrivateOutbox(it)
}
}
}
}
fun deleteFollowSet(
followSet: FollowSet,
account: Account,
@@ -223,18 +223,28 @@ class PeopleListEvent(
title: String,
description: String? = null,
isPrivate: Boolean,
firstMemberHex: String? = null,
firstPublicMembers: List<String> = emptyList(),
firstPrivateMembers: List<String> = emptyList(),
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
val isFirstMemberSpecified = firstMemberHex != null
if (description == null) {
val newListTemplate =
build(
name = title,
publicPeople = if (!isPrivate && isFirstMemberSpecified) listOf(UserTag(pubKey = firstMemberHex)) else emptyList(),
privatePeople = if (isPrivate && isFirstMemberSpecified) listOf(UserTag(pubKey = firstMemberHex)) else emptyList(),
publicPeople =
if (!isPrivate && firstPublicMembers.isNotEmpty()) {
firstPublicMembers.map { UserTag(pubKey = it) }
} else {
emptyList()
},
privatePeople =
if (isPrivate && firstPrivateMembers.isNotEmpty()) {
firstPrivateMembers.map { UserTag(pubKey = it) }
} else {
emptyList()
},
signer = signer,
dTag = dTag,
createdAt = createdAt,
@@ -245,8 +255,18 @@ class PeopleListEvent(
val event =
build(
name = title,
publicPeople = if (!isPrivate && isFirstMemberSpecified) listOf(UserTag(pubKey = firstMemberHex)) else emptyList(),
privatePeople = if (isPrivate && isFirstMemberSpecified) listOf(UserTag(pubKey = firstMemberHex)) else emptyList(),
publicPeople =
if (!isPrivate && firstPublicMembers.isNotEmpty()) {
firstPublicMembers.map { UserTag(pubKey = it) }
} else {
emptyList()
},
privatePeople =
if (isPrivate && firstPrivateMembers.isNotEmpty()) {
firstPrivateMembers.map { UserTag(pubKey = it) }
} else {
emptyList()
},
signer = signer,
dTag = dTag,
createdAt = createdAt,