Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class OtherUserLibraryFragment : BaseFragment<FragmentOtherUserLibraryBinding>(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,
Expand All @@ -63,7 +64,6 @@ class OtherUserLibraryFragment : BaseFragment<FragmentOtherUserLibraryBinding>(f
}

private fun updateUserId() {
val userId = arguments?.getLong(USER_ID_KEY) ?: 0L
otherUserLibraryViewModel.updateUserId(userId)
}

Expand Down Expand Up @@ -222,7 +222,7 @@ class OtherUserLibraryFragment : BaseFragment<FragmentOtherUserLibraryBinding>(f
}

private fun navigateToUserStorageActivity() {
websosoNavigator.navigateToUserStorageActivity(::startActivity)
websosoNavigator.navigateToUserStorageActivity(::startActivity, userId)
}

override fun onResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<Preferences>,
@LibraryFilterDataStore private val libraryFilterDataStore: DataStore<Preferences>,
@Dispatcher(WebsosoDispatchers.DEFAULT) private val dispatcher: CoroutineDispatcher,
) : MyLibraryFilterLocalDataSource {
override val myLibraryFilterFlow: Flow<LibraryFilterParams?>
get() = myLibraryFilterDataStore.data
) : LibraryFilterLocalDataSource {
override val libraryFilterFlow: Flow<LibraryFilter?>
get() = libraryFilterDataStore.data
.map { prefs ->
prefs[LIBRARY_FILTER_PARAMS_KEY]?.let { jsonString ->
withContext(dispatcher) {
Expand All @@ -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
}
}
Comment on lines +45 to 55
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

JSON 인코딩 및 DataStore 작업에 대한 오류 처리 추가 필요

JSON 인코딩이나 DataStore 쓰기 작업이 실패할 경우를 대비한 try-catch 블록 추가를 고려해보세요.

 override suspend fun updateLibraryFilter(params: LibraryFilter) {
-    val encodedJsonString = withContext(dispatcher) {
-        Json.encodeToString(
-            params.toPreferences(),
-        )
-    }
-
-    libraryFilterDataStore.edit { prefs ->
-        prefs[LIBRARY_FILTER_PARAMS_KEY] = encodedJsonString
+    try {
+        val encodedJsonString = withContext(dispatcher) {
+            Json.encodeToString(
+                params.toPreferences(),
+            )
+        }
+
+        libraryFilterDataStore.edit { prefs ->
+            prefs[LIBRARY_FILTER_PARAMS_KEY] = encodedJsonString
+        }
+    } catch (e: Exception) {
+        // 로깅 또는 에러 전파
+        throw e
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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 updateLibraryFilter(params: LibraryFilter) {
try {
val encodedJsonString = withContext(dispatcher) {
Json.encodeToString(
params.toPreferences(),
)
}
libraryFilterDataStore.edit { prefs ->
prefs[LIBRARY_FILTER_PARAMS_KEY] = encodedJsonString
}
} catch (e: Exception) {
// 로깅 또는 에러 전파
throw e
}
}
🤖 Prompt for AI Agents
In
core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt
around lines 46 to 56, the current implementation lacks error handling for JSON
encoding and DataStore editing operations. Wrap the JSON encoding and DataStore
edit calls inside a try-catch block to catch any exceptions that may occur
during these operations. In the catch block, handle or log the error
appropriately to ensure failures are managed gracefully.


override suspend fun deleteMyLibraryFilter() {
myLibraryFilterDataStore.edit { prefs ->
override suspend fun deleteLibraryFilter() {
libraryFilterDataStore.edit { prefs ->
prefs.remove(LIBRARY_FILTER_PARAMS_KEY)
}
}
Expand All @@ -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
}
Original file line number Diff line number Diff line change
@@ -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,
)
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -10,22 +9,4 @@ internal data class LibraryFilterPreferences(
val readStatuses: Map<String, Boolean>,
val attractivePoints: Map<String, Boolean>,
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,
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ internal object DataStoreModule {
private const val ACCOUNT_DATASTORE = "ACCOUNT_DATASTORE"
private val Context.accountDataStore: DataStore<Preferences> by preferencesDataStore(name = ACCOUNT_DATASTORE)

private const val MY_LIBRARY_FILTER_DATASTORE = "MY_LIBRARY_FILTER_DATASTORE"
private val Context.myLibraryFilterDataStore: DataStore<Preferences> by preferencesDataStore(
name = MY_LIBRARY_FILTER_DATASTORE,
private const val LIBRARY_FILTER_DATASTORE = "LIBRARY_FILTER_DATASTORE"
private val Context.libraryFilterDataStore: DataStore<Preferences> by preferencesDataStore(
name = LIBRARY_FILTER_DATASTORE,
)

@Provides
Expand All @@ -31,8 +31,8 @@ internal object DataStoreModule {

@Provides
@Singleton
@MyLibraryFilterDataStore
internal fun provideMyLibraryFilterPreferencesDataStore(
@LibraryFilterDataStore
internal fun provideLibraryFilterPreferencesDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.myLibraryFilterDataStore
): DataStore<Preferences> = context.libraryFilterDataStore
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ internal annotation class AccountDataStore

@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class MyLibraryFilterDataStore
internal annotation class LibraryFilterDataStore
Original file line number Diff line number Diff line change
@@ -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<LibraryFilter>

suspend fun updateFilter(
readStatuses: Map<String, Boolean>? = null,
attractivePoints: Map<String, Boolean>? = null,
novelRating: Float? = null,
isInterested: Boolean? = null,
sortCriteria: String? = null,
)
}
Original file line number Diff line number Diff line change
@@ -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<LibraryFilter?>

suspend fun updateLibraryFilter(params: LibraryFilter)

suspend fun deleteLibraryFilter()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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
import dagger.hilt.android.scopes.ViewModelScoped
import javax.inject.Provider

@Module
@InstallIn(ViewModelComponent::class)
internal object FilterRepositoryModule {
@Provides
@ViewModelScoped
fun provideFilterRepository(
savedStateHandle: SavedStateHandle,
myFilterRepository: Provider<MyLibraryFilterRepository>,
userFilterRepository: Provider<UserLibraryFilterRepository>,
): FilterRepository {
val userId: Long? = savedStateHandle["USER_ID"]
return if (userId == null) myFilterRepository.get() else userFilterRepository.get()
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Boolean> = emptyMap(),
val attractivePoints: Map<String, Boolean> = emptyMap(),
) {
val readStatusKeys: List<String> = readStatuses.toSelectedKeyList { it }
val attractivePointKeys: List<String> = attractivePoints.toSelectedKeyList { it }

private fun <K> Map<K, Boolean>.toSelectedKeyList(toSelectedKeyName: (K) -> String): List<String> =
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
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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

internal class MyLibraryFilterRepository
@Inject
constructor(
private val myLibraryFilterLocalDataSource: LibraryFilterLocalDataSource,
) : FilterRepository {
override val filterFlow: Flow<LibraryFilter> =
myLibraryFilterLocalDataSource.libraryFilterFlow
.map { it ?: LibraryFilter() }
.distinctUntilChanged()

override suspend fun updateFilter(
readStatuses: Map<String, Boolean>?,
attractivePoints: Map<String, Boolean>?,
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)
}
}
Loading