From 7daba1d42eadba27323e7db5c7654b969790f306 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:49:51 +0900 Subject: [PATCH 01/18] =?UTF-8?q?#28=20Chore:=20hilt=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 13 +++++++++---- build.gradle | 7 ++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3462d68..3dc1f75 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,6 +5,8 @@ plugins { id 'androidx.navigation.safeargs.kotlin' id 'com.google.devtools.ksp' id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.0' + id 'kotlin-kapt' + id 'dagger.hilt.android.plugin' } Properties properties = new Properties() @@ -48,7 +50,7 @@ android { dependencies { implementation 'androidx.core:core-ktx:1.13.1' - implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' @@ -58,13 +60,13 @@ dependencies { implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' implementation 'androidx.navigation:navigation-ui-ktx:2.7.7' implementation "androidx.recyclerview:recyclerview:1.3.2" - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.1' ksp 'androidx.room:room-compiler:2.6.1' implementation 'androidx.room:room-common:2.6.1' implementation 'androidx.room:room-ktx:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' - implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:retrofit:2.11.0' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3' implementation 'com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0' implementation(platform'com.squareup.okhttp3:okhttp-bom:4.10.0') @@ -72,4 +74,7 @@ dependencies { implementation'com.squareup.okhttp3:logging-interceptor' implementation 'com.github.bumptech.glide:glide:4.16.0' implementation 'com.jakewharton:process-phoenix:3.0.0' + + implementation "com.google.dagger:hilt-android:2.51.1" + kapt "com.google.dagger:hilt-android-compiler:2.51.1" } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 262fe89..d8b6b81 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,9 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + dependencies { + classpath "com.google.dagger:hilt-android-gradle-plugin:2.51.1" + } +} + plugins { id 'com.android.application' version '8.3.1' apply false id 'com.android.library' version '8.3.1' apply false From ecbd112a67d36bb8e33b9e6f9235e44c91b001a4 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:50:17 +0900 Subject: [PATCH 02/18] #28 Remove: serviceLocator --- .../main/java/com/sopt/now/ServiceLocator.kt | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 app/src/main/java/com/sopt/now/ServiceLocator.kt diff --git a/app/src/main/java/com/sopt/now/ServiceLocator.kt b/app/src/main/java/com/sopt/now/ServiceLocator.kt deleted file mode 100644 index ad73327..0000000 --- a/app/src/main/java/com/sopt/now/ServiceLocator.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.sopt.now - -import android.content.Context -import com.sopt.now.data.UserLocalDataSource -import com.sopt.now.data.UserRemoteDataSource -import com.sopt.now.data.UserRepository -import com.sopt.now.data.friend.FriendDatabase -import com.sopt.now.data.friend.FriendsRepository -import com.sopt.now.data.friend.OfflineFriendsRepository -import com.sopt.now.network.service.ServicePool -import com.sopt.now.util.AppViewModelFactory - -class ServiceLocator(context: Context) { - private val preferenceInstance by lazy { - context.getSharedPreferences("SaveLogin", Context.MODE_PRIVATE) - } - - private val userLocalDataSource by lazy { - UserLocalDataSource(preferenceInstance) - } - - private val userRemoteDataSource by lazy { - UserRemoteDataSource(ServicePool.authService) - } - - val userRepository by lazy { - UserRepository(userLocalDataSource, userRemoteDataSource) - } - - private val friendDao by lazy { - FriendDatabase.getDatabase(context).friendDao() - } - - val friendsRepository: FriendsRepository by lazy { - OfflineFriendsRepository(friendDao) - } - - val appViewModelFactory by lazy { - AppViewModelFactory(userRepository, friendsRepository) - } -} \ No newline at end of file From 9c62ae24f587fce631cdaefde41232f67a9cb982 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:50:31 +0900 Subject: [PATCH 03/18] #28 Feat: SoptApp --- app/src/main/java/com/sopt/now/SoptApp.kt | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/sopt/now/SoptApp.kt b/app/src/main/java/com/sopt/now/SoptApp.kt index b339328..d6d621f 100644 --- a/app/src/main/java/com/sopt/now/SoptApp.kt +++ b/app/src/main/java/com/sopt/now/SoptApp.kt @@ -1,23 +1,7 @@ package com.sopt.now import android.app.Application -import android.content.Context +import dagger.hilt.android.HiltAndroidApp -class SoptApp : Application() { - lateinit var serviceLocator: ServiceLocator - - companion object { - @Volatile - private lateinit var instance: SoptApp - - fun applicationContext(): Context { - return instance.applicationContext - } - } - - override fun onCreate() { - super.onCreate() - instance = this - serviceLocator = ServiceLocator(applicationContext) - } -} \ No newline at end of file +@HiltAndroidApp +class SoptApp : Application() \ No newline at end of file From ae95dfb8c718f9d3a13123f85b8ad5e1b6f59211 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:50:58 +0900 Subject: [PATCH 04/18] =?UTF-8?q?#28=20Mod:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/sopt/now/util/BaseFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/sopt/now/util/BaseFragment.kt b/app/src/main/java/com/sopt/now/util/BaseFragment.kt index f0c376c..03b701e 100644 --- a/app/src/main/java/com/sopt/now/util/BaseFragment.kt +++ b/app/src/main/java/com/sopt/now/util/BaseFragment.kt @@ -1,3 +1,5 @@ +package com.sopt.now.util + import android.os.Bundle import android.view.LayoutInflater import android.view.View From d9fa793f4452ed8f595a95c10935fee829aa980a Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:53:54 +0900 Subject: [PATCH 05/18] =?UTF-8?q?#28=20Feat:=20UserRepository,=20UserRepos?= =?UTF-8?q?itoryImpl=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/data/UserRepository.kt | 58 ++++--------------- .../com/sopt/now/data/UserRepositoryImpl.kt | 54 +++++++++++++++++ 2 files changed, 65 insertions(+), 47 deletions(-) create mode 100644 app/src/main/java/com/sopt/now/data/UserRepositoryImpl.kt diff --git a/app/src/main/java/com/sopt/now/data/UserRepository.kt b/app/src/main/java/com/sopt/now/data/UserRepository.kt index bbd1229..c415cb2 100644 --- a/app/src/main/java/com/sopt/now/data/UserRepository.kt +++ b/app/src/main/java/com/sopt/now/data/UserRepository.kt @@ -7,51 +7,15 @@ import com.sopt.now.network.response.ResponseDto import com.sopt.now.network.response.ResponseInfoDto import retrofit2.Response -class UserRepository( - private val localDataSource: UserLocalDataSource, - private val remoteDataSource: UserRemoteDataSource -) { - fun setUserLoggedIn(loggedIn: Boolean) { - localDataSource.setUserLoggedIn(loggedIn) - } - - fun isUserLoggedIn(): Boolean { - return localDataSource.isUserLoggedIn() - } - - fun logoutUser() { - localDataSource.logoutUser() - } - - fun saveUserData(user: User) { - localDataSource.saveUserData(user) - } - - fun updateUserPassword(newPassword: String) { - localDataSource.updateUserPassword(newPassword) - } - - fun setMemberId(memberId: String) { - localDataSource.setMemberId(memberId) - } - - fun getMemberId(): String? { - return localDataSource.getMemberId() - } - - suspend fun signUp(request: RequestSignUpDto): Response { - return remoteDataSource.signUp(request) - } - - suspend fun login(request: RequestLoginDto): Response { - return remoteDataSource.login(request) - } - - suspend fun getUserInfo(): Response { - return remoteDataSource.getUserInfo() - } - - suspend fun changePassword(request: RequestChangePasswordDto): Response { - return remoteDataSource.changePassword(request) - } +interface UserRepository { + fun setUserLoggedIn(loggedIn: Boolean) + fun isUserLoggedIn(): Boolean + fun logoutUser() + fun saveUserData(user: User) + fun updateUserPassword(newPassword: String) + fun setMemberId(memberId: String) + suspend fun signUp(request: RequestSignUpDto): Response + suspend fun login(request: RequestLoginDto): Response + suspend fun getUserInfo(): Response + suspend fun changePassword(request: RequestChangePasswordDto): Response } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/data/UserRepositoryImpl.kt b/app/src/main/java/com/sopt/now/data/UserRepositoryImpl.kt new file mode 100644 index 0000000..bc56e27 --- /dev/null +++ b/app/src/main/java/com/sopt/now/data/UserRepositoryImpl.kt @@ -0,0 +1,54 @@ +package com.sopt.now.data + +import com.sopt.now.network.request.RequestChangePasswordDto +import com.sopt.now.network.request.RequestLoginDto +import com.sopt.now.network.request.RequestSignUpDto +import com.sopt.now.network.response.ResponseDto +import com.sopt.now.network.response.ResponseInfoDto +import retrofit2.Response +import javax.inject.Inject + +class UserRepositoryImpl @Inject constructor( + private val localDataSource: UserLocalDataSource, + private val remoteDataSource: UserRemoteDataSource +) : UserRepository { + override fun setUserLoggedIn(loggedIn: Boolean) { + localDataSource.setUserLoggedIn(loggedIn) + } + + override fun isUserLoggedIn(): Boolean { + return localDataSource.isUserLoggedIn() + } + + override fun logoutUser() { + localDataSource.logoutUser() + } + + override fun saveUserData(user: User) { + localDataSource.saveUserData(user) + } + + override fun updateUserPassword(newPassword: String) { + localDataSource.updateUserPassword(newPassword) + } + + override fun setMemberId(memberId: String) { + localDataSource.setMemberId(memberId) + } + + override suspend fun signUp(request: RequestSignUpDto): Response { + return remoteDataSource.signUp(request) + } + + override suspend fun login(request: RequestLoginDto): Response { + return remoteDataSource.login(request) + } + + override suspend fun getUserInfo(): Response { + return remoteDataSource.getUserInfo() + } + + override suspend fun changePassword(request: RequestChangePasswordDto): Response { + return remoteDataSource.changePassword(request) + } +} \ No newline at end of file From 801d3a5542e2c577ac7bc0a86266fb05f6a02e05 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:54:40 +0900 Subject: [PATCH 06/18] #28 Feat: AppModule --- .../main/java/com/sopt/now/di/AppModule.kt | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 app/src/main/java/com/sopt/now/di/AppModule.kt diff --git a/app/src/main/java/com/sopt/now/di/AppModule.kt b/app/src/main/java/com/sopt/now/di/AppModule.kt new file mode 100644 index 0000000..4f39909 --- /dev/null +++ b/app/src/main/java/com/sopt/now/di/AppModule.kt @@ -0,0 +1,105 @@ +package com.sopt.now.di + +import android.content.Context +import android.content.SharedPreferences +import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory +import com.sopt.now.BuildConfig +import com.sopt.now.data.UserLocalDataSource +import com.sopt.now.data.UserRemoteDataSource +import com.sopt.now.data.UserRepository +import com.sopt.now.data.UserRepositoryImpl +import com.sopt.now.data.friend.FriendDao +import com.sopt.now.data.friend.FriendDatabase +import com.sopt.now.data.friend.FriendsRepository +import com.sopt.now.data.friend.OfflineFriendsRepository +import com.sopt.now.network.HeaderInterceptor +import com.sopt.now.network.service.AuthService +import com.sopt.now.network.service.FollowerService +import com.sopt.now.network.service.ServicePool +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object AppModule { + + @Provides + @Singleton + fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences = + context.getSharedPreferences("SaveLogin", Context.MODE_PRIVATE) + + @Provides + @Singleton + fun provideHeaderInterceptor( + @ApplicationContext context: Context, + sharedPreferences: SharedPreferences + ): HeaderInterceptor = HeaderInterceptor(context, sharedPreferences) + + + @Provides + @Singleton + fun provideOkHttpClient(headerInterceptor: HeaderInterceptor): OkHttpClient { + return OkHttpClient.Builder() + .addInterceptor(headerInterceptor) + .addInterceptor(HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + }) + .build() + } + + @Provides + @Singleton + fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit { + return Retrofit.Builder() + .baseUrl(BuildConfig.AUTH_BASE_URL) + .client(okHttpClient) + .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) + .build() + } + + @Provides + @Singleton + fun provideAuthService(retrofit: Retrofit): AuthService = retrofit.create(AuthService::class.java) + + @Provides + @Singleton + fun provideFollowerService(retrofit: Retrofit): FollowerService = retrofit.create(FollowerService::class.java) + + + @Provides + @Singleton + fun provideServicePool( + authService: AuthService, + followerService: FollowerService + ): ServicePool = ServicePool(authService, followerService) + + @Provides + @Singleton + fun provideUserLocalDataSource(sharedPreferences: SharedPreferences): UserLocalDataSource = + UserLocalDataSource(sharedPreferences) + + @Provides + @Singleton + fun provideUserRemoteDataSource(servicePool: ServicePool): UserRemoteDataSource = + UserRemoteDataSource(servicePool.authService) + + @Provides + @Singleton + fun provideFriendDao(@ApplicationContext context: Context) = + FriendDatabase.getDatabase(context).friendDao() + + @Provides + @Singleton + fun provideFriendsRepository(friendDao: FriendDao): FriendsRepository = + OfflineFriendsRepository(friendDao) +} \ No newline at end of file From 4f0d7b91511bad211dad89dca9884a0359f68f0c Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:56:00 +0900 Subject: [PATCH 07/18] #28 Feat: RepositoryModule --- .../java/com/sopt/now/di/RepositoryModule.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 app/src/main/java/com/sopt/now/di/RepositoryModule.kt diff --git a/app/src/main/java/com/sopt/now/di/RepositoryModule.kt b/app/src/main/java/com/sopt/now/di/RepositoryModule.kt new file mode 100644 index 0000000..6b97e75 --- /dev/null +++ b/app/src/main/java/com/sopt/now/di/RepositoryModule.kt @@ -0,0 +1,20 @@ +package com.sopt.now.di + +import com.sopt.now.data.UserRepository +import com.sopt.now.data.UserRepositoryImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class RepositoryModule { + + @Binds + @Singleton + abstract fun bindUserRepository( + impl: UserRepositoryImpl + ): UserRepository +} \ No newline at end of file From 7644b9c4e355f9819deefb299a9b983a566792b9 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:57:40 +0900 Subject: [PATCH 08/18] =?UTF-8?q?#28=20Feat:=20service=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20hilt=20di?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sopt/now/network/service/FollowerService.kt | 1 - .../com/sopt/now/network/service/ServicePool.kt | 13 +++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/sopt/now/network/service/FollowerService.kt b/app/src/main/java/com/sopt/now/network/service/FollowerService.kt index 85283c3..789d687 100644 --- a/app/src/main/java/com/sopt/now/network/service/FollowerService.kt +++ b/app/src/main/java/com/sopt/now/network/service/FollowerService.kt @@ -1,7 +1,6 @@ package com.sopt.now.network.service import com.sopt.now.network.response.ResponseFollowerDto -import retrofit2.Call import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Query diff --git a/app/src/main/java/com/sopt/now/network/service/ServicePool.kt b/app/src/main/java/com/sopt/now/network/service/ServicePool.kt index 37f7717..9e372f4 100644 --- a/app/src/main/java/com/sopt/now/network/service/ServicePool.kt +++ b/app/src/main/java/com/sopt/now/network/service/ServicePool.kt @@ -1,9 +1,10 @@ package com.sopt.now.network.service -import com.sopt.now.network.ApiFactory -import com.sopt.now.network.FollowerApiFactory +import javax.inject.Inject +import javax.inject.Singleton -object ServicePool { - val authService = ApiFactory.create() - val followerService = FollowerApiFactory.create() -} \ No newline at end of file +@Singleton +class ServicePool @Inject constructor( + val authService: AuthService, + val followerService: FollowerService +) \ No newline at end of file From 91c9cc84a772b703e0b8a839dbb74f085affbe0a Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:58:59 +0900 Subject: [PATCH 09/18] =?UTF-8?q?#28=20Feat:=20object=EB=A5=BC=20class?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=ED=9B=84=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/network/ApiFactory.kt | 33 ++++--------------- .../sopt/now/network/FollowerApiFactory.kt | 21 ++++-------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/com/sopt/now/network/ApiFactory.kt b/app/src/main/java/com/sopt/now/network/ApiFactory.kt index f89f296..b1ae0bd 100644 --- a/app/src/main/java/com/sopt/now/network/ApiFactory.kt +++ b/app/src/main/java/com/sopt/now/network/ApiFactory.kt @@ -1,33 +1,12 @@ package com.sopt.now.network -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import com.sopt.now.BuildConfig -import com.sopt.now.SoptApp -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit +import javax.inject.Inject +import javax.inject.Singleton -object ApiFactory { - private const val BASE_URL: String = BuildConfig.AUTH_BASE_URL - - private val loggingInterceptor = HttpLoggingInterceptor().apply { - level = HttpLoggingInterceptor.Level.BODY - } - - private val okHttpClient = OkHttpClient.Builder() - .addInterceptor(HeaderInterceptor(SoptApp.applicationContext())) - .addInterceptor(loggingInterceptor) - .build() - - val retrofit: Retrofit by lazy { - Retrofit.Builder() - .baseUrl(BASE_URL) - .client(okHttpClient) - .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) - .build() - } - +@Singleton +class ApiFactory @Inject constructor( + val retrofit: Retrofit +) { inline fun create(): T = retrofit.create(T::class.java) } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/network/FollowerApiFactory.kt b/app/src/main/java/com/sopt/now/network/FollowerApiFactory.kt index c7b7a4b..d951aeb 100644 --- a/app/src/main/java/com/sopt/now/network/FollowerApiFactory.kt +++ b/app/src/main/java/com/sopt/now/network/FollowerApiFactory.kt @@ -1,21 +1,12 @@ package com.sopt.now.network -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType import retrofit2.Retrofit +import javax.inject.Inject +import javax.inject.Singleton -object FollowerApiFactory { - private const val BASE_URL: String = "https://reqres.in/api/" - - private val jsonConverterFactory = Json.asConverterFactory("application/json".toMediaType()) - - val retrofit: Retrofit by lazy { - Retrofit.Builder() - .baseUrl(BASE_URL) - .addConverterFactory(jsonConverterFactory) - .build() - } - +@Singleton +class FollowerApiFactory @Inject constructor( + val retrofit: Retrofit +) { inline fun create(): T = retrofit.create(T::class.java) } \ No newline at end of file From fbbca339072a6a392979cbb2c977440f6aa4ca63 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:59:20 +0900 Subject: [PATCH 10/18] =?UTF-8?q?#28=20Feat:=20HeaderInterceptor=EC=97=90?= =?UTF-8?q?=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/network/HeaderInterceptor.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/sopt/now/network/HeaderInterceptor.kt b/app/src/main/java/com/sopt/now/network/HeaderInterceptor.kt index c23540a..c40e75f 100644 --- a/app/src/main/java/com/sopt/now/network/HeaderInterceptor.kt +++ b/app/src/main/java/com/sopt/now/network/HeaderInterceptor.kt @@ -1,17 +1,19 @@ package com.sopt.now.network import android.content.Context +import android.content.SharedPreferences import com.jakewharton.processphoenix.ProcessPhoenix -import com.sopt.now.SoptApp import okhttp3.Interceptor import okhttp3.Response +import javax.inject.Inject -class HeaderInterceptor(private val context: Context) : - Interceptor { +class HeaderInterceptor @Inject constructor( + private val context: Context, + private val sharedPreferences: SharedPreferences +) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() - val app = context.applicationContext as SoptApp - val memberId = app.serviceLocator.userRepository.getMemberId() ?: "default_member_id" + val memberId = sharedPreferences.getString("MemberID", "default_member_id") ?: "default_member_id" val newRequest = originalRequest.newBuilder() .addHeader("memberId", memberId) .build() From 28db456450f75dfcb12b25f8a7e107b7ba50cfe1 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 19:59:45 +0900 Subject: [PATCH 11/18] =?UTF-8?q?#28=20Feat:=20ChangePassword=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../now/ui/change_password/ChangePasswordFragment.kt | 10 ++++------ .../now/ui/change_password/ChangePasswordViewModel.kt | 5 ++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordFragment.kt b/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordFragment.kt index 1e99e92..a826ba6 100644 --- a/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordFragment.kt @@ -1,23 +1,21 @@ package com.sopt.now.ui.change_password -import BaseFragment import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import com.sopt.now.R -import com.sopt.now.SoptApp import com.sopt.now.databinding.FragmentChangePasswordBinding import com.sopt.now.network.request.RequestChangePasswordDto +import com.sopt.now.util.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class ChangePasswordFragment : BaseFragment( FragmentChangePasswordBinding::inflate ) { - private val changePasswordViewModel: ChangePasswordViewModel by viewModels { - val app = requireActivity().application as SoptApp - app.serviceLocator.appViewModelFactory - } + private val changePasswordViewModel: ChangePasswordViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordViewModel.kt b/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordViewModel.kt index 55f0517..5aad2f0 100644 --- a/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/change_password/ChangePasswordViewModel.kt @@ -7,10 +7,13 @@ import com.sopt.now.data.UserRepository import com.sopt.now.network.request.RequestChangePasswordDto import com.sopt.now.network.response.ResponseDto import com.sopt.now.ui.AuthState +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import retrofit2.Response +import javax.inject.Inject -class ChangePasswordViewModel( +@HiltViewModel +class ChangePasswordViewModel @Inject constructor( private val userRepository: UserRepository, ) : ViewModel() { val changePasswordStatus = MutableLiveData() From b79283a3ab01c8ef7085e0c6f3dd6ed0bab10a9d Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:00:05 +0900 Subject: [PATCH 12/18] =?UTF-8?q?#28=20Feat:=20follower=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/ui/follower/FollowerFragment.kt | 7 ++++--- .../java/com/sopt/now/ui/follower/FollowerViewModel.kt | 9 +++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/follower/FollowerFragment.kt b/app/src/main/java/com/sopt/now/ui/follower/FollowerFragment.kt index f477dc3..b88472f 100644 --- a/app/src/main/java/com/sopt/now/ui/follower/FollowerFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/follower/FollowerFragment.kt @@ -7,14 +7,15 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import com.sopt.now.databinding.FragmentFollowerBinding +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class FollowerFragment : Fragment() { private var _binding: FragmentFollowerBinding? = null private val binding: FragmentFollowerBinding get() = requireNotNull(_binding) { "FragmentFollowerBinding is not initialized" } private val viewModel: FollowerViewModel by viewModels() - private lateinit var followerAdapter: FollowerAdapter override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -33,13 +34,13 @@ class FollowerFragment : Fragment() { } private fun setupRecyclerView() { - followerAdapter = FollowerAdapter(requireContext()) + val followerAdapter = FollowerAdapter(requireContext()) binding.rvFollower.adapter = followerAdapter } private fun observeViewModel() { viewModel.followers.observe(viewLifecycleOwner) { followers -> - followerAdapter.submitList(followers) + (binding.rvFollower.adapter as FollowerAdapter).submitList(followers) } } diff --git a/app/src/main/java/com/sopt/now/ui/follower/FollowerViewModel.kt b/app/src/main/java/com/sopt/now/ui/follower/FollowerViewModel.kt index deb2706..d8be2b5 100644 --- a/app/src/main/java/com/sopt/now/ui/follower/FollowerViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/follower/FollowerViewModel.kt @@ -7,17 +7,22 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.now.network.response.ResponseFollowerDto import com.sopt.now.network.service.ServicePool +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import retrofit2.Response +import javax.inject.Inject -class FollowerViewModel : ViewModel() { +@HiltViewModel +class FollowerViewModel @Inject constructor( + private val servicePool: ServicePool +) : ViewModel() { private val _followers = MutableLiveData>() val followers: LiveData> get() = _followers fun loadFollowers() { viewModelScope.launch { runCatching { - ServicePool.followerService.getFollowers(2) + servicePool.followerService.getFollowers(2) }.onSuccess { response -> handleSuccess(response) }.onFailure {t -> From c2a2c8045c04b000b74aea7fcb8daf0313cf1d48 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:00:14 +0900 Subject: [PATCH 13/18] =?UTF-8?q?#28=20Feat:=20home=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/sopt/now/ui/home/HomeFragment.kt | 10 ++++------ .../main/java/com/sopt/now/ui/home/HomeViewModel.kt | 7 ++++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/home/HomeFragment.kt b/app/src/main/java/com/sopt/now/ui/home/HomeFragment.kt index 92886cc..7891aa8 100644 --- a/app/src/main/java/com/sopt/now/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/home/HomeFragment.kt @@ -1,6 +1,5 @@ package com.sopt.now.ui.home -import BaseFragment import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -9,17 +8,16 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.viewModels import androidx.recyclerview.widget.ConcatAdapter import com.sopt.now.R -import com.sopt.now.SoptApp import com.sopt.now.data.friend.Friend import com.sopt.now.databinding.FragmentHomeBinding +import com.sopt.now.util.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class HomeFragment : BaseFragment( FragmentHomeBinding::inflate ) { - private val viewModel: HomeViewModel by viewModels { - val app = requireActivity().application as SoptApp - HomeViewModelFactory(app.serviceLocator.friendsRepository) - } + private val viewModel: HomeViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/sopt/now/ui/home/HomeViewModel.kt b/app/src/main/java/com/sopt/now/ui/home/HomeViewModel.kt index 57938cc..b6d38f2 100644 --- a/app/src/main/java/com/sopt/now/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/home/HomeViewModel.kt @@ -10,9 +10,14 @@ import com.sopt.now.R import com.sopt.now.data.Profile import com.sopt.now.data.friend.Friend import com.sopt.now.data.friend.FriendsRepository +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import javax.inject.Inject -class HomeViewModel(private val friendsRepository: FriendsRepository) : ViewModel() { +@HiltViewModel +class HomeViewModel @Inject constructor( + private val friendsRepository: FriendsRepository +) : ViewModel() { val friends: LiveData> = friendsRepository.getAllFriends().asLiveData() fun addFriend(friend: Friend) { From fce867d0960d416496949c21d09b72115914e9c0 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:00:21 +0900 Subject: [PATCH 14/18] =?UTF-8?q?#28=20Feat:=20login=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sopt/now/ui/login/LoginFragment.kt | 10 ++++------ .../main/java/com/sopt/now/ui/login/LoginViewModel.kt | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/login/LoginFragment.kt b/app/src/main/java/com/sopt/now/ui/login/LoginFragment.kt index 8e5ba3f..22ece3d 100644 --- a/app/src/main/java/com/sopt/now/ui/login/LoginFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/login/LoginFragment.kt @@ -1,23 +1,21 @@ package com.sopt.now.ui.login -import BaseFragment import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import com.sopt.now.R -import com.sopt.now.SoptApp import com.sopt.now.databinding.FragmentLoginBinding import com.sopt.now.network.request.RequestLoginDto +import com.sopt.now.util.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class LoginFragment : BaseFragment( FragmentLoginBinding::inflate ) { - private val loginViewModel: LoginViewModel by viewModels { - val app = requireActivity().application as SoptApp - app.serviceLocator.appViewModelFactory - } + private val loginViewModel: LoginViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/sopt/now/ui/login/LoginViewModel.kt b/app/src/main/java/com/sopt/now/ui/login/LoginViewModel.kt index f9e28d0..88ccf85 100644 --- a/app/src/main/java/com/sopt/now/ui/login/LoginViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/login/LoginViewModel.kt @@ -1,6 +1,5 @@ package com.sopt.now.ui.login -import android.util.Log import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -8,10 +7,13 @@ import com.sopt.now.data.UserRepository import com.sopt.now.network.request.RequestLoginDto import com.sopt.now.network.response.ResponseDto import com.sopt.now.ui.AuthState +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import retrofit2.Response +import javax.inject.Inject -class LoginViewModel( +@HiltViewModel +class LoginViewModel @Inject constructor( private val userRepository: UserRepository, ) : ViewModel() { val loginStatus = MutableLiveData() From 17e693ea4fcf69280b49080f4c0c45b8c4eed458 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:00:32 +0900 Subject: [PATCH 15/18] =?UTF-8?q?#28=20Feat:=20mypage=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/ui/mypage/MypageFragment.kt | 11 ++++------- .../java/com/sopt/now/ui/mypage/MypageViewModel.kt | 5 ++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/mypage/MypageFragment.kt b/app/src/main/java/com/sopt/now/ui/mypage/MypageFragment.kt index d21be39..c95e4df 100644 --- a/app/src/main/java/com/sopt/now/ui/mypage/MypageFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/mypage/MypageFragment.kt @@ -1,23 +1,20 @@ package com.sopt.now.ui.mypage -import BaseFragment import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.sopt.now.R -import com.sopt.now.SoptApp import com.sopt.now.databinding.FragmentMypageBinding +import com.sopt.now.util.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class MypageFragment : BaseFragment( FragmentMypageBinding::inflate ) { - private val mypageViewModel: MypageViewModel by viewModels { - val app = requireActivity().application as SoptApp - app.serviceLocator.appViewModelFactory - } - + private val mypageViewModel: MypageViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/sopt/now/ui/mypage/MypageViewModel.kt b/app/src/main/java/com/sopt/now/ui/mypage/MypageViewModel.kt index 163ec53..4bb34ea 100644 --- a/app/src/main/java/com/sopt/now/ui/mypage/MypageViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/mypage/MypageViewModel.kt @@ -7,10 +7,13 @@ import com.sopt.now.data.UserRepository import com.sopt.now.network.response.ResponseInfoDto import com.sopt.now.network.response.UserInfo import com.sopt.now.ui.AuthState +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import retrofit2.Response +import javax.inject.Inject -class MypageViewModel( +@HiltViewModel +class MypageViewModel @Inject constructor( private val userRepository: UserRepository, ) : ViewModel() { From fcd9664e79dac5cf56e3a2b275d0fda95592a594 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:00:42 +0900 Subject: [PATCH 16/18] =?UTF-8?q?#28=20Feat:=20signup=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20Hilt=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sopt/now/ui/signup/SignupFragment.kt | 10 ++++------ .../java/com/sopt/now/ui/signup/SignupViewModel.kt | 5 ++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/signup/SignupFragment.kt b/app/src/main/java/com/sopt/now/ui/signup/SignupFragment.kt index 1b9931b..ab1b26e 100644 --- a/app/src/main/java/com/sopt/now/ui/signup/SignupFragment.kt +++ b/app/src/main/java/com/sopt/now/ui/signup/SignupFragment.kt @@ -1,24 +1,22 @@ package com.sopt.now.ui.signup -import BaseFragment import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import com.sopt.now.R -import com.sopt.now.SoptApp import com.sopt.now.databinding.FragmentSignupBinding import com.sopt.now.network.request.RequestSignUpDto +import com.sopt.now.util.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class SignupFragment : BaseFragment( FragmentSignupBinding::inflate ) { - private val signupViewModel: SignupViewModel by viewModels { - val app = requireActivity().application as SoptApp - app.serviceLocator.appViewModelFactory - } + private val signupViewModel: SignupViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initSignupBtnClickListener() diff --git a/app/src/main/java/com/sopt/now/ui/signup/SignupViewModel.kt b/app/src/main/java/com/sopt/now/ui/signup/SignupViewModel.kt index 68cbc3e..1001a1c 100644 --- a/app/src/main/java/com/sopt/now/ui/signup/SignupViewModel.kt +++ b/app/src/main/java/com/sopt/now/ui/signup/SignupViewModel.kt @@ -8,10 +8,13 @@ import com.sopt.now.data.UserRepository import com.sopt.now.network.request.RequestSignUpDto import com.sopt.now.network.response.ResponseDto import com.sopt.now.ui.AuthState +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import retrofit2.Response +import javax.inject.Inject -class SignupViewModel( +@HiltViewModel +class SignupViewModel @Inject constructor( private val userRepository: UserRepository, ) : ViewModel() { val signupStatus = MutableLiveData() From 1277f4704797f04a052b17609cc16f135a53e54a Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 20:01:01 +0900 Subject: [PATCH 17/18] #28 Feat: mainActivity Hilt DI --- .../main/java/com/sopt/now/ui/main/MainActivity.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/sopt/now/ui/main/MainActivity.kt b/app/src/main/java/com/sopt/now/ui/main/MainActivity.kt index 23f82f7..4cef9ab 100644 --- a/app/src/main/java/com/sopt/now/ui/main/MainActivity.kt +++ b/app/src/main/java/com/sopt/now/ui/main/MainActivity.kt @@ -8,13 +8,23 @@ import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupWithNavController import com.google.android.material.snackbar.Snackbar import com.sopt.now.R -import com.sopt.now.SoptApp +import com.sopt.now.data.UserRepository import com.sopt.now.databinding.ActivityMainBinding +import com.sopt.now.network.ApiFactory import com.sopt.now.ui.home.HomeFragment +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject +@AndroidEntryPoint class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding + @Inject + lateinit var userRepository: UserRepository + + @Inject + lateinit var apiFactory: ApiFactory + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) @@ -39,7 +49,6 @@ class MainActivity : AppCompatActivity() { binding.mainBnv.setupWithNavController(navController) hideBottomNavigationView(navController) - val userRepository = (application as SoptApp).serviceLocator.userRepository if (userRepository.isUserLoggedIn()) { navController.navigate(R.id.homeFragment) } else { From ecb4acad5815b13fa6c0c04ae4c72f2fee7bf381 Mon Sep 17 00:00:00 2001 From: 0se0 <030ggong@gmail.com> Date: Fri, 7 Jun 2024 21:54:08 +0900 Subject: [PATCH 18/18] #28 Remove: AppViewModelFactory --- .../com/sopt/now/util/AppViewModelFactory.kt | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 app/src/main/java/com/sopt/now/util/AppViewModelFactory.kt diff --git a/app/src/main/java/com/sopt/now/util/AppViewModelFactory.kt b/app/src/main/java/com/sopt/now/util/AppViewModelFactory.kt deleted file mode 100644 index f89c3e2..0000000 --- a/app/src/main/java/com/sopt/now/util/AppViewModelFactory.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.sopt.now.util - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import com.sopt.now.data.UserRepository -import com.sopt.now.data.friend.FriendsRepository -import com.sopt.now.ui.home.HomeViewModel -import com.sopt.now.ui.login.LoginViewModel -import com.sopt.now.ui.mypage.MypageViewModel -import com.sopt.now.ui.signup.SignupViewModel - -class AppViewModelFactory( - private val userRepository: UserRepository, - private val friendsRepository: FriendsRepository -) : ViewModelProvider.Factory { - - @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T { - return when { - modelClass.isAssignableFrom(SignupViewModel::class.java) -> { - SignupViewModel(userRepository) as T - } - modelClass.isAssignableFrom(MypageViewModel::class.java) -> { - MypageViewModel(userRepository) as T - } - modelClass.isAssignableFrom(LoginViewModel::class.java) -> { - LoginViewModel(userRepository) as T - } - modelClass.isAssignableFrom(HomeViewModel::class.java) -> { - HomeViewModel(friendsRepository) as T - } - else -> throw IllegalArgumentException("Unknown ViewModel class") - } - } -} \ No newline at end of file