Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/profile image #47

Merged
merged 5 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
android:value="androidx.startup" />
</provider>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.dkin.chevit.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--Context.getFilesDir()-->
<files-path name="files" path="." />

<!--getCacheDir()-->
<cache-path name="cache" path="." />

<!--Environment.getExternalStorageDirectory()-->
<external-path name="external" path="." />

<!--Context.getExternalFilesDir(null)-->
<external-files-path name="external_files" path="."/>

<!--Context.getExternalCacheDir()-->
<external-cache-path name="external_cache" path="."/>

<!--only available on API 21+ devices.-->
<!--Context.getExternalMediaDirs()-->
<external-media-path name="external_media" path="."/>
</paths>
27 changes: 27 additions & 0 deletions data/src/debug/java/com/dkin/chevit/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Converter
import retrofit2.Retrofit
import javax.inject.Named

@Module
@InstallIn(SingletonComponent::class)
Expand Down Expand Up @@ -86,6 +87,20 @@ internal object NetworkModule {
.addInterceptor(tokenInterceptor)
.build()

@Provides
@Singleton
@Named("Pure")
fun providePureOkHttpClient(
httpLoggingInterceptor: HttpLoggingInterceptor,
chuckerInterceptor: ChuckerInterceptor,
) = OkHttpClient.Builder()
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'

.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(chuckerInterceptor)
.build()

@Provides
@Singleton
fun provideRetrofit(
Expand All @@ -96,4 +111,16 @@ internal object NetworkModule {
.addConverterFactory(jsonConverter)
.baseUrl(BuildConfig.API_URL)
.build()

@Provides
@Singleton
@Named("Pure")
fun providePureRetrofit(
@Named("Pure") okHttpClient: OkHttpClient,
@JsonConverter jsonConverter: Converter.Factory,
): Retrofit = Retrofit.Builder()
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:multiline-expression-wrapping reported by reviewdog 🐶
A multiline expression should start on a new line

Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:function-signature reported by reviewdog 🐶
Newline expected before expression body

Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'

.client(okHttpClient)
.addConverterFactory(jsonConverter)
.baseUrl(BuildConfig.API_URL)
.build()
}
8 changes: 8 additions & 0 deletions data/src/main/java/com/dkin/chevit/data/di/RetrofitModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dkin.chevit.data.di

import com.dkin.chevit.data.remote.AuthAPI
import com.dkin.chevit.data.remote.ImageAPI
import com.dkin.chevit.data.remote.NotificationAPI
import com.dkin.chevit.data.remote.PlanAPI
import com.dkin.chevit.data.remote.ServiceAPI
Expand All @@ -10,6 +11,7 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import retrofit2.Retrofit
import javax.inject.Named

@Module
@InstallIn(SingletonComponent::class)
Expand Down Expand Up @@ -37,4 +39,10 @@ internal object RetrofitModule {
fun providePlanAPI(
retrofit: Retrofit
): PlanAPI = retrofit.create(PlanAPI::class.java)

@Provides
@Singleton
fun provideImageAPI(
@Named("Pure") retrofit: Retrofit
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-declaration-site reported by reviewdog 🐶
Missing trailing comma before ")"

): ImageAPI = retrofit.create(ImageAPI::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package com.dkin.chevit.data.di.usecase

import com.dkin.chevit.domain.base.CoroutineDispatcherProvider
import com.dkin.chevit.domain.repository.AuthRepository
import com.dkin.chevit.domain.usecase.auth.GetProfileImageDataUseCase
import com.dkin.chevit.domain.usecase.auth.GetUserStateUseCase
import com.dkin.chevit.domain.usecase.auth.GetUserUseCase
import com.dkin.chevit.domain.usecase.auth.SignOutUseCase
import com.dkin.chevit.domain.usecase.auth.SignUpUserUseCase
import com.dkin.chevit.domain.usecase.auth.UpdateUserUseCase
import com.dkin.chevit.domain.usecase.auth.UploadProfileImageUseCase
import com.dkin.chevit.domain.usecase.auth.WithDrawUserUseCase
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -69,4 +71,22 @@ internal object AuthUseCaseModule {
coroutineDispatcherProvider,
authRepository
)

@Provides
fun provideGetProfileImageDataUseCase(
coroutineDispatcherProvider: CoroutineDispatcherProvider,
authRepository: AuthRepository,
) = GetProfileImageDataUseCase(
coroutineDispatcherProvider,
authRepository
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-call-site reported by reviewdog 🐶
Missing trailing comma before ")"

)

@Provides
fun provideUploadProfileImageUseCase(
coroutineDispatcherProvider: CoroutineDispatcherProvider,
authRepository: AuthRepository,
) = UploadProfileImageUseCase(
coroutineDispatcherProvider,
authRepository
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-call-site reported by reviewdog 🐶
Missing trailing comma before ")"

)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dkin.chevit.data.model.request

import com.dkin.chevit.data.DataModel
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
internal data class ProfileImageUploadPayload(
@SerialName("fileSize") val fileSize: Int,
@SerialName("mimeType") val mimeType: String,
) : DataModel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dkin.chevit.data.model.response

import com.dkin.chevit.data.DataModel
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
internal data class ProfileImageUploadResponse(
@SerialName("uploadMethod") val uploadMethod: String = "",
@SerialName("uploadURL") val uploadURL: String = "",
@SerialName("imageURL") val imageURL: String = "",
) : DataModel
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:final-newline reported by reviewdog 🐶
File must end with a newline (\n)

11 changes: 11 additions & 0 deletions data/src/main/java/com/dkin/chevit/data/remote/AuthAPI.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package com.dkin.chevit.data.remote

import com.dkin.chevit.data.model.request.ProfileImageUploadPayload
import com.dkin.chevit.data.model.request.SignUpPayload
import com.dkin.chevit.data.model.request.UpdateUserPayload
import com.dkin.chevit.data.model.request.ValidationNicknamePayload
import com.dkin.chevit.data.model.response.ProfileImageUploadResponse
import com.dkin.chevit.data.model.response.UserResponse
import com.dkin.chevit.domain.base.None
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import okhttp3.MultipartBody
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import okhttp3.RequestBody
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Multipart
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import retrofit2.http.Url
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import


/**
* 유저 정보 및 인증 관련 API 모음
Expand All @@ -29,4 +37,7 @@ internal interface AuthAPI {

@DELETE("deleteUser")
suspend fun deleteUser(): Response<Unit>

@POST("getProfileUploadURL")
suspend fun getProfileUploadURL(@Body body: ProfileImageUploadPayload): ProfileImageUploadResponse
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:parameter-list-wrapping reported by reviewdog 🐶
Parameter should start on a newline

Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:function-signature reported by reviewdog 🐶
Newline expected after opening parenthesis

Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:parameter-list-wrapping reported by reviewdog 🐶
Missing newline before ")"

Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:function-signature reported by reviewdog 🐶
Newline expected before closing parenthesis

}
14 changes: 14 additions & 0 deletions data/src/main/java/com/dkin/chevit/data/remote/ImageAPI.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.dkin.chevit.data.remote

import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.PUT
import retrofit2.http.Url

internal interface ImageAPI {
@PUT
suspend fun uploadProfileImage(
@Url url: String,
@Body file: RequestBody
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-declaration-site reported by reviewdog 🐶
Missing trailing comma before ")"

)
}
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:final-newline reported by reviewdog 🐶
File must end with a newline (\n)

Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
package com.dkin.chevit.data.repository

import com.dkin.chevit.data.model.request.ProfileImageUploadPayload
import com.dkin.chevit.data.model.request.SignUpPayload
import com.dkin.chevit.data.model.request.UpdateUserPayload
import com.dkin.chevit.data.model.response.toUser
import com.dkin.chevit.data.remote.AuthAPI
import com.dkin.chevit.data.remote.ImageAPI
import com.dkin.chevit.domain.base.None
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import com.dkin.chevit.domain.model.ProfileImageData
import com.dkin.chevit.domain.model.UserState
import com.dkin.chevit.domain.repository.AuthRepository
import com.google.firebase.auth.FirebaseAuth
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import javax.inject.Inject

internal class AuthRepositoryImpl @Inject constructor(
private val authAPI: AuthAPI,
private val auth: FirebaseAuth
private val imageAPI: ImageAPI,
private val auth: FirebaseAuth,
) : AuthRepository {
override suspend fun getUserState(): UserState {
return runCatching {
Expand Down Expand Up @@ -43,4 +53,29 @@ internal class AuthRepositoryImpl @Inject constructor(
auth.signOut()
return getUserState()
}

override suspend fun getProfileUploadURL(fileSize: Int): ProfileImageData {
val result = authAPI.getProfileUploadURL(
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:multiline-expression-wrapping reported by reviewdog 🐶
A multiline expression should start on a new line

ProfileImageUploadPayload(
fileSize = fileSize,
mimeType = "image/jpeg"
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-call-site reported by reviewdog 🐶
Missing trailing comma before ")"

)
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-call-site reported by reviewdog 🐶
Missing trailing comma before ")"

)
return ProfileImageData(
uploadMethod = result.uploadMethod,
uploadURL = result.uploadURL,
uploadHeaders = "{\"Content-Type\": [\"image/jpeg\"]}",
imageURL = result.imageURL,
)
}

override suspend fun uploadProfileImage(
uploadURL: String,
uploadMethod: String,
uploadHeaders: String,
file: File
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-declaration-site reported by reviewdog 🐶
Missing trailing comma before ")"

) {
val requestFile: RequestBody = file.asRequestBody("image/jpeg".toMediaTypeOrNull())
return imageAPI.uploadProfileImage(uploadURL, requestFile)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dkin.chevit.domain.model

import com.dkin.chevit.domain.base.DomainModel

data class ProfileImageData(
val uploadMethod: String,
val uploadURL: String,
val uploadHeaders: String,
val imageURL: String
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:trailing-comma-on-declaration-site reported by reviewdog 🐶
Missing trailing comma before ")"

) : DomainModel
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:final-newline reported by reviewdog 🐶
File must end with a newline (\n)

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package com.dkin.chevit.domain.model
import com.dkin.chevit.domain.base.DomainModel

sealed interface UserState : DomainModel {
object Guest : UserState
data object Guest : UserState

object NotRegister : UserState
data object NotRegister : UserState

data class User(
val id: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.dkin.chevit.domain.repository

import com.dkin.chevit.domain.base.None
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import

import com.dkin.chevit.domain.model.ProfileImageData
import com.dkin.chevit.domain.model.UserState
import java.io.File

interface AuthRepository {
suspend fun getUserState(): UserState
Expand All @@ -12,4 +15,8 @@ interface AuthRepository {
suspend fun signOutUser(): UserState

suspend fun withDrawUser(): UserState

suspend fun getProfileUploadURL(fileSize: Int): ProfileImageData

suspend fun uploadProfileImage(uploadURL: String, uploadMethod: String, uploadHeaders: String, file: File)
Copy link

Choose a reason for hiding this comment

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

🚫 [ktlint] standard:function-signature reported by reviewdog 🐶
Newline expected after opening parenthesis

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.dkin.chevit.domain.usecase.auth

import com.dkin.chevit.domain.base.CoroutineDispatcherProvider
import com.dkin.chevit.domain.base.IOUseCase
import com.dkin.chevit.domain.model.ProfileImageData
import com.dkin.chevit.domain.repository.AuthRepository

class GetProfileImageDataUseCase(
coroutineDispatcherProvider: CoroutineDispatcherProvider,
private val authRepository: AuthRepository,
) : IOUseCase<GetProfileImageDataUseCase.Param, ProfileImageData>(coroutineDispatcherProvider = coroutineDispatcherProvider) {
override suspend fun execute(params: Param): ProfileImageData {
return authRepository.getProfileUploadURL(params.fileSize)
}

@JvmInline
value class Param(val fileSize: Int)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.dkin.chevit.domain.usecase.auth

import com.dkin.chevit.domain.base.CoroutineDispatcherProvider
import com.dkin.chevit.domain.base.IOUseCase
import com.dkin.chevit.domain.base.None
import com.dkin.chevit.domain.repository.AuthRepository
import java.io.File

class UploadProfileImageUseCase(
coroutineDispatcherProvider: CoroutineDispatcherProvider,
private val authRepository: AuthRepository,
) : IOUseCase<UploadProfileImageUseCase.Param, None>(coroutineDispatcherProvider = coroutineDispatcherProvider) {
override suspend fun execute(params: Param): None {
authRepository.uploadProfileImage(
uploadURL = params.uploadURL,
uploadMethod = params.uploadMethod,
uploadHeaders = params.uploadHeaders,
file = params.file
)
return None
}

data class Param(
val uploadURL: String,
val uploadMethod: String,
val uploadHeaders: String,
val file: File
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private fun HomeStable(
.crossfade(true)
.build(),
contentDescription = "",
contentScale = ContentScale.Fit,
contentScale = ContentScale.FillBounds,
error = painterResource(id = R.drawable.ic_profile_empty)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fun UserContents(
.crossfade(true)
.build(),
contentDescription = "",
contentScale = ContentScale.Fit,
contentScale = ContentScale.FillBounds,
error = painterResource(id = drawable.ic_profile_empty)
)
}
Expand Down
Loading
Loading