diff --git a/app/src/main/java/com/yapp/twix/di/InitKoin.kt b/app/src/main/java/com/yapp/twix/di/InitKoin.kt
index 54cea66b..2c333cef 100644
--- a/app/src/main/java/com/yapp/twix/di/InitKoin.kt
+++ b/app/src/main/java/com/yapp/twix/di/InitKoin.kt
@@ -4,6 +4,7 @@ import android.content.Context
import com.twix.data.di.dataModule
import com.twix.datastore.di.dataStoreModule
import com.twix.network.di.networkModule
+import com.twix.util.di.utilModule
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import org.koin.core.module.Module
@@ -24,6 +25,7 @@ fun initKoin(
add(uiModule)
add(dataStoreModule)
add(appModule)
+ add(utilModule)
},
)
}
diff --git a/app/src/main/java/com/yapp/twix/main/MainActivity.kt b/app/src/main/java/com/yapp/twix/main/MainActivity.kt
index 81e672c9..501149bc 100644
--- a/app/src/main/java/com/yapp/twix/main/MainActivity.kt
+++ b/app/src/main/java/com/yapp/twix/main/MainActivity.kt
@@ -6,6 +6,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
@@ -30,7 +31,8 @@ class MainActivity : ComponentActivity() {
Box(
modifier =
Modifier
- .fillMaxSize(),
+ .fillMaxSize()
+ .safeContentPadding(),
) {
AppNavHost()
diff --git a/build-logic/convention/src/main/kotlin/com/twix/convention/FeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/twix/convention/FeatureConventionPlugin.kt
index 8597f405..9d9f2715 100644
--- a/build-logic/convention/src/main/kotlin/com/twix/convention/FeatureConventionPlugin.kt
+++ b/build-logic/convention/src/main/kotlin/com/twix/convention/FeatureConventionPlugin.kt
@@ -15,6 +15,7 @@ class FeatureConventionPlugin : BuildLogicConventionPlugin({
implementation(project(":core:design-system"))
implementation(project(":core:navigation"))
implementation(project(":core:ui"))
+ implementation(project(":core:util"))
implementation(project(":core:result"))
implementation(project(":domain"))
}
diff --git a/core/design-system/src/main/res/values/strings.xml b/core/design-system/src/main/res/values/strings.xml
index 0a0434c8..3325a37f 100644
--- a/core/design-system/src/main/res/values/strings.xml
+++ b/core/design-system/src/main/res/values/strings.xml
@@ -59,6 +59,7 @@
종료 날짜가 시작 날짜보다 이전입니다.
목표 조회에 실패했습니다.
+ 목표 생성에 실패했습니다.
%s\n목표를 이루셨나요?
diff --git a/core/network/src/main/java/com/twix/network/model/request/goal/mapper/GoalMapper.kt b/core/network/src/main/java/com/twix/network/model/request/goal/mapper/GoalMapper.kt
new file mode 100644
index 00000000..c93d9a12
--- /dev/null
+++ b/core/network/src/main/java/com/twix/network/model/request/goal/mapper/GoalMapper.kt
@@ -0,0 +1,14 @@
+package com.twix.network.model.request.goal.mapper
+
+import com.twix.domain.model.goal.CreateGoalParam
+import com.twix.network.model.request.goal.model.CreateGoalRequest
+
+fun CreateGoalParam.toRequest(): CreateGoalRequest =
+ CreateGoalRequest(
+ name = name,
+ icon = icon.toApi(),
+ repeatCycle = repeatCycle.toApi(),
+ repeatCount = repeatCount,
+ startDate = startDate.toString(),
+ endDate = endDate?.toString(),
+ )
diff --git a/core/network/src/main/java/com/twix/network/model/request/goal/model/CreateGoalRequest.kt b/core/network/src/main/java/com/twix/network/model/request/goal/model/CreateGoalRequest.kt
new file mode 100644
index 00000000..f5c8c602
--- /dev/null
+++ b/core/network/src/main/java/com/twix/network/model/request/goal/model/CreateGoalRequest.kt
@@ -0,0 +1,14 @@
+package com.twix.network.model.request.goal.model
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CreateGoalRequest(
+ @SerialName("name") val name: String,
+ @SerialName("icon") val icon: String,
+ @SerialName("repeatCycle") val repeatCycle: String,
+ @SerialName("repeatCount") val repeatCount: Int,
+ @SerialName("startDate") val startDate: String,
+ @SerialName("endDate") val endDate: String?,
+)
diff --git a/core/network/src/main/java/com/twix/network/model/response/goal/mapper/GoalMapper.kt b/core/network/src/main/java/com/twix/network/model/response/goal/mapper/GoalMapper.kt
index ee46b98e..6c62c5de 100644
--- a/core/network/src/main/java/com/twix/network/model/response/goal/mapper/GoalMapper.kt
+++ b/core/network/src/main/java/com/twix/network/model/response/goal/mapper/GoalMapper.kt
@@ -3,12 +3,15 @@ package com.twix.network.model.response.goal.mapper
import com.twix.domain.model.enums.GoalIconType
import com.twix.domain.model.enums.GoalReactionType
import com.twix.domain.model.enums.RepeatCycle
+import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.Goal
import com.twix.domain.model.goal.GoalList
import com.twix.domain.model.goal.GoalVerification
+import com.twix.network.model.response.goal.model.CreateGoalResponse
import com.twix.network.model.response.goal.model.GoalListResponse
import com.twix.network.model.response.goal.model.GoalResponse
import com.twix.network.model.response.goal.model.VerificationResponse
+import java.time.LocalDate
fun GoalListResponse.toDomain(): GoalList =
GoalList(
@@ -37,3 +40,15 @@ fun VerificationResponse.toDomainOrNull(): GoalVerification? =
reaction = GoalReactionType.fromApi(reaction),
uploadedAt = uploadedAt,
)
+
+fun CreateGoalResponse.toDomain(): CreatedGoal =
+ CreatedGoal(
+ goalId = goalId,
+ name = name,
+ icon = GoalIconType.fromApi(icon),
+ repeatCycle = RepeatCycle.fromApi(repeatCycle),
+ repeatCount = repeatCount,
+ startDate = LocalDate.parse(startDate),
+ endDate = endDate?.let(LocalDate::parse),
+ createdAt = createdAt,
+ )
diff --git a/core/network/src/main/java/com/twix/network/model/response/goal/model/CreateGoalResponse.kt b/core/network/src/main/java/com/twix/network/model/response/goal/model/CreateGoalResponse.kt
new file mode 100644
index 00000000..7150b5a6
--- /dev/null
+++ b/core/network/src/main/java/com/twix/network/model/response/goal/model/CreateGoalResponse.kt
@@ -0,0 +1,17 @@
+package com.twix.network.model.response.goal.model
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CreateGoalResponse(
+ @SerialName("goalId") val goalId: Long,
+ @SerialName("name") val name: String,
+ @SerialName("icon") val icon: String,
+ @SerialName("repeatCycle") val repeatCycle: String,
+ @SerialName("repeatCount") val repeatCount: Int,
+ @SerialName("startDate") val startDate: String,
+ @SerialName("endDate") val endDate: String?,
+ @SerialName("goalStatus") val goalStatus: String,
+ @SerialName("createdAt") val createdAt: String,
+)
diff --git a/core/network/src/main/java/com/twix/network/service/GoalService.kt b/core/network/src/main/java/com/twix/network/service/GoalService.kt
index 8ff116e7..3a46205d 100644
--- a/core/network/src/main/java/com/twix/network/service/GoalService.kt
+++ b/core/network/src/main/java/com/twix/network/service/GoalService.kt
@@ -1,7 +1,11 @@
package com.twix.network.service
+import com.twix.network.model.request.goal.model.CreateGoalRequest
+import com.twix.network.model.response.goal.model.CreateGoalResponse
import com.twix.network.model.response.goal.model.GoalListResponse
+import de.jensklingenberg.ktorfit.http.Body
import de.jensklingenberg.ktorfit.http.GET
+import de.jensklingenberg.ktorfit.http.POST
import de.jensklingenberg.ktorfit.http.Query
interface GoalService {
@@ -9,4 +13,9 @@ interface GoalService {
suspend fun fetchGoals(
@Query("date") date: String,
): GoalListResponse
+
+ @POST("api/v1/goals")
+ suspend fun createGoal(
+ @Body body: CreateGoalRequest,
+ ): CreateGoalResponse
}
diff --git a/core/ui/src/main/java/com/twix/ui/base/BaseViewModel.kt b/core/ui/src/main/java/com/twix/ui/base/BaseViewModel.kt
index 09b49864..8334db70 100644
--- a/core/ui/src/main/java/com/twix/ui/base/BaseViewModel.kt
+++ b/core/ui/src/main/java/com/twix/ui/base/BaseViewModel.kt
@@ -69,6 +69,10 @@ abstract class BaseViewModel(
sideEffectHolder.emit(effect)
}
+ protected fun tryEmitSideEffect(effect: SE) {
+ sideEffectHolder.tryEmit(effect)
+ }
+
/**
* Intent를 처리하는 메서드
* */
diff --git a/core/ui/src/main/java/com/twix/ui/base/SideEffectHolder.kt b/core/ui/src/main/java/com/twix/ui/base/SideEffectHolder.kt
index 83d09440..8db5436a 100644
--- a/core/ui/src/main/java/com/twix/ui/base/SideEffectHolder.kt
+++ b/core/ui/src/main/java/com/twix/ui/base/SideEffectHolder.kt
@@ -10,4 +10,8 @@ class SideEffectHolder {
suspend fun emit(effect: S) {
channel.send(effect)
}
+
+ fun tryEmit(effect: S) {
+ channel.trySend(effect)
+ }
}
diff --git a/core/util/build.gradle.kts b/core/util/build.gradle.kts
index 03c85182..53267b6b 100644
--- a/core/util/build.gradle.kts
+++ b/core/util/build.gradle.kts
@@ -1,5 +1,6 @@
plugins {
alias(libs.plugins.twix.android.library)
+ alias(libs.plugins.twix.koin)
}
android {
diff --git a/core/util/src/main/java/com/twix/util/bus/GoalRefreshBus.kt b/core/util/src/main/java/com/twix/util/bus/GoalRefreshBus.kt
new file mode 100644
index 00000000..c2fd72a6
--- /dev/null
+++ b/core/util/src/main/java/com/twix/util/bus/GoalRefreshBus.kt
@@ -0,0 +1,15 @@
+package com.twix.util.bus
+
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
+
+class GoalRefreshBus {
+ private val _events =
+ MutableSharedFlow(
+ replay = 0,
+ extraBufferCapacity = 1,
+ )
+ val events: SharedFlow = _events
+
+ fun notifyChanged() = _events.tryEmit(Unit)
+}
diff --git a/core/util/src/main/java/com/twix/util/di/UtilModule.kt b/core/util/src/main/java/com/twix/util/di/UtilModule.kt
new file mode 100644
index 00000000..0ad75b92
--- /dev/null
+++ b/core/util/src/main/java/com/twix/util/di/UtilModule.kt
@@ -0,0 +1,9 @@
+package com.twix.util.di
+
+import com.twix.util.bus.GoalRefreshBus
+import org.koin.dsl.module
+
+val utilModule =
+ module {
+ single { GoalRefreshBus() }
+ }
diff --git a/data/src/main/java/com/twix/data/repository/DefaultGoalRepository.kt b/data/src/main/java/com/twix/data/repository/DefaultGoalRepository.kt
index f145b393..1cf57d01 100644
--- a/data/src/main/java/com/twix/data/repository/DefaultGoalRepository.kt
+++ b/data/src/main/java/com/twix/data/repository/DefaultGoalRepository.kt
@@ -1,8 +1,11 @@
package com.twix.data.repository
+import com.twix.domain.model.goal.CreateGoalParam
+import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.GoalList
import com.twix.domain.repository.GoalRepository
import com.twix.network.execute.safeApiCall
+import com.twix.network.model.request.goal.mapper.toRequest
import com.twix.network.model.response.goal.mapper.toDomain
import com.twix.network.service.GoalService
import com.twix.result.AppResult
@@ -11,4 +14,9 @@ class DefaultGoalRepository(
private val service: GoalService,
) : GoalRepository {
override suspend fun fetchGoalList(date: String): AppResult = safeApiCall { service.fetchGoals(date).toDomain() }
+
+ override suspend fun createGoal(param: CreateGoalParam): AppResult =
+ safeApiCall {
+ service.createGoal(param.toRequest()).toDomain()
+ }
}
diff --git a/domain/src/main/java/com/twix/domain/model/enums/GoalIconType.kt b/domain/src/main/java/com/twix/domain/model/enums/GoalIconType.kt
index 0f4870e4..7e5a84bc 100644
--- a/domain/src/main/java/com/twix/domain/model/enums/GoalIconType.kt
+++ b/domain/src/main/java/com/twix/domain/model/enums/GoalIconType.kt
@@ -11,6 +11,18 @@ enum class GoalIconType {
LAPTOP,
;
+ fun toApi(): String =
+ when (this) {
+ DEFAULT -> "ICON_DEFAULT"
+ CLEAN -> "ICON_CLEAN"
+ EXERCISE -> "ICON_EXERCISE"
+ BOOK -> "ICON_BOOK"
+ PENCIL -> "ICON_PENCIL"
+ HEALTH -> "ICON_HEALTH"
+ HEART -> "ICON_HEART"
+ LAPTOP -> "ICON_LAPTOP"
+ }
+
companion object {
fun fromApi(icon: String): GoalIconType =
when (icon) {
diff --git a/domain/src/main/java/com/twix/domain/model/enums/RepeatCycle.kt b/domain/src/main/java/com/twix/domain/model/enums/RepeatCycle.kt
index 2931eaf9..5948f781 100644
--- a/domain/src/main/java/com/twix/domain/model/enums/RepeatCycle.kt
+++ b/domain/src/main/java/com/twix/domain/model/enums/RepeatCycle.kt
@@ -6,6 +6,8 @@ enum class RepeatCycle {
MONTHLY,
;
+ fun toApi(): String = name
+
companion object {
fun fromApi(value: String): RepeatCycle = runCatching { valueOf(value) }.getOrElse { DAILY }
}
diff --git a/domain/src/main/java/com/twix/domain/model/goal/CreateGoalParam.kt b/domain/src/main/java/com/twix/domain/model/goal/CreateGoalParam.kt
new file mode 100644
index 00000000..b4a0bee7
--- /dev/null
+++ b/domain/src/main/java/com/twix/domain/model/goal/CreateGoalParam.kt
@@ -0,0 +1,14 @@
+package com.twix.domain.model.goal
+
+import com.twix.domain.model.enums.GoalIconType
+import com.twix.domain.model.enums.RepeatCycle
+import java.time.LocalDate
+
+data class CreateGoalParam(
+ val name: String,
+ val icon: GoalIconType,
+ val repeatCycle: RepeatCycle,
+ val repeatCount: Int,
+ val startDate: LocalDate,
+ val endDate: LocalDate?,
+)
diff --git a/domain/src/main/java/com/twix/domain/model/goal/CreatedGoal.kt b/domain/src/main/java/com/twix/domain/model/goal/CreatedGoal.kt
new file mode 100644
index 00000000..fdb95343
--- /dev/null
+++ b/domain/src/main/java/com/twix/domain/model/goal/CreatedGoal.kt
@@ -0,0 +1,16 @@
+package com.twix.domain.model.goal
+
+import com.twix.domain.model.enums.GoalIconType
+import com.twix.domain.model.enums.RepeatCycle
+import java.time.LocalDate
+
+data class CreatedGoal(
+ val goalId: Long,
+ val name: String,
+ val icon: GoalIconType,
+ val repeatCycle: RepeatCycle,
+ val repeatCount: Int,
+ val startDate: LocalDate,
+ val endDate: LocalDate?,
+ val createdAt: String,
+)
diff --git a/domain/src/main/java/com/twix/domain/repository/GoalRepository.kt b/domain/src/main/java/com/twix/domain/repository/GoalRepository.kt
index be0958f9..c79b7732 100644
--- a/domain/src/main/java/com/twix/domain/repository/GoalRepository.kt
+++ b/domain/src/main/java/com/twix/domain/repository/GoalRepository.kt
@@ -1,8 +1,12 @@
package com.twix.domain.repository
+import com.twix.domain.model.goal.CreateGoalParam
+import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.GoalList
import com.twix.result.AppResult
interface GoalRepository {
suspend fun fetchGoalList(date: String): AppResult
+
+ suspend fun createGoal(param: CreateGoalParam): AppResult
}
diff --git a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorScreen.kt b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorScreen.kt
index 3e59a370..89e116e4 100644
--- a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorScreen.kt
+++ b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorScreen.kt
@@ -85,6 +85,7 @@ fun GoalEditorRoute(
viewModel.sideEffect.collect { effect ->
when (effect) {
is GoalEditorSideEffect.ShowToast -> toastManager.tryShow(ToastData(currentContext.getString(effect.resId), effect.type))
+ is GoalEditorSideEffect.NavigateToHome -> navigateToBack()
}
}
}
@@ -332,7 +333,7 @@ private fun RepeatCountBottomSheetContent(
.padding(horizontal = 12.dp, vertical = 5.5.dp)
.noRippleClickable(onClick = {
internalSelectedRepeatType = RepeatCycle.WEEKLY
- internalRepeatCount = 0
+ internalRepeatCount = 1
}),
)
@@ -348,7 +349,7 @@ private fun RepeatCountBottomSheetContent(
.padding(horizontal = 12.dp, vertical = 5.5.dp)
.noRippleClickable(onClick = {
internalSelectedRepeatType = RepeatCycle.MONTHLY
- internalRepeatCount = 0
+ internalRepeatCount = 1
}),
)
}
diff --git a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorSideEffect.kt b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorSideEffect.kt
index 6e2fcd2a..0594cdb3 100644
--- a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorSideEffect.kt
+++ b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorSideEffect.kt
@@ -9,4 +9,6 @@ interface GoalEditorSideEffect : SideEffect {
@param:StringRes val resId: Int,
val type: ToastType,
) : GoalEditorSideEffect
+
+ object NavigateToHome : GoalEditorSideEffect
}
diff --git a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorViewModel.kt b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorViewModel.kt
index c0c7a7e8..8958f0e4 100644
--- a/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorViewModel.kt
+++ b/feature/goal-editor/src/main/java/com/twix/goal_editor/GoalEditorViewModel.kt
@@ -6,15 +6,20 @@ import com.twix.designsystem.components.toast.model.ToastType
import com.twix.domain.model.enums.GoalIconType
import com.twix.domain.model.enums.GoalReactionType
import com.twix.domain.model.enums.RepeatCycle
+import com.twix.domain.model.goal.CreateGoalParam
import com.twix.domain.model.goal.Goal
import com.twix.domain.model.goal.GoalVerification
+import com.twix.domain.repository.GoalRepository
import com.twix.goal_editor.model.GoalEditorUiState
import com.twix.ui.base.BaseViewModel
+import com.twix.util.bus.GoalRefreshBus
import kotlinx.coroutines.launch
import java.time.LocalDate
-class GoalEditorViewModel :
- BaseViewModel(
+class GoalEditorViewModel(
+ private val goalRepository: GoalRepository,
+ private val goalRefreshBus: GoalRefreshBus,
+) : BaseViewModel(
GoalEditorUiState(),
) {
override suspend fun handleIntent(intent: GoalEditorIntent) {
@@ -42,7 +47,7 @@ class GoalEditorViewModel :
}
private fun setRepeatType(repeatCycle: RepeatCycle) {
- reduce { copy(selectedRepeatCycle = repeatCycle) }
+ reduce { copy(selectedRepeatCycle = repeatCycle, repeatCount = 1) }
}
private fun setRepeatCount(repeatCount: Int) {
@@ -72,6 +77,15 @@ class GoalEditorViewModel :
}
return
}
+
+ launchResult(
+ block = { goalRepository.createGoal(currentState.toCreateParam()) },
+ onSuccess = {
+ goalRefreshBus.notifyChanged()
+ tryEmitSideEffect(GoalEditorSideEffect.NavigateToHome)
+ },
+ onError = { emitSideEffect(GoalEditorSideEffect.ShowToast(R.string.toast_create_goal_failed, ToastType.ERROR)) },
+ )
}
private fun initGoal(id: Long) {
@@ -113,4 +127,14 @@ class GoalEditorViewModel :
)
}
}
+
+ private fun GoalEditorUiState.toCreateParam(): CreateGoalParam =
+ CreateGoalParam(
+ name = goalTitle.trim(),
+ icon = selectedIcon,
+ repeatCycle = selectedRepeatCycle,
+ repeatCount = repeatCount,
+ startDate = startDate,
+ endDate = if (endDateEnabled) endDate else null,
+ )
}
diff --git a/feature/goal-editor/src/main/java/com/twix/goal_editor/model/GoalEditorUiState.kt b/feature/goal-editor/src/main/java/com/twix/goal_editor/model/GoalEditorUiState.kt
index 7cc8ca7b..8add180f 100644
--- a/feature/goal-editor/src/main/java/com/twix/goal_editor/model/GoalEditorUiState.kt
+++ b/feature/goal-editor/src/main/java/com/twix/goal_editor/model/GoalEditorUiState.kt
@@ -11,11 +11,11 @@ data class GoalEditorUiState(
val selectedIcon: GoalIconType = GoalIconType.DEFAULT,
val goalTitle: String = "",
val selectedRepeatCycle: RepeatCycle = RepeatCycle.DAILY,
- val repeatCount: Int = 0,
+ val repeatCount: Int = 1,
val startDate: LocalDate = LocalDate.now(),
val endDateEnabled: Boolean = false,
val endDate: LocalDate = LocalDate.now(),
) : State {
val isEnabled: Boolean
- get() = goalTitle.isNotBlank() && repeatCount > 0
+ get() = goalTitle.isNotBlank() && (selectedRepeatCycle == RepeatCycle.DAILY || repeatCount > 0)
}
diff --git a/feature/main/src/main/java/com/twix/home/HomeViewModel.kt b/feature/main/src/main/java/com/twix/home/HomeViewModel.kt
index 66465446..db68185d 100644
--- a/feature/main/src/main/java/com/twix/home/HomeViewModel.kt
+++ b/feature/main/src/main/java/com/twix/home/HomeViewModel.kt
@@ -8,18 +8,31 @@ import com.twix.domain.repository.GoalRepository
import com.twix.home.model.CalendarState
import com.twix.home.model.HomeUiState
import com.twix.ui.base.BaseViewModel
+import com.twix.util.bus.GoalRefreshBus
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
import java.time.LocalDate
class HomeViewModel(
private val goalRepository: GoalRepository,
+ private val goalRefreshBus: GoalRefreshBus,
) : BaseViewModel(
HomeUiState(),
) {
+ init {
+ fetchGoalList()
+
+ viewModelScope.launch {
+ goalRefreshBus.events.collect {
+ fetchGoalList()
+ }
+ }
+ }
+
val calendarState: StateFlow =
uiState
.map { state ->
@@ -40,10 +53,6 @@ class HomeViewModel(
),
)
- init {
- fetchGoalList()
- }
-
override suspend fun handleIntent(intent: HomeIntent) {
when (intent) {
is HomeIntent.SelectDate -> updateDate(intent.date)
diff --git a/feature/main/src/main/java/com/twix/home/model/HomeUiState.kt b/feature/main/src/main/java/com/twix/home/model/HomeUiState.kt
index 90b34936..a411ad27 100644
--- a/feature/main/src/main/java/com/twix/home/model/HomeUiState.kt
+++ b/feature/main/src/main/java/com/twix/home/model/HomeUiState.kt
@@ -1,12 +1,7 @@
package com.twix.home.model
import androidx.compose.runtime.Immutable
-import com.twix.domain.model.enums.GoalIconType
-import com.twix.domain.model.enums.GoalReactionType
-import com.twix.domain.model.enums.RepeatCycle
-import com.twix.domain.model.goal.Goal
import com.twix.domain.model.goal.GoalList
-import com.twix.domain.model.goal.GoalVerification
import com.twix.ui.base.State
import java.time.LocalDate
import java.time.YearMonth
@@ -17,80 +12,7 @@ data class HomeUiState(
val visibleDate: LocalDate = LocalDate.now(), // 홈 화면 상단에 존재하는 월, 년 텍스트를 위한 상태 변수
val selectedDate: LocalDate = LocalDate.now(),
val referenceDate: LocalDate = LocalDate.now(), // 7일 달력을 생성하기 위한 레퍼런스 날짜
- val goalList: GoalList =
- GoalList(
- goals =
- listOf(
- Goal(
- goalId = 1,
- name = "운동",
- icon = GoalIconType.EXERCISE,
- repeatCycle = RepeatCycle.WEEKLY,
- myCompleted = true,
- partnerCompleted = false,
- myVerification = null,
- partnerVerification = null,
- ),
- Goal(
- goalId = 2,
- name = "운동",
- icon = GoalIconType.EXERCISE,
- repeatCycle = RepeatCycle.WEEKLY,
- myCompleted = true,
- partnerCompleted = false,
- myVerification =
- GoalVerification(
- photologId = 1,
- imageUrl = "https://picsum.photos/400/300",
- comment = null,
- reaction = GoalReactionType.LOVE,
- uploadedAt = "2023-05-05",
- ),
- partnerVerification = null,
- ),
- Goal(
- goalId = 3,
- name = "잠자기",
- icon = GoalIconType.HEART,
- repeatCycle = RepeatCycle.WEEKLY,
- myCompleted = false,
- partnerCompleted = true,
- myVerification = null,
- partnerVerification =
- GoalVerification(
- photologId = 1,
- imageUrl = "https://picsum.photos/400/300",
- comment = null,
- reaction = GoalReactionType.LOVE,
- uploadedAt = "2023-05-05",
- ),
- ),
- Goal(
- goalId = 4,
- name = "밥무라",
- icon = GoalIconType.DEFAULT,
- repeatCycle = RepeatCycle.WEEKLY,
- myCompleted = true,
- partnerCompleted = true,
- myVerification =
- GoalVerification(
- photologId = 1,
- imageUrl = "https://picsum.photos/400/300",
- comment = null,
- reaction = GoalReactionType.LOVE,
- uploadedAt = "2023-05-05",
- ),
- partnerVerification =
- GoalVerification(
- photologId = 1,
- imageUrl = "https://picsum.photos/400/300",
- comment = null,
- reaction = GoalReactionType.LOVE,
- uploadedAt = "2023-05-05",
- ),
- ),
- ),
- ),
+ val goalList: GoalList = GoalList(),
) : State {
val monthYear: String
get() = "${visibleDate.month.value}월 ${visibleDate.year}"