diff --git a/domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCase.kt index 93cec98..0cf967f 100644 --- a/domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCase.kt +++ b/domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCase.kt @@ -3,25 +3,40 @@ 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.interactor.entity.CutFrameTypeV1 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 +@Deprecated("Not in use") class GeneratePhotoFrameUseCase @Inject constructor( @ApplicationContext private val context: Context, private val imageRepositoryInterface: ImageRepositoryInterface ){ - fun getCutFrameType(): CutFrameType = imageRepositoryInterface.getCutFrameType() + // 네컷 프레임 선택하는 UseCase + @Deprecated("Not in use") + fun getCutFrameType(): CutFrameTypeV1 = imageRepositoryInterface.getCutFrameType() + @Deprecated("Not in use") suspend fun setCutFrameType(type: Int) = imageRepositoryInterface.setCutFrameType(type) + + // 촬영한 이미지 리스트 관리 + @Deprecated("Not in use") fun getCapturedImageListUri(): List = imageRepositoryInterface.getCachedImageUriList() + @Deprecated("Not in use") suspend fun clearCapturedImageList() = imageRepositoryInterface.clearCacheDir() + + + // 화면 요소를 이미지로 저장 + @Deprecated("Not in use") suspend fun saveGraphicsLayerImage(image: Bitmap, fileName: String) = imageRepositoryInterface.cachingImage(image, fileName) + @Deprecated("Not in use") suspend fun saveFinalImage(image: Bitmap, fileName: String) = imageRepositoryInterface.saveToStorage(image, fileName) + + // 최종 이미지 URL 가져오기 + @Deprecated("Not in use") fun getFinalSingleImageUri(): Uri { var finalSingleImageUri: Uri = Uri.EMPTY context.cacheDir.listFiles().forEach { @@ -29,7 +44,7 @@ class GeneratePhotoFrameUseCase @Inject constructor( } return finalSingleImageUri } - + @Deprecated("Not in use") fun getFinalTwoImageUri(): Uri { var finalTwoImageUri: Uri = Uri.EMPTY context.cacheDir.listFiles().forEach { diff --git a/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameType.kt b/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameType.kt index c13693b..49d8cac 100644 --- a/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameType.kt +++ b/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameType.kt @@ -1,26 +1,19 @@ package com.foke.together.domain.interactor.entity -enum class CutFrameType { - MAKER_FAIRE, - FOURCUT_LIGHT, - FOURCUT_DARK; +import androidx.annotation.DrawableRes +import com.foke.together.domain.R - 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") - } - } - } -} \ No newline at end of file +sealed class CutFrame ( + @DrawableRes val frameImageSrc: Int, // TODO: asset 에 추가 및 src 값을 넣어서 처리 + val additionalFrameImageSrc: List, + val photoPosition: List +) + +// TODO: add information of frames +class FourCutLightFrame: CutFrame(R.drawable.fourcut_frame_medium_light, emptyList(), emptyList()) +class FourCurDarkFrame: CutFrame(R.drawable.fourcut_frame_medium_dark, emptyList(), emptyList()) +class MakerFaireFrame: CutFrame(R.drawable.maker_faire_frame, emptyList(), emptyList()) +class WeddingFrame1: CutFrame(R.drawable.maker_faire_frame, emptyList(), emptyList()) +class WeddingFrame2: CutFrame(R.drawable.maker_faire_frame, emptyList(), emptyList()) + +class NoneFrame: CutFrame(0, emptyList(), emptyList()) diff --git a/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameTypeV1.kt b/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameTypeV1.kt new file mode 100644 index 0000000..91822fc --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/entity/CutFrameTypeV1.kt @@ -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") + } + } + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/entity/PhotoPosition.kt b/domain/src/main/java/com/foke/together/domain/interactor/entity/PhotoPosition.kt new file mode 100644 index 0000000..91c42fd --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/entity/PhotoPosition.kt @@ -0,0 +1,8 @@ +package com.foke.together.domain.interactor.entity + +data class PhotoPosition ( + val x: Int, + val y: Int, + val height: Int, + val width: Int, +) \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionData.kt b/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionData.kt new file mode 100644 index 0000000..f8e5837 --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionData.kt @@ -0,0 +1,15 @@ +package com.foke.together.domain.interactor.entity + +data class SessionData ( + val sessionId: SessionId? = null, + val cutFrame: CutFrame, + val status: Status +) + +enum class Status { + INIT, + SELECT_FRAME, + CAPTURE, + GENERATE_PHOTO, + SHARE +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionId.kt b/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionId.kt new file mode 100644 index 0000000..dc71da9 --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/entity/SessionId.kt @@ -0,0 +1,9 @@ +package com.foke.together.domain.interactor.entity + +data class SessionId ( + val startAt: Long +) { + override fun toString(): String { + return startAt.toString() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/session/ClearSessionUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/session/ClearSessionUseCase.kt new file mode 100644 index 0000000..6f6233a --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/session/ClearSessionUseCase.kt @@ -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() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/session/CreateNewSessionUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/session/CreateNewSessionUseCase.kt new file mode 100644 index 0000000..6cc1ce3 --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/session/CreateNewSessionUseCase.kt @@ -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() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/session/GetCurrentSessionUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/session/GetCurrentSessionUseCase.kt new file mode 100644 index 0000000..fa006e2 --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/session/GetCurrentSessionUseCase.kt @@ -0,0 +1,13 @@ +package com.foke.together.domain.interactor.session + +import com.foke.together.domain.interactor.entity.SessionData +import com.foke.together.domain.output.SessionRepositoryInterface +import javax.inject.Inject + +class GetCurrentSessionUseCase @Inject constructor( + private val sessionRepository: SessionRepositoryInterface +) { + operator fun invoke(): SessionData? { + return sessionRepository.getSession() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/session/UpdateSessionStatusUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/session/UpdateSessionStatusUseCase.kt new file mode 100644 index 0000000..925c909 --- /dev/null +++ b/domain/src/main/java/com/foke/together/domain/interactor/session/UpdateSessionStatusUseCase.kt @@ -0,0 +1,18 @@ +package com.foke.together.domain.interactor.session + +import com.foke.together.domain.interactor.entity.CutFrame +import com.foke.together.domain.interactor.entity.Status +import com.foke.together.domain.output.SessionRepositoryInterface +import javax.inject.Inject + +class UpdateSessionStatusUseCase @Inject constructor( + private val sessionRepository: SessionRepositoryInterface +) { + operator fun invoke(status: Status) { + sessionRepository.updateSession(status) + } + + operator fun invoke(cutFrame: CutFrame) { + sessionRepository.updateSession(cutFrame) + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/interactor/web/SessionKeyUseCase.kt b/domain/src/main/java/com/foke/together/domain/interactor/web/SessionKeyUseCase.kt deleted file mode 100644 index 7683d1d..0000000 --- a/domain/src/main/java/com/foke/together/domain/interactor/web/SessionKeyUseCase.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.foke.together.domain.interactor.web - -import com.foke.together.domain.output.SessionRepositoryInterface -import javax.inject.Inject - -class SessionKeyUseCase @Inject constructor( - private val sessionRepository: SessionRepositoryInterface -) { - suspend fun setSessionKey() { - sessionRepository.setSessionKey() - } - - fun getSessionKey(): String { - return sessionRepository.getSessionKey() - } -} \ No newline at end of file diff --git a/domain/src/main/java/com/foke/together/domain/output/ImageRepositoryInterface.kt b/domain/src/main/java/com/foke/together/domain/output/ImageRepositoryInterface.kt index bad7154..cd037c1 100644 --- a/domain/src/main/java/com/foke/together/domain/output/ImageRepositoryInterface.kt +++ b/domain/src/main/java/com/foke/together/domain/output/ImageRepositoryInterface.kt @@ -2,12 +2,10 @@ package com.foke.together.domain.output import android.graphics.Bitmap import android.net.Uri -import android.os.Environment -import com.foke.together.domain.interactor.entity.CutFrameType -import kotlinx.coroutines.flow.Flow +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 interface ImageRepositoryInterface { - fun getCutFrameType(): CutFrameType + fun getCutFrameType(): CutFrameTypeV1 suspend fun setCutFrameType(type: Int) // 촬영한 사진들 모음 suspend fun cachingImage(image: Bitmap, fileName: String) : Uri diff --git a/domain/src/main/java/com/foke/together/domain/output/SessionRepositoryInterface.kt b/domain/src/main/java/com/foke/together/domain/output/SessionRepositoryInterface.kt index ce27d42..716fe73 100644 --- a/domain/src/main/java/com/foke/together/domain/output/SessionRepositoryInterface.kt +++ b/domain/src/main/java/com/foke/together/domain/output/SessionRepositoryInterface.kt @@ -1,6 +1,17 @@ package com.foke.together.domain.output +import com.foke.together.domain.interactor.entity.CutFrame +import com.foke.together.domain.interactor.entity.SessionData +import com.foke.together.domain.interactor.entity.Status + interface SessionRepositoryInterface { - suspend fun setSessionKey() - fun getSessionKey(): String + fun createSession() + + fun getSession(): SessionData? + + fun updateSession(cutFrame: CutFrame) + fun updateSession(status: Status) + fun updateSession(cutFrame: CutFrame, status: Status) + + fun clearSession() } \ No newline at end of file diff --git a/presenter/src/main/res/drawable/fourcut_frame_medium_dark.png b/domain/src/main/res/drawable/fourcut_frame_medium_dark.png similarity index 100% rename from presenter/src/main/res/drawable/fourcut_frame_medium_dark.png rename to domain/src/main/res/drawable/fourcut_frame_medium_dark.png diff --git a/presenter/src/main/res/drawable/fourcut_frame_medium_light.png b/domain/src/main/res/drawable/fourcut_frame_medium_light.png similarity index 100% rename from presenter/src/main/res/drawable/fourcut_frame_medium_light.png rename to domain/src/main/res/drawable/fourcut_frame_medium_light.png diff --git a/presenter/src/main/res/drawable/maker_faire_frame.png b/domain/src/main/res/drawable/maker_faire_frame.png similarity index 100% rename from presenter/src/main/res/drawable/maker_faire_frame.png rename to domain/src/main/res/drawable/maker_faire_frame.png diff --git a/external/src/main/java/com/foke/together/external/repository/ImageRepository.kt b/external/src/main/java/com/foke/together/external/repository/ImageRepository.kt index 5483cdc..7e86701 100644 --- a/external/src/main/java/com/foke/together/external/repository/ImageRepository.kt +++ b/external/src/main/java/com/foke/together/external/repository/ImageRepository.kt @@ -4,26 +4,21 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.ImageDecoder import android.net.Uri -import android.provider.MediaStore -import com.foke.together.domain.interactor.entity.CutFrameType +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 import com.foke.together.domain.output.ImageRepositoryInterface import com.foke.together.util.AppPolicy import com.foke.together.util.ImageFileUtil import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.map import javax.inject.Inject class ImageRepository @Inject constructor( @ApplicationContext private val context: Context ): ImageRepositoryInterface{ - private var cutFrameType: CutFrameType = CutFrameType.MAKER_FAIRE + private var cutFrameType: CutFrameTypeV1 = CutFrameTypeV1.MAKER_FAIRE - override fun getCutFrameType(): CutFrameType = cutFrameType + override fun getCutFrameType(): CutFrameTypeV1 = cutFrameType override suspend fun setCutFrameType(type: Int) { - cutFrameType = CutFrameType.findBy(type) + cutFrameType = CutFrameTypeV1.findBy(type) } override suspend fun cachingImage(image: Bitmap, fileName: String): Uri { diff --git a/external/src/main/java/com/foke/together/external/repository/SessionRepository.kt b/external/src/main/java/com/foke/together/external/repository/SessionRepository.kt index f6a6540..df4eafe 100644 --- a/external/src/main/java/com/foke/together/external/repository/SessionRepository.kt +++ b/external/src/main/java/com/foke/together/external/repository/SessionRepository.kt @@ -1,16 +1,72 @@ package com.foke.together.external.repository +import com.foke.together.domain.interactor.entity.CutFrame +import com.foke.together.domain.interactor.entity.NoneFrame +import com.foke.together.domain.interactor.entity.SessionData +import com.foke.together.domain.interactor.entity.SessionId +import com.foke.together.domain.interactor.entity.Status import com.foke.together.domain.output.SessionRepositoryInterface +import com.foke.together.util.AppLog import com.foke.together.util.TimeUtil import javax.inject.Inject class SessionRepository @Inject constructor(): SessionRepositoryInterface { - private var sessionKey: String = "" - override suspend fun setSessionKey() { - sessionKey = TimeUtil.getCurrentTimeSec() + + private var sessionData: SessionData? = null + + override fun createSession() { + sessionData = SessionData( + SessionId(startAt = TimeUtil.getCurrentTimestamp()), + cutFrame = NoneFrame(), + status = Status.INIT + ) + AppLog.i(TAG, "createSession", "sessionData: $sessionData") + + // TODO: save session data to Pref. + } + + override fun getSession(): SessionData? { + AppLog.i(TAG, "getSession", "sessionData: $sessionData") + + return sessionData + // TODO: read session data to Pref. + } + + override fun updateSession(cutFrame: CutFrame) { + sessionData = sessionData?.let { + SessionData(it.sessionId, cutFrame, it.status) + } + AppLog.i(TAG, "updateSession", "sessionData: $sessionData") + + // TODO: save session data to Pref. + } + + override fun updateSession(status: Status) { + sessionData = sessionData?.let { + SessionData(it.sessionId, it.cutFrame, status) + } + AppLog.i(TAG, "updateSession", "sessionData: $sessionData") + + // TODO: save session data to Pref. + } + + override fun updateSession(cutFrame: CutFrame, status: Status) { + sessionData = sessionData?.let { + SessionData(it.sessionId, cutFrame, status) + } + AppLog.i(TAG, "updateSession", "sessionData: $sessionData") + + // TODO: save session data to Pref. + } + + override fun clearSession() { + sessionData = null + AppLog.i(TAG, "clearSession", "sessionData: $sessionData") + + // TODO: clear session data to Pref. } - override fun getSessionKey(): String { - return sessionKey + companion object { + private val TAG = SessionRepository::class.java.simpleName } } \ No newline at end of file diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/CameraScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/CameraScreen.kt index 86b1582..7c3e0c6 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/CameraScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/CameraScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.layer.drawLayer @@ -42,6 +43,11 @@ fun CameraScreen( popBackStack: () -> Unit, viewModel: CameraViewModel = hiltViewModel() ) { + DisposableEffect(Unit) { + viewModel.updateSessionStatus() + onDispose { } + } + val TAG = "CameraScreen" var mjpegView: MjpegView? = null val externalCameraIP = viewModel.externalCameraIP diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/GenerateSingleRowImageScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/GenerateSingleRowImageScreen.kt index 1274ac3..89fd4f2 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/GenerateSingleRowImageScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/GenerateSingleRowImageScreen.kt @@ -1,6 +1,5 @@ package com.foke.together.presenter.screen -import android.net.Uri import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize @@ -9,7 +8,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.graphics.rememberGraphicsLayer import androidx.compose.ui.text.font.FontWeight @@ -19,11 +17,7 @@ import androidx.constraintlayout.compose.ConstraintLayout import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect -import com.foke.together.domain.interactor.entity.CutFrameType -import com.foke.together.presenter.frame.FourCutFrame -import com.foke.together.presenter.frame.MakerFaireFrame import com.foke.together.presenter.theme.FourCutTogetherTheme -import com.foke.together.presenter.theme.mediumContrastLightColorScheme import com.foke.together.presenter.viewmodel.GenerateSingleRowImageViewModel import com.foke.together.util.AppLog import kotlinx.coroutines.launch diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/GenerateTwoRowImageScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/GenerateTwoRowImageScreen.kt index b743f02..5ed0e14 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/GenerateTwoRowImageScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/GenerateTwoRowImageScreen.kt @@ -18,7 +18,7 @@ import androidx.constraintlayout.compose.ConstraintLayout import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect -import com.foke.together.domain.interactor.entity.CutFrameType +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 import com.foke.together.domain.interactor.entity.FramePosition import com.foke.together.presenter.frame.FourCutFrame import com.foke.together.presenter.frame.MakerFaireFrame @@ -53,6 +53,10 @@ fun GenerateTwoRowImageScreen( fontWeight = FontWeight.Bold, fontSize = 24.sp, ) + + + + // ===== 여기가 프레임 생성하는 구간 ===== Row( modifier = Modifier .constrainAs(editFrame) { @@ -80,6 +84,10 @@ fun GenerateTwoRowImageScreen( position = FramePosition.RIGHT ) } + // ===== 여기가 프레임 생성하는 구간 ===== + + + } LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { @@ -99,18 +107,18 @@ fun GetFrame( position: FramePosition? = null ) { when(cutFrameType) { - CutFrameType.MAKER_FAIRE.ordinal -> MakerFaireFrame( + CutFrameTypeV1.MAKER_FAIRE.ordinal -> MakerFaireFrame( cameraImageUrlList = imageUri, position = position ) - CutFrameType.FOURCUT_LIGHT.ordinal -> FourCutFrame( + CutFrameTypeV1.FOURCUT_LIGHT.ordinal -> FourCutFrame( designColorScheme = mediumContrastLightColorScheme, cameraImageUrlList = imageUri, position = position ) - CutFrameType.FOURCUT_DARK.ordinal -> FourCutFrame( + CutFrameTypeV1.FOURCUT_DARK.ordinal -> FourCutFrame( designColorScheme = mediumContrastDarkColorScheme, cameraImageUrlList = imageUri, position = position diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/HomeScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/HomeScreen.kt index e9218b3..3320e4e 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/HomeScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/HomeScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -28,6 +29,11 @@ fun HomeScreen( popBackStack: () -> Unit, viewModel: HomeViewModel = hiltViewModel() ) { + DisposableEffect(Unit) { + viewModel.createSession() + onDispose { } + } + FourCutTogetherTheme() { ConstraintLayout( modifier = Modifier.fillMaxSize() diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/SelectFrameScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/SelectFrameScreen.kt index 401236e..0c90617 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/SelectFrameScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/SelectFrameScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource @@ -31,7 +32,7 @@ import androidx.compose.ui.unit.sp import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import androidx.hilt.navigation.compose.hiltViewModel -import com.foke.together.domain.interactor.entity.CutFrameType +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 import com.foke.together.presenter.R import com.foke.together.presenter.theme.FourCutTogetherTheme import com.foke.together.presenter.viewmodel.SelectFrameViewModel @@ -42,11 +43,16 @@ fun SelectFrameScreen( popBackStack: () -> Unit, viewModel: SelectFrameViewModel = hiltViewModel() ) { + DisposableEffect(Unit) { + viewModel.updateSessionStatus() + onDispose { } + } + FourCutTogetherTheme { val pagerState = rememberPagerState( - initialPage = CutFrameType.MAKER_FAIRE.ordinal + initialPage = CutFrameTypeV1.MAKER_FAIRE.ordinal ) { - CutFrameType.entries.size // 총 페이지 수 설정 + CutFrameTypeV1.entries.size // 총 페이지 수 설정 } ConstraintLayout( modifier = Modifier.fillMaxSize() @@ -107,8 +113,11 @@ fun SelectFrameScreen( end = 40.dp ) ) { page -> + + // TODO: usecase를 통해서 모든 프레임 정보를 가져오도록 함 + when(page){ - CutFrameType.MAKER_FAIRE.ordinal -> { + CutFrameTypeV1.MAKER_FAIRE.ordinal -> { Box( contentAlignment = Alignment.Center, modifier = Modifier @@ -116,9 +125,9 @@ fun SelectFrameScreen( viewModel.setCutFrameType(pagerState.currentPage) navigateToMethod() } - ) { Image(painter = painterResource(id = R.drawable.maker_faire_frame), contentDescription = "maker_faire_frame") } + ) { Image(painter = painterResource(id = com.foke.together.domain.R.drawable.maker_faire_frame), contentDescription = "maker_faire_frame") } } - CutFrameType.FOURCUT_LIGHT.ordinal -> { + CutFrameTypeV1.FOURCUT_LIGHT.ordinal -> { Box( contentAlignment = Alignment.Center, modifier = Modifier @@ -127,9 +136,9 @@ fun SelectFrameScreen( navigateToMethod() } - ) { Image(painter = painterResource(id = R.drawable.fourcut_frame_medium_light), contentDescription = "fourcut_frame_medium_light") } + ) { Image(painter = painterResource(id = com.foke.together.domain.R.drawable.fourcut_frame_medium_light), contentDescription = "fourcut_frame_medium_light") } } - CutFrameType.FOURCUT_DARK.ordinal -> { + CutFrameTypeV1.FOURCUT_DARK.ordinal -> { Box( modifier = Modifier .clickable { @@ -137,7 +146,7 @@ fun SelectFrameScreen( navigateToMethod() }, contentAlignment = Alignment.Center - ) { Image(painter = painterResource(id = R.drawable.fourcut_frame_medium_dark), contentDescription = "fourcut_frame_medium_dark") } + ) { Image(painter = painterResource(id = com.foke.together.domain.R.drawable.fourcut_frame_medium_dark), contentDescription = "fourcut_frame_medium_dark") } } } } diff --git a/presenter/src/main/java/com/foke/together/presenter/screen/ShareScreen.kt b/presenter/src/main/java/com/foke/together/presenter/screen/ShareScreen.kt index 0cea2ac..1a77c02 100644 --- a/presenter/src/main/java/com/foke/together/presenter/screen/ShareScreen.kt +++ b/presenter/src/main/java/com/foke/together/presenter/screen/ShareScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -33,6 +34,11 @@ fun ShareScreen( popBackStack: () -> Unit, viewModel: ShareViewModel = hiltViewModel() ) { + DisposableEffect(Unit) { + viewModel.updateSessionStatus() + onDispose { } + } + val context = LocalContext.current ConstraintLayout( modifier = Modifier.fillMaxSize() @@ -75,7 +81,10 @@ fun ShareScreen( ) { IconButton( - onClick = { popBackStack() }, + onClick = { + viewModel.closeSession() + popBackStack() + }, modifier = Modifier.weight(1f) ) { Icon( diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/CameraViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/CameraViewModel.kt index b67edda..99a481a 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/CameraViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/CameraViewModel.kt @@ -12,7 +12,8 @@ import androidx.lifecycle.viewModelScope import com.foke.together.domain.interactor.CaptureWithExternalCameraUseCase import com.foke.together.domain.interactor.GeneratePhotoFrameUseCase import com.foke.together.domain.interactor.GetExternalCameraPreviewUrlUseCase -import com.foke.together.domain.interactor.web.SessionKeyUseCase +import com.foke.together.domain.interactor.entity.Status +import com.foke.together.domain.interactor.session.UpdateSessionStatusUseCase import com.foke.together.util.AppPolicy import com.foke.together.util.AppPolicy.CAPTURE_INTERVAL import com.foke.together.util.AppPolicy.COUNTDOWN_INTERVAL @@ -28,7 +29,7 @@ class CameraViewModel @Inject constructor( getExternalCameraPreviewUrlUseCase: GetExternalCameraPreviewUrlUseCase, private val captureWithExternalCameraUseCase: CaptureWithExternalCameraUseCase, private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase, - private val sessionKeyUseCase: SessionKeyUseCase + private val updateSessionStatusUseCase: UpdateSessionStatusUseCase ): ViewModel() { val externalCameraIP = getExternalCameraPreviewUrlUseCase() @@ -39,6 +40,7 @@ class CameraViewModel @Inject constructor( val captureCount: Int by _captureCount private var captureTimer: CountDownTimer? = null private var mTimerState = false + fun setCaptureTimer( graphicsLayer: GraphicsLayer, nextNavigate: () -> Unit @@ -67,7 +69,6 @@ class CameraViewModel @Inject constructor( _captureCount.intValue += 1 mTimerState = false } else { - sessionKeyUseCase.setSessionKey() stopCaptureTimer() _captureCount.intValue = 1 nextNavigate() @@ -92,4 +93,8 @@ class CameraViewModel @Inject constructor( captureTimer!!.cancel() } } + + fun updateSessionStatus() { + updateSessionStatusUseCase(Status.CAPTURE) + } } \ No newline at end of file diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateSingleRowImageViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateSingleRowImageViewModel.kt index beaf3e9..29599d2 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateSingleRowImageViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateSingleRowImageViewModel.kt @@ -4,7 +4,7 @@ import androidx.compose.ui.graphics.asAndroidBitmap import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.lifecycle.ViewModel import com.foke.together.domain.interactor.GeneratePhotoFrameUseCase -import com.foke.together.domain.interactor.entity.CutFrameType +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 import com.foke.together.util.AppLog import com.foke.together.util.AppPolicy import dagger.hilt.android.lifecycle.HiltViewModel @@ -14,7 +14,7 @@ import javax.inject.Inject class GenerateSingleRowImageViewModel @Inject constructor( private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase, ): ViewModel() { - val cutFrameType: CutFrameType = generatePhotoFrameUseCase.getCutFrameType() + val cutFrameType: CutFrameTypeV1 = generatePhotoFrameUseCase.getCutFrameType() val imageUri = generatePhotoFrameUseCase.getCapturedImageListUri() suspend fun generateImage(graphicsLayer: GraphicsLayer) { diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateTwoRowImageViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateTwoRowImageViewModel.kt index 47850f1..a03ecbc 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateTwoRowImageViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/GenerateTwoRowImageViewModel.kt @@ -1,23 +1,20 @@ package com.foke.together.presenter.viewmodel -import android.content.Context import androidx.compose.ui.graphics.asAndroidBitmap import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.lifecycle.ViewModel import com.foke.together.domain.interactor.GeneratePhotoFrameUseCase -import com.foke.together.domain.interactor.entity.CutFrameType +import com.foke.together.domain.interactor.entity.CutFrameTypeV1 import com.foke.together.util.AppLog import com.foke.together.util.AppPolicy import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject @HiltViewModel class GenerateTwoRowImageViewModel @Inject constructor( - @ApplicationContext private val context: Context, private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase ): ViewModel() { - val cutFrameType: CutFrameType = generatePhotoFrameUseCase.getCutFrameType() + val cutFrameType: CutFrameTypeV1 = generatePhotoFrameUseCase.getCutFrameType() val imageUri = generatePhotoFrameUseCase.getCapturedImageListUri() suspend fun generateImage(graphicsLayer: GraphicsLayer) { diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/HomeViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/HomeViewModel.kt index d561952..5bb70bc 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/HomeViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/HomeViewModel.kt @@ -3,6 +3,7 @@ package com.foke.together.presenter.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.foke.together.domain.interactor.AppInitUseCase +import com.foke.together.domain.interactor.session.CreateNewSessionUseCase import com.foke.together.domain.interactor.web.GetCurrentUserInformationUseCase import com.foke.together.domain.interactor.web.SignInUseCase import com.foke.together.util.AppLog @@ -17,7 +18,8 @@ class HomeViewModel @Inject constructor( @IODispatcher private val ioDispatcher: CoroutineDispatcher, private val signInUseCase: SignInUseCase, private val getCurrentUserInformationUseCase: GetCurrentUserInformationUseCase, - private val appInitUseCase: AppInitUseCase + private val appInitUseCase: AppInitUseCase, + private val createNewSessionUseCase: CreateNewSessionUseCase ): ViewModel() { init { viewModelScope.launch(ioDispatcher) { @@ -41,6 +43,10 @@ class HomeViewModel @Inject constructor( } } + fun createSession() { + createNewSessionUseCase() + } + companion object { private val TAG = HomeViewModel::class.java.simpleName } diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/SelectFrameViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/SelectFrameViewModel.kt index f3bca66..9329434 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/SelectFrameViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/SelectFrameViewModel.kt @@ -3,15 +3,26 @@ package com.foke.together.presenter.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.foke.together.domain.interactor.GeneratePhotoFrameUseCase +import com.foke.together.domain.interactor.entity.MakerFaireFrame +import com.foke.together.domain.interactor.entity.Status +import com.foke.together.domain.interactor.session.UpdateSessionStatusUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class SelectFrameViewModel @Inject constructor( - private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase + private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase, + private val updateSessionStatusUseCase: UpdateSessionStatusUseCase ): ViewModel() { + + fun updateSessionStatus() { + updateSessionStatusUseCase(Status.SELECT_FRAME) + } + fun setCutFrameType(type:Int) = viewModelScope.launch { - generatePhotoFrameUseCase.setCutFrameType(type) + // TODO: remove deprecated code + generatePhotoFrameUseCase.setCutFrameType(type) + updateSessionStatusUseCase(MakerFaireFrame()) } } \ No newline at end of file diff --git a/presenter/src/main/java/com/foke/together/presenter/viewmodel/ShareViewModel.kt b/presenter/src/main/java/com/foke/together/presenter/viewmodel/ShareViewModel.kt index 833bb46..cd6a60a 100644 --- a/presenter/src/main/java/com/foke/together/presenter/viewmodel/ShareViewModel.kt +++ b/presenter/src/main/java/com/foke/together/presenter/viewmodel/ShareViewModel.kt @@ -12,8 +12,11 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.foke.together.domain.interactor.GeneratePhotoFrameUseCase import com.foke.together.domain.interactor.GetQRCodeUseCase +import com.foke.together.domain.interactor.entity.Status +import com.foke.together.domain.interactor.session.ClearSessionUseCase +import com.foke.together.domain.interactor.session.GetCurrentSessionUseCase +import com.foke.together.domain.interactor.session.UpdateSessionStatusUseCase import com.foke.together.domain.interactor.web.GetDownloadUrlUseCase -import com.foke.together.domain.interactor.web.SessionKeyUseCase import com.foke.together.domain.interactor.web.UploadFileUseCase import com.foke.together.util.AppLog import com.foke.together.util.AppPolicy @@ -28,9 +31,11 @@ class ShareViewModel @Inject constructor( @ApplicationContext private val context: Context, private val getQRCodeUseCase: GetQRCodeUseCase, private val getDownloadUrlUseCase: GetDownloadUrlUseCase, - private val sessionKeyUseCase: SessionKeyUseCase, private val uploadFileUseCase: UploadFileUseCase, - private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase + private val generatePhotoFrameUseCase: GeneratePhotoFrameUseCase, + private val getCurrentSessionUseCase: GetCurrentSessionUseCase, + private val updateSessionStatusUseCase: UpdateSessionStatusUseCase, + private val clearSessionUseCase: ClearSessionUseCase ): ViewModel() { var qrCodeBitmap by mutableStateOf(null) val singleImageUri: Uri = generatePhotoFrameUseCase.getFinalSingleImageUri() @@ -54,16 +59,19 @@ class ShareViewModel @Inject constructor( } private suspend fun generateQRcode() { - val result = uploadFileUseCase(sessionKeyUseCase.getSessionKey(), singleImageUri.toFile()) - AppLog.d("GenerateImageViewModel", "UploadFile" ,"result: $result") - val sessionKey = sessionKeyUseCase.getSessionKey() - val downloadUrl: String = getDownloadUrlUseCase(sessionKey).getOrElse { "https://4cuts.store" } + getCurrentSessionUseCase()?.let { session -> + val sessionKey = session.sessionId.toString() - if (AppPolicy.isDebugMode) { - AppLog.e(TAG, "generateQRcode", "sessionKey: $sessionKey") - AppLog.e(TAG, "generateQRcode", "downloadUrl: $downloadUrl") + val result = uploadFileUseCase(sessionKey, singleImageUri.toFile()) + AppLog.d("GenerateImageViewModel", "UploadFile" ,"result: $result") + + val downloadUrl: String = getDownloadUrlUseCase(sessionKey).getOrElse { "https://4cuts.store" } + if (AppPolicy.isDebugMode) { + AppLog.e(TAG, "generateQRcode", "sessionKey: $sessionKey") + AppLog.e(TAG, "generateQRcode", "downloadUrl: $downloadUrl") + } + qrCodeBitmap = getQRCodeUseCase(sessionKey, downloadUrl).getOrNull() } - qrCodeBitmap = getQRCodeUseCase(sessionKey, downloadUrl).getOrNull() } fun shareImage() { @@ -79,6 +87,14 @@ class ShareViewModel @Inject constructor( ImageFileUtil.printFromUri(activityContext,twoImageUri) } + fun updateSessionStatus() { + updateSessionStatusUseCase(Status.SHARE) + } + + fun closeSession() { + clearSessionUseCase() + } + companion object { private val TAG = ShareViewModel::class.java.simpleName } diff --git a/presenter/src/main/res/drawable/ic_launcher_background.xml b/presenter/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9..0000000 --- a/presenter/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/presenter/src/main/res/drawable/ic_launcher_foreground.xml b/presenter/src/main/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1..0000000 --- a/presenter/src/main/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/util/src/main/java/com/foke/together/util/AppPolicy.kt b/util/src/main/java/com/foke/together/util/AppPolicy.kt index 3607233..792efb2 100644 --- a/util/src/main/java/com/foke/together/util/AppPolicy.kt +++ b/util/src/main/java/com/foke/together/util/AppPolicy.kt @@ -1,7 +1,7 @@ package com.foke.together.util object AppPolicy { - const val isDebugMode = false + const val isDebugMode = true // TODO: change to false // network const val WEB_SERVER_URL = "https://4cuts.store/" diff --git a/util/src/main/java/com/foke/together/util/TimeUtil.kt b/util/src/main/java/com/foke/together/util/TimeUtil.kt index 3d579bc..4f272e3 100644 --- a/util/src/main/java/com/foke/together/util/TimeUtil.kt +++ b/util/src/main/java/com/foke/together/util/TimeUtil.kt @@ -4,6 +4,11 @@ import java.text.SimpleDateFormat import java.util.Date object TimeUtil { + fun getCurrentTimestamp(): Long { + // TODO: LocalDate로 변경 + return System.currentTimeMillis() + } + fun getCurrentDisplayTime(): String { val dateFormat = "yyyy.MM.dd" // TODO: LocalDate로 변경