From 58a98f68aef7afd5c70f18b786da473b2b6112f5 Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Tue, 5 May 2026 20:14:11 +0200 Subject: [PATCH] Feed syncs events from twelveHours --- .../1.json | 18 +++++++++-- .../dao/BroadcastNostrEventRequestDao.kt | 6 ++-- .../compose/database/dao/NostrEventDao.kt | 18 +++++++---- .../model/BroadcastNostrEventRequest.kt | 9 +++++- .../repository/DatabaseNostrRepository.kt | 30 +++++++++++++++---- .../compose/ui/view/model/HomeViewModel.kt | 10 +++---- 6 files changed, 69 insertions(+), 22 deletions(-) diff --git a/composeApp/schemas/ac.cord.auxiliary.compose.database.AuxDatabase/1.json b/composeApp/schemas/ac.cord.auxiliary.compose.database.AuxDatabase/1.json index 6fea3997..03251bd9 100644 --- a/composeApp/schemas/ac.cord.auxiliary.compose.database.AuxDatabase/1.json +++ b/composeApp/schemas/ac.cord.auxiliary.compose.database.AuxDatabase/1.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "e3fd82a42262f8b5acb481175a99a3e0", + "identityHash": "49c580a762a1c128bf5b4fc6f93eeea4", "entities": [ { "tableName": "BroadcastNostrEventReceipt", @@ -96,7 +96,7 @@ }, { "tableName": "BroadcastNostrEventRequest", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nostrEventId` TEXT NOT NULL, `unsignedNostrEventId` INTEGER, `status` TEXT NOT NULL, `relayURL` TEXT NOT NULL, 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` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nostrEventId` TEXT NOT NULL, `unsignedNostrEventId` INTEGER, `status` TEXT NOT NULL, `relayURL` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, 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": [ { "fieldPath": "id", @@ -126,6 +126,18 @@ "columnName": "relayURL", "affinity": "TEXT", "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updatedAt", + "columnName": "updatedAt", + "affinity": "INTEGER", + "notNull": true } ], "primaryKey": { @@ -2054,7 +2066,7 @@ ], "setupQueries": [ "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, 'e3fd82a42262f8b5acb481175a99a3e0')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '49c580a762a1c128bf5b4fc6f93eeea4')" ] } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/BroadcastNostrEventRequestDao.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/BroadcastNostrEventRequestDao.kt index c41f5fad..305b4757 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/BroadcastNostrEventRequestDao.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/BroadcastNostrEventRequestDao.kt @@ -7,14 +7,16 @@ import androidx.room3.Insert import androidx.room3.Query import androidx.room3.Upsert import kotlinx.coroutines.flow.Flow +import kotlin.time.Clock +import kotlin.time.Instant @Dao interface BroadcastNostrEventRequestDao { @Query("SELECT * FROM BroadcastNostrEventRequest") fun getAllBroadcastNostrEventRequests(): List - @Query("SELECT * FROM BroadcastNostrEventRequest WHERE status = :status") - fun observeBroadcastNostrEventRequestsByStatus(status: String): Flow> + @Query("SELECT * FROM BroadcastNostrEventRequest WHERE status = :status AND createdAt > :createdAt") + fun observeBroadcastNostrEventRequestsByStatus(status: String, createdAt: Instant = Clock.System.now()): Flow> @Query("SELECT * FROM BroadcastNostrEventRequest WHERE nostrEventId = :nostrEventId") fun observeBroadcastNostrEventRequestByNostrEventId(nostrEventId: String): Flow diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/NostrEventDao.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/NostrEventDao.kt index 41f6c986..745c0a04 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/NostrEventDao.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/dao/NostrEventDao.kt @@ -69,7 +69,7 @@ interface NostrEventDao { @Query("SELECT * FROM NostrEvent WHERE kind in (:kinds) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit") fun getNostrEvents( kinds: Array, - since: Instant = GENESIS_AT, + since: Instant, limit: Int ): List @@ -78,7 +78,7 @@ interface NostrEventDao { fun getFilteredNostrEvents( kinds: Array, search: String, - since: Instant = GENESIS_AT, + since: Instant, limit: Int ): List @@ -87,7 +87,15 @@ interface NostrEventDao { fun getFilteredNostrEvents( kinds: Array, ids: Array, - since: Instant = GENESIS_AT, + since: Instant, + limit: Int + ): List + + @Transaction + @Query("SELECT * FROM NostrEvent WHERE id in (:ids) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit") + fun getNostrEventsByIds( + ids: Array, + since: Instant, limit: Int ): List @@ -96,7 +104,7 @@ interface NostrEventDao { fun getAuthoredNostrEvents( kinds: Array, authors: Array, - since: Instant = GENESIS_AT, + since: Instant, limit: Int ): List @@ -105,7 +113,7 @@ interface NostrEventDao { fun getPublicKeyMentionedNostrEvents( kinds: Array, publicKey: HexKey, - since: Instant = GENESIS_AT, + since: Instant, limit: Int ): List diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/model/BroadcastNostrEventRequest.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/model/BroadcastNostrEventRequest.kt index 920bc8f7..32a1be64 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/model/BroadcastNostrEventRequest.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/model/BroadcastNostrEventRequest.kt @@ -1,12 +1,16 @@ package ac.cord.auxiliary.compose.database.model import ac.cord.auxiliary.compose.database.model.traits.NostrEventEntity +import ac.cord.auxiliary.compose.database.model.traits.TimestampedEntity import ac.cord.auxiliary.compose.database.model.traits.UnsignedNostrEventEntity +import ac.cord.auxiliary.compose.network.serialization.encodeToJsonString import androidx.room3.Entity import androidx.room3.ForeignKey import androidx.room3.Index import androidx.room3.PrimaryKey import com.vitorpamplona.quartz.nip01Core.core.HexKey +import kotlin.time.Clock +import kotlin.time.Instant @Entity( foreignKeys = [ @@ -35,4 +39,7 @@ data class BroadcastNostrEventRequest( override val unsignedNostrEventId: Long? = null, val status: String = "pending", val relayURL: String, -): NostrEventEntity, UnsignedNostrEventEntity \ No newline at end of file + + override val createdAt: Instant = Clock.System.now(), + override val updatedAt: Instant = Clock.System.now(), +): NostrEventEntity, UnsignedNostrEventEntity, TimestampedEntity \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/repository/DatabaseNostrRepository.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/repository/DatabaseNostrRepository.kt index 6362ec38..64d49d05 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/repository/DatabaseNostrRepository.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/database/repository/DatabaseNostrRepository.kt @@ -62,6 +62,7 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlin.collections.emptyMap import kotlin.collections.plus +import kotlin.math.sin import kotlin.time.Clock import kotlin.time.Instant @@ -563,10 +564,11 @@ class DatabaseNostrRepository( return when { synchronizationFilter.kinds != null && synchronizationFilter.search != null -> { - logger.d("observeFilteredNostrEvents: $synchronizationFilter") + logger.d("getFilteredNostrEvents($applyLimits): $synchronizationFilter") database.nostrEventDao().getFilteredNostrEvents( kinds = synchronizationFilter.kinds, search = synchronizationFilter.search, + since = synchronizationFilter.since ?: GENESIS_AT, limit = if (applyLimits) { synchronizationFilter.limit ?: 50 } else { @@ -575,10 +577,23 @@ class DatabaseNostrRepository( ) } synchronizationFilter.kinds != null && synchronizationFilter.ids != null -> { - logger.d("observeFilteredNostrEvents: $synchronizationFilter") + logger.d("getFilteredNostrEvents($applyLimits): $synchronizationFilter") database.nostrEventDao().getFilteredNostrEvents( kinds = synchronizationFilter.kinds, ids = synchronizationFilter.ids, + since = synchronizationFilter.since ?: GENESIS_AT, + limit = if (applyLimits) { + synchronizationFilter.limit ?: 50 + } else { + -1 + } + ) + } + synchronizationFilter.ids != null -> { + logger.d("getNostrEventsByIds($applyLimits): $synchronizationFilter") + database.nostrEventDao().getNostrEventsByIds( + ids = synchronizationFilter.ids, + since = synchronizationFilter.since ?: GENESIS_AT, limit = if (applyLimits) { synchronizationFilter.limit ?: 50 } else { @@ -587,10 +602,11 @@ class DatabaseNostrRepository( ) } synchronizationFilter.kinds != null && synchronizationFilter.authors != null -> { - logger.d("observeAuthoredNostrEvents: $synchronizationFilter") + logger.d("getAuthoredNostrEvents($applyLimits): $synchronizationFilter") database.nostrEventDao().getAuthoredNostrEvents( kinds = synchronizationFilter.kinds, authors = synchronizationFilter.authors, + since = synchronizationFilter.since ?: GENESIS_AT, limit = if (applyLimits) { synchronizationFilter.limit ?: 50 } else { @@ -599,7 +615,7 @@ class DatabaseNostrRepository( ) } synchronizationFilter.kinds != null && synchronizationFilter.since != null && synchronizationFilter.tags?.contains("e") == true && synchronizationFilter.tags["e"]?.first()?.isNotEmpty() == true -> { - logger.d("observePublicKeyMentionedNostrEvents: $synchronizationFilter") + logger.d("getNostrEventReplies($applyLimits): $synchronizationFilter") database.nostrEventDao().getNostrEventReplies( kinds = synchronizationFilter.kinds, eventId = synchronizationFilter.tags["e"]?.first()!!, @@ -612,10 +628,11 @@ class DatabaseNostrRepository( ) } synchronizationFilter.kinds != null && synchronizationFilter.tags?.contains("p") == true && synchronizationFilter.tags["p"]?.first()?.isNotEmpty() == true -> { - logger.d("observePublicKeyMentionedNostrEvents: $synchronizationFilter") + logger.d("getPublicKeyMentionedNostrEvents($applyLimits): $synchronizationFilter") database.nostrEventDao().getPublicKeyMentionedNostrEvents( kinds = synchronizationFilter.kinds, publicKey = synchronizationFilter.tags["p"]?.first()!!, + since = synchronizationFilter.since ?: GENESIS_AT, limit = if (applyLimits) { synchronizationFilter.limit ?: 50 } else { @@ -624,11 +641,12 @@ class DatabaseNostrRepository( ) } else -> { - logger.d("NostrEvent: $synchronizationFilter") + logger.d("getNostrEvents($applyLimits): $synchronizationFilter") database.nostrEventDao().getNostrEvents( kinds = arrayOf( TextNoteEvent.KIND, ), + since = synchronizationFilter.since ?: GENESIS_AT, limit = if (applyLimits) { synchronizationFilter.limit ?: 50 } else { diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/HomeViewModel.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/HomeViewModel.kt index 60fe987e..0ea3c987 100755 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/HomeViewModel.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/HomeViewModel.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.launch import kotlin.time.Clock -import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.hours enum class HomeScreenType { Following, Mentions, Messages @@ -77,7 +77,7 @@ class HomeViewModel( ): SynchronizationFilter { val publicKey = SeedManager.activePublicKey().toHexKey() - val threeDaysAgo = Clock.System.now().minus(3.days) + val twelveHoursAgo = Clock.System.now().minus(12.hours) val now = Clock.System.now() return when (homeScreenType) { @@ -88,7 +88,7 @@ class HomeViewModel( TextNoteEvent.KIND, RepostEvent.KIND, ), - since = threeDaysAgo, + since = twelveHoursAgo, until = now, limit = 50 ) @@ -109,7 +109,7 @@ class HomeViewModel( tags = mapOf( Pair("p", listOf(publicKey)) ), - since = threeDaysAgo, + since = twelveHoursAgo, until = now, limit = 50 ) @@ -122,7 +122,7 @@ class HomeViewModel( kinds = arrayOf( LongTextNoteEvent.KIND, ), - since = threeDaysAgo, + since = twelveHoursAgo, until = now, limit = 50 )