Skip to content

Commit 237f498

Browse files
authored
Feat: 챙겨야할 목록 뷰 (#7)
* feat: 물건 이름 도메인 VO 작성 * feat: 물건 이름 표시 컴포넌트 작성 * feat: 바운스 클릭 이벤트 유틸 작성 * feat: 토글 변경 가능한 아이템 컴포넌트 추가 * feat: 물건 컴포넌트 이름 수정 * feat: icon 에셋 추가 * feat: 물건 Row 최소 크기 영역 지정 * feat: icon 버튼 intercativeSize 제거된 버전 제작 * feat: 삭제 가능한 물건 아이템 작성 * feat: 삭제 가능한 물건 아이템 Row 수정 * feat: 물건 추가 버튼 작성 * feat: 물건 이름 관련 로직 수정 물건 이름에 관련된 부분은 도메인이 아닌 뷰에서 보여지는 로직이므로 이를 변경함 * feat: 물건 목록 컴포넌트 작성 * feat: 크로스 페이드 애니메이션 컴포넌트 작성 * feat: 물건 목록 상단 바 작성 * feat: 물건 목록 Preview 제공자 작성 * style: 불필요한 Import 삭제 * style: TopBar Icon 버튼 크기 고정 * feat: Grid state 파라미터 추가 * feat: StuffScreen 작성 * style: 불필요한 Import 삭제 * style: 불필요한 라인 삭제 * chore: 라벨러 조건 수정 * feat: 수정 모드 관련 State 작성 * feat: 하단 컨탠츠 분리 * feat: Collapsed Title 적용 * feat: Text includeFontPadding 제거 * feat: scroll collapse 제외 구현 * feat: 상단바 접힘 기능 구현 * feat: 프리뷰 제공 데이터 수정 * feat: 상단바가 스크롤 할 수 없는 상태일때 접히던 문제 해결
1 parent af94a05 commit 237f498

29 files changed

+1225
-8
lines changed

.github/workflows/labeler.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,30 @@ jobs:
3030

3131
- name: add label Bug
3232
uses: actions-ecosystem/action-add-labels@v1
33-
if: ${{ startsWith(github.event.pull_request.title, 'Bug:') }}
33+
if: ${{ startsWith(github.event.pull_request.title, 'Bug') }}
3434
with:
3535
labels: bug
3636

3737
- name: add label Chore
3838
uses: actions-ecosystem/action-add-labels@v1
39-
if: ${{ startsWith(github.event.pull_request.title, 'Chore:') }}
39+
if: ${{ startsWith(github.event.pull_request.title, 'Chore') }}
4040
with:
4141
labels: chore
4242

4343
- name: add label Document
4444
uses: actions-ecosystem/action-add-labels@v1
45-
if: ${{ startsWith(github.event.pull_request.title, 'Docs:') }}
45+
if: ${{ startsWith(github.event.pull_request.title, 'Docs') }}
4646
with:
4747
labels: documentation
4848

4949
- name: add label Feature
5050
uses: actions-ecosystem/action-add-labels@v1
51-
if: ${{ startsWith(github.event.pull_request.title, 'Feat:') }}
51+
if: ${{ startsWith(github.event.pull_request.title, 'Feat') }}
5252
with:
5353
labels: enhancement
5454

5555
- name: add label Hotfix
5656
uses: actions-ecosystem/action-add-labels@v1
57-
if: ${{ startsWith(github.event.pull_request.title, 'Hotfix:') }}
57+
if: ${{ startsWith(github.event.pull_request.title, 'Hotfix') && startsWith(github.event.pull_request.title, 'Fix') }}
5858
with:
5959
labels: Hotfix

app/src/androidTest/java/org/care/packie/ExampleInstrumentedTest.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ package org.care.packie
22

33
import androidx.test.platform.app.InstrumentationRegistry
44
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import org.junit.Assert.assertEquals
56

67
import org.junit.Test
78
import org.junit.runner.RunWith
89

9-
import org.junit.Assert.*
10-
1110
/**
1211
* Instrumented test, which will execute on an Android device.
1312
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.care.packie
2+
3+
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
4+
5+
object StuffsPreviewProvider {
6+
val mockStuffs: Map<String, Boolean> = listOf(
7+
"에어팟",
8+
"지갑",
9+
"애플 워치",
10+
"갤럭시 워치",
11+
"갤럭시 탭",
12+
"아이패드",
13+
"갤럭시북",
14+
"맥북",
15+
"립밤",
16+
"랜즈통",
17+
"칫솔",
18+
"치약"
19+
).associateWith { false }
20+
21+
val previewMockData = (1..100).associate { "item${it}" to false }
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.care.packie.feature.stuffs
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.width
6+
import androidx.compose.foundation.lazy.grid.LazyGridState
7+
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.tooling.preview.Preview
11+
import org.care.packie.ui.component.stuff.MutableStuffsGrid
12+
import org.care.packie.ui.component.stuff.StuffsGrid
13+
import org.care.packie.ui.theme.PackieTheme
14+
import org.care.packie.utils.ui.CrossfadeToggle
15+
16+
@Composable
17+
fun StuffsContent(
18+
modifier: Modifier = Modifier,
19+
state: LazyGridState = rememberLazyGridState(),
20+
isEditMode: Boolean,
21+
stuffs: Map<String, Boolean>,
22+
onAdd: () -> Unit = {},
23+
onRemove: (String) -> Unit = {},
24+
onToggle: (Boolean) -> Unit = {},
25+
) {
26+
Box(
27+
modifier = modifier
28+
) {
29+
CrossfadeToggle(
30+
isEnable = isEditMode,
31+
enableComposable = {
32+
MutableStuffsGrid(
33+
state = state,
34+
stuffs = stuffs,
35+
onAdd = onAdd,
36+
onRemove = onRemove
37+
)
38+
},
39+
disableComposable = {
40+
StuffsGrid(
41+
state = state,
42+
stuffs = stuffs,
43+
onToggle = onToggle
44+
)
45+
}
46+
)
47+
}
48+
49+
}
50+
51+
@Preview
52+
@Composable
53+
fun StuffsContentPreview() {
54+
PackieTheme {
55+
Column {
56+
StuffsScreenTopBar(
57+
category = "출근",
58+
isEditMode = false
59+
)
60+
StuffsContent(
61+
modifier = Modifier.weight(1f),
62+
isEditMode = false,
63+
stuffs = (1..100).associate { "item${it}" to false }
64+
)
65+
StuffsStickyBottom(isEditMode = false)
66+
}
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package org.care.packie.feature.stuffs
2+
3+
import androidx.compose.animation.AnimatedVisibility
4+
import androidx.compose.animation.fadeIn
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.padding
7+
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
8+
import androidx.compose.material3.Scaffold
9+
import androidx.compose.material3.SnackbarHost
10+
import androidx.compose.material3.SnackbarHostState
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.getValue
13+
import androidx.compose.runtime.mutableStateMapOf
14+
import androidx.compose.runtime.mutableStateOf
15+
import androidx.compose.runtime.remember
16+
import androidx.compose.runtime.rememberCoroutineScope
17+
import androidx.compose.runtime.setValue
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.graphics.Color
20+
import androidx.compose.ui.input.nestedscroll.nestedScroll
21+
import androidx.compose.ui.tooling.preview.Preview
22+
import androidx.compose.ui.unit.dp
23+
import kotlinx.coroutines.launch
24+
import org.care.packie.StuffsPreviewProvider
25+
import org.care.packie.ui.AddDialogType
26+
import org.care.packie.ui.component.dialog.AddDialog
27+
import org.care.packie.ui.component.stuff.rememberEditModeState
28+
import org.care.packie.ui.theme.PackieTheme
29+
import org.care.packie.utils.ui.scroll.PackieTopBarScrollBehavior
30+
import org.care.packie.utils.ui.scroll.rememberPackieTopBarState
31+
32+
private const val MIN_SPACER_SIZE = 4
33+
private const val MAX_SPACER_SIZE = 110
34+
35+
@Composable
36+
fun StuffsScreen(
37+
category: String,
38+
currentStuffs: Map<String, Boolean>,
39+
onClickToggle: (Boolean) -> Unit = {},
40+
onClickRemove: (String) -> Unit = {},
41+
onClickAdd: () -> Unit = {},
42+
onClickUpdate: (Map<String, Boolean>) -> Unit = {},
43+
) {
44+
val editableStuffs =
45+
remember { mutableStateMapOf<String, Boolean>().apply { putAll(currentStuffs) } }
46+
val editMode = rememberEditModeState()
47+
val scope = rememberCoroutineScope()
48+
val snackBarHostState = remember { SnackbarHostState() }
49+
var isDialogOpen by remember { mutableStateOf(false) }
50+
51+
val topBarScrollState = rememberPackieTopBarState(
52+
maxHeight = StuffsTopBarSpacerToken.maxHeight,
53+
minHeight = StuffsTopBarSpacerToken.minHeight
54+
)
55+
val lazyGridState = rememberLazyGridState()
56+
val topBarScrollBehavior = PackieTopBarScrollBehavior.rememberExitUntilCollapsedScrollState(
57+
topBarScrollState = topBarScrollState,
58+
scrollableState = lazyGridState
59+
)
60+
Scaffold(
61+
modifier = Modifier
62+
.fillMaxSize()
63+
.padding(horizontal = 16.dp)
64+
.nestedScroll(topBarScrollBehavior),
65+
containerColor = Color.Transparent,
66+
snackbarHost = {
67+
SnackbarHost(hostState = snackBarHostState)
68+
},
69+
topBar = {
70+
StuffsScreenTopBar(
71+
category = category,
72+
isEditMode = editMode.isEditMode,
73+
onCategoryClick = {},
74+
onBackClick = {},
75+
state = topBarScrollState
76+
)
77+
},
78+
bottomBar = {
79+
StuffsStickyBottom(
80+
isEditMode = editMode.isEditMode,
81+
onClickEdit = {
82+
editMode.enableEditMode()
83+
},
84+
onClickUpdate = {
85+
editMode.disableEditMode()
86+
onClickUpdate(editableStuffs)
87+
},
88+
)
89+
}
90+
) {
91+
StuffsContent(
92+
modifier = Modifier.padding(it),
93+
isEditMode = editMode.isEditMode,
94+
stuffs = if (editMode.isEditMode) editableStuffs else currentStuffs,
95+
onAdd = {
96+
isDialogOpen = true
97+
},
98+
onRemove = {stuffName ->
99+
editableStuffs.remove(stuffName)
100+
},
101+
onToggle = onClickToggle,
102+
state = lazyGridState
103+
)
104+
}
105+
106+
AnimatedVisibility(
107+
visible = isDialogOpen,
108+
enter = fadeIn()
109+
) {
110+
AddDialog(
111+
type = AddDialogType.STUFF,
112+
onConfirmation = {
113+
if (editableStuffs.put(it, false) != null) {
114+
scope.launch {
115+
snackBarHostState.showSnackbar("${it}은 이미 추가된 물건이에요")
116+
}
117+
}
118+
isDialogOpen = false
119+
},
120+
onDismiss = { isDialogOpen = false }
121+
)
122+
}
123+
}
124+
125+
@Preview
126+
@Composable
127+
fun StuffScreenPreview() {
128+
PackieTheme {
129+
StuffsScreen(
130+
category = "출근",
131+
currentStuffs = StuffsPreviewProvider.mockStuffs
132+
)
133+
}
134+
}

0 commit comments

Comments
 (0)