-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
더보기 탭 닉네임 기능 #211
더보기 탭 닉네임 기능 #211
Changes from all commits
1091d85
a67a1c2
93b4e35
c34c2b5
777d0ba
1dc8710
758001b
e5b7dbc
27950c6
a22c20b
60020ce
6394cb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.wafflestudio.snutt2.lib | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.platform.LocalDensity | ||
import androidx.compose.ui.unit.TextUnit | ||
|
||
@Composable | ||
fun TextUnit.toDp() = with(LocalDensity.current) { | ||
this@toDp.toDp() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.wafflestudio.snutt2.lib.network.dto | ||
|
||
import com.wafflestudio.snutt2.lib.network.dto.core.UserDto | ||
|
||
typealias PatchUserInfoResults = UserDto |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.wafflestudio.snutt2.lib.network.dto.core | ||
|
||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.JsonClass | ||
|
||
@JsonClass(generateAdapter = true) | ||
data class NicknameDto( | ||
@Json(name = "nickname") val nickname: String = "", | ||
@Json(name = "tag") val tag: String = "", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UserDto의 nickNameDto 필드에 초기값 들어있어서 하위호환성은 지키는 것 같은데, NicknameDto 내부의 필드들에도 초기값을 넣어야 하나 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nullable이 아니면 초기값은 반드시 있는 게 좋지 |
||
) { | ||
override fun toString(): String { | ||
return "$nickname#$tag" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ object NavigationDestination { | |
const val TeamInfo = "team_info" | ||
const val TimeTableConfig = "timetable_config" | ||
const val UserConfig = "user_config" | ||
const val ChangeNickname = "change_nickname" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이것도 iOS랑 딥링크 스킴 맞춰야해? 모든 navigation destination을 다 맞추는거? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저기 쓴거대로 intent에 extra로 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 근데 |
||
const val PersonalInformationPolicy = "personal_information_policy" | ||
const val ThemeModeSelect = "theme_mode_select" | ||
const val Bookmark = "bookmark" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
package com.wafflestudio.snutt2.views.logged_in.home.settings | ||
|
||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.* | ||
import androidx.compose.foundation.text.KeyboardActionScope | ||
import androidx.compose.foundation.text.KeyboardActions | ||
import androidx.compose.foundation.text.KeyboardOptions | ||
import androidx.compose.material.Text | ||
import androidx.compose.runtime.* | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.ExperimentalComposeUiApi | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.focus.onFocusChanged | ||
import androidx.compose.ui.graphics.ColorFilter | ||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.text.* | ||
import androidx.compose.ui.text.input.ImeAction | ||
import androidx.compose.ui.text.style.TextIndent | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.unit.sp | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
import com.wafflestudio.snutt2.R | ||
import com.wafflestudio.snutt2.components.compose.* | ||
import com.wafflestudio.snutt2.lib.toDp | ||
import com.wafflestudio.snutt2.ui.SNUTTColors | ||
import com.wafflestudio.snutt2.ui.SNUTTTypography | ||
import com.wafflestudio.snutt2.views.* | ||
import com.wafflestudio.snutt2.views.logged_in.lecture_detail.Margin | ||
import kotlinx.coroutines.launch | ||
|
||
@Composable | ||
fun ChangeNicknamePage() { | ||
val navController = LocalNavController.current | ||
val apiOnProgress = LocalApiOnProgress.current | ||
val apiOnError = LocalApiOnError.current | ||
val scope = rememberCoroutineScope() | ||
val userViewModel = hiltViewModel<UserViewModel>() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UserConfigPage와는 다른 viewModel이 생기지만, userDto가 스토리지 단에서 갱신되기 때문에 UserConfigPage에서도 바뀐 닉네임이 잘 반영된다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일단 ㄱㄱ 복잡하지 않은 페이지에서는 새 route에 뷰모델 막 생성해도 큰 문제 없으니까 |
||
|
||
val user by userViewModel.userInfo.collectAsState() | ||
val initialNickname = user?.nickname?.nickname ?: "" | ||
var nicknameField by remember { mutableStateOf(user?.nickname?.nickname ?: "") } | ||
val nicknameRequirementTexts = listOf( | ||
stringResource(R.string.settings_change_nickname_requirement_0), | ||
stringResource(R.string.settings_change_nickname_requirement_1), | ||
stringResource(R.string.settings_change_nickname_requirement_2), | ||
) | ||
|
||
val onBackPressed = { | ||
if (navController.currentDestination?.route == NavigationDestination.ChangeNickname) { | ||
navController.popBackStack() | ||
} | ||
} | ||
|
||
val handleChangeNickname = { | ||
scope.launch { | ||
launchSuspendApi(apiOnProgress, apiOnError) { | ||
userViewModel.changeNickname(nicknameField) | ||
onBackPressed() | ||
} | ||
} | ||
} | ||
|
||
Column( | ||
modifier = Modifier | ||
.fillMaxSize() | ||
.background(SNUTTColors.Gray100), | ||
) { | ||
TopBar( | ||
title = { | ||
Text( | ||
text = stringResource(R.string.settings_change_nickname_app_bar_title), | ||
style = SNUTTTypography.h2, | ||
) | ||
}, | ||
navigationIcon = { | ||
ArrowBackIcon( | ||
modifier = Modifier | ||
.size(30.dp) | ||
.clicks { onBackPressed() }, | ||
colorFilter = ColorFilter.tint(SNUTTColors.Black900), | ||
) | ||
}, | ||
actions = { | ||
Text( | ||
text = stringResource(R.string.settings_change_nickname_app_bar_save), | ||
style = SNUTTTypography.body1, | ||
color = if (nicknameField.isEmpty() || nicknameField == initialNickname) SNUTTColors.Black500 else SNUTTColors.Black900, | ||
modifier = Modifier | ||
.clicks { | ||
if (nicknameField.isNotEmpty() && nicknameField != initialNickname) { | ||
handleChangeNickname() | ||
} | ||
}, | ||
) | ||
}, | ||
) | ||
Margin(10.dp) | ||
SettingColumn( | ||
title = stringResource(R.string.settings_change_nickname_title), | ||
) { | ||
NicknameEditText( | ||
value = nicknameField, | ||
onValueChange = { nicknameField = it }, | ||
onDone = { | ||
if (nicknameField.isNotEmpty() && nicknameField != initialNickname) { | ||
handleChangeNickname() | ||
} | ||
}, | ||
hint = initialNickname, | ||
) | ||
} | ||
Margin(12.dp) | ||
Column( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 30.dp), | ||
) { | ||
Text( | ||
text = stringResource(R.string.settings_change_nickname_guide), | ||
style = SNUTTTypography.body2.copy( | ||
color = SNUTTColors.Black500, | ||
), | ||
) | ||
Margin(30.dp) | ||
Column( | ||
verticalArrangement = Arrangement.spacedBy(2.sp.toDp()), | ||
) { | ||
Text( | ||
text = stringResource(R.string.settings_change_nickname_requirement_title), | ||
style = SNUTTTypography.h5.copy( | ||
color = SNUTTColors.Black500, | ||
), | ||
) | ||
nicknameRequirementTexts.forEach { | ||
BulletedParagraph( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bulletpoint가 있는 문단을 구현해야 하는데, 문단 끼리의 줄 간격과 문단 내에서의 줄 간격이 달라야 한다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. annotatedString이 매우 쓰기 불편하긴 하지 |
||
text = it, | ||
style = SNUTTTypography.body2.copy( | ||
color = SNUTTColors.Black500, | ||
), | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
@OptIn(ExperimentalComposeUiApi::class) | ||
@Composable | ||
fun NicknameEditText( | ||
value: String, | ||
onValueChange: (String) -> Unit, | ||
onDone: (KeyboardActionScope.() -> Unit), | ||
hint: String, | ||
modifier: Modifier = Modifier, | ||
) { | ||
Row( | ||
modifier = modifier | ||
.fillMaxWidth() | ||
.height(45.dp) | ||
.background(SNUTTColors.White900) | ||
.padding(horizontal = 35.dp), | ||
verticalAlignment = Alignment.CenterVertically, | ||
) { | ||
val keyboardController = LocalSoftwareKeyboardController.current | ||
var isFocused by remember { mutableStateOf(false) } | ||
EditText( | ||
modifier = Modifier | ||
.weight(1f) | ||
.onFocusChanged { isFocused = it.isFocused } | ||
.clearFocusOnKeyboardDismiss(), | ||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), | ||
keyboardActions = KeyboardActions(onDone = onDone), | ||
value = value, | ||
onValueChange = onValueChange, | ||
hint = hint, | ||
underlineEnabled = false, | ||
textStyle = SNUTTTypography.body1.copy( | ||
fontSize = 16.sp, | ||
), | ||
) | ||
if (isFocused) { | ||
CloseCircleIcon( | ||
modifier = Modifier | ||
.size(30.dp) | ||
.clicks { | ||
onValueChange("") | ||
keyboardController?.hide() | ||
}, | ||
) | ||
} | ||
Text( | ||
text = "#NNNN", | ||
JuTaK97 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
style = SNUTTTypography.body1.copy( | ||
color = SNUTTColors.Black300, | ||
fontSize = 16.sp, | ||
), | ||
) | ||
} | ||
} | ||
|
||
@Composable | ||
fun BulletedParagraph( | ||
text: String, | ||
style: TextStyle, | ||
) { | ||
Text( | ||
text = buildAnnotatedString { | ||
withStyle(ParagraphStyle(textIndent = TextIndent(restLine = style.fontSize))) { | ||
append("\u2022") | ||
append("\t\t") | ||
append(text) | ||
} | ||
}, | ||
style = style, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
restapi 메서드가 patch로 바뀌어서 레포지토리에서도 그대로 patch로 썼어
레포지토리의 메서드 이름 지을 때 api의 메서드 따라서 짓는 거 맞아?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
별 규칙은 없긴해