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 @@ -4,8 +4,10 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import com.into.websoso.core.datastore.di.UserDataStore
import com.into.websoso.user.datasource.UserLocalDataSource
import com.into.websoso.user.model.UserInfoEntity
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -19,19 +21,36 @@ internal class DefaultUserDataSource
constructor(
@UserDataStore private val userDataStorage: DataStore<Preferences>,
) : UserLocalDataSource {
override suspend fun getUserId(): Long {
override suspend fun getUserInfo(): UserInfoEntity {
val preferences = userDataStorage.data.first()
return preferences[USER_ID] ?: -1L

val userId = preferences[USER_ID] ?: -1L
val nickname = preferences[USER_NICKNAME_KEY] ?: ""
val gender = preferences[USER_GENDER_KEY] ?: ""

return UserInfoEntity(
userId = userId,
nickname = nickname,
gender = gender,
)
}

override suspend fun updateUserId(userId: Long) {
override suspend fun updateUserInfo(
userId: Long,
nickname: String,
gender: String,
) {
userDataStorage.edit { preferences ->
preferences[USER_ID] = userId
preferences[USER_NICKNAME_KEY] = nickname
preferences[USER_GENDER_KEY] = gender
}
}

companion object {
private val USER_ID = longPreferencesKey("USERID")
private val USER_NICKNAME_KEY = stringPreferencesKey("USER_NICKNAME")
private val USER_GENDER_KEY = stringPreferencesKey("USER_GENDER")
}
}

Expand All @@ -40,5 +59,5 @@ internal class DefaultUserDataSource
internal interface UserDataStorage {
@Binds
@Singleton
fun bindUserLocalDataSource(defaultUserDataSource: DefaultUserDataSource): DefaultUserDataSource
fun bindUserLocalDataSource(defaultUserDataSource: DefaultUserDataSource): UserLocalDataSource
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ internal object DataStoreModule {
name = LIBRARY_FILTER_DATASTORE,
)

private const val USER_DATASTORE = "USER_DATASTORE"
private val Context.userDataStore: DataStore<Preferences> by preferencesDataStore(
name = USER_DATASTORE,
)

@Provides
@Singleton
@AccountDataStore
Expand All @@ -35,4 +40,11 @@ internal object DataStoreModule {
internal fun provideLibraryFilterPreferencesDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.libraryFilterDataStore

@Provides
@Singleton
@UserDataStore
fun provideUserDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.userDataStore
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.into.websoso.core.network.datasource.user

import com.into.websoso.core.network.datasource.user.model.MyProfileResponseDto
import com.into.websoso.core.network.datasource.user.model.UserFeedsResponseDto
import com.into.websoso.core.network.datasource.user.model.UserInfoResponseDto
import dagger.Module
Expand All @@ -18,10 +19,17 @@ interface UserApi {
@Path("userId") userId: Long,
@Query("lastFeedId") lastFeedId: Long,
@Query("size") size: Int,
@Query("genres") genres: Array<String>?,
@Query("isVisible") isVisible: Boolean?,
@Query("isUnVisible") isUnVisible: Boolean?,
@Query("sortCriteria") sortCriteria: String?,
): UserFeedsResponseDto

@GET("users/me")
suspend fun getUserInfo(): UserInfoResponseDto

@GET("users/my-profile")
suspend fun getMyProfile(): MyProfileResponseDto
}

@Module
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.into.websoso.core.network.datasource.user.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class MyProfileResponseDto(
@SerialName("nickname")
val nickname: String,
@SerialName("intro")
val intro: String,
@SerialName("avatarImage")
val avatarImage: String,
@SerialName("genrePreferences")
val genrePreferences: List<String>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ data class UserFeedsResponseDto(
val novelRatingCount: Int?,
@SerialName("relevantCategories")
val relevantCategories: List<String>,
@SerialName("genre")
val genre: String?,
@SerialName("userNovelRating")
val userNovelRating: Float?,
@SerialName("thumbnailUrl")
val thumbnailUrl: String?,
@SerialName("imageCount")
val imageCount: Int,
@SerialName("feedWriterNovelRating")
val feedWriterNovelRating: Float?,
@SerialName("title")
val title: String?,
)
Expand Down
14 changes: 14 additions & 0 deletions core/resource/src/main/res/drawable/ic_novel_unselected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12C0,5.373 5.373,0 12,0Z"
android:fillColor="#DDDDE3"
android:fillType="evenOdd"/>
<path
android:pathData="M18.473,7.265C18.664,7.456 18.771,7.715 18.771,7.985C18.771,8.254 18.664,8.513 18.473,8.704L10.846,16.332C10.745,16.433 10.625,16.513 10.493,16.567C10.362,16.622 10.221,16.65 10.078,16.65C9.935,16.65 9.794,16.622 9.663,16.567C9.531,16.513 9.411,16.433 9.31,16.332L5.521,12.543C5.423,12.449 5.346,12.337 5.293,12.212C5.239,12.088 5.211,11.955 5.21,11.819C5.209,11.684 5.235,11.55 5.286,11.425C5.337,11.3 5.412,11.187 5.508,11.091C5.604,10.995 5.717,10.92 5.842,10.869C5.967,10.818 6.101,10.792 6.236,10.793C6.372,10.794 6.505,10.822 6.629,10.876C6.753,10.929 6.866,11.007 6.96,11.104L10.078,14.222L17.034,7.265C17.128,7.171 17.24,7.096 17.364,7.044C17.487,6.993 17.62,6.967 17.754,6.967C17.887,6.967 18.02,6.993 18.143,7.044C18.267,7.096 18.379,7.171 18.473,7.265Z"
android:fillColor="#EEEEF2"
android:fillType="evenOdd"/>
</vector>
10 changes: 10 additions & 0 deletions core/resource/src/main/res/drawable/ic_unvisible.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:pathData="M5.25,7.5V5.25C5.25,4.255 5.645,3.302 6.348,2.598C7.052,1.895 8.005,1.5 9,1.5C9.995,1.5 10.948,1.895 11.652,2.598C12.355,3.302 12.75,4.255 12.75,5.25V7.5H13.5C13.898,7.5 14.279,7.658 14.561,7.939C14.842,8.221 15,8.602 15,9V15C15,15.398 14.842,15.779 14.561,16.061C14.279,16.342 13.898,16.5 13.5,16.5H4.5C4.102,16.5 3.721,16.342 3.439,16.061C3.158,15.779 3,15.398 3,15V9C3,8.602 3.158,8.221 3.439,7.939C3.721,7.658 4.102,7.5 4.5,7.5H5.25ZM4.5,9V15H13.5V9H4.5ZM6.75,7.5H11.25V5.25C11.25,4.653 11.013,4.081 10.591,3.659C10.169,3.237 9.597,3 9,3C8.403,3 7.831,3.237 7.409,3.659C6.987,4.081 6.75,4.653 6.75,5.25V7.5ZM10.5,10.5H12V13.5H10.5V10.5Z"
android:fillColor="#949399"
android:fillType="evenOdd"/>
</vector>
10 changes: 10 additions & 0 deletions core/resource/src/main/res/drawable/ic_visible.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:pathData="M2.744,9.512L2.515,8.997L2.744,8.482C3.271,7.296 4.131,6.289 5.219,5.582C6.307,4.875 7.577,4.498 8.874,4.498C10.172,4.498 11.442,4.875 12.53,5.582C13.618,6.289 14.477,7.296 15.004,8.482L15.232,8.997L15.003,9.512C14.476,10.698 13.617,11.705 12.529,12.412C11.441,13.119 10.171,13.495 8.874,13.495C7.576,13.495 6.307,13.119 5.219,12.412C4.131,11.705 3.271,10.698 2.744,9.512ZM1.374,7.873L1.114,8.458C1.039,8.628 1,8.812 1,8.998C1,9.183 1.039,9.367 1.114,9.537L1.374,10.121C2.019,11.572 3.071,12.804 4.402,13.669C5.733,14.534 7.287,14.994 8.874,14.994C10.462,14.994 12.015,14.534 13.346,13.669C14.678,12.804 15.729,11.572 16.374,10.121L16.634,9.537C16.71,9.367 16.749,9.183 16.749,8.997C16.749,8.811 16.71,8.627 16.634,8.457L16.374,7.873C15.729,6.423 14.678,5.19 13.346,4.325C12.015,3.46 10.462,3 8.874,3C7.287,3 5.733,3.46 4.402,4.325C3.071,5.19 2.019,6.423 1.374,7.873ZM10.374,8.997C10.374,9.395 10.216,9.776 9.935,10.058C9.654,10.339 9.272,10.497 8.874,10.497C8.477,10.497 8.095,10.339 7.814,10.058C7.532,9.776 7.374,9.395 7.374,8.997C7.374,8.599 7.532,8.218 7.814,7.936C8.095,7.655 8.477,7.497 8.874,7.497C9.272,7.497 9.654,7.655 9.935,7.936C10.216,8.218 10.374,8.599 10.374,8.997ZM11.874,8.997C11.874,9.793 11.558,10.556 10.996,11.118C10.433,11.681 9.67,11.997 8.874,11.997C8.079,11.997 7.316,11.681 6.753,11.118C6.19,10.556 5.874,9.793 5.874,8.997C5.874,8.201 6.19,7.438 6.753,6.876C7.316,6.313 8.079,5.997 8.874,5.997C9.67,5.997 10.433,6.313 10.996,6.876C11.558,7.438 11.874,8.201 11.874,8.997Z"
android:fillColor="#949399"
android:fillType="evenOdd"/>
</vector>
47 changes: 39 additions & 8 deletions data/user/src/main/java/com/into/websoso/user/UserRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.into.websoso.user
import com.into.websoso.core.network.datasource.user.UserApi
import com.into.websoso.user.datasource.UserLocalDataSource
import com.into.websoso.user.mapper.toData
import com.into.websoso.user.model.MyProfileEntity
import com.into.websoso.user.model.UserFeedsEntity
import com.into.websoso.user.model.UserInfoEntity
import jakarta.inject.Inject
Expand All @@ -15,27 +16,57 @@ class UserRepository
) {
suspend fun fetchUserInfo(): UserInfoEntity {
val userInfo = userApi.getUserInfo().toData()
saveUserInfo(userInfo.userId)
saveUserInfo(userInfo.userId, userInfo.nickname, userInfo.gender)
return userInfo
}

private suspend fun saveUserInfo(userId: Long) {
userLocalDataSource.updateUserId(userId)
private suspend fun saveUserInfo(
userId: Long,
nickname: String,
gender: String,
) {
userLocalDataSource.updateUserInfo(userId, nickname, gender)
}

suspend fun fetchMyActivities(
lastFeedId: Long,
size: Int,
genres: Array<String>?,
isVisible: Boolean?,
isUnVisible: Boolean?,
sortCriteria: String?,
): UserFeedsEntity {
val myUserId = fetchUserId()
return fetchUserFeeds(myUserId, lastFeedId, size)
val myUserId = fetchUserInfo().userId
return fetchUserFeeds(
myUserId,
lastFeedId,
size,
genres,
isVisible,
isUnVisible,
sortCriteria,
)
}

suspend fun fetchUserId(): Long = userLocalDataSource.getUserId()

suspend fun fetchUserFeeds(
userId: Long,
lastFeedId: Long,
size: Int,
): UserFeedsEntity = userApi.getUserFeeds(userId, lastFeedId, size).toData()
genres: Array<String>? = null,
isVisible: Boolean? = null,
isUnVisible: Boolean? = null,
sortCriteria: String? = null,
): UserFeedsEntity =
userApi
.getUserFeeds(
userId,
lastFeedId,
size,
genres,
isVisible,
isUnVisible,
sortCriteria,
).toData()

suspend fun fetchMyProfile(): MyProfileEntity = userApi.getMyProfile().toData()
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.into.websoso.user.datasource

import com.into.websoso.user.model.UserInfoEntity

interface UserLocalDataSource {
suspend fun getUserId(): Long
suspend fun getUserInfo(): UserInfoEntity

suspend fun updateUserId(userId: Long)
suspend fun updateUserInfo(
userId: Long,
nickname: String,
gender: String,
)
}
15 changes: 15 additions & 0 deletions data/user/src/main/java/com/into/websoso/user/mapper/UserMapper.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.into.websoso.user.mapper

import com.into.websoso.core.network.datasource.user.model.MyProfileResponseDto
import com.into.websoso.core.network.datasource.user.model.UserFeedsResponseDto
import com.into.websoso.core.network.datasource.user.model.UserInfoResponseDto
import com.into.websoso.user.model.MyProfileEntity
import com.into.websoso.user.model.UserFeedsEntity
import com.into.websoso.user.model.UserInfoEntity

Expand All @@ -27,6 +29,11 @@ fun UserFeedsResponseDto.UserFeedResponseDto.toData(): UserFeedsEntity.UserFeedE
novelRatingCount = this.novelRatingCount,
novelRating = this.novelRating,
relevantCategories = this.relevantCategories,
genre = this.genre,
userNovelRating = this.userNovelRating,
thumbnailUrl = this.thumbnailUrl,
imageCount = this.imageCount,
feedWriterNovelRating = this.feedWriterNovelRating,
)

fun UserInfoResponseDto.toData(): UserInfoEntity =
Expand All @@ -35,3 +42,11 @@ fun UserInfoResponseDto.toData(): UserInfoEntity =
nickname = this.nickname,
gender = this.gender,
)

fun MyProfileResponseDto.toData(): MyProfileEntity =
MyProfileEntity(
nickname = this.nickname,
intro = this.intro,
avatarImage = this.avatarImage,
genrePreferences = this.genrePreferences,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.into.websoso.user.model

data class MyProfileEntity(
val nickname: String,
val intro: String,
val avatarImage: String,
val genrePreferences: List<String>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ data class UserFeedsEntity(
val novelRatingCount: Int?,
val novelRating: Float?,
val relevantCategories: List<String>,
val genre: String?,
val userNovelRating: Float?,
val thumbnailUrl: String?,
val imageCount: Int,
val feedWriterNovelRating: Float?,
)
}
1 change: 1 addition & 0 deletions domain/feed/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ android {
dependencies {
implementation(projects.core.common)
implementation(projects.data.feed)
implementation(projects.data.user)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.into.websoso.feed

import com.into.websoso.feed.mapper.toDomain
import com.into.websoso.feed.model.Feeds
import com.into.websoso.user.UserRepository
import com.into.websoso.user.model.MyProfileEntity
import com.into.websoso.user.model.UserFeedsEntity
import javax.inject.Inject

class GetMyFeedsUseCase
@Inject
constructor(
private val userRepository: UserRepository,
) {
private var myProfile: MyProfileEntity? = null
private var myId: Long? = null

suspend operator fun invoke(
lastFeedId: Long = INITIAL_ID,
size: Int = INITIAL_REQUEST_SIZE,
genres: List<String>? = null,
isVisible: Boolean? = null,
isUnVisible: Boolean? = null,
sortCriteria: String? = null,
): Feeds {
val isFeedRefreshed: Boolean = lastFeedId == INITIAL_ID
val profile = myProfile ?: userRepository.fetchMyProfile().also { myProfile = it }
val myId = myId ?: userRepository.fetchUserInfo().userId.also { myId = it }

val myFeeds: UserFeedsEntity = userRepository.fetchMyActivities(
lastFeedId = lastFeedId,
size = if (isFeedRefreshed) INITIAL_REQUEST_SIZE else ADDITIONAL_REQUEST_SIZE,
genres = genres?.toTypedArray(),
isVisible = isVisible,
isUnVisible = isUnVisible,
sortCriteria = sortCriteria,
)

return Feeds(
category = "내 활동",
isLoadable = myFeeds.isLoadable,
feeds = myFeeds.feeds.map { it.toDomain(myProfile = profile, id = myId) },
)
}

companion object {
private const val INITIAL_ID: Long = 0
private const val INITIAL_REQUEST_SIZE = 40
private const val ADDITIONAL_REQUEST_SIZE = 20
}
}
Loading