Skip to content

Commit

Permalink
[feature/push-alarm-config] 푸시알람 설정화면 구현 (#49)
Browse files Browse the repository at this point in the history
* feat: Part 도메인 정의

feature/push-alarm-config

* feat: 체크박스 구현

feature/push-alarm-config

* feat: 푸시알림 화면 체크박스 제외 구현 중

feature/push-alarm-config

* fix: lint check

feature/push-alarm-config

* fix: gradle config change

* feat: Checkbox 활용한 UI 구현

* feat: 푸시 알림 화면 구현 완료

feature/push-alarm-config
  • Loading branch information
l2hyunwoo authored Oct 28, 2022
1 parent ed45491 commit 482946f
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.sopt.official.designsystem.components

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.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.sopt.official.R
import org.sopt.official.designsystem.style.SoptTheme

@Composable
fun CheckBox(
containerModifier: Modifier = Modifier.size(48.dp),
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
) {
Box(
modifier = containerModifier
.clickable { onCheckedChange(!checked) },
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
.size(24.dp)
.background(
color = if (checked) SoptTheme.colors.primary else SoptTheme.colors.onSurface20,
shape = RoundedCornerShape(4.dp)
),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = R.drawable.ic_check),
contentDescription = "체크 아이콘"
)
}
}
}

@Preview
@Composable
fun CheckedCheckboxPreview() {
SoptTheme {
CheckBox(
checked = true,
onCheckedChange = {}
)
}
}

@Preview
@Composable
fun UncheckedCheckboxPreview() {
SoptTheme {
CheckBox(
checked = false,
onCheckedChange = {}
)
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/org/sopt/official/domain/entity/Part.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.official.domain.entity

enum class Part(
val title: String,
val soptTitle: String,
) {
ALL("all", "전체 공지"),
PLAN("plan", "기획"),
DESIGN("design", "디자인"),
WEB("web", "Web"),
ANDROID("android", "Android"),
IOS("ios", "iOS"),
SERVER("server", "Server");

companion object {
fun of(title: String): Part {
return values().first { it.title == title }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.sopt.official.feature.setting

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import org.sopt.official.domain.entity.Part
import javax.inject.Inject

@HiltViewModel
class PushAlarmConfigViewModel @Inject constructor() : ViewModel() {
var selectedItems by mutableStateOf(setOf<Part>())
private set

fun onItemCheckedChange(part: Part, isChecked: Boolean) {
selectedItems = if (isChecked) {
selectedItems + part
} else {
selectedItems - part
}
}

fun isSelected(part: Part) = selectedItems.contains(part)
}
187 changes: 187 additions & 0 deletions app/src/main/java/org/sopt/official/feature/setting/PushAlarmScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package org.sopt.official.feature.setting

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
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.foundation.layout.wrapContentSize
import androidx.compose.material.Divider
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import org.sopt.official.R
import org.sopt.official.config.navigation.SettingNavGraph
import org.sopt.official.designsystem.components.CheckBox
import org.sopt.official.designsystem.components.TopBarIconButton
import org.sopt.official.designsystem.style.SoptTheme
import org.sopt.official.domain.entity.Part
import org.sopt.official.feature.setting.model.PushSelectItem

@SettingNavGraph
@Destination("push_alarm")
@Composable
fun PushAlarmScreen(
navigator: DestinationsNavigator,
viewModel: PushAlarmConfigViewModel = hiltViewModel()
) {
SoptTheme {
Column(modifier = Modifier.fillMaxSize()) {
Toolbar(
onBack = { navigator.popBackStack() },
onConfirm = {}
)
Part.values()
.map { part ->
PushSelectItem(
part,
viewModel.isSelected(part)
) { isChecked ->
viewModel.onItemCheckedChange(part, isChecked)
}
}.forEach {
SelectBox(
item = it,
value = it.value,
onCheckedChange = it.onCheckedChange
)
}
}
}
}

@Composable
private fun SelectBox(
item: PushSelectItem,
value: Boolean,
onCheckedChange: (Boolean) -> Unit
) {
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = item.part.soptTitle,
style = SoptTheme.typography.b1,
modifier = Modifier.padding(start = 16.dp)
)
CheckBox(checked = value, onCheckedChange = onCheckedChange)
}
Divider(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
color = SoptTheme.colors.onSurface20,
thickness = 1.dp
)
}
}

@Composable
private fun Toolbar(
onBack: () -> Unit,
onConfirm: () -> Unit
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
elevation = 3.dp
) {
Row(
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(
modifier = Modifier.wrapContentSize(),
verticalAlignment = Alignment.CenterVertically
) {
TopBarIconButton(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_back),
onClick = onBack
)
Text(
text = "설정",
style = SoptTheme.typography.h5
)
}
Text(
text = "확인",
style = SoptTheme.typography.b1,
color = SoptTheme.colors.primary,
modifier = Modifier
.clickable { onConfirm() }
.padding(16.dp)
)
}
}
}

@Preview(showBackground = true)
@Composable
fun PushAlarmScreenPreview() {
PushAlarmScreen(navigator = EmptyDestinationsNavigator)
}

@Preview(
name = "툴바 Preview",
showBackground = true
)
@Composable
fun ToolbarPreview() {
SoptTheme {
Toolbar(onBack = {}, onConfirm = {})
}
}

@Preview(
name = "체크박스 Checked Preview",
showBackground = true
)
@Composable
fun CheckedCheckBoxPreview() {
SoptTheme {
SelectBox(
item = PushSelectItem(Part.ANDROID),
value = true,
onCheckedChange = {}
)
}
}

@Preview(
name = "체크박스 Unchecked Preview",
showBackground = true
)
@Composable
fun UncheckedCheckBoxPreview() {
SoptTheme {
SelectBox(
item = PushSelectItem(Part.ANDROID),
value = false,
onCheckedChange = {}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.official.feature.setting.model

import org.sopt.official.domain.entity.Part

data class PushSelectItem(
val part: Part,
val value: Boolean = false,
val onCheckedChange: (Boolean) -> Unit = {}
)
11 changes: 11 additions & 0 deletions app/src/main/res/drawable/ic_check.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="13dp"
android:viewportWidth="18"
android:viewportHeight="13">
<path
android:pathData="M1,4.846L7.095,11L17,1"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
</vector>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4092m -Dfile.encoding\=UTF-8
android.useAndroidX=true
kotlin.incremental.usePreciseJavaTracking=true
android.enableJetifier=true
android.enableJetifier=false

0 comments on commit 482946f

Please sign in to comment.