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.
1 change: 1 addition & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.ui.graphics.android)
implementation(libs.camerax.view)
implementation(libs.camerax.lifecycle)
testImplementation(libs.junit)
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,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
@@ -1,26 +1,168 @@
package com.foke.together.domain.interactor.entity

enum class CutFrameType {
MAKER_FAIRE,
FOURCUT_LIGHT,
FOURCUT_DARK;

companion object {
fun findBy(name: String): CutFrameType {
return when (name) {
MAKER_FAIRE.name -> MAKER_FAIRE
FOURCUT_LIGHT.name -> FOURCUT_LIGHT
FOURCUT_DARK.name -> FOURCUT_DARK
else -> throw IllegalArgumentException("Unknown value: $name")
}
}
fun findBy(ordinal: Int): CutFrameType {
return when (ordinal) {
MAKER_FAIRE.ordinal -> MAKER_FAIRE
FOURCUT_LIGHT.ordinal -> FOURCUT_LIGHT
FOURCUT_DARK.ordinal -> FOURCUT_DARK
else -> throw IllegalArgumentException("Unknown value: $ordinal")
}
}
}
import androidx.annotation.DrawableRes
import com.foke.together.domain.R

abstract class CutFrame(
val index: Int,
val frameTitle: String,
val cutCount: Int,
val width: Int,
val height: Int,
@DrawableRes val frameImageSrc: Int, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
val photoPosition: List<PhotoPosition>,
val additionalFrameImageSrc: List<Int>, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
)

sealed class DefaultCutFrameSet (
index: Int,
frameTitle: String,
cutCount: Int,
width: Int,
height: Int,
frameImageSrc: Int, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
photoPosition: List<PhotoPosition>,
additionalFrameImageSrc: List<Int>, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
var isDateString: Boolean = false,
val dateStringHeight: Int = 0,
): CutFrame(index, frameTitle, cutCount, width, height, frameImageSrc, photoPosition, additionalFrameImageSrc) {
val cutFrameSetTitle = "기본"
val cutFrameCoverImageSrc = ""

// TODO: add information of frames
data object FourCutLight: DefaultCutFrameSet(
7,
"같이네컷 화이트",
4, 190, 570,
R.drawable.fourcut_frame_medium_light,
listOf(
PhotoPosition(159, 106, 16, 36),
PhotoPosition(159, 106, 16, 147),
PhotoPosition(159, 106, 16, 258),
PhotoPosition(159, 106, 16, 369),
),
emptyList()
)

data object FourCurDark: DefaultCutFrameSet(
8,
"같이네컷 다크",
4, 190, 570,
R.drawable.fourcut_frame_medium_dark,
listOf(
PhotoPosition(159, 106, 16, 36),
PhotoPosition(159, 106, 16, 147),
PhotoPosition(159, 106, 16, 258),
PhotoPosition(159, 106, 16, 369),
),
emptyList()
)

data object MakerFaire: DefaultCutFrameSet(
9,
"Maker Faire Seoul 2024",
4, 190, 570,
R.drawable.maker_faire_frame,
listOf(
PhotoPosition(159, 106, 16, 36),
PhotoPosition(159, 106, 16, 147),
PhotoPosition(159, 106, 16, 258),
PhotoPosition(159, 106, 16, 369),
),
emptyList()
)

data object Bride1: DefaultCutFrameSet(
3,
"신부 1",
4, 190, 570,
R.drawable.bride1,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
emptyList(),
dateStringHeight = 498
)

data object Bride2: DefaultCutFrameSet(
4,
"신부 2",
4, 190, 570,
R.drawable.bride2,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
emptyList(),
dateStringHeight = 495
)

data object Groom1: DefaultCutFrameSet(
5,
"신랑 1",
4, 190, 570,
R.drawable.groom1,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
emptyList(),
dateStringHeight = 495
)

data object Groom2: DefaultCutFrameSet(
6,
"신랑 2",
4, 190, 570,
R.drawable.groom2,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
emptyList(),
dateStringHeight = 495
)

data object Wedding1: DefaultCutFrameSet(
1,
"웨딩 1",
4, 190, 570,
R.drawable.wedding,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
listOf(
R.drawable.wedding_overlay1
),
dateStringHeight = 495
)

data object Wedding2: DefaultCutFrameSet(
2,
"웨딩 2",
4, 190, 570,
R.drawable.wedding,
listOf(
PhotoPosition(172, 115, 9, 9),
PhotoPosition(172, 115, 9, 133),
PhotoPosition(172, 115, 9, 256),
PhotoPosition(172, 115, 9, 383),
),
listOf(
R.drawable.wedding_overlay2
),
dateStringHeight = 495
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.foke.together.domain.interactor.entity

enum class CutFrameTypeV1 {
MAKER_FAIRE,
FOURCUT_LIGHT,
FOURCUT_DARK;

companion object {
fun findBy(name: String): CutFrameTypeV1 {
return when (name) {
MAKER_FAIRE.name -> MAKER_FAIRE
FOURCUT_LIGHT.name -> FOURCUT_LIGHT
FOURCUT_DARK.name -> FOURCUT_DARK
else -> throw IllegalArgumentException("Unknown value: $name")
}
}
fun findBy(ordinal: Int): CutFrameTypeV1 {
return when (ordinal) {
MAKER_FAIRE.ordinal -> MAKER_FAIRE
FOURCUT_LIGHT.ordinal -> FOURCUT_LIGHT
FOURCUT_DARK.ordinal -> FOURCUT_DARK
else -> throw IllegalArgumentException("Unknown value: $ordinal")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.foke.together.domain.interactor.entity

data class PhotoPosition (
val width: Int,
val height: Int,
val x: Int,
val y: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.foke.together.domain.interactor.entity

data class SessionData (
val sessionId: SessionId,
val cutFrame: CutFrame? = null,
val status: Status
)

enum class Status {
INIT,
SELECT_FRAME,
CAPTURE,
GENERATE_PHOTO,
SHARE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.foke.together.domain.interactor.entity

data class SessionId (
val startAt: Long
) {
override fun toString(): String {
return startAt.toString()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.foke.together.domain.interactor.session

import com.foke.together.domain.output.SessionRepositoryInterface
import javax.inject.Inject

class ClearSessionUseCase @Inject constructor(
private val sessionRepository: SessionRepositoryInterface
) {
operator fun invoke() {
sessionRepository.clearSession()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.foke.together.domain.interactor.session

import com.foke.together.domain.output.SessionRepositoryInterface
import javax.inject.Inject

class CreateNewSessionUseCase @Inject constructor(
private val sessionRepository: SessionRepositoryInterface
) {
operator fun invoke() {
sessionRepository.createSession()
}
}
Loading