-
Notifications
You must be signed in to change notification settings - Fork 0
[QA] 연락처에 등록된 이미지로 프로필 이미지 수정 #65
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
Changes from all commits
d0db640
d832841
7696037
c7e4a20
a2b8d8a
c4d82c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package com.alarmy.near.local.contact | ||
|
|
||
| import android.content.ContentResolver | ||
| import android.webkit.MimeTypeMap | ||
| import androidx.core.net.toUri | ||
| import javax.inject.Inject | ||
|
|
||
| data class ContactImageData( | ||
| val fileName: String, | ||
| val contentType: String, | ||
| val fileSize: Int, | ||
| val data: ByteArray, | ||
| ) { | ||
| override fun equals(other: Any?): Boolean { | ||
| if (this === other) return true | ||
| if (javaClass != other?.javaClass) return false | ||
| other as ContactImageData | ||
| if (fileName != other.fileName) return false | ||
| if (contentType != other.contentType) return false | ||
| if (fileSize != other.fileSize) return false | ||
| if (!data.contentEquals(other.data)) return false | ||
| return true | ||
| } | ||
|
|
||
| override fun hashCode(): Int { | ||
| var result = fileName.hashCode() | ||
| result = 31 * result + contentType.hashCode() | ||
| result = 31 * result + fileSize | ||
| result = 31 * result + data.contentHashCode() | ||
| return result | ||
| } | ||
| } | ||
|
|
||
| class ContactImageReader | ||
| @Inject | ||
| constructor( | ||
| private val contentResolver: ContentResolver, | ||
| ) { | ||
| fun read(uriString: String): ContactImageData? { | ||
| val uri = runCatching { uriString.toUri() }.getOrNull() ?: return null | ||
| val bytes = contentResolver.openInputStream(uri)?.use { inputStream -> inputStream.readBytes() } ?: return null | ||
| val resolvedMimeType = contentResolver.getType(uri) ?: guessMimeType(uriString) ?: DEFAULT_MIME_TYPE | ||
| val extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(resolvedMimeType) ?: DEFAULT_EXTENSION | ||
| val fileName = "contact_${System.currentTimeMillis()}.$extension" | ||
| return ContactImageData( | ||
| fileName = fileName, | ||
| contentType = resolvedMimeType, | ||
| fileSize = bytes.size, | ||
| data = bytes, | ||
| ) | ||
| } | ||
|
|
||
| private fun guessMimeType(uriString: String): String? { | ||
| val lowerCase = uriString.lowercase() | ||
| return when { | ||
| lowerCase.endsWith(".png") -> "image/png" | ||
| lowerCase.endsWith(".webp") -> "image/webp" | ||
| lowerCase.endsWith(".jpg") || lowerCase.endsWith(".jpeg") -> "image/jpeg" | ||
| else -> null | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| private const val DEFAULT_MIME_TYPE = "image/jpeg" | ||
| private const val DEFAULT_EXTENSION = "jpg" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package com.alarmy.near.network.uploader | ||
|
|
||
| import kotlinx.coroutines.Dispatchers | ||
| import kotlinx.coroutines.withContext | ||
| import okhttp3.MediaType.Companion.toMediaTypeOrNull | ||
| import okhttp3.OkHttpClient | ||
| import okhttp3.Request | ||
| import okhttp3.RequestBody.Companion.toRequestBody | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| @Singleton | ||
| class ImageUploader | ||
| @Inject | ||
| constructor( | ||
| private val okHttpClient: OkHttpClient, | ||
| ) { | ||
|
|
||
| suspend fun upload( | ||
| url: String, | ||
| contentType: String, | ||
| data: ByteArray, | ||
| ) = withContext(Dispatchers.IO) { | ||
| val requestBody = data.toRequestBody(contentType.toMediaTypeOrNull()) | ||
| val request = | ||
| Request | ||
| .Builder() | ||
| .url(url) | ||
| .put(requestBody) | ||
| .build() | ||
| okHttpClient.newCall(request).execute().use { response -> | ||
| if (!response.isSuccessful) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사소한 것인데 반영은 안하셔도 됩니다!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 디테일한 코멘트 감사합니다!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 개인 취향인데, 저는 자연어처럼 코드가 읽히는 것을 선호해서 not을 꽤 쓰는 편인 것 같아요! |
||
| throw IllegalStateException("이미지 업로드에 실패했습니다.") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
byteArray가 값이 다르면 다른 객체로 인식해서 equals 및 hashCode를 재정의하라는 경고가 뜨네요!
해결 방법으로 option+ enter로 해당 코드를 자동으로 추가할 수 있습니다! 코드가 복잡해진다면 필요한 곳에서 byteArray를 맵핑해주는 방법이 있을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다! equals, hashCode를 재정의 하는 코드가 크게 복잡하지 않아 우선 재정의 하는 방법으로 개선해보았습니다!