Skip to content

Commit

Permalink
[Feature] History 구조 추가 (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajou4095 authored Feb 5, 2024
1 parent b8d1023 commit 762e9d9
Show file tree
Hide file tree
Showing 36 changed files with 782 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

import ac.dnd.bookkeeping.android.presentation.ui.main.home.history.HistoryConstant

object HistoryDetailConstant {
const val ROUTE: String = "${HistoryConstant.ROUTE}/detail"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

import ac.dnd.bookkeeping.android.presentation.common.util.ErrorObserver
import ac.dnd.bookkeeping.android.presentation.ui.main.ApplicationState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable

fun NavGraphBuilder.historyDetailDestination(
appState: ApplicationState
) {
composable(
route = HistoryDetailConstant.ROUTE
) {
val viewModel: HistoryDetailViewModel = hiltViewModel()

val model: HistoryDetailModel = let {
val state by viewModel.state.collectAsStateWithLifecycle()

HistoryDetailModel(
state = state
)
}

ErrorObserver(viewModel)

HistoryDetailScreen(
appState = appState,
model = model,
event = viewModel.event,
intent = viewModel::onIntent,
handler = viewModel.handler
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

sealed interface HistoryDetailEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

sealed interface HistoryDetailIntent
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

data class HistoryDetailModel(
val state: HistoryDetailState,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

import ac.dnd.bookkeeping.android.presentation.common.util.LaunchedEffectWithLifecycle
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.EventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.MutableEventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.eventObserve
import ac.dnd.bookkeeping.android.presentation.ui.main.ApplicationState
import ac.dnd.bookkeeping.android.presentation.ui.main.rememberApplicationState
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.tooling.preview.Preview
import kotlinx.coroutines.CoroutineExceptionHandler

@Composable
fun HistoryDetailScreen(
appState: ApplicationState,
model: HistoryDetailModel,
event: EventFlow<HistoryDetailEvent>,
intent: (HistoryDetailIntent) -> Unit,
handler: CoroutineExceptionHandler
) {
val scope = rememberCoroutineScope()

Box {

}

LaunchedEffectWithLifecycle(event, handler) {
event.eventObserve { event ->

}
}
}

@Preview
@Composable
fun HistoryDetailScreenPreview() {
HistoryDetailScreen(
appState = rememberApplicationState(),
model = HistoryDetailModel(
state = HistoryDetailState.Init
),
event = MutableEventFlow(),
intent = {},
handler = CoroutineExceptionHandler { _, _ -> }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

sealed interface HistoryDetailState {
data object Init : HistoryDetailState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail

import ac.dnd.bookkeeping.android.presentation.common.base.BaseViewModel
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.EventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.MutableEventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.asEventFlow
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

@HiltViewModel
class HistoryDetailViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
) : BaseViewModel() {

private val _state: MutableStateFlow<HistoryDetailState> =
MutableStateFlow(HistoryDetailState.Init)
val state: StateFlow<HistoryDetailState> = _state.asStateFlow()

private val _event: MutableEventFlow<HistoryDetailEvent> = MutableEventFlow()
val event: EventFlow<HistoryDetailEvent> = _event.asEventFlow()

fun onIntent(intent: HistoryDetailIntent) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

sealed interface HistoryDetailEditEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

sealed interface HistoryDetailEditIntent
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

data class HistoryDetailEditModel(
val state: HistoryDetailEditState,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

import ac.dnd.bookkeeping.android.presentation.common.theme.Gray200
import ac.dnd.bookkeeping.android.presentation.common.theme.Headline2
import ac.dnd.bookkeeping.android.presentation.common.util.ErrorObserver
import ac.dnd.bookkeeping.android.presentation.common.util.LaunchedEffectWithLifecycle
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.EventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.MutableEventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.eventObserve
import ac.dnd.bookkeeping.android.presentation.common.view.BottomSheetScreen
import ac.dnd.bookkeeping.android.presentation.common.view.confirm.ConfirmButton
import ac.dnd.bookkeeping.android.presentation.common.view.confirm.ConfirmButtonProperties
import ac.dnd.bookkeeping.android.presentation.common.view.confirm.ConfirmButtonSize
import ac.dnd.bookkeeping.android.presentation.common.view.confirm.ConfirmButtonType
import ac.dnd.bookkeeping.android.presentation.ui.main.ApplicationState
import ac.dnd.bookkeeping.android.presentation.ui.main.rememberApplicationState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.holix.android.bottomsheetdialog.compose.BottomSheetBehaviorProperties
import com.holix.android.bottomsheetdialog.compose.BottomSheetDialogProperties
import kotlinx.coroutines.CoroutineExceptionHandler

@Composable
fun HistoryDetailEditScreen(
appState: ApplicationState,
onDismissRequest: () -> Unit,
onResult: () -> Unit,
viewModel: HistoryDetailEditViewModel = hiltViewModel()
) {
val model: HistoryDetailEditModel = Unit.let {
val state by viewModel.state.collectAsStateWithLifecycle()

HistoryDetailEditModel(
state = state
)
}
ErrorObserver(viewModel)

HistoryDetailEditScreen(
appState = appState,
model = model,
event = viewModel.event,
intent = viewModel::onIntent,
handler = viewModel.handler,
onDismissRequest = onDismissRequest,
onResult = onResult
)
}

@Composable
private fun HistoryDetailEditScreen(
appState: ApplicationState,
model: HistoryDetailEditModel,
event: EventFlow<HistoryDetailEditEvent>,
intent: (HistoryDetailEditIntent) -> Unit,
handler: CoroutineExceptionHandler,
onDismissRequest: () -> Unit,
onResult: () -> Unit,
) {
val scope = rememberCoroutineScope()

BottomSheetScreen(
onDismissRequest = onDismissRequest,
properties = BottomSheetDialogProperties(
behaviorProperties = BottomSheetBehaviorProperties(
state = BottomSheetBehaviorProperties.State.Expanded,
skipCollapsed = true
)
)
) {
Column(
modifier = Modifier
.wrapContentHeight()
.background(Gray200)
.padding(20.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Center
) {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "",
style = Headline2
)
Spacer(modifier = Modifier.height(10.dp))
ConfirmButton(
modifier = Modifier.fillMaxWidth(),
properties = ConfirmButtonProperties(
size = ConfirmButtonSize.Xlarge,
type = ConfirmButtonType.Primary
),
onClick = {
onResult()
}
) { style ->
Text(
text = "확인",
style = style
)
}
Spacer(modifier = Modifier.height(10.dp))
}
}

LaunchedEffectWithLifecycle(event, handler) {
event.eventObserve { event ->

}
}
}

@Preview(apiLevel = 33)
@Composable
private fun HistoryDetailEditScreenPreview() {
HistoryDetailEditScreen(
appState = rememberApplicationState(),
model = HistoryDetailEditModel(state = HistoryDetailEditState.Init),
event = MutableEventFlow(),
intent = {},
handler = CoroutineExceptionHandler { _, _ -> },
onDismissRequest = {},
onResult = {}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

sealed interface HistoryDetailEditState {
data object Init : HistoryDetailEditState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.edit

import ac.dnd.bookkeeping.android.presentation.common.base.BaseViewModel
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.EventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.MutableEventFlow
import ac.dnd.bookkeeping.android.presentation.common.util.coroutine.event.asEventFlow
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

@HiltViewModel
class HistoryDetailEditViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
) : BaseViewModel() {

private val _state: MutableStateFlow<HistoryDetailEditState> =
MutableStateFlow(HistoryDetailEditState.Init)
val state: StateFlow<HistoryDetailEditState> = _state.asStateFlow()

private val _event: MutableEventFlow<HistoryDetailEditEvent> = MutableEventFlow()
val event: EventFlow<HistoryDetailEditEvent> = _event.asEventFlow()

fun onIntent(intent: HistoryDetailEditIntent) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.growth

import ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.HistoryDetailConstant

object HistoryDetailGrowthConstant {
const val ROUTE: String = "${HistoryDetailConstant.ROUTE}/growth"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.growth

import ac.dnd.bookkeeping.android.presentation.common.util.ErrorObserver
import ac.dnd.bookkeeping.android.presentation.ui.main.ApplicationState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable

fun NavGraphBuilder.historyDetailGrowthDestination(
appState: ApplicationState
) {
composable(
route = HistoryDetailGrowthConstant.ROUTE
) {
val viewModel: HistoryDetailGrowthViewModel = hiltViewModel()

val model: HistoryDetailGrowthModel = let {
val state by viewModel.state.collectAsStateWithLifecycle()

HistoryDetailGrowthModel(
state = state
)
}

ErrorObserver(viewModel)

HistoryDetailGrowthScreen(
appState = appState,
model = model,
event = viewModel.event,
intent = viewModel::onIntent,
handler = viewModel.handler
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.growth

sealed interface HistoryDetailGrowthEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.growth

sealed interface HistoryDetailGrowthIntent
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ac.dnd.bookkeeping.android.presentation.ui.main.home.history.detail.growth

data class HistoryDetailGrowthModel(
val state: HistoryDetailGrowthState,
)
Loading

0 comments on commit 762e9d9

Please sign in to comment.