Skip to content

Commit 0b74fbb

Browse files
authored
Merge pull request #132 from rbqks529/refactor/#131_ver_1.2.x
[Refactor] 1.2.x 나머지 수정사항 진행 (알림 제외)
2 parents 47e1df3 + 9ba1d76 commit 0b74fbb

15 files changed

Lines changed: 290 additions & 34 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<application
88
android:name=".ThipApplication"
9-
android:allowBackup="true"
9+
android:allowBackup="false"
1010
android:networkSecurityConfig="@xml/network_security_config"
1111
android:dataExtractionRules="@xml/data_extraction_rules"
1212
android:fullBackupContent="@xml/backup_rules"

app/src/main/java/com/texthip/thip/MainActivity.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,50 @@ import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
66
import androidx.activity.enableEdgeToEdge
77
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.LaunchedEffect
89
import androidx.navigation.compose.NavHost
910
import androidx.navigation.compose.composable
1011
import androidx.navigation.compose.rememberNavController
12+
import com.texthip.thip.data.manager.AuthStateManager
1113
import com.texthip.thip.data.manager.TokenManager
1214
import com.texthip.thip.ui.navigator.navigations.authNavigation
1315
import com.texthip.thip.ui.navigator.routes.CommonRoutes
1416
import com.texthip.thip.ui.theme.ThipTheme
1517
import dagger.hilt.android.AndroidEntryPoint
18+
import kotlinx.coroutines.flow.collectLatest
1619
import javax.inject.Inject
1720

1821
@AndroidEntryPoint
1922
class MainActivity : ComponentActivity() {
2023
@Inject
2124
lateinit var tokenManager: TokenManager
25+
@Inject
26+
lateinit var authStateManager: AuthStateManager
2227

2328
override fun onCreate(savedInstanceState: Bundle?) {
2429
super.onCreate(savedInstanceState)
2530
enableEdgeToEdge()
2631
setContent {
2732
ThipTheme {
28-
RootNavHost()
33+
RootNavHost(authStateManager)
2934
}
3035
}
3136
// getKakaoKeyHash(this)
3237
}
3338
}
3439

3540
@Composable
36-
fun RootNavHost() {
41+
fun RootNavHost(authStateManager: AuthStateManager) {
3742
val navController = rememberNavController()
43+
44+
LaunchedEffect(Unit) {
45+
authStateManager.tokenExpiredEvent.collectLatest {
46+
navController.navigate(CommonRoutes.Login) {
47+
popUpTo(0) { inclusive = true }
48+
}
49+
}
50+
}
51+
3852
NavHost(
3953
navController = navController,
4054
startDestination = CommonRoutes.Splash
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.texthip.thip.data.manager
2+
3+
import kotlinx.coroutines.flow.MutableSharedFlow
4+
import kotlinx.coroutines.flow.asSharedFlow
5+
import javax.inject.Inject
6+
import javax.inject.Singleton
7+
8+
@Singleton
9+
class AuthStateManager @Inject constructor() {
10+
private val _tokenExpiredEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
11+
val tokenExpiredEvent = _tokenExpiredEvent.asSharedFlow()
12+
13+
fun triggerTokenExpired() {
14+
_tokenExpiredEvent.tryEmit(Unit)
15+
}
16+
}

app/src/main/java/com/texthip/thip/data/repository/UserRepository.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,10 @@ class UserRepository @Inject constructor(
137137
.handleBaseResponse()
138138
.getOrThrow()
139139
}
140+
141+
suspend fun deleteAccount(): Result<Unit?> = runCatching {
142+
userService.deleteAccount()
143+
.handleBaseResponse()
144+
.getOrThrow()
145+
}
140146
}

app/src/main/java/com/texthip/thip/data/service/UserService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.texthip.thip.data.model.users.response.SignupResponse
1515
import com.texthip.thip.data.model.users.response.UserSearchResponse
1616
import com.texthip.thip.data.model.users.response.UsersMyFollowingsRecentFeedsResponse
1717
import retrofit2.http.Body
18+
import retrofit2.http.DELETE
1819
import retrofit2.http.GET
1920
import retrofit2.http.Header
2021
import retrofit2.http.PATCH
@@ -74,4 +75,7 @@ interface UserService {
7475
@Query("size") size: Int = 30
7576
): BaseResponse<UserSearchResponse>
7677

78+
@DELETE("users")
79+
suspend fun deleteAccount(): BaseResponse<Unit>
80+
7781
}

app/src/main/java/com/texthip/thip/ui/common/cards/CardAlarm.kt renamed to app/src/main/java/com/texthip/thip/ui/common/alarmpage/component/CardAlarm.kt

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.texthip.thip.ui.common.cards
1+
package com.texthip.thip.ui.common.alarmpage.component
22

33
import androidx.compose.foundation.background
44
import androidx.compose.foundation.border
@@ -111,18 +111,25 @@ fun CardAlarm(
111111
Column(
112112
horizontalAlignment = Alignment.End
113113
) {
114-
// 안읽음 상태일 때만 빨간 점
115-
if (!isRead) {
116-
Box(
117-
modifier = Modifier
118-
.size(6.dp)
119-
.clip(RoundedCornerShape(3.dp))
120-
.background(color = colors.Red)
121-
)
114+
// 빨간 점을 위한 고정 공간 (항상 6dp 높이 유지)
115+
Box(
116+
modifier = Modifier
117+
.size(6.dp),
118+
contentAlignment = Alignment.Center
119+
) {
120+
// 안읽음 상태일 때만 빨간 점 표시
121+
if (!isRead) {
122+
Box(
123+
modifier = Modifier
124+
.size(6.dp)
125+
.clip(RoundedCornerShape(3.dp))
126+
.background(color = colors.Red)
127+
)
128+
}
122129
}
123130

124131
Text(
125-
text = timeAgo + stringResource(R.string.time_ago),
132+
text = timeAgo,
126133
style = typography.timedate_r400_s11,
127134
color = if (isRead) colors.Grey02 else colors.Grey01,
128135
modifier = Modifier
@@ -161,7 +168,7 @@ fun PreviewNotificationCards() {
161168
title = "같이 읽기를 시작했어요!",
162169
badgeText = "모임",
163170
message = "한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다.",
164-
timeAgo = "12",
171+
timeAgo = "12시간 전",
165172
isRead = isRead
166173
) {
167174
isRead = true
@@ -172,31 +179,31 @@ fun PreviewNotificationCards() {
172179
title = "같이 읽기를 시작했어요!",
173180
badgeText = "모임",
174181
message = "한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다.",
175-
timeAgo = "12",
182+
timeAgo = "12시간 전",
176183
isRead = true
177184
)
178185

179186
CardAlarm(
180187
title = "같이 읽기를 시작했어요!",
181188
badgeText = "피드",
182189
message = "한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다.",
183-
timeAgo = "12",
190+
timeAgo = "12시간 전",
184191
isRead = false
185192
)
186193

187194
CardAlarm(
188195
title = "같이 읽기를 시작했어요!",
189196
badgeText = "좋아요",
190197
message = "한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다.",
191-
timeAgo = "12",
198+
timeAgo = "12시간 전",
192199
isRead = isRead
193200
)
194201

195202
CardAlarm(
196203
title = "같이 읽기를 시작했어요!",
197204
badgeText = "댓글",
198205
message = "한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다. 한줄만 입력이 가능합니다.",
199-
timeAgo = "12",
206+
timeAgo = "12시간 전",
200207
isRead = isRead
201208
)
202209
}

app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp
2323
import com.texthip.thip.R
2424
import com.texthip.thip.ui.common.alarmpage.component.AlarmFilterRow
2525
import com.texthip.thip.ui.common.alarmpage.mock.AlarmItem
26-
import com.texthip.thip.ui.common.cards.CardAlarm
26+
import com.texthip.thip.ui.common.alarmpage.component.CardAlarm
2727
import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar
2828
import com.texthip.thip.ui.theme.ThipTheme
2929
import com.texthip.thip.ui.theme.ThipTheme.colors

app/src/main/java/com/texthip/thip/ui/common/alarmpage/viewmodel/AlarmViewModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class AlarmViewModel : ViewModel() {
1515
_alarmItems.value = listOf(
1616
AlarmItem(1, "피드", "내 글을 좋아합니다.", "user123님이 내 글에 좋아요를 눌렀어요.", "2시간 전", false),
1717
AlarmItem(2, "모임", "같이 읽기를 시작했어요!", "모임방에서 20분 동안 같이 읽기가 시작되었어요!", "7시간 전", false),
18-
AlarmItem(3, "피드", "내 글에 댓글이 달렸어요.", "user1: 진짜 공감합니다!", "2025.01.12", true),
1918
AlarmItem(4, "모임", "투표가 시작되었어요!", "투표지를 먼저 열람합니다.", "17시간 전", false),
2019
AlarmItem(5, "피드", "팔로워가 새 글을 올렸어요.", "user456님이 새 리뷰를 작성했습니다.", "1일 전", true),
2120
AlarmItem(6, "모임", "새로운 모임방 초대", "호르몬 체인지 완독하는 방에 초대되었습니다.", "2일 전", false)

app/src/main/java/com/texthip/thip/ui/feed/component/MySubscribelistBar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ private fun EmptyMySubscriptionBar() {
136136
modifier = Modifier
137137
.fillMaxWidth()
138138
.height(42.dp)
139-
.clip(RoundedCornerShape(8.dp))
139+
.clip(RoundedCornerShape(12.dp))
140140
.background(colors.DarkGrey02)
141141
.clickable { }
142142
) {

app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageLeavethipScreen.kt

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.texthip.thip.ui.mypage.screen
22

3+
import android.widget.Toast
34
import androidx.compose.foundation.background
45
import androidx.compose.foundation.clickable
56
import androidx.compose.foundation.layout.Arrangement
@@ -12,15 +13,18 @@ import androidx.compose.foundation.layout.fillMaxWidth
1213
import androidx.compose.foundation.layout.height
1314
import androidx.compose.foundation.layout.padding
1415
import androidx.compose.foundation.shape.RoundedCornerShape
16+
import androidx.compose.material3.CircularProgressIndicator
1517
import androidx.compose.material3.Icon
1618
import androidx.compose.material3.Text
1719
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.LaunchedEffect
1821
import androidx.compose.runtime.getValue
1922
import androidx.compose.runtime.mutableStateOf
2023
import androidx.compose.runtime.saveable.rememberSaveable
2124
import androidx.compose.runtime.setValue
2225
import androidx.compose.ui.Alignment
2326
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.platform.LocalContext
2428
import androidx.compose.ui.res.painterResource
2529
import androidx.compose.ui.res.stringResource
2630
import androidx.compose.ui.text.SpanStyle
@@ -29,22 +33,44 @@ import androidx.compose.ui.text.withStyle
2933
import androidx.compose.ui.tooling.preview.Preview
3034
import androidx.compose.ui.unit.dp
3135
import androidx.compose.ui.window.Dialog
36+
import androidx.hilt.navigation.compose.hiltViewModel
37+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3238
import com.texthip.thip.R
3339
import com.texthip.thip.ui.common.buttons.CheckboxButton
3440
import com.texthip.thip.ui.common.modal.DialogPopup
3541
import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar
42+
import com.texthip.thip.ui.mypage.viewmodel.DeleteAccountViewModel
3643
import com.texthip.thip.ui.theme.DarkGrey02
3744
import com.texthip.thip.ui.theme.Red
3845
import com.texthip.thip.ui.theme.ThipTheme.colors
3946
import com.texthip.thip.ui.theme.ThipTheme.typography
4047

4148
@Composable
4249
fun DeleteAccountScreen(
43-
onNavigateBack: () -> Unit
50+
onNavigateBack: () -> Unit,
51+
onNavigateToLogin: () -> Unit,
52+
viewModel: DeleteAccountViewModel = hiltViewModel()
4453
) {
54+
val context = LocalContext.current
55+
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
56+
4557
var isChecked by rememberSaveable { mutableStateOf(false) }
4658
val backgroundColor = if (isChecked) colors.Purple else colors.Grey02
4759
var isDialogVisible by rememberSaveable { mutableStateOf(false) }
60+
61+
// 회원탈퇴 완료 시 로그인 화면으로 이동
62+
LaunchedEffect(uiState.isDeleteCompleted) {
63+
if (uiState.isDeleteCompleted) {
64+
onNavigateToLogin()
65+
}
66+
}
67+
68+
// 에러 메시지 표시
69+
LaunchedEffect(uiState.errorMessage) {
70+
uiState.errorMessage?.let { message ->
71+
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
72+
}
73+
}
4874

4975
Column(
5076
Modifier
@@ -159,19 +185,30 @@ fun DeleteAccountScreen(
159185
onCancel = { isDialogVisible = false },
160186
onConfirm = {
161187
isDialogVisible = false
162-
// TODO: 회원탈퇴 로직
188+
viewModel.deleteAccount(context)
163189
}
164190
)
165191
}
166192
}
167193
}
194+
195+
// 로딩 중일 때 전체 화면에 로딩 인디케이터 표시
196+
if (uiState.isLoading) {
197+
Box(
198+
modifier = Modifier.fillMaxSize(),
199+
contentAlignment = Alignment.Center
200+
) {
201+
CircularProgressIndicator()
202+
}
203+
}
168204
}
169205
}
170206

171207
@Preview
172208
@Composable
173209
private fun DeleteAccountScreenPrev() {
174210
DeleteAccountScreen(
175-
onNavigateBack = {}
211+
onNavigateBack = {},
212+
onNavigateToLogin = {}
176213
)
177214
}

0 commit comments

Comments
 (0)