Skip to content

Commit

Permalink
날짜 이상하게 나오는 현상 수정, 누락된 체크리스트 삭제 추가 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
leesa-l committed Dec 15, 2023
1 parent 3a030c4 commit 50a9a66
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import java.util.TimeZone

internal object FormattedTimeMapper {
fun mapDomain(unixMillis: Long, format: String = "yyyy.MM.dd"): FormattedTime {
val formatted = SimpleDateFormat(format, Locale.getDefault()).format(unixMillis)
val formatted = SimpleDateFormat(format, Locale.getDefault()).format(unixMillis * 1000)
return FormattedTime(unixMillis = unixMillis, formatted = formatted)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.dkin.chevit.presentation.common.ext

import java.time.LocalDate
import java.time.ZoneId
import java.time.ZoneOffset

fun LocalDate.unixMillis(): Long {
return atStartOfDay(ZoneId.systemDefault()).toEpochSecond()
return atStartOfDay().toEpochSecond(ZoneOffset.UTC)
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ fun HomeTabContents(
MyChecklistItem(
item = it,
onClickItem = { id -> homeViewModel.onClickChecklist(id) },
onLongClickItem = { _, _ -> },
modifier = Modifier.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(20.dp))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.dkin.chevit.presentation.home.contents.component

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -23,17 +25,22 @@ import com.dkin.chevit.presentation.home.HomeState
import com.dkin.chevit.presentation.home.model.CheckListItem
import com.dkin.chevit.presentation.resource.ChevitTheme

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyChecklistItem(
item: CheckListItem,
onClickItem: (id: String) -> Unit,
onLongClickItem: (id: String, title: String) -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.background(color = ChevitTheme.colors.grey4)
.clickable { onClickItem(item.id) }
.combinedClickable(
onClick = { onClickItem(item.id) },
onLongClick = { onLongClickItem(item.id, item.title) }
)
) {
AsyncImage(
modifier = Modifier.fillMaxWidth(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.dkin.chevit.presentation.home.contents.user.mylist

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.dkin.chevit.presentation.resource.ChevitBottomsheet
import com.dkin.chevit.presentation.resource.ChevitTheme
import com.dkin.chevit.presentation.resource.icon.ChevitIcon
import com.dkin.chevit.presentation.resource.icon.IconCheckboxCircleFill

@Composable
fun ChecklistMoreBottomSheet(
title: String,
deleteItem: () -> Unit,
onClose: () -> Unit
) {
ChevitBottomsheet(
modifier = Modifier.fillMaxSize(),
onClickBackground = onClose
) {
Column(modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Image(
imageVector = ChevitIcon.IconCheckboxCircleFill,
contentDescription = "",
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = title,
style = ChevitTheme.typhography.headlineMedium.copy(color = ChevitTheme.colors.textPrimary),
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
Spacer(modifier = Modifier.height(4.dp))
Column(
modifier = Modifier.fillMaxWidth().clickable { deleteItem() }
) {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "삭제하기",
style = ChevitTheme.typhography.bodyLarge.copy(color = ChevitTheme.colors.textPrimary),
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Spacer(modifier = Modifier.height(16.dp))
}
Box(
modifier = Modifier
.fillMaxWidth()
.height(1.dp)
.background(color = ChevitTheme.colors.grey0)
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.window.DialogProperties
import androidx.fragment.app.viewModels
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.dialog
import androidx.navigation.compose.rememberNavController
import androidx.navigation.findNavController
import androidx.navigation.navArgument
import com.dkin.chevit.core.mvi.MVIComposeFragment
import com.dkin.chevit.presentation.deeplink.DeepLink
import com.dkin.chevit.presentation.deeplink.deepLink
Expand All @@ -29,12 +37,37 @@ class MyCheckList :
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val state by viewModel.state.collectAsState()
MyCheckListScreen(
onClickBack = { findNavController().popBackStack() },
checkList = state.checkList,
onClickChecklist = { id -> viewModel.onClickChecklist(id) }
)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "main") {
composable("main") {
val state by viewModel.state.collectAsState()
MyCheckListScreen(
onClickBack = { findNavController().popBackStack() },
checkList = state.checkList,
onClickChecklist = { id -> viewModel.onClickChecklist(id) },
onLongClickChecklist = { id, title -> navController.navigate("more/${id}?title=${title}") }
)
}
dialog(
route = "more/{itemId}?title={title}",
arguments = listOf(
navArgument("itemId") { type = NavType.StringType },
navArgument("title") { type = NavType.StringType; defaultValue = "" },
),
dialogProperties = DialogProperties(usePlatformDefaultWidth = false),
) {
val itemId = it.arguments?.getString("itemId") ?: ""
val title = it.arguments?.getString("title") ?: ""
ChecklistMoreBottomSheet(
title = title,
deleteItem = {
navController.popBackStack()
viewModel.dispatch(MyCheckListIntent.DeleteCheckList(itemId))
},
onClose = { navController.popBackStack() }
)
}
}
}
}
}
Expand All @@ -51,6 +84,10 @@ class MyCheckList :
R.id.myChecklist
)
}

MyCheckListEffect.DeletePlanFailed -> {
Toast.makeText(requireContext(), "체크리스트 삭제에 실패하였습니다.", Toast.LENGTH_SHORT).show()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.dkin.chevit.core.mvi.ViewState
import com.dkin.chevit.presentation.home.model.CheckListItem

sealed interface MyCheckListIntent : ViewIntent {

data class DeleteCheckList(val id: String) : MyCheckListIntent
}

@Stable
Expand Down Expand Up @@ -47,4 +47,5 @@ data class MyCheckListState(

sealed interface MyCheckListEffect : ViewEffect {
data class NavigateToCheckList(val id: String) : MyCheckListEffect
object DeletePlanFailed : MyCheckListEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import com.dkin.chevit.presentation.resource.util.clickableNoRipple
fun MyCheckListScreen(
onClickBack: () -> Unit,
checkList: List<CheckListItem>,
onClickChecklist: (id: String) -> Unit
onClickChecklist: (id: String) -> Unit,
onLongClickChecklist: (id: String, title: String) -> Unit
) {
Column(
modifier = Modifier.fillMaxSize()
Expand Down Expand Up @@ -91,7 +92,9 @@ fun MyCheckListScreen(
items(count = checkList.size) {
MyChecklistItem(
item = checkList[it],
onClickItem = { id -> onClickChecklist(id) })
onClickItem = { id -> onClickChecklist(id) },
onLongClickItem = { id, title -> onLongClickChecklist(id, title) }
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.dkin.chevit.presentation.home.contents.user.mylist
import androidx.lifecycle.viewModelScope
import com.dkin.chevit.core.mvi.MVIViewModel
import com.dkin.chevit.domain.base.get
import com.dkin.chevit.domain.base.onComplete
import com.dkin.chevit.domain.usecase.plan.DeletePlanUseCase
import com.dkin.chevit.domain.usecase.plan.GetMyChecklistUseCase
import com.dkin.chevit.presentation.home.model.CheckListItem
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -11,12 +13,17 @@ import javax.inject.Inject

@HiltViewModel
class MyCheckListViewModel @Inject constructor(
private val getMyChecklistUseCase: GetMyChecklistUseCase
private val getMyChecklistUseCase: GetMyChecklistUseCase,
private val deletePlanUseCase: DeletePlanUseCase
) : MVIViewModel<MyCheckListIntent, MyCheckListState, MyCheckListEffect>() {

override fun createInitialState() = MyCheckListState.empty()

override suspend fun processIntent(intent: MyCheckListIntent) {}
override suspend fun processIntent(intent: MyCheckListIntent) {
when (intent) {
is MyCheckListIntent.DeleteCheckList -> deleteChecklist(intent.id)
}
}


fun onClickChecklist(id: String) {
Expand All @@ -41,4 +48,26 @@ class MyCheckListViewModel @Inject constructor(
}
}
}

private suspend fun deleteChecklist(id: String) {
val deleteItem = deletePlanUseCase(
DeletePlanUseCase.Param(
planId = id,
)
)
deleteItem.onComplete(
doOnComplete = {},
doOnError = {
if (it is NullPointerException) {
//성공했을 때 응답값이 null로 내려옴
initMyChecklist()
} else {
setEffect { MyCheckListEffect.DeletePlanFailed }
}
},
doOnSuccess = {
initMyChecklist()
}
)
}
}

0 comments on commit 50a9a66

Please sign in to comment.