Adds support for RelaySet event types.
This commit is contained in:
@@ -300,6 +300,19 @@ object LocalCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun consume(event: RelaySetEvent) {
|
||||||
|
val note = getOrCreateAddressableNote(event.address())
|
||||||
|
val author = getOrCreateUser(event.pubKey)
|
||||||
|
|
||||||
|
if (note.event?.id() == event.id()) return
|
||||||
|
|
||||||
|
if (event.createdAt > (note.createdAt() ?: 0)) {
|
||||||
|
note.loadEvent(event, author, emptyList())
|
||||||
|
|
||||||
|
refreshObservers(note)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun consume(event: AudioTrackEvent) {
|
private fun consume(event: AudioTrackEvent) {
|
||||||
val note = getOrCreateAddressableNote(event.address())
|
val note = getOrCreateAddressableNote(event.address())
|
||||||
val author = getOrCreateUser(event.pubKey)
|
val author = getOrCreateUser(event.pubKey)
|
||||||
@@ -1015,7 +1028,7 @@ object LocalCache {
|
|||||||
live.invalidateData(newNote)
|
live.invalidateData(newNote)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun consume(event: Event, relay: Relay?) {
|
fun verifyAndConsume(event: Event, relay: Relay?) {
|
||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
|
|
||||||
if (!event.hasValidSignature()) {
|
if (!event.hasValidSignature()) {
|
||||||
@@ -1050,7 +1063,7 @@ object LocalCache {
|
|||||||
is HighlightEvent -> consume(event, relay)
|
is HighlightEvent -> consume(event, relay)
|
||||||
is LnZapEvent -> {
|
is LnZapEvent -> {
|
||||||
event.zapRequest?.let {
|
event.zapRequest?.let {
|
||||||
consume(it, relay)
|
verifyAndConsume(it, relay)
|
||||||
}
|
}
|
||||||
consume(event)
|
consume(event)
|
||||||
}
|
}
|
||||||
@@ -1064,10 +1077,11 @@ object LocalCache {
|
|||||||
is PeopleListEvent -> consume(event)
|
is PeopleListEvent -> consume(event)
|
||||||
is ReactionEvent -> consume(event)
|
is ReactionEvent -> consume(event)
|
||||||
is RecommendRelayEvent -> consume(event)
|
is RecommendRelayEvent -> consume(event)
|
||||||
|
is RelaySetEvent -> consume(event)
|
||||||
is ReportEvent -> consume(event, relay)
|
is ReportEvent -> consume(event, relay)
|
||||||
is RepostEvent -> {
|
is RepostEvent -> {
|
||||||
event.containedPost()?.let {
|
event.containedPost()?.let {
|
||||||
consume(it, relay)
|
verifyAndConsume(it, relay)
|
||||||
}
|
}
|
||||||
consume(event)
|
consume(event)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ abstract class NostrDataSource(val debugName: String) {
|
|||||||
eventCounter = eventCounter + Pair(key, Counter(1))
|
eventCounter = eventCounter + Pair(key, Counter(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalCache.consume(event, relay)
|
LocalCache.verifyAndConsume(event, relay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ open class Event(
|
|||||||
PrivateDmEvent.kind -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig)
|
PrivateDmEvent.kind -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
ReactionEvent.kind -> ReactionEvent(id, pubKey, createdAt, tags, content, sig)
|
ReactionEvent.kind -> ReactionEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
RecommendRelayEvent.kind -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig, lenient)
|
RecommendRelayEvent.kind -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig, lenient)
|
||||||
|
RelaySetEvent.kind -> RelaySetEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
ReportEvent.kind -> ReportEvent(id, pubKey, createdAt, tags, content, sig)
|
ReportEvent.kind -> ReportEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
RepostEvent.kind -> RepostEvent(id, pubKey, createdAt, tags, content, sig)
|
RepostEvent.kind -> RepostEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
TextNoteEvent.kind -> TextNoteEvent(id, pubKey, createdAt, tags, content, sig)
|
TextNoteEvent.kind -> TextNoteEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.vitorpamplona.amethyst.service.model
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.amethyst.model.HexKey
|
||||||
|
import com.vitorpamplona.amethyst.model.toHexKey
|
||||||
|
import nostr.postr.Utils
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class RelaySetEvent(
|
||||||
|
id: HexKey,
|
||||||
|
pubKey: HexKey,
|
||||||
|
createdAt: Long,
|
||||||
|
tags: List<List<String>>,
|
||||||
|
content: String,
|
||||||
|
sig: HexKey
|
||||||
|
) : Event(id, pubKey, createdAt, kind, tags, content, sig), AddressableEvent {
|
||||||
|
|
||||||
|
override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: ""
|
||||||
|
override fun address() = ATag(kind, pubKey, dTag(), null)
|
||||||
|
|
||||||
|
fun relays() = tags.filter { it.size > 1 && it[0] == "r" }.map { it[1] }
|
||||||
|
fun description() = tags.firstOrNull() { it.size > 1 && it[0] == "description" }?.get(1)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val kind = 30022
|
||||||
|
|
||||||
|
fun create(
|
||||||
|
relays: List<String>,
|
||||||
|
privateKey: ByteArray,
|
||||||
|
createdAt: Long = Date().time / 1000
|
||||||
|
): RelaySetEvent {
|
||||||
|
val tags = mutableListOf<List<String>>()
|
||||||
|
relays.forEach {
|
||||||
|
tags.add(listOf("r", it))
|
||||||
|
}
|
||||||
|
|
||||||
|
val pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
|
||||||
|
val id = generateId(pubKey, createdAt, kind, tags, "")
|
||||||
|
val sig = Utils.sign(id, privateKey)
|
||||||
|
return RelaySetEvent(id.toHexKey(), pubKey, createdAt, tags, "", sig.toHexKey())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -23,7 +23,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
|||||||
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||||
scope.launch {
|
scope.launch {
|
||||||
// adds to database
|
// adds to database
|
||||||
LocalCache.consume(event, null)
|
LocalCache.verifyAndConsume(event, null)
|
||||||
|
|
||||||
when (event) {
|
when (event) {
|
||||||
is PrivateDmEvent -> notify(event)
|
is PrivateDmEvent -> notify(event)
|
||||||
|
|||||||
+1
-1
@@ -97,7 +97,7 @@ fun ExpandableRichTextViewer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ShowMoreButton(onClick: () -> Unit) {
|
public fun ShowMoreButton(onClick: () -> Unit) {
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.padding(top = 10.dp),
|
modifier = Modifier.padding(top = 10.dp),
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|||||||
@@ -372,10 +372,9 @@ private fun aspectRatio(dim: String?): Float? {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun DisplayUrlWithLoadingSymbol(content: ZoomableContent) {
|
private fun DisplayUrlWithLoadingSymbol(content: ZoomableContent) {
|
||||||
var cnt by remember { mutableStateOf<ZoomableContent?>(null) }
|
var cnt by remember { mutableStateOf<ZoomableContent?>(null) }
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
scope.launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
delay(200)
|
delay(200)
|
||||||
cnt = content
|
cnt = content
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
|
|||||||
import kotlinx.collections.immutable.toImmutableSet
|
import kotlinx.collections.immutable.toImmutableSet
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
val ChatBubbleShapeMe = RoundedCornerShape(15.dp, 15.dp, 3.dp, 15.dp)
|
val ChatBubbleShapeMe = RoundedCornerShape(15.dp, 15.dp, 3.dp, 15.dp)
|
||||||
val ChatBubbleShapeThem = RoundedCornerShape(3.dp, 15.dp, 15.dp, 15.dp)
|
val ChatBubbleShapeThem = RoundedCornerShape(3.dp, 15.dp, 15.dp, 15.dp)
|
||||||
@@ -348,7 +347,7 @@ fun ChatTimeAgo(time: Long) {
|
|||||||
var timeStr by remember { mutableStateOf("") }
|
var timeStr by remember { mutableStateOf("") }
|
||||||
|
|
||||||
LaunchedEffect(key1 = time) {
|
LaunchedEffect(key1 = time) {
|
||||||
withContext(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
timeStr = timeAgoShort(time, context = context)
|
timeStr = timeAgoShort(time, context = context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
|
||||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||||
import androidx.compose.ui.Alignment.Companion.TopEnd
|
import androidx.compose.ui.Alignment.Companion.TopEnd
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -109,10 +110,12 @@ import com.vitorpamplona.amethyst.service.model.PinListEvent
|
|||||||
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
|
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.ReactionEvent
|
import com.vitorpamplona.amethyst.service.model.ReactionEvent
|
||||||
|
import com.vitorpamplona.amethyst.service.model.RelaySetEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.RepostEvent
|
import com.vitorpamplona.amethyst.service.model.RepostEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
|
||||||
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
|
||||||
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
||||||
@@ -123,6 +126,7 @@ import com.vitorpamplona.amethyst.ui.components.ResizeImage
|
|||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
|
||||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ShowMoreButton
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||||
import com.vitorpamplona.amethyst.ui.components.VideoView
|
import com.vitorpamplona.amethyst.ui.components.VideoView
|
||||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContent
|
import com.vitorpamplona.amethyst.ui.components.ZoomableContent
|
||||||
@@ -510,6 +514,10 @@ fun NormalNote(
|
|||||||
RenderPeopleList(baseNote, backgroundColor, accountViewModel, nav)
|
RenderPeopleList(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RelaySetEvent -> {
|
||||||
|
RelaySetList(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
|
}
|
||||||
|
|
||||||
is AudioTrackEvent -> {
|
is AudioTrackEvent -> {
|
||||||
RenderAudioTrack(baseNote, accountViewModel, nav)
|
RenderAudioTrack(baseNote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
@@ -958,6 +966,23 @@ private fun RenderPrivateMessage(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RelaySetList(
|
||||||
|
baseNote: Note,
|
||||||
|
backgroundColor: Color,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
|
||||||
|
|
||||||
|
ReactionsRow(baseNote, accountViewModel, nav)
|
||||||
|
|
||||||
|
Divider(
|
||||||
|
modifier = Modifier.padding(top = 10.dp),
|
||||||
|
thickness = 0.25.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderPeopleList(
|
fun RenderPeopleList(
|
||||||
baseNote: Note,
|
baseNote: Note,
|
||||||
@@ -975,6 +1000,139 @@ fun RenderPeopleList(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DisplayRelaySet(
|
||||||
|
baseNote: Note,
|
||||||
|
backgroundColor: Color,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: (String) -> Unit
|
||||||
|
) {
|
||||||
|
val noteEvent = baseNote.event as? RelaySetEvent ?: return
|
||||||
|
|
||||||
|
val relays by remember {
|
||||||
|
mutableStateOf<ImmutableList<String>>(
|
||||||
|
noteEvent.relays().toImmutableList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var expanded by remember {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val toMembersShow = if (expanded) {
|
||||||
|
relays
|
||||||
|
} else {
|
||||||
|
relays.take(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
val relayListName by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
"#${noteEvent.dTag()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val relayDescription by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
noteEvent.description()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = relayListName,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(5.dp),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
|
relayDescription?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(5.dp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box {
|
||||||
|
Column(modifier = Modifier.padding(top = 5.dp)) {
|
||||||
|
toMembersShow.forEach { relay ->
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = CenterVertically) {
|
||||||
|
Text(
|
||||||
|
relay.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/"),
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 10.dp, bottom = 5.dp)
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
|
RelayOptionsAction(relay, accountViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relays.size > 3 && !expanded) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(
|
||||||
|
brush = Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
backgroundColor.copy(alpha = 0f),
|
||||||
|
backgroundColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
ShowMoreButton {
|
||||||
|
expanded = !expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RelayOptionsAction(
|
||||||
|
relay: String,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val userStateRelayInfo by accountViewModel.account.userProfile().live().relayInfo.observeAsState()
|
||||||
|
val isCurrentlyOnTheUsersList by remember(userStateRelayInfo) {
|
||||||
|
derivedStateOf {
|
||||||
|
userStateRelayInfo?.user?.latestContactList?.relays()?.none { it.key == relay } == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var wantsToAddRelay by remember {
|
||||||
|
mutableStateOf("")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantsToAddRelay.isNotEmpty()) {
|
||||||
|
NewRelayListView({ wantsToAddRelay = "" }, accountViewModel, wantsToAddRelay)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCurrentlyOnTheUsersList) {
|
||||||
|
AddRelayButton { wantsToAddRelay = relay }
|
||||||
|
} else {
|
||||||
|
RemoveRelayButton { wantsToAddRelay = relay }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DisplayPeopleList(
|
fun DisplayPeopleList(
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent
|
|||||||
import com.vitorpamplona.amethyst.service.model.PeopleListEvent
|
import com.vitorpamplona.amethyst.service.model.PeopleListEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.PinListEvent
|
import com.vitorpamplona.amethyst.service.model.PinListEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
|
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
|
||||||
|
import com.vitorpamplona.amethyst.service.model.RelaySetEvent
|
||||||
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
||||||
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists
|
||||||
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
||||||
@@ -374,6 +375,13 @@ fun NoteMaster(
|
|||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav
|
nav
|
||||||
)
|
)
|
||||||
|
} else if (noteEvent is RelaySetEvent) {
|
||||||
|
DisplayRelaySet(
|
||||||
|
baseNote,
|
||||||
|
MaterialTheme.colors.background,
|
||||||
|
accountViewModel,
|
||||||
|
nav
|
||||||
|
)
|
||||||
} else if (noteEvent is AppDefinitionEvent) {
|
} else if (noteEvent is AppDefinitionEvent) {
|
||||||
RenderAppDefinition(baseNote, accountViewModel, nav)
|
RenderAppDefinition(baseNote, accountViewModel, nav)
|
||||||
} else if (noteEvent is HighlightEvent) {
|
} else if (noteEvent is HighlightEvent) {
|
||||||
|
|||||||
+6
-3
@@ -45,6 +45,7 @@ import com.vitorpamplona.amethyst.ui.screen.ChatroomListFeedView
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.FeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.FeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListKnownFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListKnownFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@@ -150,9 +151,11 @@ fun ChatroomListScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun WatchAccountForListScreen(knownFeedViewModel: NostrChatroomListKnownFeedViewModel, newFeedViewModel: NostrChatroomListNewFeedViewModel, accountViewModel: AccountViewModel) {
|
fun WatchAccountForListScreen(knownFeedViewModel: NostrChatroomListKnownFeedViewModel, newFeedViewModel: NostrChatroomListNewFeedViewModel, accountViewModel: AccountViewModel) {
|
||||||
LaunchedEffect(accountViewModel) {
|
LaunchedEffect(accountViewModel) {
|
||||||
NostrChatroomListDataSource.start()
|
launch(Dispatchers.IO) {
|
||||||
knownFeedViewModel.invalidateData(true)
|
NostrChatroomListDataSource.start()
|
||||||
newFeedViewModel.invalidateData(true)
|
knownFeedViewModel.invalidateData(true)
|
||||||
|
newFeedViewModel.invalidateData(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ fun ChatroomScreen(
|
|||||||
var userRoom by remember { mutableStateOf<User?>(null) }
|
var userRoom by remember { mutableStateOf<User?>(null) }
|
||||||
|
|
||||||
LaunchedEffect(userId) {
|
LaunchedEffect(userId) {
|
||||||
withContext(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
val newUser = LocalCache.checkGetOrCreateUser(userId)
|
val newUser = LocalCache.checkGetOrCreateUser(userId)
|
||||||
if (newUser != userRoom) {
|
if (newUser != userRoom) {
|
||||||
userRoom = newUser
|
userRoom = newUser
|
||||||
@@ -105,10 +105,10 @@ fun ChatroomScreen(
|
|||||||
val lifeCycleOwner = LocalLifecycleOwner.current
|
val lifeCycleOwner = LocalLifecycleOwner.current
|
||||||
|
|
||||||
LaunchedEffect(baseUser, accountViewModel) {
|
LaunchedEffect(baseUser, accountViewModel) {
|
||||||
NostrChatroomDataSource.start()
|
|
||||||
feedViewModel.invalidateData()
|
|
||||||
|
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
|
NostrChatroomDataSource.start()
|
||||||
|
feedViewModel.invalidateData()
|
||||||
|
|
||||||
newPostModel.imageUploadingError.collect { error ->
|
newPostModel.imageUploadingError.collect { error ->
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@@ -138,17 +138,15 @@ fun WatchAccountForHomeScreen(
|
|||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
val account = remember(accountState) { accountState?.account } ?: return
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
var firstTime by remember(accountViewModel) { mutableStateOf(true) }
|
var firstTime by remember(accountViewModel) { mutableStateOf(true) }
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel, account.defaultHomeFollowList) {
|
LaunchedEffect(accountViewModel, accountState?.account?.defaultHomeFollowList) {
|
||||||
// Only invalidate when things change. Not in the first run
|
// Only invalidate when things change. Not in the first run
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
firstTime = false
|
firstTime = false
|
||||||
} else {
|
} else {
|
||||||
scope.launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
NostrHomeDataSource.invalidateFilters()
|
NostrHomeDataSource.invalidateFilters()
|
||||||
homeFeedViewModel.invalidateDataAndSendToTop(true)
|
homeFeedViewModel.invalidateDataAndSendToTop(true)
|
||||||
repliesFeedViewModel.invalidateDataAndSendToTop(true)
|
repliesFeedViewModel.invalidateDataAndSendToTop(true)
|
||||||
|
|||||||
+1
-2
@@ -26,7 +26,6 @@ import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
|
|||||||
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LoadRedirectScreen(eventId: String?, navController: NavController) {
|
fun LoadRedirectScreen(eventId: String?, navController: NavController) {
|
||||||
@@ -42,7 +41,7 @@ fun LoadRedirectScreen(eventId: String?, navController: NavController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(eventId) {
|
LaunchedEffect(eventId) {
|
||||||
withContext(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
val newNoteBase = LocalCache.checkGetOrCreateNote(eventId)
|
val newNoteBase = LocalCache.checkGetOrCreateNote(eventId)
|
||||||
if (newNoteBase != noteBase) {
|
if (newNoteBase != noteBase) {
|
||||||
noteBase = newNoteBase
|
noteBase = newNoteBase
|
||||||
|
|||||||
@@ -145,9 +145,11 @@ fun SearchScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun WatchAccountForSearchScreen(searchFeedViewModel: NostrGlobalFeedViewModel, accountViewModel: AccountViewModel) {
|
fun WatchAccountForSearchScreen(searchFeedViewModel: NostrGlobalFeedViewModel, accountViewModel: AccountViewModel) {
|
||||||
LaunchedEffect(accountViewModel) {
|
LaunchedEffect(accountViewModel) {
|
||||||
NostrGlobalDataSource.resetFilters()
|
launch(Dispatchers.IO) {
|
||||||
NostrSearchEventOrUserDataSource.start()
|
NostrGlobalDataSource.resetFilters()
|
||||||
searchFeedViewModel.invalidateData(true)
|
NostrSearchEventOrUserDataSource.start()
|
||||||
|
searchFeedViewModel.invalidateData(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user