-
Notifications
You must be signed in to change notification settings - Fork 3
[Refactor] 1.2.x 나머지 수정사항 진행 (알림 제외) #132
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
Changes from all commits
29e5281
ef0389c
e1d5981
9d53b24
eddfa6c
6c1d6e7
1a382a7
7816e5e
38e31ea
895ffd3
9ba1d76
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,16 @@ | ||
| package com.texthip.thip.data.manager | ||
|
|
||
| import kotlinx.coroutines.flow.MutableSharedFlow | ||
| import kotlinx.coroutines.flow.asSharedFlow | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| @Singleton | ||
| class AuthStateManager @Inject constructor() { | ||
| private val _tokenExpiredEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1) | ||
| val tokenExpiredEvent = _tokenExpiredEvent.asSharedFlow() | ||
|
|
||
| fun triggerTokenExpired() { | ||
| _tokenExpiredEvent.tryEmit(Unit) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.texthip.thip.ui.mypage.screen | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.widget.Toast | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.background | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.clickable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Arrangement | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -12,15 +13,18 @@ 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.material3.CircularProgressIndicator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Icon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.LaunchedEffect | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.getValue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.mutableStateOf | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.saveable.rememberSaveable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.setValue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Alignment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.platform.LocalContext | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.painterResource | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.stringResource | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.text.SpanStyle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -29,22 +33,44 @@ import androidx.compose.ui.text.withStyle | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.window.Dialog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.hilt.navigation.compose.hiltViewModel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.R | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.common.buttons.CheckboxButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.common.modal.DialogPopup | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.mypage.viewmodel.DeleteAccountViewModel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.theme.DarkGrey02 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.theme.Red | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.theme.ThipTheme.colors | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.texthip.thip.ui.theme.ThipTheme.typography | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fun DeleteAccountScreen( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateBack: () -> Unit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateBack: () -> Unit, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateToLogin: () -> Unit, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| viewModel: DeleteAccountViewModel = hiltViewModel() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val context = LocalContext.current | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val uiState = viewModel.uiState.collectAsStateWithLifecycle().value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var isChecked by rememberSaveable { mutableStateOf(false) } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val backgroundColor = if (isChecked) colors.Purple else colors.Grey02 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var isDialogVisible by rememberSaveable { mutableStateOf(false) } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 회원탈퇴 완료 시 로그인 화면으로 이동 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LaunchedEffect(uiState.isDeleteCompleted) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (uiState.isDeleteCompleted) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateToLogin() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 에러 메시지 표시 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LaunchedEffect(uiState.errorMessage) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uiState.errorMessage?.let { message -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Toast.makeText(context, message, Toast.LENGTH_SHORT).show() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -159,19 +185,30 @@ fun DeleteAccountScreen( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onCancel = { isDialogVisible = false }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onConfirm = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isDialogVisible = false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: 회원탈퇴 로직 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| viewModel.deleteAccount(context) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 로딩 중일 때 전체 화면에 로딩 인디케이터 표시 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (uiState.isLoading) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Box( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier.fillMaxSize(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contentAlignment = Alignment.Center | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CircularProgressIndicator() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+195
to
+203
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. 🛠️ Refactor suggestion 로딩 오버레이가 Column 자식으로는 실제 오버레이/터치 차단이 되지 않습니다 현재 구조에서는 하위에 쌓여 터치가 막히지 않을 수 있습니다. 삭제 중 중복 탭/중복 호출을 방지하려면 모달 다이얼로그로 띄워주세요. 권장 diff: - if (uiState.isLoading) {
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center
- ) {
- CircularProgressIndicator()
- }
- }
+ if (uiState.isLoading) {
+ Dialog(
+ onDismissRequest = {},
+ properties = androidx.compose.ui.window.DialogProperties(
+ dismissOnBackPress = false,
+ dismissOnClickOutside = false
+ )
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(24.dp),
+ contentAlignment = Alignment.Center
+ ) {
+ CircularProgressIndicator()
+ }
+ }
+ }(필요 시 import: 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private fun DeleteAccountScreenPrev() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DeleteAccountScreen( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateBack = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateBack = {}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onNavigateToLogin = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
🛠️ Refactor suggestion
ViewModel에 Android Context 전달 지양
viewModel.deleteAccount(context)는 누수/테스트성 저하 위험이 있습니다. UI 의존은 Composable로, 앱 컨텍스트가 필요하면@ApplicationContext로 주입하세요.권장 diff(호출부):
ViewModel 예시(참고):
🤖 Prompt for AI Agents