Have FilterArray.kt in persisted sync event
This commit is contained in:
1 parent
4e23206537
commit
2beed5e18a
11 files changed
+165
-139
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "40dc44925e9b6000404e2cc5e781e4c2",
|
"identityHash": "ba8dabe94c38a3823b4803dc0a6051ca",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "BroadcastNostrEventReceipt",
|
"tableName": "BroadcastNostrEventReceipt",
|
||||||
@@ -873,7 +873,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "SynchronizeNostrEventRequest",
|
"tableName": "SynchronizeNostrEventRequest",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `status` TEXT NOT NULL, `relayURL` TEXT NOT NULL, `eventIds` TEXT, `authorPublicKeys` TEXT, `kinds` TEXT, `tagName` TEXT, `since` INTEGER, `until` INTEGER, `limit` INTEGER, `search` TEXT, `nostrEventId` TEXT, `unsignedNostrEventId` INTEGER, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`nostrEventId`) REFERENCES `NostrEvent`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`unsignedNostrEventId`) REFERENCES `UnsignedNostrEvent`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `status` TEXT NOT NULL, `relayURL` TEXT NOT NULL, `filters` TEXT NOT NULL, `nostrEventId` TEXT, `unsignedNostrEventId` INTEGER, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`nostrEventId`) REFERENCES `NostrEvent`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`unsignedNostrEventId`) REFERENCES `UnsignedNostrEvent`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@@ -894,44 +894,10 @@
|
|||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "eventIds",
|
"fieldPath": "filters",
|
||||||
"columnName": "eventIds",
|
"columnName": "filters",
|
||||||
"affinity": "TEXT"
|
"affinity": "TEXT",
|
||||||
},
|
"notNull": true
|
||||||
{
|
|
||||||
"fieldPath": "authorPublicKeys",
|
|
||||||
"columnName": "authorPublicKeys",
|
|
||||||
"affinity": "TEXT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "kinds",
|
|
||||||
"columnName": "kinds",
|
|
||||||
"affinity": "TEXT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "tagName",
|
|
||||||
"columnName": "tagName",
|
|
||||||
"affinity": "TEXT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "since",
|
|
||||||
"columnName": "since",
|
|
||||||
"affinity": "INTEGER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "until",
|
|
||||||
"columnName": "until",
|
|
||||||
"affinity": "INTEGER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "limit",
|
|
||||||
"columnName": "limit",
|
|
||||||
"affinity": "INTEGER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "search",
|
|
||||||
"columnName": "search",
|
|
||||||
"affinity": "TEXT"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "nostrEventId",
|
"fieldPath": "nostrEventId",
|
||||||
@@ -1340,7 +1306,7 @@
|
|||||||
],
|
],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '40dc44925e9b6000404e2cc5e781e4c2')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ba8dabe94c38a3823b4803dc0a6051ca')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package ac.aux.compose.database.converters
|
package ac.aux.compose.database.converters
|
||||||
|
|
||||||
|
import ac.aux.compose.database.model.typealiases.FilterArray
|
||||||
import ac.aux.compose.database.model.typealiases.HexArray
|
import ac.aux.compose.database.model.typealiases.HexArray
|
||||||
import ac.aux.compose.database.model.typealiases.KindArray
|
import ac.aux.compose.database.model.typealiases.KindArray
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import co.touchlab.kermit.Logger
|
import co.touchlab.kermit.Logger
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
import kotlin.time.Instant
|
import kotlin.time.Instant
|
||||||
|
|
||||||
class AuxConverters {
|
class AuxConverters {
|
||||||
@@ -73,4 +77,28 @@ class AuxConverters {
|
|||||||
logger.e("Failed to convert to KindArray $value", e)
|
logger.e("Failed to convert to KindArray $value", e)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromFilterArray(value: FilterArray?): String? = try {
|
||||||
|
return value?.let { filterArray ->
|
||||||
|
Json.encodeToString(
|
||||||
|
filterArray.map { filter ->
|
||||||
|
OptimizedJsonMapper.toJson(filter)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.e("Failed to convert from FilterArray $value", e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toFilterArray(value: String?): FilterArray? = try {
|
||||||
|
return value?.let {
|
||||||
|
Json.decodeFromString<FilterArray>(it)
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.e("Failed to convert to FilterArray $value", e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,7 @@ import androidx.room.Relation
|
|||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import co.touchlab.kermit.Logger
|
import co.touchlab.kermit.Logger
|
||||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlin.time.Clock
|
import kotlin.time.Clock
|
||||||
|
|
||||||
@@ -109,8 +110,12 @@ abstract class NostrDao(
|
|||||||
logger.i("Sync Profile with PubKey: ${nostrEvent.pubKey}")
|
logger.i("Sync Profile with PubKey: ${nostrEvent.pubKey}")
|
||||||
database.synchronizeNostrEventRequestDao().upsert(
|
database.synchronizeNostrEventRequestDao().upsert(
|
||||||
SynchronizeNostrEventRequest(
|
SynchronizeNostrEventRequest(
|
||||||
authorPublicKeys = arrayOf(nostrEvent.pubKey),
|
filters = arrayOf(
|
||||||
kinds = arrayOf(0),
|
Filter(
|
||||||
|
authors = listOf(nostrEvent.pubKey),
|
||||||
|
kinds = listOf(MetadataEvent.KIND)
|
||||||
|
)
|
||||||
|
),
|
||||||
relayURL = synchronizationRelayURL
|
relayURL = synchronizationRelayURL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -150,7 +155,11 @@ abstract class NostrDao(
|
|||||||
synchronizationRelayURLs.forEach { synchronizationRelayURL ->
|
synchronizationRelayURLs.forEach { synchronizationRelayURL ->
|
||||||
database.synchronizeNostrEventRequestDao().upsert(
|
database.synchronizeNostrEventRequestDao().upsert(
|
||||||
SynchronizeNostrEventRequest(
|
SynchronizeNostrEventRequest(
|
||||||
eventIds = arrayOf(post.replyToId),
|
filters = arrayOf(
|
||||||
|
Filter(
|
||||||
|
ids = listOf(post.replyToId)
|
||||||
|
)
|
||||||
|
),
|
||||||
relayURL = synchronizationRelayURL
|
relayURL = synchronizationRelayURL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -175,7 +184,11 @@ abstract class NostrDao(
|
|||||||
synchronizationRelayURLs.forEach { synchronizationRelayURL ->
|
synchronizationRelayURLs.forEach { synchronizationRelayURL ->
|
||||||
database.synchronizeNostrEventRequestDao().upsert(
|
database.synchronizeNostrEventRequestDao().upsert(
|
||||||
SynchronizeNostrEventRequest(
|
SynchronizeNostrEventRequest(
|
||||||
eventIds = arrayOf(post.repostId),
|
filters = arrayOf(
|
||||||
|
Filter(
|
||||||
|
ids = listOf(post.repostId)
|
||||||
|
)
|
||||||
|
),
|
||||||
relayURL = synchronizationRelayURL
|
relayURL = synchronizationRelayURL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import kotlin.time.Instant
|
|||||||
Index("nostrEventId"),
|
Index("nostrEventId"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Profile(
|
data class Profile(
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
val publicKey: String,
|
val publicKey: String,
|
||||||
|
|||||||
+8
-23
@@ -3,6 +3,7 @@ package ac.aux.compose.database.model
|
|||||||
import ac.aux.compose.database.model.traits.OptionalNostrEventEntity
|
import ac.aux.compose.database.model.traits.OptionalNostrEventEntity
|
||||||
import ac.aux.compose.database.model.traits.TimestampedEntity
|
import ac.aux.compose.database.model.traits.TimestampedEntity
|
||||||
import ac.aux.compose.database.model.traits.UnsignedNostrEventEntity
|
import ac.aux.compose.database.model.traits.UnsignedNostrEventEntity
|
||||||
|
import ac.aux.compose.database.model.typealiases.FilterArray
|
||||||
import ac.aux.compose.database.model.typealiases.HexArray
|
import ac.aux.compose.database.model.typealiases.HexArray
|
||||||
import ac.aux.compose.database.model.typealiases.KindArray
|
import ac.aux.compose.database.model.typealiases.KindArray
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@@ -10,6 +11,7 @@ import androidx.room.ForeignKey
|
|||||||
import androidx.room.Index
|
import androidx.room.Index
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import kotlin.time.Clock
|
import kotlin.time.Clock
|
||||||
import kotlin.time.Instant
|
import kotlin.time.Instant
|
||||||
import kotlin.uuid.ExperimentalUuidApi
|
import kotlin.uuid.ExperimentalUuidApi
|
||||||
@@ -41,14 +43,8 @@ data class SynchronizeNostrEventRequest(
|
|||||||
val id: String = Uuid.generateV4().toHexDashString(),
|
val id: String = Uuid.generateV4().toHexDashString(),
|
||||||
val status: String = "pending",
|
val status: String = "pending",
|
||||||
val relayURL: String,
|
val relayURL: String,
|
||||||
val eventIds: HexArray? = null,
|
|
||||||
val authorPublicKeys: HexArray? = null, // TODO: PublicKeyArray
|
val filters: FilterArray,
|
||||||
val kinds: KindArray? = null, // TODO: KindArray
|
|
||||||
val tagName: String? = null,
|
|
||||||
val since: Instant? = null,
|
|
||||||
val until: Instant? = null,
|
|
||||||
val limit: Int? = null,
|
|
||||||
val search: String? = null,
|
|
||||||
|
|
||||||
override val nostrEventId: HexKey? = null,
|
override val nostrEventId: HexKey? = null,
|
||||||
override val unsignedNostrEventId: Long? = null,
|
override val unsignedNostrEventId: Long? = null,
|
||||||
@@ -61,17 +57,11 @@ data class SynchronizeNostrEventRequest(
|
|||||||
|
|
||||||
other as SynchronizeNostrEventRequest
|
other as SynchronizeNostrEventRequest
|
||||||
|
|
||||||
if (limit != other.limit) return false
|
|
||||||
if (unsignedNostrEventId != other.unsignedNostrEventId) return false
|
if (unsignedNostrEventId != other.unsignedNostrEventId) return false
|
||||||
if (id != other.id) return false
|
if (id != other.id) return false
|
||||||
if (status != other.status) return false
|
if (status != other.status) return false
|
||||||
if (relayURL != other.relayURL) return false
|
if (relayURL != other.relayURL) return false
|
||||||
if (!eventIds.contentEquals(other.eventIds)) return false
|
if (!filters.contentEquals(other.filters)) return false
|
||||||
if (!authorPublicKeys.contentEquals(other.authorPublicKeys)) return false
|
|
||||||
if (!kinds.contentEquals(other.kinds)) return false
|
|
||||||
if (tagName != other.tagName) return false
|
|
||||||
if (since != other.since) return false
|
|
||||||
if (until != other.until) return false
|
|
||||||
if (nostrEventId != other.nostrEventId) return false
|
if (nostrEventId != other.nostrEventId) return false
|
||||||
if (createdAt != other.createdAt) return false
|
if (createdAt != other.createdAt) return false
|
||||||
if (updatedAt != other.updatedAt) return false
|
if (updatedAt != other.updatedAt) return false
|
||||||
@@ -80,20 +70,15 @@ data class SynchronizeNostrEventRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = limit?.hashCode() ?: 0
|
var result = unsignedNostrEventId?.hashCode() ?: 0
|
||||||
result = 31 * result + (unsignedNostrEventId?.hashCode() ?: 0)
|
|
||||||
result = 31 * result + id.hashCode()
|
result = 31 * result + id.hashCode()
|
||||||
result = 31 * result + status.hashCode()
|
result = 31 * result + status.hashCode()
|
||||||
result = 31 * result + relayURL.hashCode()
|
result = 31 * result + relayURL.hashCode()
|
||||||
result = 31 * result + (eventIds?.contentHashCode() ?: 0)
|
result = 31 * result + filters.contentHashCode()
|
||||||
result = 31 * result + (authorPublicKeys?.contentHashCode() ?: 0)
|
|
||||||
result = 31 * result + (kinds?.contentHashCode() ?: 0)
|
|
||||||
result = 31 * result + (tagName?.hashCode() ?: 0)
|
|
||||||
result = 31 * result + (since?.hashCode() ?: 0)
|
|
||||||
result = 31 * result + (until?.hashCode() ?: 0)
|
|
||||||
result = 31 * result + (nostrEventId?.hashCode() ?: 0)
|
result = 31 * result + (nostrEventId?.hashCode() ?: 0)
|
||||||
result = 31 * result + createdAt.hashCode()
|
result = 31 * result + createdAt.hashCode()
|
||||||
result = 31 * result + updatedAt.hashCode()
|
result = 31 * result + updatedAt.hashCode()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -42,4 +42,4 @@ data class LocalProfile(
|
|||||||
)
|
)
|
||||||
val synchronizeNostrEventRequests: List<SynchronizeNostrEventRequest>,
|
val synchronizeNostrEventRequests: List<SynchronizeNostrEventRequest>,
|
||||||
|
|
||||||
)
|
)
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package ac.aux.compose.database.model.typealiases
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
|
||||||
|
typealias FilterArray = Array<Filter>
|
||||||
@@ -58,78 +58,85 @@ class NostrEventBroadcaster(
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val webSocketSession = httpClient.webSocketSession(
|
try {
|
||||||
urlString = localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL
|
val webSocketSession = httpClient.webSocketSession(
|
||||||
)
|
urlString = localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL
|
||||||
|
)
|
||||||
|
|
||||||
broadcastingJobs[localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL] = scope.launch {
|
broadcastingJobs[localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL] = scope.launch {
|
||||||
val message = OptimizedJsonMapper.toJson(
|
val message = OptimizedJsonMapper.toJson(
|
||||||
EventCmd(
|
EventCmd(
|
||||||
event
|
event
|
||||||
|
)
|
||||||
|
)
|
||||||
|
logger.d("Broadcasting (${localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL}): $message")
|
||||||
|
webSocketSession.send(
|
||||||
|
frame = Frame.Text(message)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
logger.d("Broadcasting (${localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL}): $message")
|
|
||||||
webSocketSession.send(
|
|
||||||
frame = Frame.Text(message)
|
|
||||||
)
|
|
||||||
|
|
||||||
onBroadcastRequestProcessed.invoke(localBroadcastNostrEventRequest.broadcastNostrEventRequest)
|
onBroadcastRequestProcessed.invoke(localBroadcastNostrEventRequest.broadcastNostrEventRequest)
|
||||||
|
|
||||||
webSocketSession.incoming.consumeAsFlow().collect { frame ->
|
webSocketSession.incoming.consumeAsFlow().collect { frame ->
|
||||||
when(frame) {
|
when(frame) {
|
||||||
is Frame.Text -> {
|
is Frame.Text -> {
|
||||||
frame.readText().let { text ->
|
frame.readText().let { text ->
|
||||||
try {
|
try {
|
||||||
logger.d("WebSocket Read Text: $text")
|
logger.d("WebSocket Read Text: $text")
|
||||||
val result = Json.decodeFromString<JsonArray>(text)
|
val result = Json.decodeFromString<JsonArray>(text)
|
||||||
|
|
||||||
if (result.firstOrNull()?.text == "OK") {
|
if (result.firstOrNull()?.text == "OK") {
|
||||||
result.getOrNull(1)?.text?.let { eventId ->
|
result.getOrNull(1)?.text?.let { eventId ->
|
||||||
if (eventId == localBroadcastNostrEventRequest.broadcastNostrEventRequest.nostrEventId) {
|
if (eventId == localBroadcastNostrEventRequest.broadcastNostrEventRequest.nostrEventId) {
|
||||||
|
|
||||||
onBroadcastReceipt.invoke(
|
onBroadcastReceipt.invoke(
|
||||||
BroadcastNostrEventReceipt(
|
BroadcastNostrEventReceipt(
|
||||||
nostrEventId = localBroadcastNostrEventRequest.broadcastNostrEventRequest.nostrEventId,
|
nostrEventId = localBroadcastNostrEventRequest.broadcastNostrEventRequest.nostrEventId,
|
||||||
unsignedNostrEventId = localBroadcastNostrEventRequest.broadcastNostrEventRequest.unsignedNostrEventId,
|
unsignedNostrEventId = localBroadcastNostrEventRequest.broadcastNostrEventRequest.unsignedNostrEventId,
|
||||||
messages = result.getOrNull(3)?.text,
|
messages = result.getOrNull(3)?.text,
|
||||||
isAccepted = result.getOrNull(2)?.text == "true",
|
isAccepted = result.getOrNull(2)?.text == "true",
|
||||||
relayURL = localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL
|
relayURL = localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.e("Error processing receipt: $text", e)
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
}
|
||||||
logger.e("Error processing receipt: $text", e)
|
webSocketSession.close()
|
||||||
|
broadcastingJobs.remove(localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL)?.let { job ->
|
||||||
|
job.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
webSocketSession.close()
|
is Frame.Close -> {
|
||||||
broadcastingJobs.remove(localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL)?.let { job ->
|
logger.d("Close $frame")
|
||||||
job.cancel()
|
}
|
||||||
|
is Frame.Ping -> {
|
||||||
|
logger.d("Ping: $frame")
|
||||||
|
}
|
||||||
|
is Frame.Pong -> {
|
||||||
|
logger.d("Pong: $frame")
|
||||||
|
}
|
||||||
|
is Frame.Binary -> {
|
||||||
|
logger.d("Binary Message: $frame")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
logger.d("Unsupported frame: $frame")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Frame.Close -> {
|
|
||||||
logger.d("Close $frame")
|
|
||||||
}
|
|
||||||
is Frame.Ping -> {
|
|
||||||
logger.d("Ping: $frame")
|
|
||||||
}
|
|
||||||
is Frame.Pong -> {
|
|
||||||
logger.d("Pong: $frame")
|
|
||||||
}
|
|
||||||
is Frame.Binary -> {
|
|
||||||
logger.d("Binary Message: $frame")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
logger.d("Unsupported frame: $frame")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.i("Websocket exit")
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.i("Websocket exit")
|
broadcastingJobs[localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL]?.join()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.e("Error broadcasting event: ", e)
|
||||||
|
// TODO: Save this a failure
|
||||||
|
onBroadcastRequestProcessed.invoke(localBroadcastNostrEventRequest.broadcastNostrEventRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcastingJobs[localBroadcastNostrEventRequest.broadcastNostrEventRequest.relayURL]?.join()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package ac.aux.compose.ui.view.model
|
package ac.aux.compose.ui.view.model
|
||||||
|
|
||||||
|
import ac.aux.compose.managers.SeedManager
|
||||||
import ac.aux.compose.repository.NostrRepository
|
import ac.aux.compose.repository.NostrRepository
|
||||||
import ac.aux.compose.ui.view.state.FeedListUIState
|
import ac.aux.compose.ui.view.state.FeedListUIState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -10,8 +11,15 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.lifecycle.viewmodel.initializer
|
import androidx.lifecycle.viewmodel.initializer
|
||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
|
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||||
|
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||||
|
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||||
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.IO
|
import kotlinx.coroutines.IO
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class FeedListViewModel(
|
class FeedListViewModel(
|
||||||
@@ -28,11 +36,28 @@ class FeedListViewModel(
|
|||||||
|
|
||||||
fun loadNostrFeed() {
|
fun loadNostrFeed() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val nostrFeed = nostrRepository.loadNostrFeed()
|
Filter(
|
||||||
|
kinds = listOf(
|
||||||
feedListUIState = FeedListUIState.Loaded(
|
TextNoteEvent.KIND,
|
||||||
nostrEvents = nostrFeed
|
RepostEvent.KIND,
|
||||||
|
ReactionEvent.KIND,
|
||||||
|
LnZapEvent.KIND,
|
||||||
|
),
|
||||||
|
tags = mapOf(
|
||||||
|
Pair("#p", listOf(SeedManager.activePublicKey().toHexKey()))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
val localProfile = nostrRepository.observeProfile(SeedManager.activePublicKey().toHexKey()).firstOrNull()
|
||||||
|
|
||||||
|
if (localProfile?.profile == null) {
|
||||||
|
feedListUIState = FeedListUIState.Error
|
||||||
|
} else {
|
||||||
|
val nostrFeed = nostrRepository.loadNostrFeed()
|
||||||
|
|
||||||
|
feedListUIState = FeedListUIState.Loaded(
|
||||||
|
nostrEvents = nostrFeed
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-11
@@ -147,17 +147,7 @@ class NavigationViewModel(
|
|||||||
logger.i("synchronizeNostrEventRequest: $synchronizeNostrEventRequest")
|
logger.i("synchronizeNostrEventRequest: $synchronizeNostrEventRequest")
|
||||||
val reqCommand = ReqCmd(
|
val reqCommand = ReqCmd(
|
||||||
subId = synchronizeNostrEventRequest.id,
|
subId = synchronizeNostrEventRequest.id,
|
||||||
filters = listOf(
|
filters = synchronizeNostrEventRequest.filters.toList()
|
||||||
Filter(
|
|
||||||
ids = synchronizeNostrEventRequest.eventIds?.map { eventId -> eventId },
|
|
||||||
authors = synchronizeNostrEventRequest.authorPublicKeys?.map { authorPublicKey -> authorPublicKey },
|
|
||||||
kinds = synchronizeNostrEventRequest.kinds?.map { kind -> kind },
|
|
||||||
since = synchronizeNostrEventRequest.since?.epochSeconds,
|
|
||||||
until = synchronizeNostrEventRequest.until?.epochSeconds,
|
|
||||||
limit = synchronizeNostrEventRequest.limit,
|
|
||||||
search = synchronizeNostrEventRequest.search
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|||||||
+8
-2
@@ -13,6 +13,8 @@ import androidx.lifecycle.viewmodel.initializer
|
|||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import co.touchlab.kermit.Logger
|
import co.touchlab.kermit.Logger
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.entities.Entity
|
import com.vitorpamplona.quartz.nip19Bech32.entities.Entity
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||||
@@ -58,9 +60,13 @@ class UnqueuedProfileSynchronizationViewModel(
|
|||||||
nostrRepository.queueSynchronizeNostrEvent(
|
nostrRepository.queueSynchronizeNostrEvent(
|
||||||
Relays.eventPublishRelaySet.map { normalizedRelayUrl ->
|
Relays.eventPublishRelaySet.map { normalizedRelayUrl ->
|
||||||
SynchronizeNostrEventRequest(
|
SynchronizeNostrEventRequest(
|
||||||
authorPublicKeys = arrayOf(profilePublicKey),
|
filters = arrayOf(
|
||||||
|
Filter(
|
||||||
|
authors = listOf(profilePublicKey),
|
||||||
|
kinds = listOf(MetadataEvent.KIND)
|
||||||
|
)
|
||||||
|
),
|
||||||
unsignedNostrEventId = unsignedNostrEventId,
|
unsignedNostrEventId = unsignedNostrEventId,
|
||||||
kinds = arrayOf(0),
|
|
||||||
relayURL = normalizedRelayUrl.url
|
relayURL = normalizedRelayUrl.url
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user