diff --git a/app/build.gradle b/app/build.gradle index e14663b..f8a2c40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,6 +2,9 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.20' + id 'kotlin-parcelize' + id 'kotlin-kapt' + id 'com.google.dagger.hilt.android' } Properties properties = new Properties() @@ -30,23 +33,26 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = '17' } buildFeatures { buildConfig true viewBinding true dataBinding true } - + // Allow references to generated code + kapt { + correctErrorTypes true + } } dependencies { - // parcelize - apply plugin: 'kotlin-parcelize' + implementation "com.google.dagger:hilt-android:2.44" + kapt "com.google.dagger:hilt-compiler:2.44" // viewmodel 의존성 추가 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/ApiFactory.kt b/app/src/main/java/org/sopt/dosopttemplate/data/ApiFactory.kt similarity index 67% rename from app/src/main/java/org/sopt/dosopttemplate/network/ApiFactory.kt rename to app/src/main/java/org/sopt/dosopttemplate/data/ApiFactory.kt index d2972ab..fd0b488 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/network/ApiFactory.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/data/ApiFactory.kt @@ -1,4 +1,4 @@ -package org.sopt.dosopttemplate.network +package org.sopt.dosopttemplate.data import android.util.Log import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory @@ -8,11 +8,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import org.sopt.dosopttemplate.BuildConfig -import org.sopt.dosopttemplate.network.login.AuthService +import org.sopt.dosopttemplate.data.service.AuthService +import org.sopt.dosopttemplate.data.service.ReqresService import retrofit2.Retrofit object ApiFactory { - private const val BASE_URL = BuildConfig.AUTH_BASE_URL + private const val AUTH_BASE_URL = BuildConfig.AUTH_BASE_URL + private const val USER_BASE_URL = BuildConfig.USER_BASE_URL /* 1. 일단 로깅을 해줄 인터셉트를 만들어 줍니다. 2. 이 함수는 Http통신 중 로깅을 담당 @@ -34,17 +36,25 @@ object ApiFactory { .addInterceptor(getLogOkHttpClient()) .build() - val retrofit: Retrofit by lazy { - Retrofit.Builder() - .baseUrl(BASE_URL) + private fun createRetrofit(baseUrl: String): Retrofit { + return Retrofit.Builder() + .baseUrl(baseUrl) .client(okHttpClient) // 여기에 달아준다. .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) .build() } - inline fun create(): T = retrofit.create(T::class.java) + private inline fun create(baseUrl: String): T { + return createRetrofit(baseUrl).create(T::class.java) + } object ServicePool { - val authService = ApiFactory.create() + val authService: AuthService by lazy { + create(AUTH_BASE_URL) + } + + val userService: ReqresService by lazy { + create(USER_BASE_URL) + } } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/AuthDataSource.kt b/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/AuthDataSource.kt new file mode 100644 index 0000000..70b848b --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/AuthDataSource.kt @@ -0,0 +1,10 @@ +package org.sopt.dosopttemplate.data.datasource.remote + +import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto +import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto + +interface AuthDataSource { + suspend fun login(request: RequestLoginDto): ResponseLoginDto + suspend fun signUp(request: RequestSignUpDto): Unit +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/ReqresDataSource.kt b/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/ReqresDataSource.kt new file mode 100644 index 0000000..e721d03 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/datasource/remote/ReqresDataSource.kt @@ -0,0 +1,8 @@ +package org.sopt.dosopttemplate.data.datasource.remote + +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto + +// 레포지터리 인터페이스, 데이터 접근을 추상화, 데이터를 요청하는 코드를 부름 +interface ReqresDataSource { + suspend fun getReqresList(page: Int): ResponseReqresDto +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/AuthDataSourceImpl.kt b/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/AuthDataSourceImpl.kt new file mode 100644 index 0000000..16fe254 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/AuthDataSourceImpl.kt @@ -0,0 +1,15 @@ +package org.sopt.dosopttemplate.data.datasourceimpl.remote + +import org.sopt.dosopttemplate.data.datasource.remote.AuthDataSource +import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto +import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto +import org.sopt.dosopttemplate.data.service.AuthService + +class AuthDataSourceImpl(private val authService: AuthService) : AuthDataSource { + override suspend fun login(request: RequestLoginDto): ResponseLoginDto = + authService.postLogin(request) + + override suspend fun signUp(request: RequestSignUpDto): Unit = + authService.postSignUp(request) +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/ReqresDataSourceImpl.kt b/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/ReqresDataSourceImpl.kt new file mode 100644 index 0000000..267c737 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/datasourceimpl/remote/ReqresDataSourceImpl.kt @@ -0,0 +1,14 @@ +package org.sopt.dosopttemplate.data.datasourceimpl.remote + +import org.sopt.dosopttemplate.data.datasource.remote.ReqresDataSource +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto +import org.sopt.dosopttemplate.data.service.ReqresService + +// 실제 데이터 소스를 구현하는 클래스, 네트워크 호출을 통해 데이터를 가져오는 역할 +class ReqresDataSourceImpl( + private val reqresService: ReqresService, +) : ReqresDataSource { + override suspend fun getReqresList(page: Int): ResponseReqresDto { + return reqresService.getUserList(page) + } +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/login/RequestLoginDto.kt b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestLoginDto.kt similarity index 80% rename from app/src/main/java/org/sopt/dosopttemplate/network/login/RequestLoginDto.kt rename to app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestLoginDto.kt index ed7e423..dee2b2c 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/network/login/RequestLoginDto.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestLoginDto.kt @@ -1,4 +1,4 @@ -package org.sopt.dosopttemplate.network.login +package org.sopt.dosopttemplate.data.dto.remote.request import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/login/RequestSignUpDto.kt b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestSignUpDto.kt similarity index 83% rename from app/src/main/java/org/sopt/dosopttemplate/network/login/RequestSignUpDto.kt rename to app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestSignUpDto.kt index 9c3ba32..469c792 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/network/login/RequestSignUpDto.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/request/RequestSignUpDto.kt @@ -1,4 +1,4 @@ -package org.sopt.dosopttemplate.network.login +package org.sopt.dosopttemplate.data.dto.remote.request import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseLoginDto.kt b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseLoginDto.kt new file mode 100644 index 0000000..167737e --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseLoginDto.kt @@ -0,0 +1,22 @@ +package org.sopt.dosopttemplate.data.dto.remote.respose + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.sopt.dosopttemplate.domain.entity.UserEntity + +@Serializable +data class ResponseLoginDto( + @SerialName("id") + val id: Int, + @SerialName("username") + val username: String, + @SerialName("nickname") + val nickname: String, +) { + fun toUserEntity() = UserEntity( + id = username, + pwd = "", + nickName = nickname, + mbti = "", + ) +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ResponseReqresDto.kt b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseReqresDto.kt similarity index 58% rename from app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ResponseReqresDto.kt rename to app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseReqresDto.kt index d9fb610..d48f6dd 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ResponseReqresDto.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/data/dto/remote/respose/ResponseReqresDto.kt @@ -1,6 +1,7 @@ -package org.sopt.dosopttemplate.network.doandroid +package org.sopt.dosopttemplate.data.dto.remote.respose import kotlinx.serialization.Serializable +import org.sopt.dosopttemplate.domain.entity.ReqresEntity @Serializable data class ResponseReqresDto( @@ -25,4 +26,14 @@ data class ResponseReqresDto( val text: String, val url: String, ) + + fun toReqresList(): List = data.map { + ReqresEntity( + id = it.id, + email = it.email, + first_name = it.first_name, + last_name = it.last_name, + avatar = it.avatar, + ) + } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/login/User.kt b/app/src/main/java/org/sopt/dosopttemplate/data/login/User.kt deleted file mode 100644 index 58fe7f4..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/data/login/User.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.sopt.dosopttemplate.data.login - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize -data class User( - var id: String, - var pwd: String, - var nickName: String, - var mbti: String, -) : Parcelable diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/AuthRepositoryImpl.kt b/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/AuthRepositoryImpl.kt new file mode 100644 index 0000000..fc95198 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/AuthRepositoryImpl.kt @@ -0,0 +1,31 @@ +package org.sopt.dosopttemplate.data.repositoryimpl + +import org.sopt.dosopttemplate.data.datasource.remote.AuthDataSource +import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto +import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto +import org.sopt.dosopttemplate.domain.entity.UserEntity +import org.sopt.dosopttemplate.domain.entity.UserRequestEntity +import org.sopt.dosopttemplate.domain.repository.AuthDomainRepository + +class AuthRepositoryImpl(private val authDataSource: AuthDataSource) : AuthDomainRepository { + override suspend fun login(userRequestEntity: UserRequestEntity): Result = + kotlin.runCatching { + authDataSource.login( + RequestLoginDto( + userRequestEntity.userName, + userRequestEntity.passWord, + ), + ).toUserEntity() + } + + override suspend fun signUp(userEntity: UserEntity): Result = + kotlin.runCatching { + authDataSource.signUp( + RequestSignUpDto( + userEntity.id, + userEntity.pwd, + userEntity.nickName, + ), + ) + } +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/ReqresRepositoryImpl.kt b/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/ReqresRepositoryImpl.kt new file mode 100644 index 0000000..3e0d4eb --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/repositoryimpl/ReqresRepositoryImpl.kt @@ -0,0 +1,15 @@ +package org.sopt.dosopttemplate.data.repositoryimpl + +import org.sopt.dosopttemplate.data.datasource.remote.ReqresDataSource +import org.sopt.dosopttemplate.domain.entity.ReqresEntity +import org.sopt.dosopttemplate.domain.repository.ReqresDomainRepository + +// 외부 데이터 소스(ReqresDataSource)로부터 데이터를 가져오고, 필요한 형태로 변환하여 비즈니스 로직 계층에게 제공 +class ReqresRepositoryImpl(private val reqresDataSource: ReqresDataSource) : + ReqresDomainRepository { + override suspend fun getReqresList(page: Int): Result> { + return runCatching { + reqresDataSource.getReqresList(page).toReqresList() + } + } +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/service/AuthService.kt b/app/src/main/java/org/sopt/dosopttemplate/data/service/AuthService.kt new file mode 100644 index 0000000..676c1cc --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/service/AuthService.kt @@ -0,0 +1,19 @@ +package org.sopt.dosopttemplate.data.service + +import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto +import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto +import retrofit2.http.Body +import retrofit2.http.POST + +interface AuthService { + @POST("api/v1/members/sign-in") + suspend fun postLogin( + @Body request: RequestLoginDto, + ): ResponseLoginDto + + @POST("api/v1/members") + suspend fun postSignUp( + @Body request: RequestSignUpDto, + ): Unit +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/service/ReqresService.kt b/app/src/main/java/org/sopt/dosopttemplate/data/service/ReqresService.kt new file mode 100644 index 0000000..2dc6283 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/data/service/ReqresService.kt @@ -0,0 +1,12 @@ +package org.sopt.dosopttemplate.data.service + +import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto +import retrofit2.http.GET +import retrofit2.http.Query + +interface ReqresService { + @GET("api/users") + suspend fun getUserList( + @Query("page") page: Int, + ): ResponseReqresDto +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/domain/entity/ReqresEntity.kt b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/ReqresEntity.kt new file mode 100644 index 0000000..75cbb2f --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/ReqresEntity.kt @@ -0,0 +1,9 @@ +package org.sopt.dosopttemplate.domain.entity + +data class ReqresEntity( + val id: Int, + val avatar: String, + val email: String, + val first_name: String, + val last_name: String, +) diff --git a/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserEntity.kt b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserEntity.kt new file mode 100644 index 0000000..973da7e --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserEntity.kt @@ -0,0 +1,12 @@ +package org.sopt.dosopttemplate.domain.entity + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class UserEntity( + val id: String, + val pwd: String, + val nickName: String, + val mbti: String, +) : Parcelable diff --git a/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserRequestEntity.kt b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserRequestEntity.kt new file mode 100644 index 0000000..1d00d72 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/domain/entity/UserRequestEntity.kt @@ -0,0 +1,6 @@ +package org.sopt.dosopttemplate.domain.entity + +data class UserRequestEntity( + val userName: String, + val passWord: String, +) diff --git a/app/src/main/java/org/sopt/dosopttemplate/domain/repository/AuthDomainRepository.kt b/app/src/main/java/org/sopt/dosopttemplate/domain/repository/AuthDomainRepository.kt new file mode 100644 index 0000000..f1977c4 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/domain/repository/AuthDomainRepository.kt @@ -0,0 +1,9 @@ +package org.sopt.dosopttemplate.domain.repository + +import org.sopt.dosopttemplate.domain.entity.UserEntity +import org.sopt.dosopttemplate.domain.entity.UserRequestEntity + +interface AuthDomainRepository { + suspend fun login(userRequestEntity: UserRequestEntity): Result + suspend fun signUp(userEntity: UserEntity): Result +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/domain/repository/ReqresDomainRepository.kt b/app/src/main/java/org/sopt/dosopttemplate/domain/repository/ReqresDomainRepository.kt new file mode 100644 index 0000000..85736b4 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/domain/repository/ReqresDomainRepository.kt @@ -0,0 +1,9 @@ +package org.sopt.dosopttemplate.domain.repository + +import org.sopt.dosopttemplate.domain.entity.ReqresEntity + +/*ReqresRepository 인터페이스는 도메인(Domain) 레이어에서 사용되며, +원격 데이터 소스(ReqresDataSource)로부터 Reqres 사용자 리스트를 가져오는 기능을 정의*/ +interface ReqresDomainRepository { + suspend fun getReqresList(page: Int): Result> +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ReqresService.kt b/app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ReqresService.kt deleted file mode 100644 index e9c4df3..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/network/doandroid/ReqresService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.sopt.dosopttemplate.network.doandroid - -import retrofit2.Call -import retrofit2.http.GET -import retrofit2.http.Query - -interface ReqresService { - @GET("api/users") - fun getUserList( - @Query("page") page: Int, - ): Call -} diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/login/AuthService.kt b/app/src/main/java/org/sopt/dosopttemplate/network/login/AuthService.kt deleted file mode 100644 index 864ca1d..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/network/login/AuthService.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.sopt.dosopttemplate.network.login - -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST - -interface AuthService { - @POST("api/v1/members/sign-in") - suspend fun postLogin( - @Body request: RequestLoginDto, - ): Response - - @POST("api/v1/members") - suspend fun postSignUp( - @Body request: RequestSignUpDto, - ): Response -} diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/login/ResponseLoginDto.kt b/app/src/main/java/org/sopt/dosopttemplate/network/login/ResponseLoginDto.kt deleted file mode 100644 index 6ddb8d2..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/network/login/ResponseLoginDto.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.sopt.dosopttemplate.network.login - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class ResponseLoginDto( - @SerialName("id") - val id: Int, - @SerialName("username") - val username: String, - @SerialName("nickname") - val nickname: String? = null, -) diff --git a/app/src/main/java/org/sopt/dosopttemplate/network/reqresApiFactory.kt b/app/src/main/java/org/sopt/dosopttemplate/network/reqresApiFactory.kt deleted file mode 100644 index 15761c1..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/network/reqresApiFactory.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.sopt.dosopttemplate.network // ktlint-disable filename - -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType -import org.sopt.dosopttemplate.BuildConfig -import org.sopt.dosopttemplate.network.doandroid.ReqresService -import retrofit2.Retrofit - -object reqresApiFactory { - private const val BASE_URL = BuildConfig.USER_BASE_URL - - val retrofit: Retrofit by lazy { - Retrofit.Builder() - .baseUrl(BASE_URL) - .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) - .build() - } - - inline fun create(): T = retrofit.create(T::class.java) - - object ServicePool { - val reqresService = reqresApiFactory.create() - } -} diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidFragment.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidFragment.kt index 241f0bc..773d630 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidFragment.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidFragment.kt @@ -1,30 +1,33 @@ package org.sopt.dosopttemplate.ui.doandroid import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import com.google.android.material.carousel.CarouselLayoutManager import com.google.android.material.carousel.CarouselSnapHelper import com.google.android.material.carousel.HeroCarouselStrategy +import kotlinx.coroutines.launch import org.sopt.dosopttemplate.databinding.FragmentDoAndroidBinding -import org.sopt.dosopttemplate.network.doandroid.ResponseReqresDto -import org.sopt.dosopttemplate.network.reqresApiFactory.ServicePool.reqresService import org.sopt.dosopttemplate.ui.doandroid.adapter.CarouselHeroAdapter import org.sopt.dosopttemplate.ui.doandroid.adapter.CarouselUserAdapter import org.sopt.dosopttemplate.ui.home.HomeViewModel -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import org.sopt.dosopttemplate.utils.UiState +import org.sopt.dosopttemplate.utils.ViewModelFactory class DoAndroidFragment : Fragment() { private var _binding: FragmentDoAndroidBinding? = null private val viewModel by viewModels() + private val doAndroidViewModel: DoAndroidViewModel by viewModels { + ViewModelFactory() + } + private lateinit var carouselOriginalAdapter: CarouselUserAdapter private val binding: FragmentDoAndroidBinding @@ -48,26 +51,27 @@ class DoAndroidFragment : Fragment() { } private fun initUserApi() { - reqresService.getUserList(1).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response, - ) { - if (response.isSuccessful) { - val data = response.body() ?: return - - data.let { - carouselOriginalAdapter.setCarouselList(it.data) + doAndroidViewModel.getReqresUserList(1) + lifecycleScope.launch { + doAndroidViewModel.reqresUserState.collect { + when (it) { + is UiState.Success -> { + val reqresData = it.data + carouselOriginalAdapter.setCarouselList(reqresData) } - } else { - Log.d("userlist", "fail") - } - } - override fun onFailure(call: Call, t: Throwable) { - Log.e("doandroid", "Error: ${t.message}") + is UiState.Error -> { + Toast.makeText(requireContext(), "서버 연결실패", Toast.LENGTH_SHORT).show() + } + + is UiState.Loading -> Toast.makeText( + requireContext(), + "로딩 중", + Toast.LENGTH_SHORT, + ).show() + } } - }) + } } private fun initHeroCarousel() = with(binding) { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidViewModel.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidViewModel.kt new file mode 100644 index 0000000..581bcfe --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/DoAndroidViewModel.kt @@ -0,0 +1,40 @@ +package org.sopt.dosopttemplate.ui.doandroid + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import org.sopt.dosopttemplate.domain.entity.ReqresEntity +import org.sopt.dosopttemplate.domain.repository.ReqresDomainRepository +import org.sopt.dosopttemplate.utils.UiState + +class DoAndroidViewModel(val reqresRepository: ReqresDomainRepository) : ViewModel() { + + private val _reqresUserState = MutableStateFlow>>(UiState.Loading) + val reqresUserState get() = _reqresUserState.asStateFlow() + + fun getReqresUserList(page: Int) { + viewModelScope.launch { + reqresRepository.getReqresList(page).onSuccess { + if (it.isNotEmpty()) { + val reqresUserList = it.map { entity -> + ReqresEntity( + id = entity.id, + avatar = entity.avatar, + email = entity.email, + first_name = entity.first_name, + last_name = entity.last_name, + ) + } + _reqresUserState.value = UiState.Success(reqresUserList) + } else { + Log.d("reqres", "비었음") + } + }.onFailure { + Log.d("reqres", it.message.toString()) + } + } + } +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselHeroAdapter.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselHeroAdapter.kt index 9c10b5c..b8b47bc 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselHeroAdapter.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselHeroAdapter.kt @@ -6,8 +6,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemCarouselBinding +import org.sopt.dosopttemplate.ui.model.HomeSealedItem class CarouselHeroAdapter(context: Context) : ListAdapter(diffUtil) { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselUserAdapter.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselUserAdapter.kt index fefe249..3072083 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselUserAdapter.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/doandroid/adapter/CarouselUserAdapter.kt @@ -8,15 +8,15 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import org.sopt.dosopttemplate.databinding.ItemCarouselIntroduceBinding -import org.sopt.dosopttemplate.network.doandroid.ResponseReqresDto +import org.sopt.dosopttemplate.domain.entity.ReqresEntity class CarouselUserAdapter(context: Context) : - ListAdapter(diffUtil) { + ListAdapter(diffUtil) { private val inflater by lazy { LayoutInflater.from(context) } inner class CarouseViewHolder(private val binding: ItemCarouselIntroduceBinding) : RecyclerView.ViewHolder(binding.root) { - fun bind(data: ResponseReqresDto.Data) { + fun bind(data: ReqresEntity) { Glide.with(itemView) .load(data.avatar) .into(binding.imgCarousel) @@ -36,23 +36,23 @@ class CarouselUserAdapter(context: Context) : override fun getItemCount() = currentList.size // submitList 사용 - fun setCarouselList(imgList: List) { + fun setCarouselList(imgList: List) { submitList(imgList.toMutableList()) } // diffUtill callback companion object { - private var diffUtil = object : DiffUtil.ItemCallback() { + private var diffUtil = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: ResponseReqresDto.Data, - newItem: ResponseReqresDto.Data, + oldItem: ReqresEntity, + newItem: ReqresEntity, ): Boolean { return oldItem.id == newItem.id } override fun areContentsTheSame( - oldItem: ResponseReqresDto.Data, - newItem: ResponseReqresDto.Data, + oldItem: ReqresEntity, + newItem: ReqresEntity, ): Boolean { return oldItem == newItem } diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeFragment.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeFragment.kt index 7ceab6d..d6a2c2b 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeFragment.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeFragment.kt @@ -7,9 +7,9 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.FragmentHomeBinding import org.sopt.dosopttemplate.ui.home.adapter.HomeMainAdapter +import org.sopt.dosopttemplate.ui.model.HomeSealedItem import java.time.LocalDate class HomeFragment : Fragment() { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeViewModel.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeViewModel.kt index bfd03d5..df58546 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeViewModel.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/HomeViewModel.kt @@ -2,8 +2,8 @@ package org.sopt.dosopttemplate.ui.home import androidx.lifecycle.ViewModel import org.sopt.dosopttemplate.R -import org.sopt.dosopttemplate.data.home.HomeSealedItem -import org.sopt.dosopttemplate.data.user.UserInfo +import org.sopt.dosopttemplate.ui.model.HomeSealedItem +import org.sopt.dosopttemplate.ui.model.UserInfo class HomeViewModel : ViewModel() { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeDiffCallBack.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeDiffCallBack.kt index 2fc6fc1..804ed2f 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeDiffCallBack.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeDiffCallBack.kt @@ -1,7 +1,7 @@ package org.sopt.dosopttemplate.ui.home.adapter import androidx.recyclerview.widget.DiffUtil -import org.sopt.dosopttemplate.data.home.HomeSealedItem +import org.sopt.dosopttemplate.ui.model.HomeSealedItem object HomeDiffCallBack : DiffUtil.ItemCallback() { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeMainAdapter.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeMainAdapter.kt index 605fba3..5f76373 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeMainAdapter.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/HomeMainAdapter.kt @@ -6,7 +6,6 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ViewHolder -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemBirthdayBinding import org.sopt.dosopttemplate.databinding.ItemFriendBinding import org.sopt.dosopttemplate.databinding.ItemMyProfileBinding @@ -15,6 +14,7 @@ import org.sopt.dosopttemplate.ui.home.adapter.viewholder.BirthdayViewHolder import org.sopt.dosopttemplate.ui.home.adapter.viewholder.FriendViewHolder import org.sopt.dosopttemplate.ui.home.adapter.viewholder.ProfileViewHolder import org.sopt.dosopttemplate.ui.home.adapter.viewholder.TitleLineViewHolder +import org.sopt.dosopttemplate.ui.model.HomeSealedItem import java.lang.IllegalArgumentException class HomeMainAdapter(context: Context) : diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/BirthdayViewHolder.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/BirthdayViewHolder.kt index 2b25b85..a7a7879 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/BirthdayViewHolder.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/BirthdayViewHolder.kt @@ -3,8 +3,8 @@ package org.sopt.dosopttemplate.ui.home.adapter.viewholder import DateUtils import android.view.View import androidx.recyclerview.widget.RecyclerView -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemBirthdayBinding +import org.sopt.dosopttemplate.ui.model.HomeSealedItem import java.time.LocalDate import java.time.format.DateTimeFormatter diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/FriendViewHolder.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/FriendViewHolder.kt index 812b44d..f616ddd 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/FriendViewHolder.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/FriendViewHolder.kt @@ -2,8 +2,8 @@ package org.sopt.dosopttemplate.ui.home.adapter.viewholder import android.view.View import androidx.recyclerview.widget.RecyclerView -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemFriendBinding +import org.sopt.dosopttemplate.ui.model.HomeSealedItem class FriendViewHolder(private val binding: ItemFriendBinding) : RecyclerView.ViewHolder(binding.root) { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/ProfileViewHolder.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/ProfileViewHolder.kt index a60c603..fab2ba3 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/ProfileViewHolder.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/ProfileViewHolder.kt @@ -1,8 +1,8 @@ package org.sopt.dosopttemplate.ui.home.adapter.viewholder import androidx.recyclerview.widget.RecyclerView -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemMyProfileBinding +import org.sopt.dosopttemplate.ui.model.HomeSealedItem class ProfileViewHolder(private val binding: ItemMyProfileBinding) : RecyclerView.ViewHolder(binding.root) { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/TitleLineViewHolder.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/TitleLineViewHolder.kt index 4c54ea5..10ce673 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/TitleLineViewHolder.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/home/adapter/viewholder/TitleLineViewHolder.kt @@ -1,8 +1,8 @@ package org.sopt.dosopttemplate.ui.home.adapter.viewholder import androidx.recyclerview.widget.RecyclerView -import org.sopt.dosopttemplate.data.home.HomeSealedItem import org.sopt.dosopttemplate.databinding.ItemTitleLineBinding +import org.sopt.dosopttemplate.ui.model.HomeSealedItem class TitleLineViewHolder(private val binding: ItemTitleLineBinding) : RecyclerView.ViewHolder(binding.root) { diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/AuthViewModel.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/AuthViewModel.kt index 27e9041..b3c98fc 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/AuthViewModel.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/login/AuthViewModel.kt @@ -5,17 +5,18 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch -import org.sopt.dosopttemplate.data.user.UserInfo -import org.sopt.dosopttemplate.network.ApiFactory.ServicePool.authService -import org.sopt.dosopttemplate.network.login.RequestLoginDto +import org.sopt.dosopttemplate.domain.entity.UserEntity +import org.sopt.dosopttemplate.domain.entity.UserRequestEntity +import org.sopt.dosopttemplate.domain.repository.AuthDomainRepository +import org.sopt.dosopttemplate.utils.UiState -class AuthViewModel : ViewModel() { - private val _loginState = MutableStateFlow(LoginState.Loading) - val loginState: StateFlow = _loginState.asStateFlow() +class AuthViewModel(private val authRepository: AuthDomainRepository) : ViewModel() { + private val _loginState = MutableSharedFlow>() + val loginState: SharedFlow> get() = _loginState.asSharedFlow() private val _isLoginButtonClicked: MutableLiveData = MutableLiveData(false) val isLoginButtonClicked: LiveData @@ -23,26 +24,14 @@ class AuthViewModel : ViewModel() { fun login(id: String, password: String) { viewModelScope.launch { - kotlin.runCatching { - authService.postLogin(RequestLoginDto(id, password)) - }.onSuccess { - if (it.isSuccessful) { - val response = it.body() - if (response != null) { - _loginState.value = LoginState.Success(response) - Log.d("server", _loginState.value.toString()) - UserInfo.updateUserInfo( - id = response.id.toString(), - nickName = response.nickname.toString(), - ) - } - } else { - _loginState.value = LoginState.Error - Log.d("server", it.code().toString()) + authRepository.login(UserRequestEntity(id, password)) + .onSuccess { + _loginState.emit(UiState.Success(it)) + } + .onFailure { + Log.d("server", it.message.toString()) + _loginState.emit(UiState.Error) } - }.onFailure { - Log.d("server", it.message.toString()) - } } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginActivity.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginActivity.kt index 7fe175d..2a0c5e0 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginActivity.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginActivity.kt @@ -8,12 +8,17 @@ import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch import org.sopt.dosopttemplate.databinding.ActivityLoginBinding import org.sopt.dosopttemplate.ui.HomeActivity +import org.sopt.dosopttemplate.ui.model.UserInfo +import org.sopt.dosopttemplate.utils.UiState +import org.sopt.dosopttemplate.utils.ViewModelFactory import org.sopt.dosopttemplate.utils.toast class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding - private val authViewModel by viewModels() + private val authViewModel by viewModels() { + ViewModelFactory() + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -54,13 +59,18 @@ class LoginActivity : AppCompatActivity() { lifecycleScope.launch { authViewModel.loginState.collect { loginState -> when (loginState) { - is LoginState.Success -> { + is UiState.Success -> { toast("로그인 성공") + UserInfo.updateUserInfo( + id = loginState.data.id, + nickName = loginState.data.nickName, + mbti = loginState.data.mbti, + ) startActivity(Intent(this@LoginActivity, HomeActivity::class.java)) } - is LoginState.Error -> toast("로그인 실패") - is LoginState.Loading -> toast("로그인 중") + is UiState.Error -> toast("로그인 실패") + is UiState.Loading -> {} } } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginState.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginState.kt deleted file mode 100644 index 52f16e7..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/LoginState.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.sopt.dosopttemplate.ui.login - -import org.sopt.dosopttemplate.network.login.ResponseLoginDto - -sealed class LoginState { - object Loading : LoginState() - data class Success(val data: ResponseLoginDto) : LoginState() - object Error : LoginState() -} diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpActivity.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpActivity.kt index 0d1cb71..bcbd17a 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpActivity.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpActivity.kt @@ -9,14 +9,18 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch import org.sopt.dosopttemplate.R -import org.sopt.dosopttemplate.data.login.User import org.sopt.dosopttemplate.databinding.ActivitySignUpBinding +import org.sopt.dosopttemplate.domain.entity.UserEntity +import org.sopt.dosopttemplate.utils.UiState +import org.sopt.dosopttemplate.utils.ViewModelFactory import org.sopt.dosopttemplate.utils.toast class SignUpActivity : AppCompatActivity() { private lateinit var binding: ActivitySignUpBinding - private val viewModel by viewModels() + private val viewModel by viewModels() { + ViewModelFactory() + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -35,34 +39,34 @@ class SignUpActivity : AppCompatActivity() { private fun initSignUp() { binding.btnLogin.setOnClickListener { - val userEntity = User( + val userEntity = UserEntity( id = binding.editId.text.toString(), pwd = binding.editPwd.text.toString(), nickName = binding.editNickname.text.toString(), mbti = binding.editMbti.text.toString(), ) - viewModel.signUpServer(userEntity) - observeSignUpState(userEntity) + viewModel.postSignUp(userEntity) + observeSignUpState() } } - private fun observeSignUpState(userEntity: User) { + private fun observeSignUpState() { lifecycleScope.launch { viewModel.signUpState.collect { when (it) { - is SignUpState.Success -> { - sendUserData(userEntity) + is UiState.Success -> { + sendUserData(it.data) toast(getString(R.string.toast_signUp_compeleted)) } - is SignUpState.Error -> toast(getString(R.string.toast_signUp_fail)) - is SignUpState.Loading -> toast("회원가입 중") + is UiState.Error -> toast(getString(R.string.toast_signUp_fail)) + is UiState.Loading -> {} } } } } - private fun sendUserData(userEntity: User) { + private fun sendUserData(userEntity: UserEntity) { val intent = Intent(this@SignUpActivity, LoginActivity::class.java) intent.putExtra(USER_TAG, userEntity) // LoginActivity로 결과를 반환 diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpState.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpState.kt deleted file mode 100644 index 6cfeff8..0000000 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpState.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.sopt.dosopttemplate.ui.login - -sealed class SignUpState { - object Loading : SignUpState() - object Success : SignUpState() - object Error : SignUpState() -} diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpViewModel.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpViewModel.kt index 5cf63be..c0a9a6c 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpViewModel.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/login/SignUpViewModel.kt @@ -1,6 +1,5 @@ package org.sopt.dosopttemplate.ui.login -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -9,13 +8,13 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import org.sopt.dosopttemplate.data.login.User -import org.sopt.dosopttemplate.network.ApiFactory.ServicePool.authService -import org.sopt.dosopttemplate.network.login.RequestSignUpDto +import org.sopt.dosopttemplate.domain.entity.UserEntity +import org.sopt.dosopttemplate.domain.repository.AuthDomainRepository +import org.sopt.dosopttemplate.utils.UiState -class SignUpViewModel : ViewModel() { - private val _signUpState = MutableStateFlow(SignUpState.Loading) - val signUpState: StateFlow = _signUpState.asStateFlow() +class SignUpViewModel(private val authRepository: AuthDomainRepository) : ViewModel() { + private val _signUpState = MutableStateFlow>(UiState.Loading) + val signUpState: StateFlow> = _signUpState.asStateFlow() private val id = MutableLiveData() private val password = MutableLiveData() @@ -103,25 +102,14 @@ class SignUpViewModel : ViewModel() { _isBtnSelected.value = isIdValid && isPasswordValid && isNickNameValid && isMbtiValid } - fun signUpServer(userEntity: User) { + fun postSignUp(userEntity: UserEntity) { viewModelScope.launch { - kotlin.runCatching { - authService.postSignUp( - RequestSignUpDto( - userEntity.id, - userEntity.pwd, - userEntity.nickName, - ), - ) - }.onSuccess { - if (it.isSuccessful) { - _signUpState.value = SignUpState.Success - } else { - _signUpState.value = SignUpState.Error + authRepository.signUp(userEntity) + .onSuccess { + _signUpState.value = UiState.Success(userEntity) + }.onFailure { + _signUpState.value = UiState.Error } - }.onFailure { - Log.e("SignUpActivity", "Error: ${it.message}") - } } } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/home/HomeSealedItem.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/model/HomeSealedItem.kt similarity index 93% rename from app/src/main/java/org/sopt/dosopttemplate/data/home/HomeSealedItem.kt rename to app/src/main/java/org/sopt/dosopttemplate/ui/model/HomeSealedItem.kt index ca599e1..3b0bb34 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/data/home/HomeSealedItem.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/model/HomeSealedItem.kt @@ -1,4 +1,4 @@ -package org.sopt.dosopttemplate.data.home +package org.sopt.dosopttemplate.ui.model import androidx.annotation.DrawableRes diff --git a/app/src/main/java/org/sopt/dosopttemplate/data/user/UserInfo.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/model/UserInfo.kt similarity index 75% rename from app/src/main/java/org/sopt/dosopttemplate/data/user/UserInfo.kt rename to app/src/main/java/org/sopt/dosopttemplate/ui/model/UserInfo.kt index 8f31944..ffc895a 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/data/user/UserInfo.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/model/UserInfo.kt @@ -1,9 +1,9 @@ -package org.sopt.dosopttemplate.data.user +package org.sopt.dosopttemplate.ui.model -import org.sopt.dosopttemplate.data.login.User +import org.sopt.dosopttemplate.domain.entity.UserEntity object UserInfo { - var userInfoList = User( + var userInfoList = UserEntity( id = "", pwd = "", nickName = "", diff --git a/app/src/main/java/org/sopt/dosopttemplate/ui/mypage/MyPageFragment.kt b/app/src/main/java/org/sopt/dosopttemplate/ui/mypage/MyPageFragment.kt index 2bc57d1..0d90924 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/ui/mypage/MyPageFragment.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/ui/mypage/MyPageFragment.kt @@ -5,8 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import org.sopt.dosopttemplate.data.user.UserInfo import org.sopt.dosopttemplate.databinding.FragmentMyPageBinding +import org.sopt.dosopttemplate.ui.model.UserInfo class MyPageFragment : Fragment() { diff --git a/app/src/main/java/org/sopt/dosopttemplate/utils/UiState.kt b/app/src/main/java/org/sopt/dosopttemplate/utils/UiState.kt new file mode 100644 index 0000000..84c26d0 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/utils/UiState.kt @@ -0,0 +1,12 @@ +package org.sopt.dosopttemplate.utils + +sealed interface UiState { + + object Loading : UiState + + data class Success( + val data: T, + ) : UiState + + object Error : UiState +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/utils/ViewModelFactory.kt b/app/src/main/java/org/sopt/dosopttemplate/utils/ViewModelFactory.kt new file mode 100644 index 0000000..d2c0697 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/utils/ViewModelFactory.kt @@ -0,0 +1,40 @@ +package org.sopt.dosopttemplate.utils + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import org.sopt.dosopttemplate.data.ApiFactory +import org.sopt.dosopttemplate.data.datasourceimpl.remote.AuthDataSourceImpl +import org.sopt.dosopttemplate.data.datasourceimpl.remote.ReqresDataSourceImpl +import org.sopt.dosopttemplate.data.repositoryimpl.AuthRepositoryImpl +import org.sopt.dosopttemplate.data.repositoryimpl.ReqresRepositoryImpl +import org.sopt.dosopttemplate.ui.doandroid.DoAndroidViewModel +import org.sopt.dosopttemplate.ui.login.AuthViewModel +import org.sopt.dosopttemplate.ui.login.SignUpViewModel + +class ViewModelFactory : + ViewModelProvider.Factory { + + override fun create(modelClass: Class): T { + return when { + modelClass.isAssignableFrom(AuthViewModel::class.java) -> { + val repository = + AuthRepositoryImpl(AuthDataSourceImpl(ApiFactory.ServicePool.authService)) + AuthViewModel(repository) as T + } + + modelClass.isAssignableFrom(SignUpViewModel::class.java) -> { + val repository = + AuthRepositoryImpl(AuthDataSourceImpl(ApiFactory.ServicePool.authService)) + SignUpViewModel(repository) as T + } + + modelClass.isAssignableFrom(DoAndroidViewModel::class.java) -> { + val repository = + ReqresRepositoryImpl(ReqresDataSourceImpl(ApiFactory.ServicePool.userService)) + DoAndroidViewModel(repository) as T + } + // Add more ViewModel cases as needed + else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") + } + } +} diff --git a/build.gradle b/build.gradle index fd3d478..205b53a 100644 --- a/build.gradle +++ b/build.gradle @@ -3,4 +3,5 @@ plugins { id 'com.android.application' version '8.0.2' apply false id 'com.android.library' version '8.0.2' apply false id 'org.jetbrains.kotlin.android' version '1.8.20' apply false -} \ No newline at end of file + id 'com.google.dagger.hilt.android' version '2.44' apply false +}