feat: word-based message filtering with quarantine approach (stored but hidden) (#4241)

This commit is contained in:
Mac DeCourcy 2026-01-24 08:41:17 -08:00 committed by GitHub
parent ae65e64a37
commit c0f8ed3503
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 2187 additions and 115 deletions

View file

@ -101,21 +101,30 @@ constructor(
suspend fun insert(packet: Packet) =
withContext(dispatchers.io) { dbManager.currentDb.value.packetDao().insert(packet) }
suspend fun getMessagesFrom(contact: String, limit: Int? = null, getNode: suspend (String?) -> Node) =
withContext(dispatchers.io) {
val dao = dbManager.currentDb.value.packetDao()
val flow = if (limit != null) dao.getMessagesFrom(contact, limit) else dao.getMessagesFrom(contact)
flow.mapLatest { packets ->
packets.map { packet ->
val message = packet.toMessage(getNode)
message.replyId
.takeIf { it != null && it != 0 }
?.let { getPacketByPacketId(it) }
?.toMessage(getNode)
?.let { originalMessage -> message.copy(originalMessage = originalMessage) } ?: message
}
suspend fun getMessagesFrom(
contact: String,
limit: Int? = null,
includeFiltered: Boolean = true,
getNode: suspend (String?) -> Node,
) = withContext(dispatchers.io) {
val dao = dbManager.currentDb.value.packetDao()
val flow =
when {
limit != null -> dao.getMessagesFrom(contact, limit)
!includeFiltered -> dao.getMessagesFrom(contact, includeFiltered = false)
else -> dao.getMessagesFrom(contact)
}
flow.mapLatest { packets ->
packets.map { packet ->
val message = packet.toMessage(getNode)
message.replyId
.takeIf { it != null && it != 0 }
?.let { getPacketByPacketId(it) }
?.toMessage(getNode)
?.let { originalMessage -> message.copy(originalMessage = originalMessage) } ?: message
}
}
}
fun getMessagesFromPaged(contact: String, getNode: suspend (String?) -> Node): Flow<PagingData<Message>> = Pager(
config =
@ -286,6 +295,43 @@ constructor(
suspend fun findReactionsWithId(packetId: Int) =
withContext(dispatchers.io) { dbManager.currentDb.value.packetDao().findReactionsWithId(packetId) }
fun getFilteredCountFlow(contactKey: String): Flow<Int> =
dbManager.currentDb.flatMapLatest { db -> db.packetDao().getFilteredCountFlow(contactKey) }
suspend fun getFilteredCount(contactKey: String): Int =
withContext(dispatchers.io) { dbManager.currentDb.value.packetDao().getFilteredCount(contactKey) }
fun getMessagesFromPaged(
contactKey: String,
includeFiltered: Boolean,
getNode: suspend (String?) -> Node,
): Flow<PagingData<Message>> = Pager(
config =
PagingConfig(
pageSize = MESSAGES_PAGE_SIZE,
enablePlaceholders = false,
initialLoadSize = MESSAGES_PAGE_SIZE,
),
pagingSourceFactory = {
dbManager.currentDb.value.packetDao().getMessagesFromPaged(contactKey, includeFiltered)
},
)
.flow
.map { pagingData ->
pagingData.map { packet ->
val message = packet.toMessage(getNode)
message.replyId
.takeIf { it != null && it != 0 }
?.let { getPacketByPacketId(it) }
?.toMessage(getNode)
?.let { originalMessage -> message.copy(originalMessage = originalMessage) } ?: message
}
}
suspend fun setContactFilteringDisabled(contactKey: String, disabled: Boolean) = withContext(dispatchers.io) {
dbManager.currentDb.value.packetDao().setContactFilteringDisabled(contactKey, disabled)
}
suspend fun clearPacketDB() = withContext(dispatchers.io) { dbManager.currentDb.value.packetDao().deleteAll() }
suspend fun migrateChannelsByPSK(oldSettings: List<ChannelSettings>, newSettings: List<ChannelSettings>) =