Skip to content
This repository has been archived by the owner on Apr 27, 2023. It is now read-only.

Commit

Permalink
설정화면 구현 (#98)
Browse files Browse the repository at this point in the history
* 설정화면 navigation 구현

* 🔥 Test 코드 삭제

* 💄 설정 Option Item 제작

* 💄 설정 Section Header 제작

* 📄 Update license header

* 🚚 설정 메뉴 아이템 네이밍 변경

* 💄 Section Composable 완성

* 💄 내정보 화면 구현

* 🚨 CI error fix
  • Loading branch information
l2hyunwoo authored Mar 11, 2023
1 parent 90666e2 commit 9f6185d
Show file tree
Hide file tree
Showing 14 changed files with 548 additions and 65 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/develop_PR_builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ jobs:
- name: Lint Check
run: ./gradlew ktlintCheck

- name: Spotless Apply
run: ./gradlew build

- name: Build debug APK
run: ./gradlew assembleDebug --stacktrace

Expand Down
39 changes: 0 additions & 39 deletions app/src/androidTest/java/org/sopt/stamp/ExampleInstrumentedTest.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import org.sopt.stamp.R
import org.sopt.stamp.designsystem.component.util.noRippleClickable
import org.sopt.stamp.designsystem.style.SoptTheme
import org.sopt.stamp.util.MultiFormFactorPreviews

Expand Down Expand Up @@ -74,7 +75,7 @@ fun Toolbar(
painter = painterResource(id = R.drawable.ic_back),
contentDescription = "Back Button",
modifier = Modifier
.clickable(onClick = onBack)
.noRippleClickable(onClick = onBack)
.align(Alignment.CenterVertically)
.padding(8.dp)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import org.sopt.stamp.domain.error.Error
import org.sopt.stamp.domain.model.MissionsFilter
import org.sopt.stamp.feature.destinations.MissionDetailScreenDestination
import org.sopt.stamp.feature.destinations.RankingScreenDestination
import org.sopt.stamp.feature.destinations.SettingScreenDestination
import org.sopt.stamp.feature.mission.MissionsState
import org.sopt.stamp.feature.mission.MissionsViewModel
import org.sopt.stamp.feature.mission.model.MissionListUiModel
Expand Down Expand Up @@ -110,7 +111,8 @@ fun MissionListScreen(
menuTexts = MissionsFilter.getTitleOfMissionsList(),
onMenuClick = { filter -> missionsViewModel.fetchMissions(filter = filter) },
onMissionItemClick = { item -> navigator.navigate(MissionDetailScreenDestination(item)) },
onFloatingButtonClick = { navigator.navigate(RankingScreenDestination) }
onFloatingButtonClick = { navigator.navigate(RankingScreenDestination) },
onSettingButtonClick = { navigator.navigate(SettingScreenDestination) }
)
}
}
Expand All @@ -122,14 +124,16 @@ fun MissionListScreen(
menuTexts: List<String>,
onMenuClick: (String) -> Unit = {},
onMissionItemClick: (item: MissionNavArgs) -> Unit = {},
onFloatingButtonClick: () -> Unit = {}
onFloatingButtonClick: () -> Unit = {},
onSettingButtonClick: () -> Unit = {}
) {
Scaffold(
topBar = {
MissionListHeader(
title = missionListUiModel.title,
menuTexts = menuTexts,
onMenuClick = { onMenuClick(it) }
onMenuClick = { onMenuClick(it) },
onSettingButtonClick = { onSettingButtonClick() }
)
},
floatingActionButton = {
Expand Down Expand Up @@ -207,7 +211,8 @@ fun MissionEmptyScreen(contentText: String) {
fun MissionListHeader(
title: String,
menuTexts: List<String>,
onMenuClick: (String) -> Unit = {}
onMenuClick: (String) -> Unit = {},
onSettingButtonClick: () -> Unit = {}
) {
var currentText by remember { mutableStateOf(title) }
SoptTopAppBar(
Expand All @@ -220,6 +225,13 @@ fun MissionListHeader(
onMenuClick(selectedMenuText)
}
)
},
actions = {
SoptampIconButton(
imageVector = ImageVector.vectorResource(id = R.drawable.setting)
) {
onSettingButtonClick()
}
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ fun UserMissionListHeader(
title = { MissionListHeaderTitle(title = title) },
navigationIcon = {
SoptampIconButton(
imageVector = ImageVector.vectorResource(id = R.drawable.arrow_letf),
imageVector = ImageVector.vectorResource(id = R.drawable.arrow_left),
onClick = { onClickBack() }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ fun RankingHeader(
},
navigationIcon = {
SoptampIconButton(
imageVector = ImageVector.vectorResource(id = R.drawable.arrow_letf),
imageVector = ImageVector.vectorResource(id = R.drawable.arrow_left),
onClick = { onClickBack() }
)
}
Expand Down
196 changes: 196 additions & 0 deletions app/src/main/java/org/sopt/stamp/feature/setting/SettingScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Copyright 2023 SOPT - Shout Our Passion Together
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sopt.stamp.feature.setting

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
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.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextDecoration
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.stamp.R
import org.sopt.stamp.config.navigation.SettingNavGraph
import org.sopt.stamp.designsystem.component.layout.SoptColumn
import org.sopt.stamp.designsystem.component.toolbar.Toolbar
import org.sopt.stamp.designsystem.style.Access300
import org.sopt.stamp.designsystem.style.Gray50
import org.sopt.stamp.designsystem.style.SoptTheme
import org.sopt.stamp.feature.setting.component.Section
import org.sopt.stamp.feature.setting.model.SectionUiModel
import org.sopt.stamp.util.DefaultPreview

@SettingNavGraph(true)
@Destination("menu")
@Composable
fun SettingScreen(
navigator: DestinationsNavigator,
viewModel: SettingScreenViewModel = hiltViewModel()
) {
val myInfoSectionItems = remember {
listOf(
SectionUiModel.Header(title = "내 정보"),
SectionUiModel.Option(
title = "한 마디 편집",
optionIconResId = R.drawable.arrow_right
) {
// TODO by Nunu 한 마디 편집 화면으로 넘어가기
},
SectionUiModel.Spacer,
SectionUiModel.Option(
title = "비밀번호 변경",
optionIconResId = R.drawable.arrow_right
) {
// TODO by Nunu 비밀번호 변경 화면으로 넘어가기
},
SectionUiModel.Spacer,
SectionUiModel.Option(
title = "닉네임 변경",
optionIconResId = R.drawable.arrow_right,
containerModifier = Modifier
.background(
color = Gray50,
shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp)
)
.padding(horizontal = 16.dp)
) {
// TODO by Nunu 닉네임 변경 화면으로 넘어가기
}
)
}

val serviceTermSectionItems = remember {
listOf(
SectionUiModel.Header(title = "서비스 이용방침"),
SectionUiModel.Option(
title = "개인정보처리방침",
optionIconResId = R.drawable.arrow_right
) {
// TODO by Nunu 개인정보처리방침 화면으로 넘어가기
},
SectionUiModel.Spacer,
SectionUiModel.Option(
title = "서비스 이용 약관",
optionIconResId = R.drawable.arrow_right
) {
// TODO by Nunu 서비스 이용 약관 화면으로 넘어가기
},
SectionUiModel.Spacer,
SectionUiModel.Option(
title = "서비스 의견 제안",
optionIconResId = R.drawable.arrow_right,
containerModifier = Modifier
.background(
color = Gray50,
shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp)
)
.padding(horizontal = 16.dp)
) {
// TODO by Nunu 서비스 의견 제안 화면으로 넘어가기
}
)
}

val missionSectionItems = listOf(
SectionUiModel.Header(title = "미션"),
SectionUiModel.Option(
title = "스탬프 초기화",
containerModifier = Modifier
.background(
color = Gray50,
shape = RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp)
)
.padding(horizontal = 16.dp)
) {
// TODO by Nunu 스탬프 초기화하기
}
)

val logOutSectionItems = listOf(
SectionUiModel.Option(
title = "로그아웃",
textColor = Access300,
containerModifier = Modifier
.background(
color = Gray50,
shape = RoundedCornerShape(12.dp)
)
.padding(horizontal = 16.dp)
) {
// TODO by Nunu 로그아웃하기
}
)

SoptTheme {
SoptColumn(
modifier = Modifier.fillMaxSize()
) {
Toolbar(
modifier = Modifier.padding(bottom = 10.dp),
title = {
Text(
text = "설정",
style = SoptTheme.typography.h2,
modifier = Modifier.padding(start = 4.dp),
color = SoptTheme.colors.onSurface
)
},
onBack = { navigator.popBackStack() }
)
Spacer(modifier = Modifier.height(8.dp))
Section(items = myInfoSectionItems)
Spacer(modifier = Modifier.height(16.dp))
Section(items = serviceTermSectionItems)
Spacer(modifier = Modifier.height(16.dp))
Section(items = missionSectionItems)
Spacer(modifier = Modifier.height(16.dp))
Section(items = logOutSectionItems)
Spacer(modifier = Modifier.height(24.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) {
Text(
text = "탈퇴하기",
style = SoptTheme.typography.caption1,
color = SoptTheme.colors.onSurface40,
textDecoration = TextDecoration.Underline
)
}
}
}
}

@DefaultPreview
@Composable
private fun SettingScreenPreview() {
SettingScreen(
navigator = EmptyDestinationsNavigator,
viewModel = SettingScreenViewModel()
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 SOPT - Shout Our Passion Together
* Copyright 2023 SOPT - Shout Our Passion Together
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,20 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sopt.stamp
package org.sopt.stamp.feature.setting

import org.junit.Test
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
@HiltViewModel
class SettingScreenViewModel @Inject constructor() : ViewModel()
Loading

0 comments on commit 9f6185d

Please sign in to comment.