mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-11 05:03:21 +02:00
send request, get results (still needs parsing)
This commit is contained in:
@@ -20,15 +20,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.dal
|
package com.vitorpamplona.amethyst.ui.dal
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||||
import com.vitorpamplona.quartz.events.MuteListEvent
|
import com.vitorpamplona.quartz.events.MuteListEvent
|
||||||
import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent
|
import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryResponseEvent
|
||||||
import com.vitorpamplona.quartz.events.PeopleListEvent
|
import com.vitorpamplona.quartz.events.PeopleListEvent
|
||||||
|
|
||||||
open class NIP90ContentDiscoveryFilter(
|
open class NIP90ContentDiscoveryFilter(
|
||||||
val account: Account,
|
val account: Account,
|
||||||
|
val dvmkey: String,
|
||||||
) : AdditiveFeedFilter<Note>() {
|
) : AdditiveFeedFilter<Note>() {
|
||||||
override fun feedKey(): String {
|
override fun feedKey(): String {
|
||||||
return account.userProfile().pubkeyHex + "-" + followList()
|
return account.userProfile().pubkeyHex + "-" + followList()
|
||||||
@@ -49,15 +53,28 @@ open class NIP90ContentDiscoveryFilter(
|
|||||||
val notes =
|
val notes =
|
||||||
LocalCache.notes.filterIntoSet { _, it ->
|
LocalCache.notes.filterIntoSet { _, it ->
|
||||||
val noteEvent = it.event
|
val noteEvent = it.event
|
||||||
noteEvent is NIP90ContentDiscoveryResponseEvent // && params.match(noteEvent)
|
noteEvent is NIP90ContentDiscoveryResponseEvent && it.event?.pubKey() == dvmkey && it.event?.isTaggedUser(account.keyPair.pubKey.toHexKey()) == true // && params.match(noteEvent)
|
||||||
}
|
}
|
||||||
|
var sorted = sort(notes)
|
||||||
|
var note = sorted.first()
|
||||||
|
|
||||||
return sort(notes)
|
var eventContent = note.event?.content()
|
||||||
|
|
||||||
|
var collection: Set<Note> = setOf()
|
||||||
|
val mapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
|
var json = mapper.readValue(eventContent, Array::class.java)
|
||||||
|
for (element in json) {
|
||||||
|
// var test = mapper.readValue(element.toString(), Array::class.java)
|
||||||
|
// TODO. This is ugly. how to Kotlin?
|
||||||
|
var id = element.toString().trimStart('[').trimStart('e').trimStart(',').trimEnd(']').trimStart().trimEnd()
|
||||||
|
collection + id
|
||||||
|
}
|
||||||
|
|
||||||
|
return sort(collection)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyFilter(collection: Set<Note>): Set<Note> {
|
override fun applyFilter(collection: Set<Note>): Set<Note> {
|
||||||
var result = innerApplyFilter(collection)
|
return innerApplyFilter(collection)
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildFilterParams(account: Account): FilterByListParams {
|
fun buildFilterParams(account: Account): FilterByListParams {
|
||||||
@@ -70,12 +87,38 @@ open class NIP90ContentDiscoveryFilter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
|
protected open fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
|
||||||
val params = buildFilterParams(account)
|
// val params = buildFilterParams(account)
|
||||||
|
|
||||||
return collection.filterTo(HashSet()) {
|
val notes =
|
||||||
val noteEvent = it.event
|
collection.filterTo(HashSet()) {
|
||||||
noteEvent is NIP90ContentDiscoveryResponseEvent // && params.match(noteEvent)
|
val noteEvent = it.event
|
||||||
|
noteEvent is NIP90ContentDiscoveryResponseEvent && it.event?.isTaggedUser(account.keyPair.pubKey.toHexKey()) == true // && params.match(noteEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO. We want to parse the content of the latest event to ids and get the nodes from these ids
|
||||||
|
|
||||||
|
/* var sorted = sort(notes)
|
||||||
|
var note = sorted.first()
|
||||||
|
|
||||||
|
var eventContent = note.event?.content()
|
||||||
|
|
||||||
|
val collection: Set<Note> = setOf()
|
||||||
|
val mapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
|
var json = mapper.readValue(eventContent, Array::class.java)
|
||||||
|
for (element in json) {
|
||||||
|
// var test = mapper.readValue(element.toString(), Array::class.java)
|
||||||
|
// TODO. This is ugly. how to Kotlin?
|
||||||
|
var id = element.toString().trimStart('[').trimStart('e').trimStart(',').trimEnd(']').trimStart().trimEnd()
|
||||||
|
|
||||||
|
var note = LocalCache.getNoteIfExists(id)
|
||||||
|
if (note != null) {
|
||||||
|
collection + note
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return collection
|
||||||
|
*/
|
||||||
|
return notes
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sort(collection: Set<Note>): List<Note> {
|
override fun sort(collection: Set<Note>): List<Note> {
|
||||||
|
@@ -227,11 +227,13 @@ fun AppNavigation(
|
|||||||
route.route,
|
route.route,
|
||||||
route.arguments,
|
route.arguments,
|
||||||
content = {
|
content = {
|
||||||
NIP90ContentDiscoveryScreen(
|
it.arguments?.getString("id")?.let { it1 ->
|
||||||
DVMID = it.arguments?.getString("id"),
|
NIP90ContentDiscoveryScreen(
|
||||||
accountViewModel = accountViewModel,
|
DVMID = it1,
|
||||||
nav = nav,
|
accountViewModel = accountViewModel,
|
||||||
)
|
nav = nav,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -22,8 +22,6 @@ package com.vitorpamplona.amethyst.ui.note.types
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
@@ -32,7 +30,6 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
|
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
|
||||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||||
@@ -42,7 +39,6 @@ import com.vitorpamplona.amethyst.ui.note.ReplyNoteComposition
|
|||||||
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
|
||||||
import com.vitorpamplona.quartz.events.BaseTextNoteEvent
|
import com.vitorpamplona.quartz.events.BaseTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.CommunityDefinitionEvent
|
import com.vitorpamplona.quartz.events.CommunityDefinitionEvent
|
||||||
import com.vitorpamplona.quartz.events.EmptyTagList
|
import com.vitorpamplona.quartz.events.EmptyTagList
|
||||||
@@ -66,20 +62,6 @@ fun RenderNIP90ContentDiscoveryResponse(
|
|||||||
val noteEvent = note.event
|
val noteEvent = note.event
|
||||||
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
||||||
|
|
||||||
if (noteEvent != null) {
|
|
||||||
TranslatableRichTextViewer(
|
|
||||||
content = noteEvent.content(),
|
|
||||||
canPreview = canPreview && !makeItShort,
|
|
||||||
quotesLeft = quotesLeft,
|
|
||||||
modifier = modifier,
|
|
||||||
tags = noteEvent.tags().toImmutableListOfLists(),
|
|
||||||
backgroundColor = backgroundColor,
|
|
||||||
id = note.idHex,
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
nav = nav,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val showReply by
|
val showReply by
|
||||||
remember(note) {
|
remember(note) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
@@ -140,42 +122,33 @@ fun RenderNIP90ContentDiscoveryResponse(
|
|||||||
val isAuthorTheLoggedUser =
|
val isAuthorTheLoggedUser =
|
||||||
remember(note.event) { accountViewModel.isLoggedUser(note.author) }
|
remember(note.event) { accountViewModel.isLoggedUser(note.author) }
|
||||||
|
|
||||||
if (makeItShort && isAuthorTheLoggedUser) {
|
SensitivityWarning(
|
||||||
Text(
|
note = note,
|
||||||
text = eventContent,
|
accountViewModel = accountViewModel,
|
||||||
color = MaterialTheme.colorScheme.placeholderText,
|
) {
|
||||||
maxLines = 2,
|
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
||||||
overflow = TextOverflow.Ellipsis,
|
val tags =
|
||||||
)
|
remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||||
} else {
|
|
||||||
SensitivityWarning(
|
TranslatableRichTextViewer(
|
||||||
note = note,
|
content = eventContent,
|
||||||
|
canPreview = canPreview && !makeItShort,
|
||||||
|
quotesLeft = quotesLeft,
|
||||||
|
modifier = modifier,
|
||||||
|
tags = tags,
|
||||||
|
backgroundColor = backgroundColor,
|
||||||
|
id = note.idHex,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) {
|
nav = nav,
|
||||||
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
)
|
||||||
val tags =
|
}
|
||||||
remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
|
||||||
|
|
||||||
TranslatableRichTextViewer(
|
if (note.event?.hasHashtags() == true) {
|
||||||
content = eventContent,
|
val hashtags =
|
||||||
canPreview = canPreview && !makeItShort,
|
remember(note.event) {
|
||||||
quotesLeft = quotesLeft,
|
note.event?.hashtags()?.toImmutableList() ?: persistentListOf()
|
||||||
modifier = modifier,
|
}
|
||||||
tags = tags,
|
DisplayUncitedHashtags(hashtags, eventContent, nav)
|
||||||
backgroundColor = backgroundColor,
|
|
||||||
id = note.idHex,
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
nav = nav,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note.event?.hasHashtags() == true) {
|
|
||||||
val hashtags =
|
|
||||||
remember(note.event) {
|
|
||||||
note.event?.hashtags()?.toImmutableList() ?: persistentListOf()
|
|
||||||
}
|
|
||||||
DisplayUncitedHashtags(hashtags, eventContent, nav)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -283,12 +283,12 @@ class NostrBookmarkPrivateFeedViewModel(val account: Account) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class NostrNIP90ContentDiscoveryFeedViewModel(val account: Account) :
|
class NostrNIP90ContentDiscoveryFeedViewModel(val account: Account, val dvmkey: String) :
|
||||||
// FeedViewModel(BookmarkPrivateFeedFilter(account)) {
|
// FeedViewModel(BookmarkPrivateFeedFilter(account)) {
|
||||||
FeedViewModel(NIP90ContentDiscoveryFilter(account)) {
|
FeedViewModel(NIP90ContentDiscoveryFilter(account, dvmkey)) {
|
||||||
class Factory(val account: Account) : ViewModelProvider.Factory {
|
class Factory(val account: Account, val dvmkey: String) : ViewModelProvider.Factory {
|
||||||
override fun <NostrNIP90ContentDiscoveryFeedViewModel : ViewModel> create(modelClass: Class<NostrNIP90ContentDiscoveryFeedViewModel>): NostrNIP90ContentDiscoveryFeedViewModel {
|
override fun <NostrNIP90ContentDiscoveryFeedViewModel : ViewModel> create(modelClass: Class<NostrNIP90ContentDiscoveryFeedViewModel>): NostrNIP90ContentDiscoveryFeedViewModel {
|
||||||
return NostrNIP90ContentDiscoveryFeedViewModel(account) as NostrNIP90ContentDiscoveryFeedViewModel
|
return NostrNIP90ContentDiscoveryFeedViewModel(account, dvmkey) as NostrNIP90ContentDiscoveryFeedViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,22 +33,25 @@ import androidx.compose.runtime.livedata.observeAsState
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.Client
|
||||||
import com.vitorpamplona.amethyst.ui.screen.NostrNIP90ContentDiscoveryFeedViewModel
|
import com.vitorpamplona.amethyst.ui.screen.NostrNIP90ContentDiscoveryFeedViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView
|
import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView
|
||||||
|
import com.vitorpamplona.quartz.events.NIP90ContentDiscoveryRequestEvent
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NIP90ContentDiscoveryScreen(
|
fun NIP90ContentDiscoveryScreen(
|
||||||
DVMID: String?,
|
DVMID: String,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
val resultFeedViewModel: NostrNIP90ContentDiscoveryFeedViewModel =
|
val resultFeedViewModel: NostrNIP90ContentDiscoveryFeedViewModel =
|
||||||
viewModel(
|
viewModel(
|
||||||
key = "NostrNIP90ContentDiscoveryFeedViewModel",
|
key = "NostrNIP90ContentDiscoveryFeedViewModel",
|
||||||
factory = NostrNIP90ContentDiscoveryFeedViewModel.Factory(accountViewModel.account),
|
factory = NostrNIP90ContentDiscoveryFeedViewModel.Factory(accountViewModel.account, dvmkey = DVMID),
|
||||||
)
|
)
|
||||||
|
|
||||||
val userState by accountViewModel.account.decryptBookmarks.observeAsState()
|
val userState by accountViewModel.account.decryptBookmarks.observeAsState() // TODO
|
||||||
|
|
||||||
LaunchedEffect(userState) {
|
LaunchedEffect(userState) {
|
||||||
resultFeedViewModel.invalidateData()
|
resultFeedViewModel.invalidateData()
|
||||||
@@ -75,26 +78,33 @@ private fun RenderNostrNIP90ContentDiscoveryScreen(
|
|||||||
|
|
||||||
if (DVMID != null) {
|
if (DVMID != null) {
|
||||||
// TODO 1 Send KIND 5300 Event with p tag = DVMID (crashes, because cant map to event)
|
// TODO 1 Send KIND 5300 Event with p tag = DVMID (crashes, because cant map to event)
|
||||||
|
val thread =
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
NIP90ContentDiscoveryRequestEvent.create(DVMID, accountViewModel.account.signer) {
|
||||||
|
Client.send(it)
|
||||||
|
LocalCache.justConsume(it, null)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*NIP90ContentDiscoveryRequestEvent.create(DVMID, accountViewModel.account.signer) {
|
thread.start()
|
||||||
Client.send(it)
|
}
|
||||||
LocalCache.justConsume(it, null)
|
// var keyPair = accountViewModel.account.keyPair
|
||||||
}*/
|
|
||||||
|
|
||||||
// var keyPair = accountViewModel.account.keyPair
|
// TODO 2 PARSE AND LOAD RESULTS FROM KIND 6300 REPLY to resultfeedmodel (RN this doesnt show events)
|
||||||
|
|
||||||
// TODO 2 PARSE AND LOAD RESULTS FROM KIND 6300 REPLY to resultfeedmodel (RN this doesnt show events)
|
// TODO 3 Render Results (hopefully works when 2 is working)
|
||||||
|
|
||||||
// TODO 3 Render Results (hopefully works when 2 is working)
|
HorizontalPager(state = pagerState) {
|
||||||
|
RefresheableFeedView(
|
||||||
HorizontalPager(state = pagerState) {
|
resultFeedViewModel,
|
||||||
RefresheableFeedView(
|
null,
|
||||||
resultFeedViewModel,
|
accountViewModel = accountViewModel,
|
||||||
null,
|
nav = nav,
|
||||||
accountViewModel = accountViewModel,
|
)
|
||||||
nav = nav,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user