Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ android {

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "BASE_URL", properties["base.url"].toString())
buildConfigField("String", "OPEN_URL", properties["open.url"].toString())
}

buildTypes {
Expand Down Expand Up @@ -64,6 +65,7 @@ dependencies {
implementation(libs.coil.compose)
implementation(libs.retrofit.core)
implementation(libs.retrofit.kotlin.serialization)
implementation(libs.kotlinx.immutable)
implementation(libs.okhttp.logging)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopt.dive.data.datasource

import com.sopt.dive.data.dto.response.UserListResponseDto

interface OpenApiDataSource {
suspend fun getUsers(
page: Int
): UserListResponseDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sopt.dive.data.datasourceimpl

import com.sopt.dive.data.datasource.AuthDataSource
import com.sopt.dive.data.dto.request.LogInRequestDto
import com.sopt.dive.data.dto.response.BaseResponseDto
import com.sopt.dive.data.dto.response.LoginResponseDto

class FakeAuthDataSourceImpl : AuthDataSource {
override suspend fun postLogin(request: LogInRequestDto): BaseResponseDto<LoginResponseDto> {

return if (request.username == "seungjae" && request.password == "seungjae1234!") {
// 성공 응답
BaseResponseDto(
success = true,
code = "200",
message = "로그인 성공 (Fake)",
data = LoginResponseDto(
userId = 10L,
message = "로그인 성공 (Fake)"
)
)
} else {
// 실패 응답
BaseResponseDto(
success = false,
code = "400",
message = "아이디 또는 비밀번호가 올바르지 않습니다. (Fake)",
data = null
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sopt.dive.data.datasourceimpl

import com.sopt.dive.data.datasource.OpenApiDataSource
import com.sopt.dive.data.dto.response.UserListResponseDto
import com.sopt.dive.data.service.OpenApiService

class OpenApiDataSourceImpl(
private val openApiService: OpenApiService
) : OpenApiDataSource {
override suspend fun getUsers(page: Int): UserListResponseDto =
openApiService.getUsers(page = page)
}
31 changes: 31 additions & 0 deletions app/src/main/java/com/sopt/dive/data/model/FriendListModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.sopt.dive.data.model

import com.sopt.dive.data.dto.response.UserListResponseDto
import com.sopt.dive.data.dto.response.UserResponseDto

data class FriendListModel(
val friendList: List<FriendModel>
)

data class FriendModel(
val id: Int,
val email: String,
val firstName: String,
val lastName: String,
val avatar: String
)

fun UserListResponseDto.toModel() =
FriendListModel(
friendList = this.data.map { it.toModel() }
)

fun UserResponseDto.toModel() =
FriendModel(
id = this.id,
email = this.email,
firstName = this.firstName,
lastName = this.lastName,
avatar = this.avatar
)

18 changes: 17 additions & 1 deletion app/src/main/java/com/sopt/dive/data/remote/ApiFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.create

object ApiFactory {
private const val BASE_URL: String = BuildConfig.BASE_URL
private const val OPEN_URL: String = BuildConfig.OPEN_URL

private val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
Expand All @@ -27,5 +29,19 @@ object ApiFactory {
.build()
}

inline fun <reified T> create(): T = retrofit.create(T::class.java)
val openRetrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(OPEN_URL)
.client(client)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(isOpenApi: Boolean = false): T {
return if (isOpenApi) {
openRetrofit.create()
} else {
retrofit.create()
}
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/sopt/dive/data/remote/ServicePool.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sopt.dive.data.remote

import com.sopt.dive.data.service.AuthService
import com.sopt.dive.data.service.OpenApiService
import com.sopt.dive.data.service.UserService

object ServicePool {
Expand All @@ -10,4 +11,7 @@ object ServicePool {
val authService: AuthService by lazy {
ApiFactory.create<AuthService>()
}
val openApiService: OpenApiService by lazy {
ApiFactory.create<OpenApiService>(isOpenApi = true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopt.dive.data.repository

import com.sopt.dive.data.model.FriendListModel

interface OpenApiRepository {
suspend fun getUsers(
page: Int
): Result<FriendListModel>
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.sopt.dive.data.repository

import com.sopt.dive.data.datasource.AuthDataSource
import com.sopt.dive.data.datasource.OpenApiDataSource
import com.sopt.dive.data.datasource.UserDataSource
import com.sopt.dive.data.datasourceimpl.AuthDataSourceImpl
import com.sopt.dive.data.datasourceimpl.FakeAuthDataSourceImpl
import com.sopt.dive.data.datasourceimpl.OpenApiDataSourceImpl
import com.sopt.dive.data.datasourceimpl.UserDataSourceImpl
import com.sopt.dive.data.remote.ServicePool
import com.sopt.dive.data.repositoryimpl.AuthRepositoryImpl
import com.sopt.dive.data.repositoryimpl.OpenApiRepositoryImpl
import com.sopt.dive.data.repositoryimpl.UserRepositoryImpl

object RepositoryModule {
private val authDataSource: AuthDataSource by lazy {
AuthDataSourceImpl(ServicePool.authService)
// AuthDataSourceImpl(ServicePool.authService)
FakeAuthDataSourceImpl()
}

val authRepository: AuthRepository by lazy {
Expand All @@ -25,4 +29,12 @@ object RepositoryModule {
UserRepositoryImpl(userDataSource)
}

private val openApiDataSource: OpenApiDataSource by lazy {
OpenApiDataSourceImpl(ServicePool.openApiService)
}

val openApiRepository: OpenApiRepository by lazy {
OpenApiRepositoryImpl(openApiDataSource)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.sopt.dive.data.repositoryimpl

import com.sopt.dive.core.util.suspendRunCatching
import com.sopt.dive.data.datasource.OpenApiDataSource
import com.sopt.dive.data.model.FriendListModel
import com.sopt.dive.data.model.toModel
import com.sopt.dive.data.repository.OpenApiRepository

class OpenApiRepositoryImpl(

Choose a reason for hiding this comment

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

이번 세미나에서 배운 Impl까지 벌써 활용하셨네요 !! 🤩

private val openApiDataSource: OpenApiDataSource
) : OpenApiRepository {
override suspend fun getUsers(page: Int): Result<FriendListModel> =
suspendRunCatching {
openApiDataSource.getUsers(page = page).toModel()
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/com/sopt/dive/data/service/OpenApiService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sopt.dive.data.service

import com.sopt.dive.data.dto.response.UserListResponseDto
import retrofit2.http.GET
import retrofit2.http.Query

interface OpenApiService {
@GET("/api/users")
suspend fun getUsers(
@Query("page") page: Int = 2
): UserListResponseDto
}
7 changes: 0 additions & 7 deletions app/src/main/java/com/sopt/dive/data/service/UserService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ package com.sopt.dive.data.service
import com.sopt.dive.data.dto.request.RegisterRequestDto
import com.sopt.dive.data.dto.response.BaseResponseDto
import com.sopt.dive.data.dto.response.UserDetailResponseDto
import com.sopt.dive.data.dto.response.UserListResponseDto
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query

interface UserService {
@POST("/api/v1/users")
Expand All @@ -20,9 +18,4 @@ interface UserService {
suspend fun getUser(
@Path("id") id: Long
): BaseResponseDto<UserDetailResponseDto>

@GET("api/users")
suspend fun getUsers(
@Query("page") page: Int = 2
): UserListResponseDto
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,32 @@ package com.sopt.dive.presentation.common
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.sopt.dive.data.local.UserManager
import com.sopt.dive.data.repository.AuthRepository
import com.sopt.dive.data.repository.UserRepository
import com.sopt.dive.data.repository.RepositoryModule
import com.sopt.dive.presentation.home.HomeViewModel
import com.sopt.dive.presentation.mypage.MyPageViewModel
import com.sopt.dive.presentation.signin.SignInViewModel
import com.sopt.dive.presentation.signup.SignUpViewModel

class ViewModelFactory(
private val authRepository: AuthRepository,
private val userRepository: UserRepository,
private val userManager: UserManager
) : ViewModelProvider.Factory {

override fun <T : ViewModel> create(modelClass: Class<T>): T {
return when {
modelClass.isAssignableFrom(SignInViewModel::class.java) -> {
SignInViewModel(authRepository, userManager) as T
SignInViewModel(RepositoryModule.authRepository, userManager) as T
}

modelClass.isAssignableFrom(SignUpViewModel::class.java) -> {
SignUpViewModel(userManager, userRepository) as T
SignUpViewModel(userManager, RepositoryModule.userRepository) as T
}

modelClass.isAssignableFrom(HomeViewModel::class.java) -> {
HomeViewModel(RepositoryModule.openApiRepository) as T
}

modelClass.isAssignableFrom(MyPageViewModel::class.java) -> {
MyPageViewModel(userManager, userRepository) as T
MyPageViewModel(userManager, RepositoryModule.userRepository) as T
}

else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
Expand Down
Loading