From f15a74db92fe35a6da1447a15923565050b7e3a4 Mon Sep 17 00:00:00 2001 From: s9hn Date: Tue, 29 Jul 2025 18:01:27 +0900 Subject: [PATCH 01/13] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20LibraryR?= =?UTF-8?q?epository=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UserLibraryRepository, MyLibraryRepository 분리 및 구현 --- .../websoso/data/library/LibraryRepository.kt | 96 +------------------ .../data/library/di/RepositoryModule.kt | 38 ++++++++ .../library/repository/MyLibraryRepository.kt | 51 ++++++++++ .../repository/UserLibraryRepository.kt | 57 +++++++++++ 4 files changed, 151 insertions(+), 91 deletions(-) create mode 100644 data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt diff --git a/data/library/src/main/java/com/into/websoso/data/library/LibraryRepository.kt b/data/library/src/main/java/com/into/websoso/data/library/LibraryRepository.kt index 855cfeb5c..f32964904 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/LibraryRepository.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/LibraryRepository.kt @@ -1,99 +1,13 @@ package com.into.websoso.data.library -import androidx.paging.ExperimentalPagingApi -import androidx.paging.Pager -import androidx.paging.PagingConfig import androidx.paging.PagingData -import androidx.paging.map -import com.into.websoso.core.database.entity.InDatabaseFilteredNovelEntity -import com.into.websoso.core.database.entity.InDatabaseNovelEntity -import com.into.websoso.data.account.AccountRepository -import com.into.websoso.data.library.datasource.FilteredLibraryLocalDataSource -import com.into.websoso.data.library.datasource.LibraryLocalDataSource -import com.into.websoso.data.library.datasource.LibraryRemoteDataSource -import com.into.websoso.data.library.datasource.MyLibraryFilterLocalDataSource -import com.into.websoso.data.library.mediator.FilteredNovelRemoteMediator -import com.into.websoso.data.library.mediator.NovelRemoteMediator -import com.into.websoso.data.library.model.LibraryFilterParams import com.into.websoso.data.library.model.NovelEntity -import com.into.websoso.data.library.model.toData import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.map -import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class LibraryRepository - @Inject - constructor( - private val accountRepository: AccountRepository, - private val libraryRemoteDataSource: LibraryRemoteDataSource, - private val libraryLocalDataSource: LibraryLocalDataSource, - private val filteredLibraryLocalDataSource: FilteredLibraryLocalDataSource, - private val myLibraryFilterLocalDataSource: MyLibraryFilterLocalDataSource, - ) { - val myLibraryFilter = myLibraryFilterLocalDataSource.myLibraryFilterFlow +interface LibraryRepository { + val libraryFlow: Flow> - @OptIn(ExperimentalPagingApi::class) - fun getLibrary(): Flow> = - Pager( - config = PagingConfig(pageSize = PAGE_SIZE), - remoteMediator = NovelRemoteMediator( - userId = accountRepository.userId, - libraryLocalDataSource = libraryLocalDataSource, - libraryRemoteDataSource = libraryRemoteDataSource, - ), - pagingSourceFactory = libraryLocalDataSource::selectAllNovels, - ).flow.map { pagingData -> - pagingData.map(InDatabaseNovelEntity::toData) - } - - @OptIn(ExperimentalPagingApi::class) - fun getFilteredLibrary( - readStatuses: List, - attractivePoints: List, - isInterested: Boolean, - novelRating: Float, - sortCriteria: String, - ): Flow> = - Pager( - config = PagingConfig(pageSize = PAGE_SIZE), - remoteMediator = FilteredNovelRemoteMediator( - userId = accountRepository.userId, - libraryRemoteDataSource = libraryRemoteDataSource, - filteredLibraryLocalDataSource = filteredLibraryLocalDataSource, - isInterested = isInterested, - readStatuses = readStatuses, - attractivePoints = attractivePoints, - novelRating = novelRating, - sortCriteria = sortCriteria, - ), - pagingSourceFactory = filteredLibraryLocalDataSource::selectAllNovels, - ).flow.map { pagingData -> - pagingData.map(InDatabaseFilteredNovelEntity::toData) - } - - suspend fun updateMyLibraryFilter( - readStatuses: Map? = null, - attractivePoints: Map? = null, - novelRating: Float? = null, - isInterested: Boolean? = null, - sortCriteria: String? = null, - ) { - val savedFilter = myLibraryFilter.firstOrNull() ?: LibraryFilterParams() - val updatedFilter = savedFilter.copy( - sortCriteria = sortCriteria ?: savedFilter.sortCriteria, - isInterested = isInterested ?: savedFilter.isInterested, - readStatuses = readStatuses ?: savedFilter.readStatuses, - attractivePoints = attractivePoints ?: savedFilter.attractivePoints, - novelRating = novelRating ?: savedFilter.novelRating, - ) - - myLibraryFilterLocalDataSource.updateMyLibraryFilter(params = updatedFilter) - } - - companion object { - private const val PAGE_SIZE = 10 - } + companion object { + const val PAGE_SIZE = 30 } +} diff --git a/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt b/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt new file mode 100644 index 000000000..d9660af3f --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt @@ -0,0 +1,38 @@ +package com.into.websoso.data.library.di + +import androidx.lifecycle.SavedStateHandle +import com.into.websoso.data.library.LibraryRepository +import com.into.websoso.data.library.repository.MyLibraryRepository +import com.into.websoso.data.library.repository.UserLibraryRepository.Factory +import com.into.websoso.data.library.repository.UserLibraryRepository.UserLibraryRepositoryFactory +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ViewModelComponent + +@Module +@InstallIn(ViewModelComponent::class) +object RepositoryModule { + @Module + @InstallIn(ViewModelComponent::class) + abstract class UserLibraryRepositoryModule { + @Binds + abstract fun bindUserLibraryRepositoryFactory(userLibraryRepositoryFactory: UserLibraryRepositoryFactory): Factory + } + + @Provides + fun provideLibraryRepository( + savedStateHandle: SavedStateHandle, + myLibraryRepository: MyLibraryRepository, + userLibraryRepository: Factory, + ): LibraryRepository { + val userId: Long? = savedStateHandle["USER_ID"] + + return if (userId == null) { + myLibraryRepository + } else { + userLibraryRepository.create(userId) + } + } +} diff --git a/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt b/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt new file mode 100644 index 000000000..681f12f8f --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt @@ -0,0 +1,51 @@ +package com.into.websoso.data.library.repository + +import androidx.paging.ExperimentalPagingApi +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import androidx.paging.map +import com.into.websoso.core.database.entity.InDatabaseFilteredNovelEntity +import com.into.websoso.data.account.AccountRepository +import com.into.websoso.data.filter.FilterRepository +import com.into.websoso.data.library.LibraryRepository +import com.into.websoso.data.library.LibraryRepository.Companion.PAGE_SIZE +import com.into.websoso.data.library.datasource.FilteredLibraryLocalDataSource +import com.into.websoso.data.library.datasource.LibraryRemoteDataSource +import com.into.websoso.data.library.model.NovelEntity +import com.into.websoso.data.library.model.toData +import com.into.websoso.data.library.paging.LibraryRemoteMediator +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MyLibraryRepository + @Inject + constructor( + filterRepository: FilterRepository, + private val accountRepository: AccountRepository, + private val libraryRemoteDataSource: LibraryRemoteDataSource, + private val filteredLibraryLocalDataSource: FilteredLibraryLocalDataSource, + ) : LibraryRepository { + @OptIn(ExperimentalPagingApi::class, ExperimentalCoroutinesApi::class) + override val libraryFlow: Flow> = + filterRepository.filterFlow + .flatMapLatest { filter -> + Pager( + config = PagingConfig(pageSize = PAGE_SIZE), + remoteMediator = LibraryRemoteMediator( + userId = accountRepository.userId, + libraryRemoteDataSource = libraryRemoteDataSource, + filteredLibraryLocalDataSource = filteredLibraryLocalDataSource, + libraryFilter = filter, + ), + pagingSourceFactory = filteredLibraryLocalDataSource::selectAllNovels, + ).flow.map { pagingData -> + pagingData.map(InDatabaseFilteredNovelEntity::toData) + } + } + } diff --git a/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt b/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt new file mode 100644 index 000000000..00a04492f --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt @@ -0,0 +1,57 @@ +package com.into.websoso.data.library.repository + +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.into.websoso.data.filter.FilterRepository +import com.into.websoso.data.library.LibraryRepository +import com.into.websoso.data.library.LibraryRepository.Companion.PAGE_SIZE +import com.into.websoso.data.library.datasource.LibraryRemoteDataSource +import com.into.websoso.data.library.model.NovelEntity +import com.into.websoso.data.library.paging.LibraryPagingSource +import dagger.hilt.android.scopes.ViewModelScoped +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest +import javax.inject.Inject + +class UserLibraryRepository( + private val userId: Long, + private val filterRepository: FilterRepository, + private val libraryRemoteDataSource: LibraryRemoteDataSource, +) : LibraryRepository { + @OptIn(ExperimentalCoroutinesApi::class) + override val libraryFlow: Flow> = + filterRepository.filterFlow + .flatMapLatest { filter -> + Pager( + config = PagingConfig(pageSize = PAGE_SIZE), + pagingSourceFactory = { + LibraryPagingSource( + userId = userId, + libraryRemoteDataSource = libraryRemoteDataSource, + filterParams = filter, + ) + }, + ).flow + } + + interface Factory { + fun create(userId: Long): LibraryRepository + } + + @ViewModelScoped + class UserLibraryRepositoryFactory + @Inject + constructor( + private val libraryRemoteDataSource: LibraryRemoteDataSource, + private val filterRepository: FilterRepository, + ) : Factory { + override fun create(userId: Long): LibraryRepository = + UserLibraryRepository( + userId = userId, + filterRepository = filterRepository, + libraryRemoteDataSource = libraryRemoteDataSource, + ) + } +} From 02765715e29881b0eb7d86232ad31db90b8cb412 Mon Sep 17 00:00:00 2001 From: s9hn Date: Tue, 29 Jul 2025 18:02:20 +0900 Subject: [PATCH 02/13] =?UTF-8?q?refactor:=20FilterRepository=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=ED=99=94=20=EB=B0=8F=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UserLibraryFilterRepository, MyLibraryFilterRepository 분리 및 구현 --- .../websoso/data/filter/FilterRepository.kt | 16 +++++++ .../data/filter/di/RepositoryModule.kt | 24 +++++++++++ .../data/filter/model/LibraryFilter.kt | 24 +++++++++++ .../repository/MyLibraryFilterRepository.kt | 42 +++++++++++++++++++ .../repository/UserLibraryFilterRepository.kt | 38 +++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/FilterRepository.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/model/LibraryFilter.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt diff --git a/data/library/src/main/java/com/into/websoso/data/filter/FilterRepository.kt b/data/library/src/main/java/com/into/websoso/data/filter/FilterRepository.kt new file mode 100644 index 000000000..b6b759d9f --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/FilterRepository.kt @@ -0,0 +1,16 @@ +package com.into.websoso.data.filter + +import com.into.websoso.data.filter.model.LibraryFilter +import kotlinx.coroutines.flow.Flow + +interface FilterRepository { + val filterFlow: Flow + + suspend fun updateFilter( + readStatuses: Map? = null, + attractivePoints: Map? = null, + novelRating: Float? = null, + isInterested: Boolean? = null, + sortCriteria: String? = null, + ) +} diff --git a/data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt b/data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt new file mode 100644 index 000000000..08d14aa5f --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt @@ -0,0 +1,24 @@ +package com.into.websoso.data.filter.di + +import androidx.lifecycle.SavedStateHandle +import com.into.websoso.data.filter.FilterRepository +import com.into.websoso.data.filter.repository.MyLibraryFilterRepository +import com.into.websoso.data.filter.repository.UserLibraryFilterRepository +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ViewModelComponent + +@Module +@InstallIn(ViewModelComponent::class) +internal object RepositoryModule { + @Provides + fun provideFilterRepository( + savedStateHandle: SavedStateHandle, + myFilterRepository: MyLibraryFilterRepository, + userFilterRepository: UserLibraryFilterRepository, + ): FilterRepository { + val userId: Long? = savedStateHandle["USER_ID"] + return if (userId == null) myFilterRepository else userFilterRepository + } +} diff --git a/data/library/src/main/java/com/into/websoso/data/filter/model/LibraryFilter.kt b/data/library/src/main/java/com/into/websoso/data/filter/model/LibraryFilter.kt new file mode 100644 index 000000000..dbfcbf270 --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/model/LibraryFilter.kt @@ -0,0 +1,24 @@ +package com.into.websoso.data.filter.model + +data class LibraryFilter( + val sortCriteria: String = DEFAULT_SORT_CRITERIA, + val isInterested: Boolean = DEFAULT_IS_INTERESTED, + val novelRating: Float = DEFAULT_NOVEL_RATING, + val readStatuses: Map = emptyMap(), + val attractivePoints: Map = emptyMap(), +) { + val readStatusKeys: List = readStatuses.toSelectedKeyList { it } + val attractivePointKeys: List = attractivePoints.toSelectedKeyList { it } + + private fun Map.toSelectedKeyList(toSelectedKeyName: (K) -> String): List = + this + .filterValues { it } + .keys + .map { toSelectedKeyName(it) } + + companion object { + private const val DEFAULT_SORT_CRITERIA = "RECENT" + private const val DEFAULT_IS_INTERESTED = false + private const val DEFAULT_NOVEL_RATING = 0.0f + } +} diff --git a/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt b/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt new file mode 100644 index 000000000..14727490a --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt @@ -0,0 +1,42 @@ +package com.into.websoso.data.filter.repository + +import com.into.websoso.data.filter.FilterRepository +import com.into.websoso.data.filter.datasource.LibraryFilterLocalDataSource +import com.into.websoso.data.filter.model.LibraryFilter +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MyLibraryFilterRepository + @Inject + constructor( + private val myLibraryFilterLocalDataSource: LibraryFilterLocalDataSource, + ) : FilterRepository { + override val filterFlow: Flow = + myLibraryFilterLocalDataSource.libraryFilterFlow + .map { it ?: LibraryFilter() } + .distinctUntilChanged() + + override suspend fun updateFilter( + readStatuses: Map?, + attractivePoints: Map?, + novelRating: Float?, + isInterested: Boolean?, + sortCriteria: String?, + ) { + val savedFilter = filterFlow.first() + val updatedFilter = savedFilter.copy( + sortCriteria = sortCriteria ?: savedFilter.sortCriteria, + isInterested = isInterested ?: savedFilter.isInterested, + readStatuses = readStatuses ?: savedFilter.readStatuses, + attractivePoints = attractivePoints ?: savedFilter.attractivePoints, + novelRating = novelRating ?: savedFilter.novelRating, + ) + + myLibraryFilterLocalDataSource.updateLibraryFilter(params = updatedFilter) + } + } diff --git a/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt b/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt new file mode 100644 index 000000000..e2f5e0b73 --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt @@ -0,0 +1,38 @@ +package com.into.websoso.data.filter.repository + +import com.into.websoso.data.filter.FilterRepository +import com.into.websoso.data.filter.model.LibraryFilter +import dagger.hilt.android.scopes.ViewModelScoped +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.update +import javax.inject.Inject + +@ViewModelScoped +class UserLibraryFilterRepository + @Inject + constructor() : FilterRepository { + private val _filterFlow = MutableStateFlow(LibraryFilter()) + override val filterFlow: Flow = _filterFlow.asStateFlow() + + override suspend fun updateFilter( + readStatuses: Map?, + attractivePoints: Map?, + novelRating: Float?, + isInterested: Boolean?, + sortCriteria: String?, + ) { + val savedFilter = filterFlow.first() + val updatedFilter = savedFilter.copy( + sortCriteria = sortCriteria ?: savedFilter.sortCriteria, + isInterested = isInterested ?: savedFilter.isInterested, + readStatuses = readStatuses ?: savedFilter.readStatuses, + attractivePoints = attractivePoints ?: savedFilter.attractivePoints, + novelRating = novelRating ?: savedFilter.novelRating, + ) + + _filterFlow.update { updatedFilter } + } + } From 5419b20b5fb4814cf7c9474fb16c75a6a8004284 Mon Sep 17 00:00:00 2001 From: s9hn Date: Tue, 29 Jul 2025 18:04:18 +0900 Subject: [PATCH 03/13] =?UTF-8?q?refactor:=20Datastore=20My=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=EC=A0=9C=EA=B1=B0,=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=20LibraryFilterParams=20->=20LibraryFilter=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=9E=AC=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...e.kt => DefaultLibraryFilterDataSource.kt} | 33 +++++++++---------- .../library/mapper/LibraryFilterMapper.kt | 22 +++++++++++++ .../library/model/LibraryFilterPreferences.kt | 21 +----------- .../core/datastore/di/DataStoreModule.kt | 12 +++---- .../core/datastore/di/DataStoreQualifier.kt | 2 +- .../LibraryFilterLocalDataSource.kt | 12 +++++++ .../MyLibraryFilterLocalDataSource.kt | 12 ------- .../data/library/model/LibraryFilterParams.kt | 13 -------- 8 files changed, 58 insertions(+), 69 deletions(-) rename core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/{DefaultMyLibraryFilterDataSource.kt => DefaultLibraryFilterDataSource.kt} (65%) create mode 100644 core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/mapper/LibraryFilterMapper.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/filter/datasource/LibraryFilterLocalDataSource.kt delete mode 100644 data/library/src/main/java/com/into/websoso/data/library/datasource/MyLibraryFilterLocalDataSource.kt delete mode 100644 data/library/src/main/java/com/into/websoso/data/library/model/LibraryFilterParams.kt diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultMyLibraryFilterDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt similarity index 65% rename from core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultMyLibraryFilterDataSource.kt rename to core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt index b511dc6d9..6e34a676c 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultMyLibraryFilterDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt @@ -6,11 +6,12 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import com.into.websoso.core.common.dispatchers.Dispatcher import com.into.websoso.core.common.dispatchers.WebsosoDispatchers +import com.into.websoso.core.datastore.datasource.library.mapper.toData +import com.into.websoso.core.datastore.datasource.library.mapper.toPreferences import com.into.websoso.core.datastore.datasource.library.model.LibraryFilterPreferences -import com.into.websoso.core.datastore.datasource.library.model.toPreferences -import com.into.websoso.core.datastore.di.MyLibraryFilterDataStore -import com.into.websoso.data.library.datasource.MyLibraryFilterLocalDataSource -import com.into.websoso.data.library.model.LibraryFilterParams +import com.into.websoso.core.datastore.di.LibraryFilterDataStore +import com.into.websoso.data.filter.datasource.LibraryFilterLocalDataSource +import com.into.websoso.data.filter.model.LibraryFilter import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -25,14 +26,14 @@ import kotlinx.serialization.json.Json import javax.inject.Inject import javax.inject.Singleton -internal class DefaultMyLibraryFilterDataSource +internal class DefaultLibraryFilterDataSource @Inject constructor( - @MyLibraryFilterDataStore private val myLibraryFilterDataStore: DataStore, + @LibraryFilterDataStore private val libraryFilterDataStore: DataStore, @Dispatcher(WebsosoDispatchers.DEFAULT) private val dispatcher: CoroutineDispatcher, - ) : MyLibraryFilterLocalDataSource { - override val myLibraryFilterFlow: Flow - get() = myLibraryFilterDataStore.data + ) : LibraryFilterLocalDataSource { + override val libraryFilterFlow: Flow + get() = libraryFilterDataStore.data .map { prefs -> prefs[LIBRARY_FILTER_PARAMS_KEY]?.let { jsonString -> withContext(dispatcher) { @@ -41,20 +42,20 @@ internal class DefaultMyLibraryFilterDataSource } }.distinctUntilChanged() - override suspend fun updateMyLibraryFilter(params: LibraryFilterParams) { + override suspend fun updateLibraryFilter(params: LibraryFilter) { val encodedJsonString = withContext(dispatcher) { Json.encodeToString( params.toPreferences(), ) } - myLibraryFilterDataStore.edit { prefs -> + libraryFilterDataStore.edit { prefs -> prefs[LIBRARY_FILTER_PARAMS_KEY] = encodedJsonString } } - override suspend fun deleteMyLibraryFilter() { - myLibraryFilterDataStore.edit { prefs -> + override suspend fun deleteLibraryFilter() { + libraryFilterDataStore.edit { prefs -> prefs.remove(LIBRARY_FILTER_PARAMS_KEY) } } @@ -66,10 +67,8 @@ internal class DefaultMyLibraryFilterDataSource @Module @InstallIn(SingletonComponent::class) -internal interface MyLibraryFilterDataSourceModule { +internal interface LibraryFilterDataSourceModule { @Binds @Singleton - fun bindMyLibraryFilterLocalDataSource( - defaultMyLibraryFilterDataSource: DefaultMyLibraryFilterDataSource, - ): MyLibraryFilterLocalDataSource + fun bindLibraryFilterLocalDataSource(defaultLibraryFilterDataSource: DefaultLibraryFilterDataSource): LibraryFilterLocalDataSource } diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/mapper/LibraryFilterMapper.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/mapper/LibraryFilterMapper.kt new file mode 100644 index 000000000..08afc26f5 --- /dev/null +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/mapper/LibraryFilterMapper.kt @@ -0,0 +1,22 @@ +package com.into.websoso.core.datastore.datasource.library.mapper + +import com.into.websoso.core.datastore.datasource.library.model.LibraryFilterPreferences +import com.into.websoso.data.filter.model.LibraryFilter + +internal fun LibraryFilter.toPreferences(): LibraryFilterPreferences = + LibraryFilterPreferences( + sortCriteria = sortCriteria, + isInterested = isInterested, + readStatuses = readStatuses, + attractivePoints = attractivePoints, + novelRating = novelRating, + ) + +internal fun LibraryFilterPreferences.toData(): LibraryFilter = + LibraryFilter( + sortCriteria = sortCriteria, + isInterested = isInterested, + readStatuses = readStatuses, + attractivePoints = attractivePoints, + novelRating = novelRating, + ) diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/model/LibraryFilterPreferences.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/model/LibraryFilterPreferences.kt index 4779a99b1..c02114a6a 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/model/LibraryFilterPreferences.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/model/LibraryFilterPreferences.kt @@ -1,6 +1,5 @@ package com.into.websoso.core.datastore.datasource.library.model -import com.into.websoso.data.library.model.LibraryFilterParams import kotlinx.serialization.Serializable @Serializable @@ -10,22 +9,4 @@ internal data class LibraryFilterPreferences( val readStatuses: Map, val attractivePoints: Map, val novelRating: Float, -) { - internal fun toData(): LibraryFilterParams = - LibraryFilterParams( - sortCriteria = sortCriteria, - isInterested = isInterested, - readStatuses = readStatuses, - attractivePoints = attractivePoints, - novelRating = novelRating, - ) -} - -internal fun LibraryFilterParams.toPreferences(): LibraryFilterPreferences = - LibraryFilterPreferences( - sortCriteria = sortCriteria, - isInterested = isInterested, - readStatuses = readStatuses, - attractivePoints = attractivePoints, - novelRating = novelRating, - ) +) diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreModule.kt index 9b9c95579..51388dd81 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreModule.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreModule.kt @@ -17,9 +17,9 @@ internal object DataStoreModule { private const val ACCOUNT_DATASTORE = "ACCOUNT_DATASTORE" private val Context.accountDataStore: DataStore by preferencesDataStore(name = ACCOUNT_DATASTORE) - private const val MY_LIBRARY_FILTER_DATASTORE = "MY_LIBRARY_FILTER_DATASTORE" - private val Context.myLibraryFilterDataStore: DataStore by preferencesDataStore( - name = MY_LIBRARY_FILTER_DATASTORE, + private const val LIBRARY_FILTER_DATASTORE = "LIBRARY_FILTER_DATASTORE" + private val Context.libraryFilterDataStore: DataStore by preferencesDataStore( + name = LIBRARY_FILTER_DATASTORE, ) @Provides @@ -31,8 +31,8 @@ internal object DataStoreModule { @Provides @Singleton - @MyLibraryFilterDataStore - internal fun provideMyLibraryFilterPreferencesDataStore( + @LibraryFilterDataStore + internal fun provideLibraryFilterPreferencesDataStore( @ApplicationContext context: Context, - ): DataStore = context.myLibraryFilterDataStore + ): DataStore = context.libraryFilterDataStore } diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreQualifier.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreQualifier.kt index 6f91a5ede..1499bb5a4 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreQualifier.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/di/DataStoreQualifier.kt @@ -8,4 +8,4 @@ internal annotation class AccountDataStore @Qualifier @Retention(AnnotationRetention.BINARY) -internal annotation class MyLibraryFilterDataStore +internal annotation class LibraryFilterDataStore diff --git a/data/library/src/main/java/com/into/websoso/data/filter/datasource/LibraryFilterLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/filter/datasource/LibraryFilterLocalDataSource.kt new file mode 100644 index 000000000..cf4a714ae --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/filter/datasource/LibraryFilterLocalDataSource.kt @@ -0,0 +1,12 @@ +package com.into.websoso.data.filter.datasource + +import com.into.websoso.data.filter.model.LibraryFilter +import kotlinx.coroutines.flow.Flow + +interface LibraryFilterLocalDataSource { + val libraryFilterFlow: Flow + + suspend fun updateLibraryFilter(params: LibraryFilter) + + suspend fun deleteLibraryFilter() +} diff --git a/data/library/src/main/java/com/into/websoso/data/library/datasource/MyLibraryFilterLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/library/datasource/MyLibraryFilterLocalDataSource.kt deleted file mode 100644 index b4cf5ed13..000000000 --- a/data/library/src/main/java/com/into/websoso/data/library/datasource/MyLibraryFilterLocalDataSource.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.into.websoso.data.library.datasource - -import com.into.websoso.data.library.model.LibraryFilterParams -import kotlinx.coroutines.flow.Flow - -interface MyLibraryFilterLocalDataSource { - val myLibraryFilterFlow: Flow - - suspend fun updateMyLibraryFilter(params: LibraryFilterParams) - - suspend fun deleteMyLibraryFilter() -} diff --git a/data/library/src/main/java/com/into/websoso/data/library/model/LibraryFilterParams.kt b/data/library/src/main/java/com/into/websoso/data/library/model/LibraryFilterParams.kt deleted file mode 100644 index 1960b61bd..000000000 --- a/data/library/src/main/java/com/into/websoso/data/library/model/LibraryFilterParams.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.into.websoso.data.library.model - -data class LibraryFilterParams( - val sortCriteria: String = DEFAULT_SORT_CRITERIA, - val isInterested: Boolean = DEFAULT_IS_INTERESTED, - val novelRating: Float = DEFAULT_NOVEL_RATING, - val readStatuses: Map = emptyMap(), - val attractivePoints: Map = emptyMap(), -) - -private const val DEFAULT_SORT_CRITERIA = "RECENT" -private const val DEFAULT_IS_INTERESTED = false -private const val DEFAULT_NOVEL_RATING = 0.0f From aeefb22c045fbef16e714679c17b8f70f07e641e Mon Sep 17 00:00:00 2001 From: s9hn Date: Tue, 29 Jul 2025 18:04:38 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20PagingSource=20=EB=B0=8F=20Re?= =?UTF-8?q?moteMediator=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../library/mediator/NovelRemoteMediator.kt | 57 ------------------ .../library/paging/LibraryPagingSource.kt | 58 +++++++++++++++++++ .../LibraryRemoteMediator.kt} | 25 ++++---- 3 files changed, 71 insertions(+), 69 deletions(-) delete mode 100644 data/library/src/main/java/com/into/websoso/data/library/mediator/NovelRemoteMediator.kt create mode 100644 data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt rename data/library/src/main/java/com/into/websoso/data/library/{mediator/FilteredNovelRemoteMediator.kt => paging/LibraryRemoteMediator.kt} (75%) diff --git a/data/library/src/main/java/com/into/websoso/data/library/mediator/NovelRemoteMediator.kt b/data/library/src/main/java/com/into/websoso/data/library/mediator/NovelRemoteMediator.kt deleted file mode 100644 index 825efe03b..000000000 --- a/data/library/src/main/java/com/into/websoso/data/library/mediator/NovelRemoteMediator.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.into.websoso.data.library.mediator - -import androidx.paging.ExperimentalPagingApi -import androidx.paging.LoadType -import androidx.paging.PagingState -import androidx.paging.RemoteMediator -import com.into.websoso.core.database.entity.InDatabaseNovelEntity -import com.into.websoso.data.library.datasource.LibraryLocalDataSource -import com.into.websoso.data.library.datasource.LibraryRemoteDataSource - -@OptIn(ExperimentalPagingApi::class) -class NovelRemoteMediator( - private val userId: Long, - private val libraryRemoteDataSource: LibraryRemoteDataSource, - private val libraryLocalDataSource: LibraryLocalDataSource, -) : RemoteMediator() { - override suspend fun load( - loadType: LoadType, - state: PagingState, - ): MediatorResult { - val lastUserNovelId = when (loadType) { - LoadType.REFRESH -> null - LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true) - LoadType.APPEND -> { - val lastItem = state.lastItemOrNull() - lastItem?.userNovelId ?: return MediatorResult.Success(true) - } - } ?: DEFAULT_LAST_USER_NOVEL_ID - - return try { - val response = libraryRemoteDataSource.getUserNovels( - userId = userId, - lastUserNovelId = lastUserNovelId, - size = state.config.pageSize, - sortCriteria = DEFAULT_SORT_CRITERIA, - isInterest = null, - readStatuses = null, - attractivePoints = null, - novelRating = null, - query = null, - updatedSince = null, - ) - if (loadType == LoadType.REFRESH) { - libraryLocalDataSource.deleteAllNovels() - } - libraryLocalDataSource.insertNovels(response.userNovels) - MediatorResult.Success(endOfPaginationReached = !response.isLoadable) - } catch (e: Exception) { - MediatorResult.Error(e) - } - } - - companion object { - private const val DEFAULT_LAST_USER_NOVEL_ID = 0L - private const val DEFAULT_SORT_CRITERIA = "RECENT" - } -} diff --git a/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt new file mode 100644 index 000000000..ce1ee4db5 --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt @@ -0,0 +1,58 @@ +package com.into.websoso.data.library.paging + +import androidx.paging.PagingSource +import androidx.paging.PagingState +import com.into.websoso.core.common.extensions.isCloseTo +import com.into.websoso.data.filter.model.LibraryFilter +import com.into.websoso.data.library.datasource.LibraryRemoteDataSource +import com.into.websoso.data.library.model.NovelEntity + +class LibraryPagingSource( + private val userId: Long, + private val libraryRemoteDataSource: LibraryRemoteDataSource, + private val filterParams: LibraryFilter, +) : PagingSource() { + override suspend fun load(params: LoadParams): LoadResult { + val lastUserNovelId = params.key ?: DEFAULT_LAST_USER_NOVEL_ID + + return try { + val response = libraryRemoteDataSource.getUserNovels( + userId = userId, + lastUserNovelId = lastUserNovelId, + size = params.loadSize, + sortCriteria = filterParams.sortCriteria, + isInterest = if (!filterParams.isInterested) null else true, + readStatuses = filterParams.readStatusKeys.ifEmpty { null }, + attractivePoints = filterParams.attractivePointKeys.ifEmpty { null }, + novelRating = if (filterParams.novelRating.isCloseTo(0f)) null else filterParams.novelRating, + query = null, + updatedSince = null, + ) + + val novels = response.userNovels.map { it } + + val nextKey = if (response.isLoadable && novels.isNotEmpty()) { + novels.last().userNovelId + } else { + null + } + + LoadResult.Page( + data = novels, + prevKey = null, + nextKey = nextKey, + ) + } catch (e: Exception) { + LoadResult.Error(e) + } + } + + override fun getRefreshKey(state: PagingState): Long? = + state.anchorPosition?.let { position -> + state.closestItemToPosition(position)?.userNovelId + } + + companion object { + private const val DEFAULT_LAST_USER_NOVEL_ID = 0L + } +} diff --git a/data/library/src/main/java/com/into/websoso/data/library/mediator/FilteredNovelRemoteMediator.kt b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryRemoteMediator.kt similarity index 75% rename from data/library/src/main/java/com/into/websoso/data/library/mediator/FilteredNovelRemoteMediator.kt rename to data/library/src/main/java/com/into/websoso/data/library/paging/LibraryRemoteMediator.kt index 491f158b8..df343a219 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/mediator/FilteredNovelRemoteMediator.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryRemoteMediator.kt @@ -1,4 +1,4 @@ -package com.into.websoso.data.library.mediator +package com.into.websoso.data.library.paging import androidx.paging.ExperimentalPagingApi import androidx.paging.LoadType @@ -11,19 +11,16 @@ import androidx.paging.RemoteMediator.MediatorResult.Error import androidx.paging.RemoteMediator.MediatorResult.Success import com.into.websoso.core.common.extensions.isCloseTo import com.into.websoso.core.database.entity.InDatabaseFilteredNovelEntity +import com.into.websoso.data.filter.model.LibraryFilter import com.into.websoso.data.library.datasource.FilteredLibraryLocalDataSource import com.into.websoso.data.library.datasource.LibraryRemoteDataSource @OptIn(ExperimentalPagingApi::class) -class FilteredNovelRemoteMediator( +class LibraryRemoteMediator( private val userId: Long, private val libraryRemoteDataSource: LibraryRemoteDataSource, private val filteredLibraryLocalDataSource: FilteredLibraryLocalDataSource, - private val isInterested: Boolean, - private val sortCriteria: String, - private val readStatuses: List, - private val attractivePoints: List, - private val novelRating: Float, + private val libraryFilter: LibraryFilter, ) : RemoteMediator() { override suspend fun load( loadType: LoadType, @@ -40,11 +37,15 @@ class FilteredNovelRemoteMediator( userId = userId, lastUserNovelId = lastUserNovelId, size = state.config.pageSize, - sortCriteria = sortCriteria, - isInterest = if (!isInterested) null else true, - readStatuses = readStatuses.ifEmpty { null }, - attractivePoints = attractivePoints.ifEmpty { null }, - novelRating = if (novelRating.isCloseTo(DEFAULT_NOVEL_RATING)) null else novelRating, + sortCriteria = libraryFilter.sortCriteria, + isInterest = if (!libraryFilter.isInterested) null else true, + readStatuses = libraryFilter.readStatusKeys.ifEmpty { null }, + attractivePoints = libraryFilter.attractivePointKeys.ifEmpty { null }, + novelRating = if (libraryFilter.novelRating.isCloseTo(DEFAULT_NOVEL_RATING)) { + null + } else { + libraryFilter.novelRating + }, query = null, updatedSince = null, ) From cc9bb5cd12ade20aae64c2a345f31b1981db247c Mon Sep 17 00:00:00 2001 From: s9hn Date: Tue, 29 Jul 2025 18:04:56 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20UI=20=EB=A0=88=EC=9D=B4=EC=96=B4=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/library/model/LibraryReadStatus.kt | 8 -- .../domain/library/GetLibraryUseCase.kt | 47 ---------- .../websoso/feature/library/LibraryScreen.kt | 16 ++-- .../feature/library/LibraryViewModel.kt | 94 ++++++------------- .../library/filter/LibraryFilterViewModel.kt | 6 +- 5 files changed, 39 insertions(+), 132 deletions(-) delete mode 100644 data/library/src/main/java/com/into/websoso/data/library/model/LibraryReadStatus.kt delete mode 100644 domain/library/src/main/java/com/into/websoso/domain/library/GetLibraryUseCase.kt diff --git a/data/library/src/main/java/com/into/websoso/data/library/model/LibraryReadStatus.kt b/data/library/src/main/java/com/into/websoso/data/library/model/LibraryReadStatus.kt deleted file mode 100644 index 449b592e1..000000000 --- a/data/library/src/main/java/com/into/websoso/data/library/model/LibraryReadStatus.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.into.websoso.data.library.model - -internal enum class LibraryReadStatus { - Interest, - ReadStatus, - Rating, - AttractivePoint, -} diff --git a/domain/library/src/main/java/com/into/websoso/domain/library/GetLibraryUseCase.kt b/domain/library/src/main/java/com/into/websoso/domain/library/GetLibraryUseCase.kt deleted file mode 100644 index 71636acf7..000000000 --- a/domain/library/src/main/java/com/into/websoso/domain/library/GetLibraryUseCase.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.into.websoso.domain.library - -import androidx.paging.PagingData -import com.into.websoso.data.library.LibraryRepository -import com.into.websoso.data.library.model.NovelEntity -import com.into.websoso.domain.library.model.AttractivePoints -import com.into.websoso.domain.library.model.ReadStatus -import kotlinx.coroutines.flow.Flow -import javax.inject.Inject - -class GetLibraryUseCase - @Inject - constructor( - private val libraryRepository: LibraryRepository, - ) { - operator fun invoke( - readStatuses: Map, - attractivePoints: Map, - sortCriteria: String, - isInterested: Boolean, - novelRating: Float, - ): Flow> { - val isEmptyFilter = readStatuses.values.none { it } && - attractivePoints.values.none { it } && - novelRating == 0.0f && - !isInterested && - sortCriteria == "RECENT" - - return if (isEmptyFilter) { - libraryRepository.getLibrary() - } else { - libraryRepository.getFilteredLibrary( - readStatuses = readStatuses.toSelectedKeyList { it.name }, - attractivePoints = attractivePoints.toSelectedKeyList { it.name }, - novelRating = novelRating, - isInterested = isInterested, - sortCriteria = sortCriteria, - ) - } - } - - private fun Map.toSelectedKeyList(toSelectedKeyName: (K) -> String): List = - this - .filterValues { it } - .keys - .map { toSelectedKeyName(it) } - } diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt index 2156f61d8..3418e59e0 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt @@ -58,7 +58,7 @@ fun LibraryScreen( ) { val scope = rememberCoroutineScope() val uiState by libraryViewModel.uiState.collectAsStateWithLifecycle() - val pagingItems = libraryViewModel.novelPagingData + val novels = libraryViewModel.novels .map { it.map(NovelEntity::toUiModel) } .collectAsLazyPagingItems() val latestEffect by rememberUpdatedState(libraryViewModel.scrollToTopEvent) @@ -80,7 +80,7 @@ fun LibraryScreen( LibraryScreen( libraryFilterViewModel = libraryFilterViewModel, - pagingItems = pagingItems, + novels = novels, uiState = uiState, listState = listState, gridState = gridState, @@ -114,7 +114,7 @@ fun LibraryScreen( @Composable private fun LibraryScreen( libraryFilterViewModel: LibraryFilterViewModel, - pagingItems: LazyPagingItems, + novels: LazyPagingItems, uiState: LibraryUiState, listState: LazyListState, gridState: LazyGridState, @@ -143,7 +143,7 @@ private fun LibraryScreen( LibraryFilterTopBar( libraryFilterUiState = uiState.libraryFilterUiState, - totalCount = pagingItems.itemCount, + totalCount = novels.itemCount, isGrid = uiState.isGrid, onFilterClick = onFilterClick, onSortClick = onSortClick, @@ -154,8 +154,8 @@ private fun LibraryScreen( Spacer(modifier = Modifier.height(4.dp)) when { - pagingItems.itemCount == 0 && - pagingItems.loadState.refresh !is LoadState.Loading -> { + novels.itemCount == 0 && + novels.loadState.refresh !is LoadState.Loading -> { if (uiState.libraryFilterUiState.isFilterApplied) { LibraryFilterEmptyView() } else { @@ -165,7 +165,7 @@ private fun LibraryScreen( uiState.isGrid -> { LibraryGridList( - novels = pagingItems, + novels = novels, gridState = gridState, onItemClick = onItemClick, ) @@ -173,7 +173,7 @@ private fun LibraryScreen( else -> { LibraryList( - novels = pagingItems, + novels = novels, listState = listState, onItemClick = onItemClick, ) diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt index 21382aff5..94dbf403d 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt @@ -2,25 +2,21 @@ package com.into.websoso.feature.library import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData import androidx.paging.cachedIn +import com.into.websoso.data.filter.FilterRepository import com.into.websoso.data.library.LibraryRepository -import com.into.websoso.domain.library.GetLibraryUseCase +import com.into.websoso.data.library.model.NovelEntity import com.into.websoso.domain.library.model.AttractivePoints import com.into.websoso.domain.library.model.ReadStatus import com.into.websoso.feature.library.model.LibraryUiState import com.into.websoso.feature.library.model.SortTypeUiModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.drop -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -30,8 +26,8 @@ import javax.inject.Inject class LibraryViewModel @Inject constructor( - getLibraryUseCase: GetLibraryUseCase, - private val libraryRepository: LibraryRepository, + libraryRepository: LibraryRepository, + private val filterRepository: FilterRepository, ) : ViewModel() { private val _uiState = MutableStateFlow(LibraryUiState()) val uiState: StateFlow = _uiState.asStateFlow() @@ -39,46 +35,32 @@ class LibraryViewModel private val _scrollToTopEvent = Channel(Channel.BUFFERED) val scrollToTopEvent: Flow = _scrollToTopEvent.receiveAsFlow() - @OptIn(ExperimentalCoroutinesApi::class) - val novelPagingData = uiState - .map { it.libraryFilterUiState } - .drop(INITIAL_STATE) - .distinctUntilChanged() - .flatMapLatest { filter -> - getLibraryUseCase( - readStatuses = filter.readStatuses, - attractivePoints = filter.attractivePoints, - novelRating = filter.novelRating, - isInterested = filter.isInterested, - sortCriteria = filter.selectedSortType.name, - ) - }.cachedIn(viewModelScope) + val novels: Flow> = + libraryRepository.libraryFlow.cachedIn(viewModelScope) init { - updateMyLibraryFilter() + updateLibraryFilter() } - private fun updateMyLibraryFilter() { + private fun updateLibraryFilter() { viewModelScope.launch { - libraryRepository.myLibraryFilter.collectLatest { myFilter -> - if (myFilter != null) { - _uiState.update { uiState -> - uiState.copy( - libraryFilterUiState = uiState.libraryFilterUiState.copy( - selectedSortType = SortTypeUiModel.valueOf(myFilter.sortCriteria), - isInterested = myFilter.isInterested, - readStatuses = myFilter.readStatuses - .mapKeys { - ReadStatus.from(it.key) - }.ifEmpty { uiState.libraryFilterUiState.readStatuses }, - attractivePoints = myFilter.attractivePoints - .mapKeys { - AttractivePoints.from(it.key) - }.ifEmpty { uiState.libraryFilterUiState.attractivePoints }, - novelRating = myFilter.novelRating, - ), - ) - } + filterRepository.filterFlow.collect { filter -> + _uiState.update { uiState -> + uiState.copy( + libraryFilterUiState = uiState.libraryFilterUiState.copy( + selectedSortType = SortTypeUiModel.valueOf(filter.sortCriteria), + isInterested = filter.isInterested, + readStatuses = filter.readStatuses + .mapKeys { + ReadStatus.from(it.key) + }.ifEmpty { uiState.libraryFilterUiState.readStatuses }, + attractivePoints = filter.attractivePoints + .mapKeys { + AttractivePoints.from(it.key) + }.ifEmpty { uiState.libraryFilterUiState.attractivePoints }, + novelRating = filter.novelRating, + ), + ) } } } @@ -98,36 +80,20 @@ class LibraryViewModel } viewModelScope.launch { - libraryRepository.updateMyLibraryFilter( + filterRepository.updateFilter( sortCriteria = newSortType.name, ) } - - _uiState.update { uiState -> - uiState.copy( - libraryFilterUiState = uiState.libraryFilterUiState.copy( - selectedSortType = newSortType, - ), - ) - } } fun updateInterestedNovels() { val updatedInterested = !uiState.value.libraryFilterUiState.isInterested viewModelScope.launch { - libraryRepository.updateMyLibraryFilter( + filterRepository.updateFilter( isInterested = updatedInterested, ) } - - _uiState.update { - it.copy( - libraryFilterUiState = uiState.value.libraryFilterUiState.copy( - isInterested = updatedInterested, - ), - ) - } } fun resetScrollPosition() { @@ -135,8 +101,4 @@ class LibraryViewModel _scrollToTopEvent.send(Unit) } } - - companion object { - private const val INITIAL_STATE = 1 - } } diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt b/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt index 5e8cee9a1..13f9d6c64 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt @@ -3,7 +3,7 @@ package com.into.websoso.feature.library.filter import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.into.websoso.core.common.extensions.isCloseTo -import com.into.websoso.data.library.LibraryRepository +import com.into.websoso.data.filter.FilterRepository import com.into.websoso.domain.library.model.AttractivePoints import com.into.websoso.domain.library.model.ReadStatus import com.into.websoso.feature.library.model.LibraryFilterUiState @@ -19,7 +19,7 @@ import javax.inject.Inject class LibraryFilterViewModel @Inject constructor( - private val libraryRepository: LibraryRepository, + private val filterRepository: FilterRepository, ) : ViewModel() { private val _uiState = MutableStateFlow(LibraryFilterUiState()) val uiState = _uiState.asStateFlow() @@ -68,7 +68,7 @@ class LibraryFilterViewModel fun searchFilteredNovels() { viewModelScope.launch { - libraryRepository.updateMyLibraryFilter( + filterRepository.updateFilter( readStatuses = uiState.value.readStatuses.mapKeys { it.key.key }, attractivePoints = uiState.value.attractivePoints.mapKeys { it.key.key }, novelRating = uiState.value.novelRating, From 2ea868345229ce818949fb01c23977cc8dd5d514 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:17:09 +0900 Subject: [PATCH 06/13] =?UTF-8?q?refactor:=20LibraryScreen=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9C=A0=EC=A0=80=20ID=20=EC=A0=84=EB=8B=AC?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/util/navigator/WebsosoNavigator.kt | 7 +++++-- .../otherUserLibrary/OtherUserLibraryFragment.kt | 4 ++-- .../into/websoso/ui/userStorage/UserStorageActivity.kt | 9 ++++++++- .../websoso/core/common/navigator/NavigatorProvider.kt | 5 ++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt index 0ba267bd1..bb6448099 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt @@ -46,8 +46,11 @@ internal class WebsosoNavigator startActivity(intent) } - override fun navigateToUserStorageActivity(startActivity: (Intent) -> Unit) { - val intent = UserStorageActivity.getIntent(context) + override fun navigateToUserStorageActivity( + startActivity: (Intent) -> Unit, + userId: Long, + ) { + val intent = UserStorageActivity.getIntent(context, userId) startActivity(intent) } diff --git a/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryFragment.kt b/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryFragment.kt index fc800ae3d..6d38f6370 100644 --- a/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryFragment.kt +++ b/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryFragment.kt @@ -40,6 +40,7 @@ class OtherUserLibraryFragment : BaseFragment(f RestGenrePreferenceAdapter() } private val singleEventHandler: SingleEventHandler by lazy { SingleEventHandler.from() } + private val userId by lazy { arguments?.getLong(USER_ID_KEY) ?: 0L } override fun onViewCreated( view: View, @@ -63,7 +64,6 @@ class OtherUserLibraryFragment : BaseFragment(f } private fun updateUserId() { - val userId = arguments?.getLong(USER_ID_KEY) ?: 0L otherUserLibraryViewModel.updateUserId(userId) } @@ -222,7 +222,7 @@ class OtherUserLibraryFragment : BaseFragment(f } private fun navigateToUserStorageActivity() { - websosoNavigator.navigateToUserStorageActivity(::startActivity) + websosoNavigator.navigateToUserStorageActivity(::startActivity, userId) } override fun onResume() { diff --git a/app/src/main/java/com/into/websoso/ui/userStorage/UserStorageActivity.kt b/app/src/main/java/com/into/websoso/ui/userStorage/UserStorageActivity.kt index 2ed8ddade..dc1ea1885 100644 --- a/app/src/main/java/com/into/websoso/ui/userStorage/UserStorageActivity.kt +++ b/app/src/main/java/com/into/websoso/ui/userStorage/UserStorageActivity.kt @@ -41,6 +41,13 @@ class UserStorageActivity : AppCompatActivity(R.layout.activity_storage) { } companion object { - fun getIntent(context: Context) = Intent(context, UserStorageActivity::class.java) + private const val USER_ID = "USER_ID" + + fun getIntent( + context: Context, + userId: Long, + ) = Intent(context, UserStorageActivity::class.java).apply { + putExtra(USER_ID, userId) + } } } diff --git a/core/common/src/main/java/com/into/websoso/core/common/navigator/NavigatorProvider.kt b/core/common/src/main/java/com/into/websoso/core/common/navigator/NavigatorProvider.kt index dc16ee923..af4ce8e35 100644 --- a/core/common/src/main/java/com/into/websoso/core/common/navigator/NavigatorProvider.kt +++ b/core/common/src/main/java/com/into/websoso/core/common/navigator/NavigatorProvider.kt @@ -15,7 +15,10 @@ interface NavigatorProvider { fun navigateToOnboardingActivity(startActivity: (Intent) -> Unit) - fun navigateToUserStorageActivity(startActivity: (Intent) -> Unit) + fun navigateToUserStorageActivity( + startActivity: (Intent) -> Unit, + userId: Long, + ) fun navigateToNovelDetailActivity( novelId: Long, From a075fc5e8d19f85ff96f03c5eddea1371062e232 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:24:27 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20FilterRepository=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20DI=20=EB=AA=A8=EB=93=88=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...{RepositoryModule.kt => FilterRepositoryModule.kt} | 11 +++++++---- .../filter/repository/MyLibraryFilterRepository.kt | 4 +--- .../filter/repository/UserLibraryFilterRepository.kt | 4 +--- 3 files changed, 9 insertions(+), 10 deletions(-) rename data/library/src/main/java/com/into/websoso/data/filter/di/{RepositoryModule.kt => FilterRepositoryModule.kt} (63%) diff --git a/data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt b/data/library/src/main/java/com/into/websoso/data/filter/di/FilterRepositoryModule.kt similarity index 63% rename from data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt rename to data/library/src/main/java/com/into/websoso/data/filter/di/FilterRepositoryModule.kt index 08d14aa5f..2f44f59b6 100644 --- a/data/library/src/main/java/com/into/websoso/data/filter/di/RepositoryModule.kt +++ b/data/library/src/main/java/com/into/websoso/data/filter/di/FilterRepositoryModule.kt @@ -8,17 +8,20 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.components.ViewModelComponent +import dagger.hilt.android.scopes.ViewModelScoped +import javax.inject.Provider @Module @InstallIn(ViewModelComponent::class) -internal object RepositoryModule { +internal object FilterRepositoryModule { @Provides + @ViewModelScoped fun provideFilterRepository( savedStateHandle: SavedStateHandle, - myFilterRepository: MyLibraryFilterRepository, - userFilterRepository: UserLibraryFilterRepository, + myFilterRepository: Provider, + userFilterRepository: Provider, ): FilterRepository { val userId: Long? = savedStateHandle["USER_ID"] - return if (userId == null) myFilterRepository else userFilterRepository + return if (userId == null) myFilterRepository.get() else userFilterRepository.get() } } diff --git a/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt b/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt index 14727490a..621daa5e7 100644 --- a/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt +++ b/data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt @@ -8,10 +8,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class MyLibraryFilterRepository +internal class MyLibraryFilterRepository @Inject constructor( private val myLibraryFilterLocalDataSource: LibraryFilterLocalDataSource, diff --git a/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt b/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt index e2f5e0b73..03f67c513 100644 --- a/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt +++ b/data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt @@ -2,7 +2,6 @@ package com.into.websoso.data.filter.repository import com.into.websoso.data.filter.FilterRepository import com.into.websoso.data.filter.model.LibraryFilter -import dagger.hilt.android.scopes.ViewModelScoped import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -10,8 +9,7 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update import javax.inject.Inject -@ViewModelScoped -class UserLibraryFilterRepository +internal class UserLibraryFilterRepository @Inject constructor() : FilterRepository { private val _filterFlow = MutableStateFlow(LibraryFilter()) From b144eb86f28cf005b4dbe5ba092dce29c581d4c3 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:25:13 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20LibraryRepository=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20DI=20=EB=AA=A8=EB=93=88=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../library/di/LibraryRepositoryModule.kt | 27 ++++++++ .../data/library/di/RepositoryModule.kt | 38 ---------- .../library/repository/MyLibraryRepository.kt | 4 +- .../repository/UserLibraryRepository.kt | 69 ++++++++----------- 4 files changed, 57 insertions(+), 81 deletions(-) create mode 100644 data/library/src/main/java/com/into/websoso/data/library/di/LibraryRepositoryModule.kt delete mode 100644 data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt diff --git a/data/library/src/main/java/com/into/websoso/data/library/di/LibraryRepositoryModule.kt b/data/library/src/main/java/com/into/websoso/data/library/di/LibraryRepositoryModule.kt new file mode 100644 index 000000000..d203ef1cf --- /dev/null +++ b/data/library/src/main/java/com/into/websoso/data/library/di/LibraryRepositoryModule.kt @@ -0,0 +1,27 @@ +package com.into.websoso.data.library.di + +import androidx.lifecycle.SavedStateHandle +import com.into.websoso.data.library.LibraryRepository +import com.into.websoso.data.library.repository.MyLibraryRepository +import com.into.websoso.data.library.repository.UserLibraryRepository +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ViewModelComponent +import dagger.hilt.android.scopes.ViewModelScoped +import javax.inject.Provider + +@Module +@InstallIn(ViewModelComponent::class) +internal object LibraryRepositoryModule { + @Provides + @ViewModelScoped + fun provideLibraryRepository( + savedStateHandle: SavedStateHandle, + myLibraryRepository: Provider, + userLibraryRepository: Provider + ): LibraryRepository { + val userId: Long? = savedStateHandle["USER_ID"] + return if (userId == null) myLibraryRepository.get() else userLibraryRepository.get().create(userId) + } +} diff --git a/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt b/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt deleted file mode 100644 index d9660af3f..000000000 --- a/data/library/src/main/java/com/into/websoso/data/library/di/RepositoryModule.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.into.websoso.data.library.di - -import androidx.lifecycle.SavedStateHandle -import com.into.websoso.data.library.LibraryRepository -import com.into.websoso.data.library.repository.MyLibraryRepository -import com.into.websoso.data.library.repository.UserLibraryRepository.Factory -import com.into.websoso.data.library.repository.UserLibraryRepository.UserLibraryRepositoryFactory -import dagger.Binds -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent - -@Module -@InstallIn(ViewModelComponent::class) -object RepositoryModule { - @Module - @InstallIn(ViewModelComponent::class) - abstract class UserLibraryRepositoryModule { - @Binds - abstract fun bindUserLibraryRepositoryFactory(userLibraryRepositoryFactory: UserLibraryRepositoryFactory): Factory - } - - @Provides - fun provideLibraryRepository( - savedStateHandle: SavedStateHandle, - myLibraryRepository: MyLibraryRepository, - userLibraryRepository: Factory, - ): LibraryRepository { - val userId: Long? = savedStateHandle["USER_ID"] - - return if (userId == null) { - myLibraryRepository - } else { - userLibraryRepository.create(userId) - } - } -} diff --git a/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt b/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt index 681f12f8f..b6ac84ef9 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt @@ -20,10 +20,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class MyLibraryRepository +internal class MyLibraryRepository @Inject constructor( filterRepository: FilterRepository, diff --git a/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt b/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt index 00a04492f..5b2fba9cb 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt @@ -9,49 +9,38 @@ import com.into.websoso.data.library.LibraryRepository.Companion.PAGE_SIZE import com.into.websoso.data.library.datasource.LibraryRemoteDataSource import com.into.websoso.data.library.model.NovelEntity import com.into.websoso.data.library.paging.LibraryPagingSource -import dagger.hilt.android.scopes.ViewModelScoped +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flatMapLatest -import javax.inject.Inject -class UserLibraryRepository( - private val userId: Long, - private val filterRepository: FilterRepository, - private val libraryRemoteDataSource: LibraryRemoteDataSource, -) : LibraryRepository { - @OptIn(ExperimentalCoroutinesApi::class) - override val libraryFlow: Flow> = - filterRepository.filterFlow - .flatMapLatest { filter -> - Pager( - config = PagingConfig(pageSize = PAGE_SIZE), - pagingSourceFactory = { - LibraryPagingSource( - userId = userId, - libraryRemoteDataSource = libraryRemoteDataSource, - filterParams = filter, - ) - }, - ).flow - } +internal class UserLibraryRepository + @AssistedInject + constructor( + filterRepository: FilterRepository, + @Assisted private val userId: Long, + private val libraryRemoteDataSource: LibraryRemoteDataSource, + ) : LibraryRepository { + @AssistedFactory + interface Factory { + fun create(userId: Long): UserLibraryRepository + } - interface Factory { - fun create(userId: Long): LibraryRepository + @OptIn(ExperimentalCoroutinesApi::class) + override val libraryFlow: Flow> = + filterRepository.filterFlow + .flatMapLatest { filter -> + Pager( + config = PagingConfig(pageSize = PAGE_SIZE), + pagingSourceFactory = { + LibraryPagingSource( + userId = userId, + libraryRemoteDataSource = libraryRemoteDataSource, + filterParams = filter, + ) + }, + ).flow + } } - - @ViewModelScoped - class UserLibraryRepositoryFactory - @Inject - constructor( - private val libraryRemoteDataSource: LibraryRemoteDataSource, - private val filterRepository: FilterRepository, - ) : Factory { - override fun create(userId: Long): LibraryRepository = - UserLibraryRepository( - userId = userId, - filterRepository = filterRepository, - libraryRemoteDataSource = libraryRemoteDataSource, - ) - } -} From f6fac80fa75220754d6e01b1304ba58940ffc028 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:25:34 +0900 Subject: [PATCH 09/13] =?UTF-8?q?refactor:=20LibraryFilterViewModel=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websoso/feature/library/LibraryScreen.kt | 31 ++++++-- .../feature/library/LibraryViewModel.kt | 60 +++++++++++++- .../filter/LibraryFilterBottomSheetScreen.kt | 36 +++++---- .../library/filter/LibraryFilterViewModel.kt | 78 ------------------- 4 files changed, 103 insertions(+), 102 deletions(-) delete mode 100644 feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt index 3418e59e0..79d26317e 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt @@ -22,7 +22,6 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems @@ -31,6 +30,8 @@ import androidx.paging.map import com.into.websoso.core.common.extensions.collectAsEventWithLifecycle import com.into.websoso.core.designsystem.theme.White import com.into.websoso.data.library.model.NovelEntity +import com.into.websoso.domain.library.model.AttractivePoints +import com.into.websoso.domain.library.model.ReadStatus import com.into.websoso.feature.library.component.LibraryEmptyView import com.into.websoso.feature.library.component.LibraryFilterEmptyView import com.into.websoso.feature.library.component.LibraryFilterTopBar @@ -38,11 +39,12 @@ import com.into.websoso.feature.library.component.LibraryGridList import com.into.websoso.feature.library.component.LibraryList import com.into.websoso.feature.library.component.LibraryTopBar import com.into.websoso.feature.library.filter.LibraryFilterBottomSheetScreen -import com.into.websoso.feature.library.filter.LibraryFilterViewModel import com.into.websoso.feature.library.mapper.toUiModel import com.into.websoso.feature.library.model.LibraryFilterType +import com.into.websoso.feature.library.model.LibraryFilterUiState import com.into.websoso.feature.library.model.LibraryListItemModel import com.into.websoso.feature.library.model.LibraryUiState +import com.into.websoso.feature.library.model.RatingLevelUiModel import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -54,10 +56,10 @@ fun LibraryScreen( navigateToNormalExploreActivity: () -> Unit, navigateToNovelDetailActivity: (novelId: Long) -> Unit, libraryViewModel: LibraryViewModel, - libraryFilterViewModel: LibraryFilterViewModel = hiltViewModel(), ) { val scope = rememberCoroutineScope() val uiState by libraryViewModel.uiState.collectAsStateWithLifecycle() + val filterUiState by libraryViewModel.tempFilterUiState.collectAsStateWithLifecycle() val novels = libraryViewModel.novels .map { it.map(NovelEntity::toUiModel) } .collectAsLazyPagingItems() @@ -79,9 +81,9 @@ fun LibraryScreen( } LibraryScreen( - libraryFilterViewModel = libraryFilterViewModel, novels = novels, uiState = uiState, + filterUiState = filterUiState, listState = listState, gridState = gridState, sheetState = bottomSheetState, @@ -98,7 +100,7 @@ fun LibraryScreen( isShowBottomSheet = true bottomSheetState.show() }.invokeOnCompletion { - libraryFilterViewModel.updateMyLibraryFilter(uiState.libraryFilterUiState) + libraryViewModel.updateMyLibraryFilter() } }, onSortClick = libraryViewModel::updateSortType, @@ -107,15 +109,20 @@ fun LibraryScreen( onSearchClick = { /* TODO */ }, onExploreClick = navigateToNormalExploreActivity, onInterestClick = libraryViewModel::updateInterestedNovels, + onAttractivePointClick = libraryViewModel::updateAttractivePoints, + onReadStatusClick = libraryViewModel::updateReadStatus, + onRatingClick = libraryViewModel::updateRating, + onResetClick = libraryViewModel::resetFilter, + onFilterSearchClick = libraryViewModel::searchFilteredNovels, ) } @OptIn(ExperimentalMaterial3Api::class) @Composable private fun LibraryScreen( - libraryFilterViewModel: LibraryFilterViewModel, novels: LazyPagingItems, uiState: LibraryUiState, + filterUiState: LibraryFilterUiState, listState: LazyListState, gridState: LazyGridState, sheetState: SheetState, @@ -128,6 +135,11 @@ private fun LibraryScreen( onSearchClick: () -> Unit, onExploreClick: () -> Unit, onInterestClick: () -> Unit, + onAttractivePointClick: (AttractivePoints) -> Unit, + onReadStatusClick: (ReadStatus) -> Unit, + onRatingClick: (rating: RatingLevelUiModel) -> Unit, + onResetClick: () -> Unit, + onFilterSearchClick: () -> Unit, ) { Column( modifier = Modifier @@ -183,9 +195,14 @@ private fun LibraryScreen( if (isShowBottomSheet) { LibraryFilterBottomSheetScreen( + filterUiState = filterUiState, sheetState = sheetState, onDismissRequest = onDismissRequest, - viewModel = libraryFilterViewModel, + onAttractivePointClick = onAttractivePointClick, + onReadStatusClick = onReadStatusClick, + onRatingClick = onRatingClick, + onResetClick = onResetClick, + onFilterSearchClick = onFilterSearchClick, ) } } diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt index 94dbf403d..3ac822731 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt @@ -4,12 +4,15 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn +import com.into.websoso.core.common.extensions.isCloseTo import com.into.websoso.data.filter.FilterRepository import com.into.websoso.data.library.LibraryRepository import com.into.websoso.data.library.model.NovelEntity import com.into.websoso.domain.library.model.AttractivePoints import com.into.websoso.domain.library.model.ReadStatus +import com.into.websoso.feature.library.model.LibraryFilterUiState import com.into.websoso.feature.library.model.LibraryUiState +import com.into.websoso.feature.library.model.RatingLevelUiModel import com.into.websoso.feature.library.model.SortTypeUiModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.channels.Channel @@ -32,6 +35,9 @@ class LibraryViewModel private val _uiState = MutableStateFlow(LibraryUiState()) val uiState: StateFlow = _uiState.asStateFlow() + private val _tempFilterUiState = MutableStateFlow(uiState.value.libraryFilterUiState) + val tempFilterUiState = _tempFilterUiState.asStateFlow() + private val _scrollToTopEvent = Channel(Channel.BUFFERED) val scrollToTopEvent: Flow = _scrollToTopEvent.receiveAsFlow() @@ -72,6 +78,12 @@ class LibraryViewModel } } + fun resetScrollPosition() { + viewModelScope.launch { + _scrollToTopEvent.send(Unit) + } + } + fun updateSortType() { val current = uiState.value.libraryFilterUiState.selectedSortType val newSortType = when (current) { @@ -96,9 +108,53 @@ class LibraryViewModel } } - fun resetScrollPosition() { + fun updateMyLibraryFilter() { + _tempFilterUiState.update { + uiState.value.libraryFilterUiState + } + } + + fun updateReadStatus(readStatus: ReadStatus) { + _tempFilterUiState.update { + it.copy( + readStatuses = it.readStatuses.mapValues { (key, value) -> + if (key == readStatus) !value else value + }, + ) + } + } + + fun updateAttractivePoints(attractivePoint: AttractivePoints) { + _tempFilterUiState.update { + it.copy( + attractivePoints = it.attractivePoints.mapValues { (key, value) -> + if (key == attractivePoint) !value else value + }, + ) + } + } + + fun updateRating(rating: RatingLevelUiModel) { + _tempFilterUiState.update { + it.copy( + novelRating = if (it.novelRating.isCloseTo(rating.value)) 0f else rating.value, + ) + } + } + + fun resetFilter() { + _tempFilterUiState.update { + LibraryFilterUiState() + } + } + + fun searchFilteredNovels() { viewModelScope.launch { - _scrollToTopEvent.send(Unit) + filterRepository.updateFilter( + readStatuses = _tempFilterUiState.value.readStatuses.mapKeys { it.key.key }, + attractivePoints = _tempFilterUiState.value.attractivePoints.mapKeys { it.key.key }, + novelRating = _tempFilterUiState.value.novelRating, + ) } } } diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterBottomSheetScreen.kt b/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterBottomSheetScreen.kt index 1618af38a..907f5d355 100644 --- a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterBottomSheetScreen.kt +++ b/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterBottomSheetScreen.kt @@ -13,12 +13,9 @@ import androidx.compose.material3.SheetValue import androidx.compose.material3.Text import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.into.websoso.core.designsystem.theme.Black import com.into.websoso.core.designsystem.theme.WebsosoTheme import com.into.websoso.core.designsystem.theme.White @@ -29,28 +26,32 @@ import com.into.websoso.feature.library.filter.component.LibraryFilterBottomShee import com.into.websoso.feature.library.filter.component.LibraryFilterBottomSheetHeader import com.into.websoso.feature.library.filter.component.LibraryFilterBottomSheetNovelRatingGrid import com.into.websoso.feature.library.filter.component.LibraryFilterBottomSheetReadStatus +import com.into.websoso.feature.library.model.LibraryFilterUiState import com.into.websoso.feature.library.model.RatingLevelUiModel @Composable @OptIn(ExperimentalMaterial3Api::class) internal fun LibraryFilterBottomSheetScreen( + filterUiState: LibraryFilterUiState, onDismissRequest: () -> Unit, sheetState: SheetState, - viewModel: LibraryFilterViewModel, + onAttractivePointClick: (AttractivePoints) -> Unit, + onReadStatusClick: (ReadStatus) -> Unit, + onRatingClick: (rating: RatingLevelUiModel) -> Unit, + onResetClick: () -> Unit, + onFilterSearchClick: () -> Unit, ) { - val uiState by viewModel.uiState.collectAsStateWithLifecycle() - LibraryFilterBottomSheetScreen( sheetState = sheetState, - readStatues = uiState.readStatuses, - attractivePoints = uiState.attractivePoints, - selectedRating = uiState.novelRating, + readStatues = filterUiState.readStatuses, + attractivePoints = filterUiState.attractivePoints, + selectedRating = filterUiState.novelRating, onDismissRequest = onDismissRequest, - onAttractivePointClick = viewModel::updateAttractivePoints, - onReadStatusClick = viewModel::updateReadStatus, - onRatingClick = viewModel::updateRating, - onResetClick = viewModel::resetFilter, - onFilterSearchClick = viewModel::searchFilteredNovels, + onAttractivePointClick = onAttractivePointClick, + onReadStatusClick = onReadStatusClick, + onRatingClick = onRatingClick, + onResetClick = onResetClick, + onFilterSearchClick = onFilterSearchClick, ) } @@ -134,12 +135,17 @@ private fun LibraryFilterBottomSheetScreen( private fun LibraryFilterBottomSheetPreview() { WebsosoTheme { LibraryFilterBottomSheetScreen( - viewModel = hiltViewModel(), onDismissRequest = {}, sheetState = rememberStandardBottomSheetState( initialValue = SheetValue.Expanded, skipHiddenState = false, ), + filterUiState = LibraryFilterUiState(), + onAttractivePointClick = { }, + onReadStatusClick = { }, + onRatingClick = { }, + onResetClick = { }, + onFilterSearchClick = { }, ) } } diff --git a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt b/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt deleted file mode 100644 index 13f9d6c64..000000000 --- a/feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterViewModel.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.into.websoso.feature.library.filter - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.into.websoso.core.common.extensions.isCloseTo -import com.into.websoso.data.filter.FilterRepository -import com.into.websoso.domain.library.model.AttractivePoints -import com.into.websoso.domain.library.model.ReadStatus -import com.into.websoso.feature.library.model.LibraryFilterUiState -import com.into.websoso.feature.library.model.RatingLevelUiModel -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class LibraryFilterViewModel - @Inject - constructor( - private val filterRepository: FilterRepository, - ) : ViewModel() { - private val _uiState = MutableStateFlow(LibraryFilterUiState()) - val uiState = _uiState.asStateFlow() - - fun updateMyLibraryFilter(libraryFilterUiState: LibraryFilterUiState) { - viewModelScope.launch { - _uiState.update { - libraryFilterUiState - } - } - } - - fun updateReadStatus(readStatus: ReadStatus) { - _uiState.update { - it.copy( - readStatuses = it.readStatuses.mapValues { (key, value) -> - if (key == readStatus) !value else value - }, - ) - } - } - - fun updateAttractivePoints(attractivePoint: AttractivePoints) { - _uiState.update { - it.copy( - attractivePoints = it.attractivePoints.mapValues { (key, value) -> - if (key == attractivePoint) !value else value - }, - ) - } - } - - fun updateRating(rating: RatingLevelUiModel) { - _uiState.update { - it.copy( - novelRating = if (it.novelRating.isCloseTo(rating.value)) 0f else rating.value, - ) - } - } - - fun resetFilter() { - _uiState.update { - LibraryFilterUiState() - } - } - - fun searchFilteredNovels() { - viewModelScope.launch { - filterRepository.updateFilter( - readStatuses = uiState.value.readStatuses.mapKeys { it.key.key }, - attractivePoints = uiState.value.attractivePoints.mapKeys { it.key.key }, - novelRating = uiState.value.novelRating, - ) - } - } - } From f3953c0f24c92f888892784a652ec92a7a60ba0b Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:52:16 +0900 Subject: [PATCH 10/13] =?UTF-8?q?refactor:=20=EC=84=9C=EC=9E=AC=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=97=90=20=EC=98=A4=ED=94=84?= =?UTF-8?q?=EC=85=8B=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/into/websoso/core/database/dao/FilteredNovelDao.kt | 3 +++ .../data/library/datasource/FilteredLibraryLocalDataSource.kt | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/database/src/main/java/com/into/websoso/core/database/dao/FilteredNovelDao.kt b/core/database/src/main/java/com/into/websoso/core/database/dao/FilteredNovelDao.kt index 3da9348a3..50aa44b6a 100644 --- a/core/database/src/main/java/com/into/websoso/core/database/dao/FilteredNovelDao.kt +++ b/core/database/src/main/java/com/into/websoso/core/database/dao/FilteredNovelDao.kt @@ -23,6 +23,9 @@ interface FilteredNovelDao { @Query("DELETE FROM filtered_novels") suspend fun clearAll() + + @Query("SELECT COUNT(*) FROM filtered_novels") + suspend fun selectNovelsCount(): Int } @Module diff --git a/data/library/src/main/java/com/into/websoso/data/library/datasource/FilteredLibraryLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/library/datasource/FilteredLibraryLocalDataSource.kt index a3c77a720..99c57b970 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/datasource/FilteredLibraryLocalDataSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/datasource/FilteredLibraryLocalDataSource.kt @@ -25,9 +25,10 @@ internal class DefaultFilteredLibraryLocalDataSource private val filteredNovelDao: FilteredNovelDao, ) : FilteredLibraryLocalDataSource { override suspend fun insertNovels(novels: List) { + val offset = filteredNovelDao.selectNovelsCount() filteredNovelDao.insertFilteredNovels( novels.mapIndexed { index, novelEntity -> - novelEntity.toFilteredNovelDatabase(index) + novelEntity.toFilteredNovelDatabase(offset + index) }, ) } From f3b01269b77f9ad842b5cc70844eaf3a58da6e3e Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 16:57:21 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor:=20hilt=20=EC=8A=A4=EC=BD=94?= =?UTF-8?q?=ED=94=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../into/websoso/core/common/util/navigator/WebsosoNavigator.kt | 2 +- .../common/util/sessionManager/WebsosoAuthSessionManager.kt | 2 +- .../java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt | 2 ++ .../datastore/datasource/account/DefaultAccountDataSource.kt | 2 +- .../datasource/library/DefaultLibraryFilterDataSource.kt | 2 +- .../core/network/datasource/account/DefaultAccountDataSource.kt | 2 +- .../core/network/datasource/library/DefaultLibraryDataSource.kt | 2 +- .../websoso/data/library/datasource/LibraryLocalDataSource.kt | 2 +- 8 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt index bb6448099..600ad8318 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt @@ -17,6 +17,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class WebsosoNavigator @Inject constructor( @@ -72,6 +73,5 @@ internal class WebsosoNavigator @InstallIn(SingletonComponent::class) internal interface NavigatorModule { @Binds - @Singleton fun bindWebsosoNavigator(websosoNavigator: WebsosoNavigator): NavigatorProvider } diff --git a/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt b/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt index a7b598203..48468d600 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.asSharedFlow import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class WebsosoAuthSessionManager @Inject constructor() : AuthSessionManager { @@ -26,6 +27,5 @@ internal class WebsosoAuthSessionManager @InstallIn(SingletonComponent::class) internal interface WebsosoAuthSessionManagerModule { @Binds - @Singleton fun bindWebsosoAuthSessionManager(websosoAuthSessionManager: WebsosoAuthSessionManager): AuthSessionManager } diff --git a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt index ce5e979dc..f468fc072 100644 --- a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt +++ b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt @@ -8,12 +8,14 @@ import com.kakao.sdk.common.model.ClientError import com.kakao.sdk.common.model.ClientErrorCause import com.kakao.sdk.user.UserApiClient import dagger.hilt.android.qualifiers.ActivityContext +import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.suspendCancellableCoroutine import javax.inject.Inject import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +@ActivityScoped class KakaoAuthClient @Inject constructor( diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt index 8aa6a748d..7732f0340 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.map import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -61,6 +62,5 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds - @Singleton fun bindAccountLocalDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountLocalDataSource } diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt index 6e34a676c..bf95a4b35 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt @@ -26,6 +26,7 @@ import kotlinx.serialization.json.Json import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class DefaultLibraryFilterDataSource @Inject constructor( @@ -69,6 +70,5 @@ internal class DefaultLibraryFilterDataSource @InstallIn(SingletonComponent::class) internal interface LibraryFilterDataSourceModule { @Binds - @Singleton fun bindLibraryFilterLocalDataSource(defaultLibraryFilterDataSource: DefaultLibraryFilterDataSource): LibraryFilterLocalDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt index 5d4cba9ad..71861ec4c 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt @@ -15,6 +15,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -65,6 +66,5 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds - @Singleton fun bindAccountRemoteDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountRemoteDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt index bdc1c328e..5fbb06a14 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt @@ -9,6 +9,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton +@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -45,6 +46,5 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds - @Singleton fun bindLibraryRemoteDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryRemoteDataSource } diff --git a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt index 8c186f548..a44704af2 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt @@ -19,6 +19,7 @@ interface LibraryLocalDataSource { suspend fun deleteAllNovels() } +@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -39,6 +40,5 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds - @Singleton fun bindLibraryLocalDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryLocalDataSource } From aade3151471d4349e15c2ceab2541efd0cb55798 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 17:53:02 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20hilt=20=EC=8A=A4=EC=BD=94?= =?UTF-8?q?=ED=94=84=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/util/navigator/WebsosoNavigator.kt | 2 +- .../com/into/websoso/core/auth_kakao/KakaoAuthClient.kt | 2 -- .../websoso/core/auth_kakao/di/KakaoAuthClientModule.kt | 2 ++ .../datasource/account/DefaultAccountDataSource.kt | 2 +- .../datasource/library/DefaultLibraryFilterDataSource.kt | 2 +- .../datasource/account/DefaultAccountDataSource.kt | 2 +- .../datasource/library/DefaultLibraryDataSource.kt | 2 +- .../data/library/datasource/LibraryLocalDataSource.kt | 2 +- .../websoso/data/library/paging/LibraryPagingSource.kt | 8 +++----- 9 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt index 600ad8318..bb6448099 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt @@ -17,7 +17,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class WebsosoNavigator @Inject constructor( @@ -73,5 +72,6 @@ internal class WebsosoNavigator @InstallIn(SingletonComponent::class) internal interface NavigatorModule { @Binds + @Singleton fun bindWebsosoNavigator(websosoNavigator: WebsosoNavigator): NavigatorProvider } diff --git a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt index f468fc072..ce5e979dc 100644 --- a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt +++ b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt @@ -8,14 +8,12 @@ import com.kakao.sdk.common.model.ClientError import com.kakao.sdk.common.model.ClientErrorCause import com.kakao.sdk.user.UserApiClient import dagger.hilt.android.qualifiers.ActivityContext -import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.suspendCancellableCoroutine import javax.inject.Inject import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException -@ActivityScoped class KakaoAuthClient @Inject constructor( diff --git a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt index f5f3db1ba..f04aa97fd 100644 --- a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt +++ b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt @@ -8,12 +8,14 @@ import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityComponent +import dagger.hilt.android.scopes.ActivityScoped import dagger.multibindings.IntoMap @Module @InstallIn(ActivityComponent::class) internal interface KakaoAuthClientModule { @Binds + @ActivityScoped @IntoMap @AuthPlatformKey(AuthPlatform.KAKAO) fun bindKakaoAuthClient(kakaoAuthClient: KakaoAuthClient): AuthClient diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt index 7732f0340..8aa6a748d 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt @@ -15,7 +15,6 @@ import kotlinx.coroutines.flow.map import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -62,5 +61,6 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds + @Singleton fun bindAccountLocalDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountLocalDataSource } diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt index bf95a4b35..6e34a676c 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt @@ -26,7 +26,6 @@ import kotlinx.serialization.json.Json import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultLibraryFilterDataSource @Inject constructor( @@ -70,5 +69,6 @@ internal class DefaultLibraryFilterDataSource @InstallIn(SingletonComponent::class) internal interface LibraryFilterDataSourceModule { @Binds + @Singleton fun bindLibraryFilterLocalDataSource(defaultLibraryFilterDataSource: DefaultLibraryFilterDataSource): LibraryFilterLocalDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt index 71861ec4c..5d4cba9ad 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt @@ -15,7 +15,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -66,5 +65,6 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds + @Singleton fun bindAccountRemoteDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountRemoteDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt index 5fbb06a14..bdc1c328e 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt @@ -9,7 +9,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -46,5 +45,6 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds + @Singleton fun bindLibraryRemoteDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryRemoteDataSource } diff --git a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt index a44704af2..8c186f548 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt @@ -19,7 +19,6 @@ interface LibraryLocalDataSource { suspend fun deleteAllNovels() } -@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -40,5 +39,6 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds + @Singleton fun bindLibraryLocalDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryLocalDataSource } diff --git a/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt index ce1ee4db5..f3a5db86b 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt @@ -29,16 +29,14 @@ class LibraryPagingSource( updatedSince = null, ) - val novels = response.userNovels.map { it } - - val nextKey = if (response.isLoadable && novels.isNotEmpty()) { - novels.last().userNovelId + val nextKey = if (response.isLoadable && response.userNovels.isNotEmpty()) { + response.userNovels.last().userNovelId } else { null } LoadResult.Page( - data = novels, + data = response.userNovels, prevKey = null, nextKey = nextKey, ) From 78f19d64bc9a0571dcbea6be882d0581b9c5b092 Mon Sep 17 00:00:00 2001 From: s9hn Date: Wed, 30 Jul 2025 17:53:02 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20hilt=20=EC=8A=A4=EC=BD=94?= =?UTF-8?q?=ED=94=84=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/util/navigator/WebsosoNavigator.kt | 2 +- .../util/sessionManager/WebsosoAuthSessionManager.kt | 2 +- .../com/into/websoso/core/auth_kakao/KakaoAuthClient.kt | 2 -- .../websoso/core/auth_kakao/di/KakaoAuthClientModule.kt | 2 ++ .../datasource/account/DefaultAccountDataSource.kt | 2 +- .../datasource/library/DefaultLibraryFilterDataSource.kt | 2 +- .../datasource/account/DefaultAccountDataSource.kt | 2 +- .../datasource/library/DefaultLibraryDataSource.kt | 2 +- .../data/library/datasource/LibraryLocalDataSource.kt | 2 +- .../websoso/data/library/paging/LibraryPagingSource.kt | 8 +++----- 10 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt index 600ad8318..bb6448099 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/navigator/WebsosoNavigator.kt @@ -17,7 +17,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class WebsosoNavigator @Inject constructor( @@ -73,5 +72,6 @@ internal class WebsosoNavigator @InstallIn(SingletonComponent::class) internal interface NavigatorModule { @Binds + @Singleton fun bindWebsosoNavigator(websosoNavigator: WebsosoNavigator): NavigatorProvider } diff --git a/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt b/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt index 48468d600..a7b598203 100644 --- a/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt +++ b/app/src/main/java/com/into/websoso/core/common/util/sessionManager/WebsosoAuthSessionManager.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.flow.asSharedFlow import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class WebsosoAuthSessionManager @Inject constructor() : AuthSessionManager { @@ -27,5 +26,6 @@ internal class WebsosoAuthSessionManager @InstallIn(SingletonComponent::class) internal interface WebsosoAuthSessionManagerModule { @Binds + @Singleton fun bindWebsosoAuthSessionManager(websosoAuthSessionManager: WebsosoAuthSessionManager): AuthSessionManager } diff --git a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt index f468fc072..ce5e979dc 100644 --- a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt +++ b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/KakaoAuthClient.kt @@ -8,14 +8,12 @@ import com.kakao.sdk.common.model.ClientError import com.kakao.sdk.common.model.ClientErrorCause import com.kakao.sdk.user.UserApiClient import dagger.hilt.android.qualifiers.ActivityContext -import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.suspendCancellableCoroutine import javax.inject.Inject import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException -@ActivityScoped class KakaoAuthClient @Inject constructor( diff --git a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt index f5f3db1ba..f04aa97fd 100644 --- a/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt +++ b/core/auth-kakao/src/main/java/com/into/websoso/core/auth_kakao/di/KakaoAuthClientModule.kt @@ -8,12 +8,14 @@ import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityComponent +import dagger.hilt.android.scopes.ActivityScoped import dagger.multibindings.IntoMap @Module @InstallIn(ActivityComponent::class) internal interface KakaoAuthClientModule { @Binds + @ActivityScoped @IntoMap @AuthPlatformKey(AuthPlatform.KAKAO) fun bindKakaoAuthClient(kakaoAuthClient: KakaoAuthClient): AuthClient diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt index 7732f0340..8aa6a748d 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/account/DefaultAccountDataSource.kt @@ -15,7 +15,6 @@ import kotlinx.coroutines.flow.map import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -62,5 +61,6 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds + @Singleton fun bindAccountLocalDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountLocalDataSource } diff --git a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt index bf95a4b35..6e34a676c 100644 --- a/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt +++ b/core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt @@ -26,7 +26,6 @@ import kotlinx.serialization.json.Json import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultLibraryFilterDataSource @Inject constructor( @@ -70,5 +69,6 @@ internal class DefaultLibraryFilterDataSource @InstallIn(SingletonComponent::class) internal interface LibraryFilterDataSourceModule { @Binds + @Singleton fun bindLibraryFilterLocalDataSource(defaultLibraryFilterDataSource: DefaultLibraryFilterDataSource): LibraryFilterLocalDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt index 71861ec4c..5d4cba9ad 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/account/DefaultAccountDataSource.kt @@ -15,7 +15,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultAccountDataSource @Inject constructor( @@ -66,5 +65,6 @@ internal class DefaultAccountDataSource @InstallIn(SingletonComponent::class) internal interface AccountDataSourceModule { @Binds + @Singleton fun bindAccountRemoteDataSource(defaultAccountDataSource: DefaultAccountDataSource): AccountRemoteDataSource } diff --git a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt index 5fbb06a14..bdc1c328e 100644 --- a/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt +++ b/core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt @@ -9,7 +9,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton -@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -46,5 +45,6 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds + @Singleton fun bindLibraryRemoteDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryRemoteDataSource } diff --git a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt index a44704af2..8c186f548 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryLocalDataSource.kt @@ -19,7 +19,6 @@ interface LibraryLocalDataSource { suspend fun deleteAllNovels() } -@Singleton internal class DefaultLibraryDataSource @Inject constructor( @@ -40,5 +39,6 @@ internal class DefaultLibraryDataSource @InstallIn(SingletonComponent::class) internal interface LibraryDataSourceModule { @Binds + @Singleton fun bindLibraryLocalDataSource(defaultLibraryDataSource: DefaultLibraryDataSource): LibraryLocalDataSource } diff --git a/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt index ce1ee4db5..f3a5db86b 100644 --- a/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt +++ b/data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt @@ -29,16 +29,14 @@ class LibraryPagingSource( updatedSince = null, ) - val novels = response.userNovels.map { it } - - val nextKey = if (response.isLoadable && novels.isNotEmpty()) { - novels.last().userNovelId + val nextKey = if (response.isLoadable && response.userNovels.isNotEmpty()) { + response.userNovels.last().userNovelId } else { null } LoadResult.Page( - data = novels, + data = response.userNovels, prevKey = null, nextKey = nextKey, )