Skip to content

Commit 68367bf

Browse files
authored
[merge] refactor/#87 자녀 온보딩 및 여정 뷰 수정
[refactor/#87] 자녀 온보딩 및 여정 뷰 수정
2 parents cf08097 + b96313d commit 68367bf

28 files changed

+426
-346
lines changed

.idea/deploymentTargetSelector.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.kiero.core.common.util
2+
3+
import android.content.Context
4+
import androidx.core.content.FileProvider
5+
import dagger.hilt.android.qualifiers.ApplicationContext
6+
import kotlinx.coroutines.Dispatchers
7+
import kotlinx.coroutines.withContext
8+
import timber.log.Timber
9+
import java.io.File
10+
import java.io.IOException
11+
import javax.inject.Inject
12+
13+
class ImageUriManager @Inject constructor(
14+
@param:ApplicationContext private val context: Context
15+
) {
16+
suspend fun createTempImageUri(): String? = withContext(Dispatchers.IO) {
17+
try {
18+
val directory = File(context.cacheDir, "images").apply {
19+
if (!exists()) mkdirs()
20+
}
21+
val file = File.createTempFile("IMG_", ".jpg", directory)
22+
23+
FileProvider.getUriForFile(
24+
context,
25+
"${context.packageName}.fileprovider",
26+
file
27+
).toString()
28+
} catch (e: IOException) {
29+
Timber.e(e, "파일 생성 실패")
30+
null
31+
}
32+
}
33+
}

app/src/main/java/com/kiero/data/kid/schedule/di/ScheduleDataSourceModule.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.kiero.data.kid.schedule.di
22

3+
import com.kiero.data.kid.schedule.remote.datasource.ImageUploadDataSource
34
import com.kiero.data.kid.schedule.remote.datasource.ScheduleDataSource
5+
import com.kiero.data.kid.schedule.remote.datasourceimpl.ImageUploadDataSourceImpl
46
import com.kiero.data.kid.schedule.remote.datasourceimpl.ScheduleDataSourceImpl
57
import dagger.Binds
68
import dagger.Module
@@ -16,4 +18,11 @@ abstract class ScheduleDataSourceModule {
1618
abstract fun bindScheduleDataSource(
1719
scheduleDataSourceImpl: ScheduleDataSourceImpl
1820
): ScheduleDataSource
21+
22+
@Binds
23+
@Singleton
24+
abstract fun bindImageUploadDataSource(
25+
imageUploadDataSourceImpl: ImageUploadDataSourceImpl
26+
): ImageUploadDataSource
27+
1928
}

app/src/main/java/com/kiero/data/kid/schedule/di/ScheduleRepositoryModule.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.kiero.data.kid.schedule.di
22

3+
import com.kiero.data.kid.schedule.repository.ImageUploadRepository
34
import com.kiero.data.kid.schedule.repository.ScheduleRepository
5+
import com.kiero.data.kid.schedule.repositoryimpl.ImageUploadRepositoryImpl
46
import com.kiero.data.kid.schedule.repositoryimpl.ScheduleRepositoryImpl
57
import dagger.Binds
68
import dagger.Module
@@ -16,4 +18,10 @@ interface ScheduleRepositoryModule {
1618
fun bindsScheduleRepository(
1719
scheduleRepositoryImpl: ScheduleRepositoryImpl
1820
) : ScheduleRepository
21+
22+
@Binds
23+
@Singleton
24+
fun bindImageUploadRepository(
25+
imageUploadRepositoryImpl: ImageUploadRepositoryImpl
26+
) : ImageUploadRepository
1927
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.kiero.data.kid.schedule.local.datasource
2+
3+
import android.content.Context
4+
import android.graphics.Bitmap
5+
import android.graphics.ImageDecoder
6+
import android.net.Uri
7+
import android.os.Build
8+
import androidx.core.net.toUri
9+
import dagger.hilt.android.qualifiers.ApplicationContext
10+
import timber.log.Timber
11+
import java.io.ByteArrayOutputStream
12+
import java.io.File
13+
import java.io.FileOutputStream
14+
import java.util.UUID
15+
import javax.inject.Inject
16+
import kotlin.math.max
17+
18+
class ImageLocalDataSource @Inject constructor(
19+
@param: ApplicationContext private val context: Context
20+
) {
21+
fun getOptimizedFile(uriString: String): File {
22+
val uri = uriString.toUri()
23+
val dir = getDirectory()
24+
return compressToWebP(uri, dir)
25+
}
26+
27+
fun clearCache() {
28+
getDirectory().listFiles()?.forEach { it.delete() }
29+
}
30+
31+
fun deleteOriginalUri(uriString: String) {
32+
try {
33+
context.contentResolver.delete(uriString.toUri(), null, null)
34+
} catch (e: Exception) {
35+
Timber.e(e, "원본 파일 삭제 실패")
36+
}
37+
}
38+
39+
private fun getDirectory(): File {
40+
return File(context.cacheDir, DIRECTORY).apply {
41+
if (!exists()) mkdirs()
42+
}
43+
}
44+
45+
private fun compressToWebP(uri: Uri, dir: File): File {
46+
val source = ImageDecoder.createSource(context.contentResolver, uri)
47+
val bitmap = ImageDecoder.decodeBitmap(source) { decoder, info, _ ->
48+
decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
49+
decoder.isMutableRequired = true
50+
51+
val size = info.size
52+
val targetSize = calculateTargetSize(size.width, size.height)
53+
decoder.setTargetSize(targetSize.first, targetSize.second)
54+
}
55+
56+
val format = if (Build.VERSION.SDK_INT >= 30) {
57+
Bitmap.CompressFormat.WEBP_LOSSY
58+
} else {
59+
Bitmap.CompressFormat.WEBP
60+
}
61+
62+
val byteArray = ByteArrayOutputStream().use { stream ->
63+
bitmap.compress(format, WEBP_QUALITY, stream)
64+
bitmap.recycle()
65+
stream.toByteArray()
66+
}
67+
68+
val tempFile = File(dir, "${UUID.randomUUID()}.webp")
69+
FileOutputStream(tempFile).use { it.write(byteArray) }
70+
71+
return tempFile
72+
}
73+
74+
private fun calculateTargetSize(width: Int, height: Int): Pair<Int, Int> {
75+
if (width <= MAX_SIZE && height <= MAX_SIZE) return width to height
76+
77+
val ratio = max(width.toFloat() / MAX_SIZE, height.toFloat() / MAX_SIZE)
78+
return (width / ratio).toInt() to (height / ratio).toInt()
79+
}
80+
81+
companion object {
82+
private const val DIRECTORY = "image_cache"
83+
private const val MAX_SIZE = 1024
84+
private const val WEBP_QUALITY = 80
85+
}
86+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.kiero.data.kid.schedule.remote.datasource
2+
3+
import com.kiero.core.network.model.BaseResponse
4+
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleImageUploadResponseDto
5+
import okhttp3.RequestBody
6+
import retrofit2.Response
7+
8+
interface ImageUploadDataSource {
9+
suspend fun postPresignedUrl(
10+
fileName: String,
11+
contentType: String
12+
): BaseResponse<ScheduleImageUploadResponseDto>
13+
14+
suspend fun uploadImageToS3(
15+
presignedUrl: String,
16+
image: RequestBody
17+
): Response<Unit>
18+
}

app/src/main/java/com/kiero/data/kid/schedule/remote/datasource/ScheduleDataSource.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@ package com.kiero.data.kid.schedule.remote.datasource
22

33
import com.kiero.core.network.model.BaseResponse
44
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleFireResponseDto
5-
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleImageUploadResponseDto
65
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleSkipResponseDto
76
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleTodayResponseDto
87

98
interface ScheduleDataSource {
109
suspend fun patchScheduleToday(): BaseResponse<ScheduleTodayResponseDto>
1110

12-
suspend fun postPresignedUrl(
13-
fileName: String,
14-
contentType: String
15-
): BaseResponse<ScheduleImageUploadResponseDto>
16-
1711
suspend fun patchScheduleComplete(
1812
scheduleDetailId: Long,
1913
imageUrl: String
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.kiero.data.kid.schedule.remote.datasourceimpl
2+
3+
import com.kiero.core.network.model.BaseResponse
4+
import com.kiero.data.kid.schedule.remote.api.S3Service
5+
import com.kiero.data.kid.schedule.remote.api.ScheduleService
6+
import com.kiero.data.kid.schedule.remote.datasource.ImageUploadDataSource
7+
import com.kiero.data.kid.schedule.remote.dto.request.ScheduleImageUploadRequestDto
8+
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleImageUploadResponseDto
9+
import okhttp3.RequestBody
10+
import retrofit2.Response
11+
import javax.inject.Inject
12+
13+
class ImageUploadDataSourceImpl @Inject constructor(
14+
private val scheduleService: ScheduleService,
15+
private val s3Service: S3Service
16+
) : ImageUploadDataSource {
17+
override suspend fun postPresignedUrl(
18+
fileName: String,
19+
contentType: String
20+
): BaseResponse<ScheduleImageUploadResponseDto> =
21+
scheduleService.postPresignedUrl(
22+
request = ScheduleImageUploadRequestDto(
23+
fileName = fileName,
24+
contentType = contentType
25+
)
26+
)
27+
28+
override suspend fun uploadImageToS3(
29+
presignedUrl: String,
30+
image: RequestBody
31+
): Response<Unit> =
32+
s3Service.uploadImageToS3(
33+
url = presignedUrl,
34+
image = image
35+
)
36+
}

app/src/main/java/com/kiero/data/kid/schedule/remote/datasourceimpl/ScheduleDataSourceImpl.kt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import com.kiero.core.network.model.BaseResponse
44
import com.kiero.data.kid.schedule.remote.api.ScheduleService
55
import com.kiero.data.kid.schedule.remote.datasource.ScheduleDataSource
66
import com.kiero.data.kid.schedule.remote.dto.request.ScheduleCompleteRequestDto
7-
import com.kiero.data.kid.schedule.remote.dto.request.ScheduleImageUploadRequestDto
87
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleFireResponseDto
9-
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleImageUploadResponseDto
108
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleSkipResponseDto
119
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleTodayResponseDto
1210
import javax.inject.Inject
@@ -17,17 +15,6 @@ class ScheduleDataSourceImpl @Inject constructor(
1715
override suspend fun patchScheduleToday(): BaseResponse<ScheduleTodayResponseDto> =
1816
service.patchScheduleToday()
1917

20-
override suspend fun postPresignedUrl(
21-
fileName: String,
22-
contentType: String
23-
): BaseResponse<ScheduleImageUploadResponseDto> =
24-
service.postPresignedUrl(
25-
request = ScheduleImageUploadRequestDto(
26-
fileName = fileName,
27-
contentType = contentType
28-
)
29-
)
30-
3118
override suspend fun patchScheduleComplete(
3219
scheduleDetailId: Long,
3320
imageUrl: String
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.kiero.data.kid.schedule.repository
2+
3+
interface ImageUploadRepository {
4+
suspend fun uploadImage(
5+
uriString: String,
6+
fileName: String,
7+
contentType: String = "image/jpeg"
8+
): Result<String>
9+
}

0 commit comments

Comments
 (0)