Skip to content
Closed
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
Binary file added app/src/main/assets/sample_cut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/sample_cut_portrait.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/sample_cut_square.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ dependencies {
implementation(libs.datastore.preferences.core)
implementation(libs.protobuf.javalite)

// camerax
implementation(libs.camerax.core)
// test
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.foke.together.data.repository

import androidx.annotation.IntRange
import androidx.camera.core.CameraSelector
import androidx.datastore.core.DataStore
import com.foke.together.AppPreferences
import com.foke.together.CameraSource
Expand Down Expand Up @@ -53,6 +55,64 @@ class AppPreferencesRepository @Inject constructor(
}
}

override fun getInternalCameraLensFacing(): Flow<Int> =
appPreferencesFlow.map{
it.internalCameraLensFacing
}

override suspend fun setInternalCameraLensFacing(lensFacing: Int) {
appPreferences.updateData {
it.toBuilder()
.setInternalCameraLensFacing(lensFacing)
.build()
}
}

override fun getInterenalCameraFlashMode(): Flow<Int> =
appPreferencesFlow.map{
it.internalCameraFlashMode
}

override suspend fun setInterenalCameraFlashMode(
@IntRange(from = 0, to = 3) flashMode: Int
) {
appPreferences.updateData {
it.toBuilder()
.setInternalCameraFlashMode(flashMode)
.build()
}
}

override fun getInternalCameraCaptureMode(): Flow<Int> =
appPreferencesFlow.map {
it.internalCameraCaptureMode
}

override suspend fun setInterenalCameraCaptureMode(
@IntRange(from = 0, to = 2) captureMode: Int
) {
appPreferences.updateData {
it.toBuilder()
.setInternalCameraCaptureMode(captureMode)
.build()
}
}

override fun getInternalCameraAspectRatio(): Flow<Int> =
appPreferencesFlow.map {
it.internalCameraAspectRatio
}

override suspend fun setInterenalCameraAspectRatio(
@IntRange(from = -1, to = 1) aspectRatio: Int
) {
appPreferences.updateData {
it.toBuilder()
.setInternalCameraAspectRatio(aspectRatio)
.build()
}
}

override suspend fun clearAll() {
appPreferences.updateData {
it.toBuilder().clear().build()
Expand Down
5 changes: 5 additions & 0 deletions data/src/main/proto/app_preferences.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ message AppPreferences {
CameraSource camera_source = 10;
string external_camera_ip = 11;

int32 internal_camera_lens_facing = 20;
int32 internal_camera_flash_mode = 21;
int32 internal_camera_capture_mode = 22;
int32 internal_camera_aspect_ratio = 23;

// TODO: sample code. remove later.
string sample_id = 999997;
string sample_title = 999998;
Expand Down
4 changes: 4 additions & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.camerax.view)
implementation(libs.camerax.lifecycle)
implementation(libs.androidx.ui.graphics.android)

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ class CaptureWithExternalCameraUseCase @Inject constructor(
suspend operator fun invoke(fileName: String): Result<Unit> {
externalCameraRepository.capture()
.onSuccess {
AppLog.i(TAG, "capture", "success: $it")
AppLog.i(TAG, "invoke", "success: $it")
imageRepository.cachingImage(it, fileName)
return Result.success(Unit)
}
.onFailure {
// TODO: handle network error
AppLog.i(TAG, "capture", "failure: $it")
AppLog.i(TAG, "invoke", "failure: $it")
return Result.failure(it)
}
return Result.failure(Exception("Unknown error"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.foke.together.domain.interactor

import android.content.Context
import com.foke.together.domain.output.ImageRepositoryInterface
import com.foke.together.domain.output.InternalCameraRepositoryInterface
import com.foke.together.util.AppLog
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

class CaptureWithInternalCameraUseCase @Inject constructor(
private val internalCameraRepository: InternalCameraRepositoryInterface,
private val imageRepository: ImageRepositoryInterface
) {
suspend operator fun invoke(
context: Context,
fileName: String
): Result<Unit>{
internalCameraRepository.capture(context)
.onSuccess {
AppLog.i(TAG, "invoke", "success: $it")
imageRepository.cachingImage(it, fileName)
return Result.success(Unit)
}
.onFailure {
AppLog.e(TAG, "invoke", "failure: $it")
return Result.failure(it)
}
return Result.failure(Exception("Unknown error"))
}

companion object {
private val TAG = CaptureWithInternalCameraUseCase::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.foke.together.domain.interactor

import android.net.Uri
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.layer.GraphicsLayer
import com.foke.together.domain.output.ImageRepositoryInterface
import com.foke.together.util.AppLog
import com.foke.together.util.AppPolicy
import javax.inject.Inject

class GenerateImageFromViewUseCase @Inject constructor(
private val imageRepositoryInterface: ImageRepositoryInterface
) {
// TODO: UI -> UC -> UI 흐름으로 만들어보기
suspend operator fun invoke(graphicsLayer: GraphicsLayer, filename: String? = null, isCutFrameForPrint: Boolean = false): Uri {
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
val finalCachedImageUri = imageRepositoryInterface.cachingImage(
bitmap,
filename ?: run {
if (isCutFrameForPrint) AppPolicy.TWO_ROW_FINAL_IMAGE_NAME else AppPolicy.SINGLE_ROW_FINAL_IMAGE_NAME
}
)
AppLog.d(TAG, "invoke" ,"finalCachedImageUri: $finalCachedImageUri")
return finalCachedImageUri
}

companion object {
private val TAG = GenerateImageFromViewUseCase::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,35 @@ package com.foke.together.domain.interactor
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import com.foke.together.domain.interactor.entity.CutFrameType
import com.foke.together.domain.output.ImageRepositoryInterface
import com.foke.together.util.AppPolicy
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GeneratePhotoFrameUseCase @Inject constructor(
@Deprecated("Not in use")
class GeneratePhotoFrameUseCaseV1 @Inject constructor(
@ApplicationContext private val context: Context,
private val imageRepositoryInterface: ImageRepositoryInterface
){
fun getCutFrameType(): CutFrameType = imageRepositoryInterface.getCutFrameType()
suspend fun setCutFrameType(type: Int) = imageRepositoryInterface.setCutFrameType(type)

// 촬영한 이미지 리스트 관리
// TODO: 추후 세션 관리와 엮어서 처리하기
@Deprecated("Not in use")
fun getCapturedImageListUri(): List<Uri> = imageRepositoryInterface.getCachedImageUriList()
@Deprecated("Not in use")
suspend fun clearCapturedImageList() = imageRepositoryInterface.clearCacheDir()
suspend fun saveGraphicsLayerImage(image: Bitmap, fileName: String) = imageRepositoryInterface.cachingImage(image, fileName)
suspend fun saveFinalImage(image: Bitmap, fileName: String) = imageRepositoryInterface.saveToStorage(image, fileName)


// 최종 이미지 URL 가져오기
// TODO: 추후 세션 관리와 엮어서 처리하기
@Deprecated("Not in use")
fun getFinalSingleImageUri(): Uri {
var finalSingleImageUri: Uri = Uri.EMPTY
context.cacheDir.listFiles().forEach {
file -> if (file.name.contains("${AppPolicy.SINGLE_ROW_FINAL_IMAGE_NAME}")) { finalSingleImageUri = Uri.fromFile(file) }
}
return finalSingleImageUri
}

@Deprecated("Not in use")
fun getFinalTwoImageUri(): Uri {
var finalTwoImageUri: Uri = Uri.EMPTY
context.cacheDir.listFiles().forEach {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.foke.together.domain.interactor

import com.foke.together.domain.output.AppPreferenceInterface
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetInternalCameraAspectRatioUseCase @Inject constructor(
private val appPreferenceRepository: AppPreferenceInterface
) {
operator fun invoke() : Flow<Int> = appPreferenceRepository.getInternalCameraAspectRatio()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.foke.together.domain.interactor

import com.foke.together.domain.output.AppPreferenceInterface
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetInternalCameraCaptureModeUseCase @Inject constructor(
private val appPreferenceRepository: AppPreferenceInterface
) {
operator fun invoke() : Flow<Int> = appPreferenceRepository.getInternalCameraCaptureMode()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.foke.together.domain.interactor

import com.foke.together.domain.output.AppPreferenceInterface
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetInternalCameraFlashModeUseCase @Inject constructor(
private val appPreferenceRepository: AppPreferenceInterface
) {
operator fun invoke() : Flow<Int> = appPreferenceRepository.getInterenalCameraFlashMode()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.foke.together.domain.interactor

import androidx.camera.core.CameraSelector
import com.foke.together.domain.output.AppPreferenceInterface
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class GetInternalCameraLensFacingUseCase @Inject constructor(
private val appPreferenceRepository: AppPreferenceInterface
) {
operator fun invoke() : Flow<CameraSelector> = appPreferenceRepository.getInternalCameraLensFacing().map { cameraSelectorIdx ->
CameraSelector.Builder()
.requireLensFacing(cameraSelectorIdx)
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.foke.together.domain.interactor

import android.content.Context
import androidx.annotation.IntRange
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.view.PreviewView
import androidx.lifecycle.LifecycleOwner
import com.foke.together.domain.output.InternalCameraRepositoryInterface
import javax.inject.Inject

class GetInternalCameraPreviewUseCase @Inject constructor(
private val internalCameraRepository: InternalCameraRepositoryInterface,
) {
suspend operator fun invoke(
context: Context,
previewView: PreviewView,
lifecycleOwner: LifecycleOwner,
cameraSelector: CameraSelector,
imageAnalysis: ImageAnalysis?,
@IntRange(from = 0, to = 2) captureMode: Int,
@IntRange(from = 0, to = 3) flashMode: Int,
@IntRange(from = -1, to = 1) aspectRatio: Int
) = internalCameraRepository.showCameraPreview(
context = context,
lifecycleOwner = lifecycleOwner,
previewView = previewView,
selector = cameraSelector,
imageAnalysis = imageAnalysis,
captureMode = captureMode,
flashMode = flashMode,
aspectRatio = aspectRatio
)
}
Loading