From 178f7e0711bdee9d15e1e867dc8ef748bb2f5271 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 11:44:51 +0900 Subject: [PATCH 01/14] =?UTF-8?q?chore:=20database=20module=20moshi=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/database/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 936eca18..8ebc6928 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -23,6 +23,8 @@ dependencies { // optional - Paging 3 Integration implementation(libs.androidx.room.paging) + implementation(libs.squareup.moshi.kotlin) + testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) From 57c16db91c9339fc8b0c0ef12e46baffc9c4b6c5 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 11:46:11 +0900 Subject: [PATCH 02/14] =?UTF-8?q?refactor:=20MemoryCard=20domain=20model?= =?UTF-8?q?=20imageUrl=20type=20nullable=20=ED=98=95=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed the type of `imageUrl` in the `MemoryCard` data class from `String` to `String?` to allow for nullable image URLs. --- .../src/main/java/com/teampatch/core/domain/model/MemoryCard.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/domain/src/main/java/com/teampatch/core/domain/model/MemoryCard.kt b/core/domain/src/main/java/com/teampatch/core/domain/model/MemoryCard.kt index f65cae57..9729601e 100644 --- a/core/domain/src/main/java/com/teampatch/core/domain/model/MemoryCard.kt +++ b/core/domain/src/main/java/com/teampatch/core/domain/model/MemoryCard.kt @@ -7,6 +7,6 @@ data class MemoryCard( val writerTitle: String, val writerName: String, val text: String, - val imageUrl: String, + val imageUrl: String?, val dateTime: LocalDateTime, ) \ No newline at end of file From 1f7d1479f7c262eb25eba9bc23d81be66f6ec276 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 12:58:54 +0900 Subject: [PATCH 03/14] =?UTF-8?q?feat:=20Room=20Set=20type=20conve?= =?UTF-8?q?rters=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../harmony/core/database/HarmonyDatabase.kt | 7 +++++++ .../database/converters/RoomTypeConverter.kt | 6 ++++++ .../converters/SetStringTypeTypeConverter.kt | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 core/database/src/main/java/com/harmony/core/database/converters/RoomTypeConverter.kt create mode 100644 core/database/src/main/java/com/harmony/core/database/converters/SetStringTypeTypeConverter.kt diff --git a/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt b/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt index 92ecfeaf..67356486 100644 --- a/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt +++ b/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt @@ -2,6 +2,8 @@ package com.harmony.core.database import androidx.room.Database import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import com.harmony.core.database.converters.SetStringTypeTypeConverter import com.harmony.core.database.dao.GroupDao import com.harmony.core.database.dao.QuestionDao import com.harmony.core.database.dao.TodoDao @@ -22,6 +24,11 @@ import com.harmony.core.database.model.UserEntity ], version = 1 ) +@TypeConverters( + value = [ + SetStringTypeTypeConverter::class + ] +) internal abstract class HarmonyDatabase : RoomDatabase() { abstract fun todoDao(): TodoDao abstract fun userDao(): UserDao diff --git a/core/database/src/main/java/com/harmony/core/database/converters/RoomTypeConverter.kt b/core/database/src/main/java/com/harmony/core/database/converters/RoomTypeConverter.kt new file mode 100644 index 00000000..f74fa342 --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/converters/RoomTypeConverter.kt @@ -0,0 +1,6 @@ +package com.harmony.core.database.converters + +internal abstract class RoomTypeConverter { + abstract fun fromObjectToJson(value: T): String + abstract fun fromJsonToObject(value: String): T +} \ No newline at end of file diff --git a/core/database/src/main/java/com/harmony/core/database/converters/SetStringTypeTypeConverter.kt b/core/database/src/main/java/com/harmony/core/database/converters/SetStringTypeTypeConverter.kt new file mode 100644 index 00000000..936d08a5 --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/converters/SetStringTypeTypeConverter.kt @@ -0,0 +1,19 @@ +package com.harmony.core.database.converters + +import androidx.room.TypeConverter +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi + +internal class SetStringTypeTypeConverter : RoomTypeConverter>() { + + @TypeConverter + override fun fromObjectToJson(value: Set): String = adapter.toJson(value) + + @TypeConverter + override fun fromJsonToObject(value: String): Set = adapter.fromJson(value)!! + + companion object { + private val moshi: Moshi = Moshi.Builder().build() + private val adapter: JsonAdapter> = moshi.adapter>(Set::class.java) + } +} \ No newline at end of file From 52d691798e8198f829db7ea0ecf7612638ddcdba Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 13:01:38 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20MemoryCard=20db=20Entity=20Dao=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../harmony/core/database/HarmonyDatabase.kt | 6 +++- .../core/database/dao/MemoryCardDao.kt | 27 ++++++++++++++++++ .../core/database/di/DatabaseModule.kt | 6 ++++ .../core/database/model/MemoryCardEntity.kt | 28 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 core/database/src/main/java/com/harmony/core/database/dao/MemoryCardDao.kt create mode 100644 core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt diff --git a/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt b/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt index 67356486..bc8294ca 100644 --- a/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt +++ b/core/database/src/main/java/com/harmony/core/database/HarmonyDatabase.kt @@ -5,10 +5,12 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import com.harmony.core.database.converters.SetStringTypeTypeConverter import com.harmony.core.database.dao.GroupDao +import com.harmony.core.database.dao.MemoryCardDao import com.harmony.core.database.dao.QuestionDao import com.harmony.core.database.dao.TodoDao import com.harmony.core.database.dao.UserDao import com.harmony.core.database.model.GroupEntity +import com.harmony.core.database.model.MemoryCardEntity import com.harmony.core.database.model.QuestionCommentEntity import com.harmony.core.database.model.QuestionEntity import com.harmony.core.database.model.TodoEntity @@ -20,7 +22,8 @@ import com.harmony.core.database.model.UserEntity UserEntity::class, GroupEntity::class, QuestionEntity::class, - QuestionCommentEntity::class + QuestionCommentEntity::class, + MemoryCardEntity::class ], version = 1 ) @@ -34,6 +37,7 @@ internal abstract class HarmonyDatabase : RoomDatabase() { abstract fun userDao(): UserDao abstract fun groupDao(): GroupDao abstract fun questionDao(): QuestionDao + abstract fun memoryCardDao(): MemoryCardDao companion object { internal const val DB_NAME = "harmony.db" diff --git a/core/database/src/main/java/com/harmony/core/database/dao/MemoryCardDao.kt b/core/database/src/main/java/com/harmony/core/database/dao/MemoryCardDao.kt new file mode 100644 index 00000000..2a33fb81 --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/dao/MemoryCardDao.kt @@ -0,0 +1,27 @@ +package com.harmony.core.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update +import com.harmony.core.database.model.MemoryCardEntity +import kotlinx.coroutines.flow.Flow + +@Dao +interface MemoryCardDao { + + @Query("SELECT * FROM memory_card") + fun getAllMemoryStorage(): Flow> + + @Query("SELECT * FROM memory_card WHERE id = :id") + fun getMemoryStorageById(id: Long): Flow + + @Insert(MemoryCardEntity::class) + fun insertMemoryStorage(memoryCardEntity: MemoryCardEntity) + + @Update(MemoryCardEntity::class) + fun updateMemoryStorage(memoryCardEntity: MemoryCardEntity) + + @Query("DELETE FROM memory_card WHERE id = :id") + fun deleteMemoryStorageById(id: Long) +} \ No newline at end of file diff --git a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt index 9c1e9521..5dc434e9 100644 --- a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt +++ b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt @@ -6,6 +6,7 @@ import androidx.room.RoomDatabase.Callback import androidx.sqlite.db.SupportSQLiteDatabase import com.harmony.core.database.HarmonyDatabase import com.harmony.core.database.dao.GroupDao +import com.harmony.core.database.dao.MemoryCardDao import com.harmony.core.database.dao.QuestionDao import com.harmony.core.database.dao.TodoDao import com.harmony.core.database.dao.UserDao @@ -66,4 +67,9 @@ internal object DatabaseModule { fun providesQuestionDao( harmonyDatabase: HarmonyDatabase, ): QuestionDao = harmonyDatabase.questionDao() + + @Provides + fun providesMemoryCardDao( + harmonyDatabase: HarmonyDatabase, + ): MemoryCardDao = harmonyDatabase.memoryCardDao() } \ No newline at end of file diff --git a/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt new file mode 100644 index 00000000..896e4aed --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt @@ -0,0 +1,28 @@ +package com.harmony.core.database.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity( + tableName = "memory_card", + foreignKeys = [ + ForeignKey( + entity = QuestionEntity::class, + parentColumns = ["id"], + childColumns = ["question_id"] + ) + ] +) +data class MemoryCardEntity( + @PrimaryKey(autoGenerate = true) val id: Long? = null, + @ColumnInfo("question_id") val questionId: Long, + @ColumnInfo("written_uid") val writtenUid: Long, + @ColumnInfo("title") val title: String, + @ColumnInfo("created_at") val createdAt: String, + @ColumnInfo("modified_at") val modifiedAt: String, + @ColumnInfo("image_uri") val imageUri: String?, + @ColumnInfo("image_url") val imageUrl: String?, + @ColumnInfo("tags") val tags: Set, +) \ No newline at end of file From 8e9df0ff3b8c5b1579e095ea5fa3d12191c981c8 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 13:02:31 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20MemoryCard=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/database/di/DatabaseModule.kt | 4 +- .../model/preload/MemoryCardPreloadData.kt | 105 ++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt diff --git a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt index 5dc434e9..ec57775d 100644 --- a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt +++ b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt @@ -10,6 +10,7 @@ import com.harmony.core.database.dao.MemoryCardDao import com.harmony.core.database.dao.QuestionDao import com.harmony.core.database.dao.TodoDao import com.harmony.core.database.dao.UserDao +import com.harmony.core.database.model.preload.MemoryCardPreloadData import com.harmony.core.database.model.preload.QuestionPreloadData import com.harmony.core.database.model.preload.TodoPreloadData import dagger.Module @@ -33,7 +34,8 @@ internal object DatabaseModule { super.onCreate(db) listOf( QuestionPreloadData(), - TodoPreloadData() + TodoPreloadData(), + MemoryCardPreloadData() ) .forEach { it.insertPreloadData(db) } } diff --git a/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt b/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt new file mode 100644 index 00000000..6ba11c2a --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt @@ -0,0 +1,105 @@ +package com.harmony.core.database.model.preload + +import android.content.ContentValues + +internal class MemoryCardPreloadData : DataPreloadHelper() { + + companion object { + private const val TABLE_NAME = "memory_card" + } + + override val tableName: String = TABLE_NAME + + override val preloadData: List = listOf( + ContentValues().apply { + put("question_id", 1) + put("written_uid", 101) + put("title", "할머니는 어릴 때 어떤 놀이를 가장 좋아하셨어요?") + put("created_at", "2024-06-12 14:30:00") + put("modified_at", "2024-06-12 14:45:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"추억\",\"놀이\"]") + }, + ContentValues().apply { + put("question_id", 2) + put("written_uid", 102) + put("title", "어릴 때 가장 기억에 남는 음식은 뭐예요?") + put("created_at", "2024-06-13 10:15:00") + put("modified_at", "2024-06-13 10:30:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"음식\",\"기억\"]") + }, + ContentValues().apply { + put("question_id", 3) + put("written_uid", 103) + put("title", "가장 소중한 추억은 언제인가요?") + put("created_at", "2024-06-14 16:45:00") + put("modified_at", "2024-06-14 17:00:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"추억\",\"기억\"]") + }, + ContentValues().apply { + put("question_id", 4) + put("written_uid", 104) + put("title", "예전에는 어떤 음악을 즐겨 들으셨나요?") + put("created_at", "2024-06-15 09:20:00") + put("modified_at", "2024-06-15 09:35:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"음악\",\"옛날\"]") + }, + ContentValues().apply { + put("question_id", 5) + put("written_uid", 105) + put("title", "가장 기억에 남는 여행지는 어디인가요?") + put("created_at", "2024-06-16 14:00:00") + put("modified_at", "2024-06-16 14:15:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"여행\",\"기억\"]") + }, + ContentValues().apply { + put("question_id", 6) + put("written_uid", 106) + put("title", "어릴 때 가장 좋아했던 책은 무엇인가요?") + put("created_at", "2024-06-17 20:30:00") + put("modified_at", "2024-06-17 20:45:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"책\",\"추억\"]") + }, + ContentValues().apply { + put("question_id", 7) + put("written_uid", 107) + put("title", "예전에는 어떤 직업을 꿈꾸셨나요?") + put("created_at", "2024-06-18 08:00:00") + put("modified_at", "2024-06-18 08:20:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"직업\",\"꿈\"]") + }, + ContentValues().apply { + put("question_id", 8) + put("written_uid", 108) + put("title", "젊었을 때 가장 즐겼던 취미는 무엇인가요?") + put("created_at", "2024-06-19 11:50:00") + put("modified_at", "2024-06-19 12:10:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"취미\",\"기억\"]") + }, + ContentValues().apply { + put("question_id", 9) + put("written_uid", 109) + put("title", "어릴 때 가장 무서웠던 경험은 무엇인가요?") + put("created_at", "2024-06-20 17:10:00") + put("modified_at", "2024-06-20 17:30:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"공포\",\"추억\"]") + }, + ContentValues().apply { + put("question_id", 10) + put("written_uid", 110) + put("title", "가장 존경하는 인물은 누구인가요?") + put("created_at", "2024-06-21 22:40:00") + put("modified_at", "2024-06-21 22:55:00") + put("image_url", "https://picsum.photos/400") + put("tags", "[\"존경\",\"인물\"]") + } + ) +} \ No newline at end of file From 364f7d4d0445e6651e08f485480820fca7808b96 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 13:05:09 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20Room=20db=EB=A5=BC=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=ED=95=98=EB=8A=94=20LocalMemoryCardRepositoryImpl=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/data/di/DataSingletonModule.kt | 4 +- .../core/data/mapper/MemoryCardMapper.kt | 22 +++++++ .../repository/MemoryCardRepositoryImpl.kt | 19 ------ .../local/LocalMemoryCardRepositoryImpl.kt | 63 +++++++++++++++++++ .../domain/repository/MemoryCardRepository.kt | 7 +++ 5 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 core/data/src/main/java/com/teampatch/core/data/mapper/MemoryCardMapper.kt delete mode 100644 core/data/src/main/java/com/teampatch/core/data/repository/MemoryCardRepositoryImpl.kt create mode 100644 core/data/src/main/java/com/teampatch/core/data/repository/local/LocalMemoryCardRepositoryImpl.kt diff --git a/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt b/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt index dd1c1c20..75d33c8f 100644 --- a/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt +++ b/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt @@ -3,7 +3,7 @@ package com.teampatch.core.data.di import com.teampatch.core.data.entity.TokenManagerImpl import com.teampatch.core.data.repository.AnswerRepositoryImpl import com.teampatch.core.data.repository.AppManagementRepositoryImpl -import com.teampatch.core.data.repository.MemoryCardRepositoryImpl +import com.teampatch.core.data.repository.local.LocalMemoryCardRepositoryImpl import com.teampatch.core.data.repository.TodoOfflineRepositoryImpl import com.teampatch.core.data.repository.local.LocalAuthenticationRepositoryImpl import com.teampatch.core.data.repository.local.LocalGroupManagementRepositoryImpl @@ -34,7 +34,7 @@ internal abstract class DataSingletonModule { @Binds abstract fun bindsMemoryCardRepository( - memoryCardRepositoryImpl: MemoryCardRepositoryImpl, + localMemoryCardRepositoryImpl: LocalMemoryCardRepositoryImpl, ): MemoryCardRepository @Binds diff --git a/core/data/src/main/java/com/teampatch/core/data/mapper/MemoryCardMapper.kt b/core/data/src/main/java/com/teampatch/core/data/mapper/MemoryCardMapper.kt new file mode 100644 index 00000000..21492800 --- /dev/null +++ b/core/data/src/main/java/com/teampatch/core/data/mapper/MemoryCardMapper.kt @@ -0,0 +1,22 @@ +package com.teampatch.core.data.mapper + +import com.harmony.core.database.LOCAL_DB_DATE_TIME_FORMATTER +import com.harmony.core.database.model.MemoryCardEntity +import com.teampatch.core.domain.model.MemoryCard +import java.time.LocalDateTime + +fun MemoryCardEntity.toDomain( + writerName: String, +): MemoryCard = MemoryCard( + id = id.toString(), + writerTitle = "", + writerName = writerName, + text = title, + imageUrl = imageUrl, + dateTime = LocalDateTime.parse( + /* text = */ + modifiedAt, + /* formatter = */ + LOCAL_DB_DATE_TIME_FORMATTER + ) +) \ No newline at end of file diff --git a/core/data/src/main/java/com/teampatch/core/data/repository/MemoryCardRepositoryImpl.kt b/core/data/src/main/java/com/teampatch/core/data/repository/MemoryCardRepositoryImpl.kt deleted file mode 100644 index 833641e4..00000000 --- a/core/data/src/main/java/com/teampatch/core/data/repository/MemoryCardRepositoryImpl.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.teampatch.core.data.repository - -import com.teampatch.core.domain.fake.FakeMemoryCardQuestion -import com.teampatch.core.domain.model.MemoryCardQuestion -import com.teampatch.core.domain.repository.MemoryCardRepository -import java.io.InputStream -import javax.inject.Inject - -internal class MemoryCardRepositoryImpl @Inject constructor() : MemoryCardRepository { - - override suspend fun addCommunication( - memoryCardId: String, - question: String, - audioFile: InputStream, - ) { - } - - override suspend fun getQuestionMessage(memoryCardId: String): MemoryCardQuestion = FakeMemoryCardQuestion().get() -} \ No newline at end of file diff --git a/core/data/src/main/java/com/teampatch/core/data/repository/local/LocalMemoryCardRepositoryImpl.kt b/core/data/src/main/java/com/teampatch/core/data/repository/local/LocalMemoryCardRepositoryImpl.kt new file mode 100644 index 00000000..cd82e394 --- /dev/null +++ b/core/data/src/main/java/com/teampatch/core/data/repository/local/LocalMemoryCardRepositoryImpl.kt @@ -0,0 +1,63 @@ +package com.teampatch.core.data.repository.local + +import android.util.Log +import androidx.paging.PagingData +import com.harmony.core.database.dao.MemoryCardDao +import com.harmony.core.database.dao.UserDao +import com.teampatch.core.data.mapper.toDomain +import com.teampatch.core.domain.fake.FakeMemoryCardQuestion +import com.teampatch.core.domain.model.MemoryCard +import com.teampatch.core.domain.model.MemoryCardQuestion +import com.teampatch.core.domain.repository.MemoryCardRepository +import java.io.InputStream +import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map + +internal class LocalMemoryCardRepositoryImpl @Inject constructor( + private val memoryCardDao: MemoryCardDao, + private val userDao: UserDao, +) : MemoryCardRepository { + + override suspend fun addCommunication( + memoryCardId: String, + question: String, + audioFile: InputStream, + ) { + } + + override suspend fun getQuestionMessage(memoryCardId: String): MemoryCardQuestion = FakeMemoryCardQuestion().get() + + override fun getMemoryCards(): Flow> { + return memoryCardDao.getAllMemoryStorage().map { memoryCardEntities -> + memoryCardEntities.mapNotNull { memoryCardEntity -> + val writerUserInfo = userDao.getUserById(memoryCardEntity.writtenUid).firstOrNull() + + if (writerUserInfo == null) { + Log.e(TAG, "function: getMemoryCards(), data: writerUserInfo is null") + return@mapNotNull null + } + + memoryCardEntity.toDomain(writerUserInfo.name) + } + .let { + PagingData.from(it) + } + } + } + + @OptIn(ExperimentalCoroutinesApi::class) + override fun getMemoryCardById(memoryCardId: String): Flow = memoryCardDao.getMemoryStorageById(memoryCardId.toLong()) + .flatMapLatest { memoryCardEntity -> + userDao.getUserById(memoryCardEntity.writtenUid).map { writerUserInfo -> + memoryCardEntity.toDomain(writerUserInfo.name) + } + } + + companion object { + private const val TAG = "MemoryCardRepositoryImpl" + } +} \ No newline at end of file diff --git a/core/domain/src/main/java/com/teampatch/core/domain/repository/MemoryCardRepository.kt b/core/domain/src/main/java/com/teampatch/core/domain/repository/MemoryCardRepository.kt index 50ff6d73..817edc36 100644 --- a/core/domain/src/main/java/com/teampatch/core/domain/repository/MemoryCardRepository.kt +++ b/core/domain/src/main/java/com/teampatch/core/domain/repository/MemoryCardRepository.kt @@ -1,7 +1,10 @@ package com.teampatch.core.domain.repository +import androidx.paging.PagingData +import com.teampatch.core.domain.model.MemoryCard import com.teampatch.core.domain.model.MemoryCardQuestion import java.io.InputStream +import kotlinx.coroutines.flow.Flow interface MemoryCardRepository { @@ -22,4 +25,8 @@ interface MemoryCardRepository { */ suspend fun getQuestionMessage(memoryCardId: String): MemoryCardQuestion + + fun getMemoryCards(): Flow> + + fun getMemoryCardById(memoryCardId: String): Flow } \ No newline at end of file From 8c25ad8488ffdf66797c2c897c0b981ab2920fdb Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 13:59:06 +0900 Subject: [PATCH 07/14] =?UTF-8?q?feat:=20UserEntity=20db=20entity=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20snake=20case=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/harmony/core/database/dao/UserDao.kt | 2 +- .../main/java/com/harmony/core/database/model/UserEntity.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/database/src/main/java/com/harmony/core/database/dao/UserDao.kt b/core/database/src/main/java/com/harmony/core/database/dao/UserDao.kt index 0fec50e7..6f109070 100644 --- a/core/database/src/main/java/com/harmony/core/database/dao/UserDao.kt +++ b/core/database/src/main/java/com/harmony/core/database/dao/UserDao.kt @@ -19,7 +19,7 @@ interface UserDao { @Query("SELECT * FROM user WHERE uid = :uid") fun getUserById(uid: Long): Flow - @Query("SELECT * FROM user WHERE groupId = :id") + @Query("SELECT * FROM user WHERE group_id = :id") fun getUserByGroupId(id: Long): Flow> @Query("SELECT * FROM user WHERE sns_id = :id") diff --git a/core/database/src/main/java/com/harmony/core/database/model/UserEntity.kt b/core/database/src/main/java/com/harmony/core/database/model/UserEntity.kt index 9037c144..48145c6f 100644 --- a/core/database/src/main/java/com/harmony/core/database/model/UserEntity.kt +++ b/core/database/src/main/java/com/harmony/core/database/model/UserEntity.kt @@ -7,10 +7,10 @@ import androidx.room.PrimaryKey @Entity(tableName = "user") data class UserEntity( @PrimaryKey(autoGenerate = true) val uid: Long? = null, - @ColumnInfo(name = "groupId") val groupId: Long?, + @ColumnInfo(name = "group_id") val groupId: Long?, @ColumnInfo(name = "name") val name: String, @ColumnInfo(name = "relation") val relation: String, - @ColumnInfo(name = "profileImageUri") val profileImageUri: String?, + @ColumnInfo(name = "profile_image_uri") val profileImageUri: String?, @ColumnInfo(name = "role") val role: String, @ColumnInfo(name = "sns_id") val snsId: String, @ColumnInfo(name = "is_me") val isMe: Boolean, From c03c965ab7c84c6f0d0a755cd43a246cb9dab261 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:00:37 +0900 Subject: [PATCH 08/14] =?UTF-8?q?feat:=20User=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/database/di/DatabaseModule.kt | 2 ++ .../database/model/preload/UserPreloadData.kt | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 core/database/src/main/java/com/harmony/core/database/model/preload/UserPreloadData.kt diff --git a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt index ec57775d..1069a14e 100644 --- a/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt +++ b/core/database/src/main/java/com/harmony/core/database/di/DatabaseModule.kt @@ -13,6 +13,7 @@ import com.harmony.core.database.dao.UserDao import com.harmony.core.database.model.preload.MemoryCardPreloadData import com.harmony.core.database.model.preload.QuestionPreloadData import com.harmony.core.database.model.preload.TodoPreloadData +import com.harmony.core.database.model.preload.UserPreloadData import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -35,6 +36,7 @@ internal object DatabaseModule { listOf( QuestionPreloadData(), TodoPreloadData(), + UserPreloadData(), MemoryCardPreloadData() ) .forEach { it.insertPreloadData(db) } diff --git a/core/database/src/main/java/com/harmony/core/database/model/preload/UserPreloadData.kt b/core/database/src/main/java/com/harmony/core/database/model/preload/UserPreloadData.kt new file mode 100644 index 00000000..16b30d42 --- /dev/null +++ b/core/database/src/main/java/com/harmony/core/database/model/preload/UserPreloadData.kt @@ -0,0 +1,23 @@ +package com.harmony.core.database.model.preload + +import android.content.ContentValues + +internal class UserPreloadData : DataPreloadHelper() { + + companion object { + private const val TABLE_NAME = "user" + } + + override val tableName: String = TABLE_NAME + + override val preloadData: List = listOf( + ContentValues().apply { + put("uid", 9999) + put("name", "operator") + put("relation", "operator") + put("role", "v") + put("sns_id", "9999999999") + put("is_me", false) + } + ) +} \ No newline at end of file From fec5b3c03eb0081722a962ec976c6378c48ef71a Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:02:09 +0900 Subject: [PATCH 09/14] =?UTF-8?q?feat:=20MemoryCardEntity=20content=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/database/model/MemoryCardEntity.kt | 1 + .../model/preload/MemoryCardPreloadData.kt | 70 +++++++++++-------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt index 896e4aed..08d4b441 100644 --- a/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt +++ b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt @@ -20,6 +20,7 @@ data class MemoryCardEntity( @ColumnInfo("question_id") val questionId: Long, @ColumnInfo("written_uid") val writtenUid: Long, @ColumnInfo("title") val title: String, + @ColumnInfo("content") val content: String, @ColumnInfo("created_at") val createdAt: String, @ColumnInfo("modified_at") val modifiedAt: String, @ColumnInfo("image_uri") val imageUri: String?, diff --git a/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt b/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt index 6ba11c2a..f57f5c4e 100644 --- a/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt +++ b/core/database/src/main/java/com/harmony/core/database/model/preload/MemoryCardPreloadData.kt @@ -13,93 +13,103 @@ internal class MemoryCardPreloadData : DataPreloadHelper() { override val preloadData: List = listOf( ContentValues().apply { put("question_id", 1) - put("written_uid", 101) - put("title", "할머니는 어릴 때 어떤 놀이를 가장 좋아하셨어요?") + put("written_uid", 9999) + put("title", "다은이 태어난 날") + put("content", "다은이가 이때부터 참 많이 울었지~ 아주 우렁차게 울어대서 커서 뭐가 되려나 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-12 14:30:00") put("modified_at", "2024-06-12 14:45:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"추억\",\"놀이\"]") + put("tags", "[\"추억\",\"가족\"]") }, ContentValues().apply { put("question_id", 2) - put("written_uid", 102) - put("title", "어릴 때 가장 기억에 남는 음식은 뭐예요?") + put("written_uid", 9999) + put("title", "가족 여행의 추억") + put("content", "여름방학마다 떠났던 가족 여행. 그때마다 설렜던 기억이 나네~ 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-13 10:15:00") put("modified_at", "2024-06-13 10:30:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"음식\",\"기억\"]") + put("tags", "[\"여행\",\"추억\"]") }, ContentValues().apply { put("question_id", 3) - put("written_uid", 103) - put("title", "가장 소중한 추억은 언제인가요?") + put("written_uid", 9999) + put("title", "학교에서의 첫 발표") + put("content", "엄청 떨렸던 발표 시간, 목소리는 떨렸지만 끝나고 나니 뿌듯했던 기억이 나네... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-14 16:45:00") put("modified_at", "2024-06-14 17:00:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"추억\",\"기억\"]") + put("tags", "[\"학교\",\"추억\"]") }, ContentValues().apply { put("question_id", 4) - put("written_uid", 104) - put("title", "예전에는 어떤 음악을 즐겨 들으셨나요?") + put("written_uid", 9999) + put("title", "어릴 때 가장 좋아했던 음식") + put("content", "김치볶음밥과 떡볶이! 언제 먹어도 맛있는 음식, 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-15 09:20:00") put("modified_at", "2024-06-15 09:35:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"음악\",\"옛날\"]") + put("tags", "[\"음식\",\"기억\"]") }, ContentValues().apply { put("question_id", 5) - put("written_uid", 105) - put("title", "가장 기억에 남는 여행지는 어디인가요?") + put("written_uid", 9999) + put("title", "첫 자전거 타기") + put("content", "넘어지고 또 넘어졌지만 결국 혼자서 탈 수 있었던 순간! 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-16 14:00:00") put("modified_at", "2024-06-16 14:15:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"여행\",\"기억\"]") + put("tags", "[\"취미\",\"도전\"]") }, ContentValues().apply { put("question_id", 6) - put("written_uid", 106) - put("title", "어릴 때 가장 좋아했던 책은 무엇인가요?") + put("written_uid", 9999) + put("title", "처음 받은 편지") + put("content", "친구가 손으로 정성껏 써준 편지, 아직도 간직하고 있지... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-17 20:30:00") put("modified_at", "2024-06-17 20:45:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"책\",\"추억\"]") + put("tags", "[\"우정\",\"추억\"]") }, ContentValues().apply { put("question_id", 7) - put("written_uid", 107) - put("title", "예전에는 어떤 직업을 꿈꾸셨나요?") + put("written_uid", 9999) + put("title", "예전 꿈 이야기") + put("content", "어릴 때는 우주 비행사가 되고 싶었는데, 지금은 전혀 다른 길을 가고 있네... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-18 08:00:00") put("modified_at", "2024-06-18 08:20:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"직업\",\"꿈\"]") + put("tags", "[\"꿈\",\"성장\"]") }, ContentValues().apply { put("question_id", 8) - put("written_uid", 108) - put("title", "젊었을 때 가장 즐겼던 취미는 무엇인가요?") + put("written_uid", 9999) + put("title", "가장 좋아했던 놀이") + put("content", "숨바꼭질! 친구들과 해가 질 때까지 뛰어다녔던 기억이 나네... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-19 11:50:00") put("modified_at", "2024-06-19 12:10:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"취미\",\"기억\"]") + put("tags", "[\"놀이\",\"추억\"]") }, ContentValues().apply { put("question_id", 9) - put("written_uid", 109) - put("title", "어릴 때 가장 무서웠던 경험은 무엇인가요?") + put("written_uid", 9999) + put("title", "가장 감동적인 순간") + put("content", "가족이 생일날 깜짝 파티를 해줬을 때, 정말 감동이었지... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-20 17:10:00") put("modified_at", "2024-06-20 17:30:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"공포\",\"추억\"]") + put("tags", "[\"가족\",\"감동\"]") }, ContentValues().apply { put("question_id", 10) - put("written_uid", 110) - put("title", "가장 존경하는 인물은 누구인가요?") + put("written_uid", 9999) + put("title", "어릴 때 가장 좋아했던 동물") + put("content", "강아지! 항상 같이 놀고 싶었고 강아지랑 산책하는 꿈도 꾸었지... 어쩌구 저쩌구 더미 텍스트 블라블라...") put("created_at", "2024-06-21 22:40:00") put("modified_at", "2024-06-21 22:55:00") put("image_url", "https://picsum.photos/400") - put("tags", "[\"존경\",\"인물\"]") + put("tags", "[\"동물\",\"추억\"]") } ) } \ No newline at end of file From e8004b46f7bb0c36b73e0f9a398d8dd6edbc8512 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:02:25 +0900 Subject: [PATCH 10/14] =?UTF-8?q?feat:=20MemoryCardEntity=20User=20id=20?= =?UTF-8?q?=EC=99=B8=EB=9E=98=ED=82=A4=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/harmony/core/database/model/MemoryCardEntity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt index 08d4b441..0628d5ec 100644 --- a/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt +++ b/core/database/src/main/java/com/harmony/core/database/model/MemoryCardEntity.kt @@ -12,6 +12,11 @@ import androidx.room.PrimaryKey entity = QuestionEntity::class, parentColumns = ["id"], childColumns = ["question_id"] + ), + ForeignKey( + entity = UserEntity::class, + parentColumns = ["uid"], + childColumns = ["written_uid"] ) ] ) From 4c68808cbf985660c3fa39c76ed7050a91cc09e1 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:03:55 +0900 Subject: [PATCH 11/14] =?UTF-8?q?chore:=20memoryStorage=20paging=20module?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/memorystorage/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/feature/memorystorage/build.gradle.kts b/feature/memorystorage/build.gradle.kts index f225a286..39ce139b 100644 --- a/feature/memorystorage/build.gradle.kts +++ b/feature/memorystorage/build.gradle.kts @@ -15,6 +15,9 @@ dependencies { implementation(project(":core:domain")) implementation(project(":core:designsystem")) + implementation(libs.androidx.paging.runtime) + implementation(libs.androidx.paging.compose) + implementation(libs.coil.compose) testImplementation(libs.junit) From bf0e12e4cecafa0a157c5030dcd09e9130ae5c03 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:09:21 +0900 Subject: [PATCH 12/14] =?UTF-8?q?feat:=20db=EC=97=90=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EB=90=9C=20=EC=B6=94=EC=96=B5=EC=B9=B4=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20usecase=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=A9=EB=8B=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/usecase/memory/GetMemoryCardUseCase.kt | 9 ++++++--- .../usecase/memory/GetMemoryCardsUseCase.kt | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardsUseCase.kt diff --git a/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardUseCase.kt b/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardUseCase.kt index 3c31578f..adb9f195 100644 --- a/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardUseCase.kt +++ b/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardUseCase.kt @@ -1,10 +1,13 @@ package com.teampatch.core.domain.usecase.memory -import com.teampatch.core.domain.fake.FakeMemoryCard import com.teampatch.core.domain.model.MemoryCard +import com.teampatch.core.domain.repository.MemoryCardRepository import javax.inject.Inject +import kotlinx.coroutines.flow.first -class GetMemoryCardUseCase @Inject constructor() { +class GetMemoryCardUseCase @Inject constructor( + private val memoryCardRepository: MemoryCardRepository, +) { - suspend operator fun invoke(memoryCardId: String): MemoryCard = FakeMemoryCard().get().first() + suspend operator fun invoke(memoryCardId: String): MemoryCard = memoryCardRepository.getMemoryCardById(memoryCardId).first() } \ No newline at end of file diff --git a/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardsUseCase.kt b/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardsUseCase.kt new file mode 100644 index 00000000..1a650538 --- /dev/null +++ b/core/domain/src/main/java/com/teampatch/core/domain/usecase/memory/GetMemoryCardsUseCase.kt @@ -0,0 +1,15 @@ +package com.teampatch.core.domain.usecase.memory + +import androidx.paging.PagingData +import com.teampatch.core.domain.model.MemoryCard +import com.teampatch.core.domain.repository.MemoryCardRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow + +class GetMemoryCardsUseCase @Inject constructor( + private val memoryCardRepository: MemoryCardRepository, + +) { + + operator fun invoke(): Flow> = memoryCardRepository.getMemoryCards() +} \ No newline at end of file From b5be3c3780eb9c634a71762cea3c110feb4304d0 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:09:48 +0900 Subject: [PATCH 13/14] =?UTF-8?q?feat:=20=EC=B6=94=EC=96=B5=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EC=86=8C=20=ED=99=94=EB=A9=B4=EC=9D=B4=20db=EC=9D=98?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=AC=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=84=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memorystorage/MemoryStorageScreen.kt | 97 ++++++++++--------- .../memorystorage/MemoryStorageUiState.kt | 6 +- .../memorystorage/MemoryStorageViewModel.kt | 42 +++----- 3 files changed, 65 insertions(+), 80 deletions(-) diff --git a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageScreen.kt b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageScreen.kt index 7426079e..35e32e28 100644 --- a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageScreen.kt +++ b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageScreen.kt @@ -40,6 +40,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.paging.PagingData +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.compose.itemKey import com.teampatch.core.designsystem.R.drawable import com.teampatch.core.designsystem.R.drawable.btn_search import com.teampatch.core.designsystem.component.AppBar @@ -51,6 +55,7 @@ import com.teampatch.core.designsystem.theme.PretendardFontFamily import com.teampatch.core.designsystem.utils.noRippleClickable import com.teampatch.core.domain.model.MemoryCard import java.time.LocalDateTime +import kotlinx.coroutines.flow.flowOf @Composable internal fun MemoryStorageRoute( @@ -59,17 +64,21 @@ internal fun MemoryStorageRoute( ) { val context = LocalContext.current val memoryStorageUiState by memoryStorageViewModel.memoryStorageUiState.collectAsStateWithLifecycle() + val memoryCards: LazyPagingItems = + memoryStorageViewModel.memoryCards.collectAsLazyPagingItems() when (memoryStorageUiState) { is MemoryStorageUiState.Loading -> { // 로딩 화면 표시 } + is MemoryStorageUiState.Success -> { MemoryStorageScreen( onDetailPageRequest = onDetailPageRequest, - memoryStorageUiState = memoryStorageUiState as MemoryStorageUiState.Success + memoryCardsLazyItems = memoryCards ) } + is MemoryStorageUiState.Error -> { LaunchedEffect(Unit) { Toast.makeText( @@ -85,7 +94,7 @@ internal fun MemoryStorageRoute( @Composable internal fun MemoryStorageScreen( onDetailPageRequest: () -> Unit, - memoryStorageUiState: MemoryStorageUiState, + memoryCardsLazyItems: LazyPagingItems, ) { // 상태 관리 var isSearchMode by remember { mutableStateOf(false) } @@ -206,10 +215,6 @@ internal fun MemoryStorageScreen( } } ) { scaffoldPaddingValues -> - val memoryList = when (memoryStorageUiState) { - is MemoryStorageUiState.Success -> memoryStorageUiState.memories.toList() - else -> emptyList() - } LazyVerticalGrid( columns = GridCells.Fixed(2), @@ -219,8 +224,8 @@ internal fun MemoryStorageScreen( .padding(scaffoldPaddingValues) ) { items( - count = memoryList.size, - key = { index -> memoryList[index].first }, // key는 Map의 Key (String) + count = memoryCardsLazyItems.itemCount, + key = memoryCardsLazyItems.itemKey(), span = { index -> if (index == 0) { GridItemSpan(maxLineSpan) @@ -229,11 +234,9 @@ internal fun MemoryStorageScreen( } } ) { index -> - val memory = memoryList[index].second // ID를 사용하지 않으므로 second만 가져옴 - TempMemoryCard( - title = memory.writerTitle, - description = memory.dateTime.toString(), + title = memoryCardsLazyItems[index]?.text ?: "", + description = memoryCardsLazyItems[index]?.dateTime.toString(), painter = painterResource(id = drawable.img_test_memory_card), modifier = Modifier.noRippleClickable { onDetailPageRequest() // ID가 필요 없다면 인자를 제거 @@ -250,42 +253,44 @@ private fun MemoryStorageScreenPreview() { HarmonyTheme { MemoryStorageScreen( onDetailPageRequest = { }, - memoryStorageUiState = MemoryStorageUiState.Success( - memories = mapOf( - "1" to MemoryCard( - id = "1", - writerTitle = "손자", - writerName = "김민준", - text = "title", - imageUrl = "", - dateTime = LocalDateTime.now() - ), - "2" to MemoryCard( - id = "2", - writerTitle = "할머니", - writerName = "이영희", - text = "어릴 적 사진", - imageUrl = "", - dateTime = LocalDateTime.now() - ), - "3" to MemoryCard( - id = "3", - writerTitle = "할머니", - writerName = "이영희", - text = "어릴 적 사진", - imageUrl = "", - dateTime = LocalDateTime.now() - ), - "4" to MemoryCard( - id = "4", - writerTitle = "할머니", - writerName = "이영희", - text = "어릴 적 사진", - imageUrl = "", - dateTime = LocalDateTime.now() + flowOf( + PagingData.from( + listOf( + MemoryCard( + id = "1", + writerTitle = "손자", + writerName = "김민준", + text = "title", + imageUrl = "", + dateTime = LocalDateTime.now() + ), + MemoryCard( + id = "2", + writerTitle = "할머니", + writerName = "이영희", + text = "어릴 적 사진", + imageUrl = "", + dateTime = LocalDateTime.now() + ), + MemoryCard( + id = "3", + writerTitle = "할머니", + writerName = "이영희", + text = "어릴 적 사진", + imageUrl = "", + dateTime = LocalDateTime.now() + ), + MemoryCard( + id = "4", + writerTitle = "할머니", + writerName = "이영희", + text = "어릴 적 사진", + imageUrl = "", + dateTime = LocalDateTime.now() + ) ) ) - ) + ).collectAsLazyPagingItems() ) } } \ No newline at end of file diff --git a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageUiState.kt b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageUiState.kt index fc3cd98a..76c949e9 100644 --- a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageUiState.kt +++ b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageUiState.kt @@ -1,11 +1,9 @@ package com.teampatch.feature.memorystorage -import com.teampatch.core.domain.model.MemoryCard - sealed interface MemoryStorageUiState { - object Loading : MemoryStorageUiState + data object Loading : MemoryStorageUiState - data class Success(val memories: Map) : MemoryStorageUiState + data object Success : MemoryStorageUiState data class Error(val message: String) : MemoryStorageUiState } \ No newline at end of file diff --git a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt index 99730b55..51fb892e 100644 --- a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt +++ b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt @@ -1,45 +1,27 @@ package com.teampatch.feature.memorystorage import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.teampatch.core.domain.usecase.memory.GetLatestMemoryCardUseCase -import com.teampatch.core.domain.usecase.memory.GetMemoryCardUseCase +import androidx.paging.PagingData +import com.teampatch.core.common.flowErrorCatch +import com.teampatch.core.domain.model.MemoryCard +import com.teampatch.core.domain.usecase.memory.GetMemoryCardsUseCase import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel internal class MemoryStorageViewModel @Inject constructor( - private val getLatestMemoryCardUseCase: GetLatestMemoryCardUseCase, - private val getMemoryCardUseCase: GetMemoryCardUseCase, + private val getMemoryCardsUseCase: GetMemoryCardsUseCase, ) : ViewModel() { - private val _event: Channel = Channel() - val event: Flow = _event.receiveAsFlow() - - private val _memoryStorageUiState = MutableStateFlow(MemoryStorageUiState.Loading) + private val _memoryStorageUiState = + MutableStateFlow(MemoryStorageUiState.Loading) val memoryStorageUiState = _memoryStorageUiState.asStateFlow() - init { - loadData() - } - - private fun loadData() = viewModelScope.launch { - _memoryStorageUiState.value = MemoryStorageUiState.Loading - - try { - val memoryCard = getMemoryCardUseCase("someId") // 예제 코드 - _memoryStorageUiState.value = MemoryStorageUiState.Success( - memories = mapOf(memoryCard.id to memoryCard) - ) - } catch (e: Exception) { - _memoryStorageUiState.value = MemoryStorageUiState.Error("데이터 로딩 실패") - _event.send(MemoryStorageEvent.LoadError) - } - } + val memoryCards: Flow> = flowErrorCatch( + block = { getMemoryCardsUseCase() }, + action = { it.printStackTrace() } + ) } \ No newline at end of file From a81e8eb3a90727e76d7aad32549fa6f64a184019 Mon Sep 17 00:00:00 2001 From: agvber Date: Wed, 14 May 2025 14:10:10 +0900 Subject: [PATCH 14/14] style: ktlinter code cleanup --- .../main/java/com/teampatch/core/data/di/DataSingletonModule.kt | 2 +- .../teampatch/feature/memorystorage/MemoryStorageViewModel.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt b/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt index 75d33c8f..1f922987 100644 --- a/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt +++ b/core/data/src/main/java/com/teampatch/core/data/di/DataSingletonModule.kt @@ -3,10 +3,10 @@ package com.teampatch.core.data.di import com.teampatch.core.data.entity.TokenManagerImpl import com.teampatch.core.data.repository.AnswerRepositoryImpl import com.teampatch.core.data.repository.AppManagementRepositoryImpl -import com.teampatch.core.data.repository.local.LocalMemoryCardRepositoryImpl import com.teampatch.core.data.repository.TodoOfflineRepositoryImpl import com.teampatch.core.data.repository.local.LocalAuthenticationRepositoryImpl import com.teampatch.core.data.repository.local.LocalGroupManagementRepositoryImpl +import com.teampatch.core.data.repository.local.LocalMemoryCardRepositoryImpl import com.teampatch.core.data.repository.local.LocalQuestionRepositoryImpl import com.teampatch.core.data.repository.local.LocalUserRepositoryImpl import com.teampatch.core.domain.entity.TokenManager diff --git a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt index 51fb892e..e05b83d1 100644 --- a/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt +++ b/feature/memorystorage/src/main/java/com/teampatch/feature/memorystorage/MemoryStorageViewModel.kt @@ -6,10 +6,10 @@ import com.teampatch.core.common.flowErrorCatch import com.teampatch.core.domain.model.MemoryCard import com.teampatch.core.domain.usecase.memory.GetMemoryCardsUseCase import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import javax.inject.Inject @HiltViewModel internal class MemoryStorageViewModel @Inject constructor(