diff --git a/core/di/src/main/java/com/idiotfrogs/di/DataSourceModule.kt b/core/di/src/main/java/com/idiotfrogs/di/DataSourceModule.kt index cf2a0f9..ec764cf 100644 --- a/core/di/src/main/java/com/idiotfrogs/di/DataSourceModule.kt +++ b/core/di/src/main/java/com/idiotfrogs/di/DataSourceModule.kt @@ -4,6 +4,8 @@ import com.idiotfrogs.local.LocalDataSource import com.idiotfrogs.local.LocalDataSourceImpl import com.idiotfrogs.data.datasource.auth.AuthDataSource import com.idiotfrogs.data.datasource.auth.AuthDataSourceImpl +import com.idiotfrogs.data.datasource.user.UserDataSource +import com.idiotfrogs.data.datasource.user.UserDataSourceImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -21,4 +23,9 @@ interface DataSourceModule { fun bindsAuthDataSource( authDataSourceImpl: AuthDataSourceImpl ): AuthDataSource + + @Binds + fun bindsUserDataSource( + userDataSourceImpl: UserDataSourceImpl + ): UserDataSource } \ No newline at end of file diff --git a/core/di/src/main/java/com/idiotfrogs/di/NetworkModule.kt b/core/di/src/main/java/com/idiotfrogs/di/NetworkModule.kt index f843741..0bbb4a3 100644 --- a/core/di/src/main/java/com/idiotfrogs/di/NetworkModule.kt +++ b/core/di/src/main/java/com/idiotfrogs/di/NetworkModule.kt @@ -2,6 +2,7 @@ package com.idiotfrogs.di import com.idiotfrogs.network.service.AuthService import com.idiotfrogs.network.interceptor.TokenInterceptor +import com.idiotfrogs.network.service.UserService import com.idiotfrogs.network.util.BaseClient import com.idiotfrogs.network.util.TokenClient import dagger.Module @@ -22,7 +23,9 @@ import javax.inject.Singleton object NetworkModule { @Provides @Singleton - fun providesJson() = Json {} + fun providesJson() = Json { + ignoreUnknownKeys = true + } @Provides @Singleton @@ -54,4 +57,9 @@ object NetworkModule { @Singleton fun providesAuthService(retrofit: Retrofit): AuthService = retrofit.create(AuthService::class.java) + + @Provides + @Singleton + fun providesUserService(retrofit: Retrofit): UserService = + retrofit.create(UserService::class.java) } \ No newline at end of file diff --git a/core/di/src/main/java/com/idiotfrogs/di/RepositoryModule.kt b/core/di/src/main/java/com/idiotfrogs/di/RepositoryModule.kt new file mode 100644 index 0000000..e195524 --- /dev/null +++ b/core/di/src/main/java/com/idiotfrogs/di/RepositoryModule.kt @@ -0,0 +1,17 @@ +package com.idiotfrogs.di + +import com.idiotfrogs.data.repository.user.UserRepository +import com.idiotfrogs.data.repository.user.UserRepositoryImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +interface RepositoryModule { + @Binds + fun bindsUserRepository( + userRepositoryImpl: UserRepositoryImpl + ): UserRepository +} \ No newline at end of file diff --git a/core/model/src/main/java/com/idiotfrogs/model/user/UserResponse.kt b/core/model/src/main/java/com/idiotfrogs/model/user/UserResponse.kt new file mode 100644 index 0000000..35491e7 --- /dev/null +++ b/core/model/src/main/java/com/idiotfrogs/model/user/UserResponse.kt @@ -0,0 +1,11 @@ +package com.idiotfrogs.model.user + +import kotlinx.serialization.Serializable + +@Serializable +data class UserResponse( + val id: Long, + val nickname: String, + val profileImageUrl: String, + val email: String +) \ No newline at end of file diff --git a/core/model/src/main/java/com/idiotfrogs/model/user/UserUpdateRequest.kt b/core/model/src/main/java/com/idiotfrogs/model/user/UserUpdateRequest.kt new file mode 100644 index 0000000..6f396f9 --- /dev/null +++ b/core/model/src/main/java/com/idiotfrogs/model/user/UserUpdateRequest.kt @@ -0,0 +1,9 @@ +package com.idiotfrogs.model.user + +import kotlinx.serialization.Serializable + +@Serializable +data class UserUpdateRequest( + val nickname: String, + val email: String +) \ No newline at end of file diff --git a/core/network/src/main/java/com/idiotfrogs/network/service/UserService.kt b/core/network/src/main/java/com/idiotfrogs/network/service/UserService.kt new file mode 100644 index 0000000..7b20777 --- /dev/null +++ b/core/network/src/main/java/com/idiotfrogs/network/service/UserService.kt @@ -0,0 +1,23 @@ +package com.idiotfrogs.network.service + +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import okhttp3.MultipartBody +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.PUT +import retrofit2.http.Part +import retrofit2.http.Path + +interface UserService { + @GET("users/me") + suspend fun getMyProfile(): UserResponse + + @PUT("users/{userId}") + @Multipart + suspend fun updateMyProfile( + @Path("userId") userId: Long, + @Part("profileImage") profileImage: MultipartBody.Part, + @Part("userUpdateDto") userUpdateRequest: UserUpdateRequest + ): UserResponse +} \ No newline at end of file diff --git a/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSource.kt b/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSource.kt new file mode 100644 index 0000000..1940af4 --- /dev/null +++ b/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSource.kt @@ -0,0 +1,15 @@ +package com.idiotfrogs.data.datasource.user + +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import okhttp3.MultipartBody + +interface UserDataSource { + suspend fun getMyProfile(): UserResponse + + suspend fun updateMyProfile( + userId: Long, + profileImage: MultipartBody.Part, + userUpdateRequest: UserUpdateRequest + ): UserResponse +} \ No newline at end of file diff --git a/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSourceImpl.kt b/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSourceImpl.kt new file mode 100644 index 0000000..ced05f6 --- /dev/null +++ b/data/src/main/java/com/idiotfrogs/data/datasource/user/UserDataSourceImpl.kt @@ -0,0 +1,27 @@ +package com.idiotfrogs.data.datasource.user + +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import com.idiotfrogs.network.service.UserService +import okhttp3.MultipartBody +import javax.inject.Inject + +class UserDataSourceImpl @Inject constructor( + private val userService: UserService +) : UserDataSource { + override suspend fun getMyProfile(): UserResponse { + return userService.getMyProfile() + } + + override suspend fun updateMyProfile( + userId: Long, + profileImage: MultipartBody.Part, + userUpdateRequest: UserUpdateRequest + ): UserResponse { + return userService.updateMyProfile( + userId = userId, + profileImage = profileImage, + userUpdateRequest = userUpdateRequest + ) + } +} \ No newline at end of file diff --git a/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepository.kt b/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepository.kt new file mode 100644 index 0000000..92e8450 --- /dev/null +++ b/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepository.kt @@ -0,0 +1,15 @@ +package com.idiotfrogs.data.repository.user + +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import java.io.File + +interface UserRepository { + suspend fun getMyProfile(): UserResponse + + suspend fun updateMyProfile( + userId: Long, + profileImage: File, + userUpdateRequest: UserUpdateRequest + ): UserResponse +} \ No newline at end of file diff --git a/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepositoryImpl.kt b/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepositoryImpl.kt new file mode 100644 index 0000000..8aa2b35 --- /dev/null +++ b/data/src/main/java/com/idiotfrogs/data/repository/user/UserRepositoryImpl.kt @@ -0,0 +1,32 @@ +package com.idiotfrogs.data.repository.user + +import com.idiotfrogs.data.datasource.user.UserDataSource +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody +import java.io.File +import javax.inject.Inject + +class UserRepositoryImpl @Inject constructor( + private val userDataSource: UserDataSource +) : UserRepository { + override suspend fun getMyProfile(): UserResponse { + return userDataSource.getMyProfile() + } + + override suspend fun updateMyProfile( + userId: Long, + profileImage: File, + userUpdateRequest: UserUpdateRequest + ): UserResponse { + val imageRequestBody = profileImage.asRequestBody("image/jpeg".toMediaType()) + val imagePart = MultipartBody.Part.createFormData("profileImage", profileImage.name, imageRequestBody) + return userDataSource.updateMyProfile( + userId = userId, + profileImage = imagePart, + userUpdateRequest = userUpdateRequest + ) + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/idiotfrogs/domain/.gitkeep b/domain/src/main/java/com/idiotfrogs/domain/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/domain/src/main/java/com/idiotfrogs/domain/usecase/user/GetMyProfileUseCase.kt b/domain/src/main/java/com/idiotfrogs/domain/usecase/user/GetMyProfileUseCase.kt new file mode 100644 index 0000000..6e3dad5 --- /dev/null +++ b/domain/src/main/java/com/idiotfrogs/domain/usecase/user/GetMyProfileUseCase.kt @@ -0,0 +1,13 @@ +package com.idiotfrogs.domain.usecase.user + +import com.idiotfrogs.data.repository.user.UserRepository +import com.idiotfrogs.model.user.UserResponse +import javax.inject.Inject + +class GetMyProfileUseCase @Inject constructor( + private val userRepository: UserRepository +) { + suspend operator fun invoke(): UserResponse { + return userRepository.getMyProfile() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/idiotfrogs/domain/usecase/user/UpdateMyProfileUseCase.kt b/domain/src/main/java/com/idiotfrogs/domain/usecase/user/UpdateMyProfileUseCase.kt new file mode 100644 index 0000000..ccbcc02 --- /dev/null +++ b/domain/src/main/java/com/idiotfrogs/domain/usecase/user/UpdateMyProfileUseCase.kt @@ -0,0 +1,15 @@ +package com.idiotfrogs.domain.usecase.user + +import com.idiotfrogs.data.repository.user.UserRepository +import com.idiotfrogs.model.user.UserResponse +import com.idiotfrogs.model.user.UserUpdateRequest +import java.io.File +import javax.inject.Inject + +class UpdateMyProfileUseCase @Inject constructor( + private val userRepository: UserRepository +) { + suspend operator fun invoke(userId: Long, profileImage: File, userUpdateRequest: UserUpdateRequest): UserResponse { + return userRepository.updateMyProfile(userId, profileImage, userUpdateRequest) + } +} \ No newline at end of file