From 3bc768ab8fed9a4dedd03d26bac73ba2333a905a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AA=85=EC=84=9D?= Date: Thu, 9 Feb 2023 11:25:45 +0900 Subject: [PATCH] =?UTF-8?q?Issues=20#287=20feat:=20data-storage=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lighthouse/data/storage/di/DataModule.kt | 19 ++++ .../GifticonStorageRepositoryImpl.kt | 98 +++++++++++++++++++ .../gifticon/GifticonStorageRepository.kt | 21 ++++ .../model/gifticon/GifticonCropImageResult.kt | 7 ++ 4 files changed, 145 insertions(+) create mode 100644 data/data-storage/src/main/java/com/lighthouse/data/storage/di/DataModule.kt create mode 100644 data/data-storage/src/main/java/com/lighthouse/data/storage/repository/GifticonStorageRepositoryImpl.kt create mode 100644 data/data/src/main/java/com/lighthouse/repository/gifticon/GifticonStorageRepository.kt create mode 100644 model/src/main/java/com/lighthouse/beep/model/gifticon/GifticonCropImageResult.kt diff --git a/data/data-storage/src/main/java/com/lighthouse/data/storage/di/DataModule.kt b/data/data-storage/src/main/java/com/lighthouse/data/storage/di/DataModule.kt new file mode 100644 index 000000000..d069da807 --- /dev/null +++ b/data/data-storage/src/main/java/com/lighthouse/data/storage/di/DataModule.kt @@ -0,0 +1,19 @@ +package com.lighthouse.data.storage.di + +import com.lighthouse.data.storage.repository.GifticonStorageRepositoryImpl +import com.lighthouse.repository.gifticon.GifticonStorageRepository +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Suppress("unused") +@Module +@InstallIn(SingletonComponent::class) +internal abstract class DataModule { + + @Binds + abstract fun bindsGifticonStorageRepository( + repository: GifticonStorageRepositoryImpl + ): GifticonStorageRepository +} diff --git a/data/data-storage/src/main/java/com/lighthouse/data/storage/repository/GifticonStorageRepositoryImpl.kt b/data/data-storage/src/main/java/com/lighthouse/data/storage/repository/GifticonStorageRepositoryImpl.kt new file mode 100644 index 000000000..7ae3c087e --- /dev/null +++ b/data/data-storage/src/main/java/com/lighthouse/data/storage/repository/GifticonStorageRepositoryImpl.kt @@ -0,0 +1,98 @@ +package com.lighthouse.data.storage.repository + +import android.content.Context +import android.graphics.Bitmap +import android.net.Uri +import com.lighthouse.beep.model.gifticon.GifticonCropImageResult +import com.lighthouse.beep.model.gifticon.GifticonImageResult +import com.lighthouse.core.android.exts.calculateSampleSize +import com.lighthouse.core.android.exts.centerCrop +import com.lighthouse.core.android.exts.compressBitmap +import com.lighthouse.core.android.exts.decodeBitmap +import com.lighthouse.core.android.exts.decodeSampledBitmap +import com.lighthouse.core.android.exts.deleteFile +import com.lighthouse.core.android.exts.exists +import com.lighthouse.core.android.exts.openInputStream +import com.lighthouse.repository.gifticon.GifticonStorageRepository +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream +import java.util.Date +import javax.inject.Inject + +internal class GifticonStorageRepositoryImpl @Inject constructor( + @ApplicationContext private val context: Context +) : GifticonStorageRepository { + + override suspend fun saveImage( + userId: String, + inputOriginUri: Uri?, + inputCropUri: Uri? + ): Result = runCatching { + withContext(Dispatchers.IO) { + inputOriginUri ?: throw NullPointerException("originUri 가 Null 입니다.") + inputCropUri ?: throw NullPointerException("oldCroppedUri 가 Null 입니다.") + + val outputOriginFile = getOriginFile(userId) + + val sampleSize = context.calculateSampleSize(inputOriginUri) + val sampledOriginBitmap = context.decodeSampledBitmap(inputOriginUri, sampleSize) + outputOriginFile.compressBitmap(sampledOriginBitmap, Bitmap.CompressFormat.JPEG, 100) + + val outputCroppedFile = getCropFile(userId) + val cropped = if (context.exists(inputCropUri)) { + context.decodeBitmap(inputCropUri) + } else { + sampledOriginBitmap.centerCrop(1f) + } + outputCroppedFile.compressBitmap(cropped, Bitmap.CompressFormat.JPEG, 100) + GifticonImageResult(sampleSize, outputOriginFile, outputCroppedFile) + } + } + + override suspend fun updateCropImage( + userId: String, + inputCropUri: Uri? + ): Result = runCatching { + withContext(Dispatchers.IO) { + inputCropUri ?: throw NullPointerException("newCroppedUri 가 Null 입니다.") + + val outputCroppedFile = getCropFile(userId) + + val inputStream = context.openInputStream(inputCropUri) + val outputStream = FileOutputStream(outputCroppedFile) + + inputStream.use { input -> + outputStream.use { output -> + input.copyTo(output) + } + } + + GifticonCropImageResult(outputCroppedFile) + } + } + + override suspend fun deleteFile(uri: Uri): Result = runCatching { + if (context.exists(uri).not()) { + return@runCatching + } + withContext(Dispatchers.IO) { + context.deleteFile(uri) + } + } + + private fun getOriginFile(userId: String): File { + return context.getFileStreamPath("${ORIGIN_PREFIX}$userId") + } + + private fun getCropFile(userId: String, updated: Date = Date()): File { + return context.getFileStreamPath("${CROPPED_PREFIX}$userId${updated.time}") + } + + companion object { + private const val ORIGIN_PREFIX = "origin" + private const val CROPPED_PREFIX = "cropped" + } +} diff --git a/data/data/src/main/java/com/lighthouse/repository/gifticon/GifticonStorageRepository.kt b/data/data/src/main/java/com/lighthouse/repository/gifticon/GifticonStorageRepository.kt new file mode 100644 index 000000000..0fd3dd8a0 --- /dev/null +++ b/data/data/src/main/java/com/lighthouse/repository/gifticon/GifticonStorageRepository.kt @@ -0,0 +1,21 @@ +package com.lighthouse.repository.gifticon + +import android.net.Uri +import com.lighthouse.beep.model.gifticon.GifticonCropImageResult +import com.lighthouse.beep.model.gifticon.GifticonImageResult + +interface GifticonStorageRepository { + + suspend fun saveImage( + userId: String, + inputOriginUri: Uri?, + inputCropUri: Uri? + ): Result + + suspend fun updateCropImage( + userId: String, + inputCropUri: Uri? + ): Result + + suspend fun deleteFile(uri: Uri): Result +} diff --git a/model/src/main/java/com/lighthouse/beep/model/gifticon/GifticonCropImageResult.kt b/model/src/main/java/com/lighthouse/beep/model/gifticon/GifticonCropImageResult.kt new file mode 100644 index 000000000..d8d627658 --- /dev/null +++ b/model/src/main/java/com/lighthouse/beep/model/gifticon/GifticonCropImageResult.kt @@ -0,0 +1,7 @@ +package com.lighthouse.beep.model.gifticon + +import java.io.File + +data class GifticonCropImageResult( + val croppedFile: File +)