diff --git a/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/Chat.kt b/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/Chat.kt index 7e289480..042edb16 100644 --- a/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/Chat.kt +++ b/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/Chat.kt @@ -8,4 +8,5 @@ data class Chat( val name: String?, val avatar: MediaFile?, val creatorID: MemberID, + val direct: Member? = null, ) diff --git a/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/ChatsStore.kt b/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/ChatsStore.kt index 79a4e6d9..78653449 100644 --- a/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/ChatsStore.kt +++ b/libraries/data/api/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/api/ChatsStore.kt @@ -27,6 +27,7 @@ interface ChatsStore { name: String?, avatar: MediaFile?, creatorID: MemberID, + directID: MemberID? = null, ): ChatID @OptIn(ExperimentalTime::class) diff --git a/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/DefaultChatsStore.kt b/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/DefaultChatsStore.kt index c6bf7a06..92e4f852 100644 --- a/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/DefaultChatsStore.kt +++ b/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/DefaultChatsStore.kt @@ -47,12 +47,39 @@ class DefaultChatsStore( transacter = systemDatabase.chatQueries, context = coroutineDispatchers.io, queryProvider = { limit, offset -> - systemDatabase.chatQueries.chats(limit, offset) { id, name, creatorId, avatar -> + systemDatabase.chatQueries.chats(limit, offset) { + id, + name, + creatorID, + avatar, + directID, + directName, + directDescription, + directAvatar, + directCover, + directPreferences, + directRoles, + directBirth, + directAdmin -> Chat( id = ChatID(id), name = name, avatar = avatar?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, - creatorID = MemberID(creatorId), + creatorID = MemberID(creatorID), + direct = + directID?.let { directID -> + Member( + id = MemberID(directID), + name = directName!!, + description = directDescription, + avatar = directAvatar?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, + cover = directCover?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, + preferences = directPreferences, + roles = directRoles, + birth = directBirth, + admin = directAdmin!!, + ) + }, ) } }, @@ -63,12 +90,39 @@ class DefaultChatsStore( override fun getChatDetail(id: ChatID): Flow = systemDatabase.chatQueries - .chatDetail(id.value) { id, name, creatorID, avatar -> + .chatDetail(id.value) { + id, + name, + creatorID, + avatar, + directID, + directName, + directDescription, + directAvatar, + directCover, + directPreferences, + directRoles, + directBirth, + directAdmin -> Chat( id = ChatID(id), name = name, avatar = avatar?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, creatorID = MemberID(creatorID), + direct = + directID?.let { directID -> + Member( + id = MemberID(directID), + name = directName!!, + description = directDescription, + avatar = directAvatar?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, + cover = directCover?.toAbsolute(filesDir.toString())?.let { MediaFile(it) }, + preferences = directPreferences, + roles = directRoles, + birth = directBirth, + admin = directAdmin!!, + ) + }, ) } .asFlow() @@ -302,6 +356,7 @@ class DefaultChatsStore( name: String?, avatar: MediaFile?, creatorID: MemberID, + directID: MemberID?, ): ChatID = withContext(coroutineDispatchers.io) { with(fileSystem) { @@ -311,6 +366,20 @@ class DefaultChatsStore( name = name, avatar = avatar?.rewriteToPersisted(filesDir = filesDir, cacheDir = cacheDir)?.let { MediaFile(it) }, creatorID = creatorID, + direct = + directID?.let { + Member( + id = it, + name = "", + description = null, + avatar = null, + cover = null, + preferences = null, + roles = null, + birth = null, + admin = false, + ) + }, ) systemDatabase.chatQueries.insertChat(model.toDbModel()) diff --git a/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/db/ModelMappers.kt b/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/db/ModelMappers.kt index 5a001867..fd3fb0ee 100644 --- a/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/db/ModelMappers.kt +++ b/libraries/data/impl/src/commonMain/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/db/ModelMappers.kt @@ -16,6 +16,7 @@ internal fun ModelChat.toDbModel() = name = name, creatorId = creatorID.value, avatar = avatar?.value, + directId = direct?.id?.value, ) internal fun ModelSystem.toDbModel() = diff --git a/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/3.sqm b/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/3.sqm new file mode 100644 index 00000000..401a713d --- /dev/null +++ b/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/3.sqm @@ -0,0 +1 @@ +ALTER TABLE chat ADD COLUMN directId TEXT DEFAULT NULL; diff --git a/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/Chat.sq b/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/Chat.sq index 3359f8ad..9d88c2e8 100644 --- a/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/Chat.sq +++ b/libraries/data/impl/src/commonMain/sqldelight/system/io/github/shadowrz/projectkafka/libraries/data/impl/db/Chat.sq @@ -2,13 +2,47 @@ lastInsertRowId: SELECT last_insert_rowid(); chats: -SELECT * FROM chat LIMIT :limit OFFSET :offset; +SELECT + chat.id AS id, + chat.name AS name, + chat.creatorId AS creatorID, + chat.avatar AS avatar, + member.id AS directID, + member.name AS directName, + member.description AS directDescription, + member.avatar AS directAvatar, + member.cover AS directCover, + member.preferences AS directPreferences, + member.roles AS directRoles, + member.birth AS directBirth, + member.admin AS directAdmin +FROM chat +LEFT JOIN + member ON member.id = chat.directId +LIMIT :limit OFFSET :offset; chatsCount: SELECT COUNT(*) FROM chat; chatDetail: -SELECT * FROM chat WHERE id = ?; +SELECT + chat.id AS id, + chat.name AS name, + chat.creatorId AS creatorID, + chat.avatar AS avatar, + member.id AS directID, + member.name AS directName, + member.description AS directDescription, + member.avatar AS directAvatar, + member.cover AS directCover, + member.preferences AS directPreferences, + member.roles AS directRoles, + member.birth AS directBirth, + member.admin AS directAdmin +FROM chat +LEFT JOIN + member ON member.id = chat.directId +WHERE chat.id = :id; insertChat: INSERT INTO chat VALUES ?; diff --git a/libraries/data/impl/src/commonTest/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/ChatsRepositoryTest.kt b/libraries/data/impl/src/commonTest/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/ChatsRepositoryTest.kt index 49d41371..d08a12c1 100644 --- a/libraries/data/impl/src/commonTest/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/ChatsRepositoryTest.kt +++ b/libraries/data/impl/src/commonTest/kotlin/io/github/shadowrz/projectkafka/libraries/data/impl/ChatsRepositoryTest.kt @@ -275,5 +275,46 @@ class ChatsRepositoryTest : FreeSpec() { result.data shouldBeEqual listOf(message2, message1) } } + + "with direct member" { + runTest { + val creator = + membersStore.createMember( + name = "Futaba", + description = "(Description)", + avatar = null, + cover = null, + preferences = "(Preferences)", + roles = "(Roles)", + birth = LocalDate(2024, 1, 1), + admin = false, + ) + val other = + membersStore.createMember( + name = "Akane", + description = "(Description)", + avatar = null, + cover = null, + preferences = "(Preferences)", + roles = "(Roles)", + birth = LocalDate(2024, 2, 2), + admin = false, + ) + val chatID = + store.addChat( + name = "Test", + avatar = null, + creatorID = creator.id, + directID = other.id, + ) + + val chat = store.getChatDetail(chatID).first() + + advanceUntilIdle() + + chat.name shouldBe "Test" + chat.direct shouldBe other + } + } } }