Skip to content
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

[Fix/#871] 마이페이지 오류 수정 #907

Merged
merged 31 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b91142f
[fix/#871] remove logout responses
leeeyubin Sep 26, 2024
661e1b5
[fix/#871] delete LogOutResponse.kt
leeeyubin Sep 26, 2024
44b6727
[feature/#871] pull from develop
leeeyubin Sep 30, 2024
ec9c02d
[feature/#871] get Profile Message
leeeyubin Sep 30, 2024
749226f
[feature/#871] modify button enable condition
leeeyubin Sep 30, 2024
f6a3495
[feature/#871] modify button enable condition
leeeyubin Sep 30, 2024
9d9b32c
[feature/#871] git pull from develop
leeeyubin Oct 5, 2024
6270326
[feature/#871] git pull from develop
leeeyubin Oct 5, 2024
9eec6da
[feature/#871] make adjust sentence toast
leeeyubin Oct 6, 2024
70f077e
[feature/#871] delete mypage nickname view
leeeyubin Oct 7, 2024
eb25798
[feature/#871] make resetSoptamp success
leeeyubin Oct 10, 2024
7194eff
[feature/#871] add refreshToken empty function
leeeyubin Oct 10, 2024
2afdbfc
[feature/#871] modify login and logout logic
leeeyubin Oct 10, 2024
a994e4b
[feature/#871] change mypage state
leeeyubin Oct 12, 2024
880fb19
[feature/#871] delete delay function
leeeyubin Oct 12, 2024
eea9cc4
[feature/#871] git pull from develop
leeeyubin Oct 12, 2024
adf5d5b
[feature/#871] code refactoring
leeeyubin Oct 13, 2024
fdfaf0b
[feature/#871] code refactoring
leeeyubin Oct 13, 2024
b12835f
[feature/#871] git pull from develop
leeeyubin Oct 13, 2024
9b6b873
[feature/#871] MIT License
leeeyubin Oct 13, 2024
c487625
[feature/#871] change ui state
leeeyubin Oct 14, 2024
7746918
[feature/#871] rename onDismiss function
leeeyubin Oct 14, 2024
2f50399
[feature/#871] update 함수 사용
leeeyubin Oct 14, 2024
8dc7cac
[feature/#871] myPageState 변수명 수정
leeeyubin Oct 14, 2024
8bac4ac
[feature/#871] sealed class -> sealed interface
leeeyubin Oct 14, 2024
abd79f9
[feature/#871] 초기 한마디 변수명 수정
leeeyubin Oct 14, 2024
f8d30f3
[feature/#871] git pull from develop
leeeyubin Oct 15, 2024
482e355
[feature/#871] git pull from develop
leeeyubin Oct 17, 2024
8fd8527
[feature/#871] logout -> deleteUserInfo
leeeyubin Oct 17, 2024
6083cb9
[feature/#871] 타입 명시
leeeyubin Oct 17, 2024
e22c296
[feature/#871] License
leeeyubin Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@
android:name=".feature.mypage.signOut.SignOutActivity"
android:exported="false"
android:theme="@style/Theme.SOPT" />
<activity
android:name=".feature.mypage.soptamp.nickName.ChangeNickNameActivity"
android:exported="false"
android:theme="@style/Theme.SOPT" />
<activity
android:name=".feature.mypage.soptamp.sentence.AdjustSentenceActivity"
android:exported="false"
Expand Down
1,799 changes: 21 additions & 1,778 deletions app/src/release/generated/baselineProfiles/baseline-prof.txt

Large diffs are not rendered by default.

1,799 changes: 21 additions & 1,778 deletions app/src/release/generated/baselineProfiles/startup-prof.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ package org.sopt.official.auth.impl.api

import org.sopt.official.auth.impl.model.request.AuthRequest
import org.sopt.official.auth.impl.model.response.LogOutRequest
import org.sopt.official.auth.impl.model.response.LogOutResponse
import org.sopt.official.network.model.response.AuthResponse
import retrofit2.http.Body
import retrofit2.http.DELETE
Expand All @@ -41,5 +40,5 @@ interface AuthService {
suspend fun withdraw()

@HTTP(method = "DELETE", path = "user/logout", hasBody = true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 그냥 궁금한건데 Delete 어노테이션과 차이가 있나요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete에 body 값이 안들어가는게 원칙인데 굳이 넣어줘야할 때에는 이렇게 사용하는걸로 알고 있음

Copy link
Member

@l2hyunwoo l2hyunwoo Oct 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저거 무시하고 그냥 body 패러미터 넣으면 에러 일으킴ㅋㅋㅋ

그래서 원칙적으로는

  1. 서버한테 바디 패러미터 빼달라고 하거나
  2. 저렇게 사용하거나

인데 난 갠적으로 1로 쇼부치는게 더 깔끔하다고 생각하긴함. (정 안되면 2번)

Copy link
Contributor

@s9hn s9hn Oct 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오.. 신기하네 하나 알아갑니다. 저도 같은이유라면 서버에게 요청하고 안되면 뭐 2번해야쥬

suspend fun logOut(@Body body: LogOutRequest): LogOutResponse
suspend fun deleteUserInfo(@Body body: LogOutRequest)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ package org.sopt.official.auth.impl.remote
import javax.inject.Inject
import org.sopt.official.auth.impl.api.AuthService
import org.sopt.official.auth.impl.model.response.LogOutRequest
import org.sopt.official.auth.impl.model.response.LogOutResponse
import org.sopt.official.auth.impl.source.RemoteAuthDataSource
import org.sopt.official.common.di.Auth
import org.sopt.official.network.model.request.RefreshRequest
Expand All @@ -46,7 +45,7 @@ class DefaultRemoteAuthDataSource @Inject constructor(
authService.withdraw()
}

override suspend fun logout(request: LogOutRequest): LogOutResponse {
return authService.logOut(request)
override suspend fun deleteUserInfo(request: LogOutRequest) {
authService.deleteUserInfo(request)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class AuthRepositoryImpl @Inject constructor(
remoteAuthDataSource.withdraw()
}

override suspend fun logout(pushToken: String): Result<Unit> = runCatching {
remoteAuthDataSource.logout(
override suspend fun logout(pushToken: String) = runCatching {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

토큰은 로컬 저장소에 저장 및 관리되고 있고 로그아웃은 무조건 본인의 토큰만을 보낼 것 같은데 파라미터로 받는 이유가 있으신가요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushToken을 파라미터로 받을 이유가 없다는 말씀이신가요..?!
로그아웃 로직을 살펴보니 기존 코드는 파이어베이스에서 pushToken을 가져와 파라미터로 넣어주고 있는 것 같습니다.
파이어베이스에 저장되어 있는 토큰과 로컬 저장소에 저장되어 있는 토큰이 차이점이 있을까요.........?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 저도 실제 사용처 찾아보니 파이어베이스 토큰을 호출해서 넣어주고 있었네요.
아마 유빈님이 작성하신 코드는 아닌 것으로 보이는데 뷰모델에서 런캐칭으로 Firebase의 토큰을 호출해주고 다음 logout함수에 전달해주고 있는 것 같아요.
저라면 Firebase에서 토큰을 가져오는 행위를 뷰모델에서 하지 않았을 것 같아요.
해당 코드는 레거시 코드이니 이번 PR에서 리팩터링 하실지는 선택에 맡기겠습니다 :)

remoteAuthDataSource.deleteUserInfo(
LogOutRequest(
platform = "Android",
pushToken = pushToken
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@
package org.sopt.official.auth.impl.source

import org.sopt.official.auth.impl.model.response.LogOutRequest
import org.sopt.official.auth.impl.model.response.LogOutResponse
import org.sopt.official.network.model.request.RefreshRequest
import org.sopt.official.network.model.response.AuthResponse

interface RemoteAuthDataSource {
suspend fun refresh(token: RefreshRequest): AuthResponse
suspend fun withdraw()
suspend fun logout(request: LogOutRequest): LogOutResponse
suspend fun deleteUserInfo(request: LogOutRequest)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ package org.sopt.official.network.authenticator
import android.content.Context
import com.jakewharton.processphoenix.ProcessPhoenix
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.runBlocking
import okhttp3.Authenticator
import okhttp3.Request
Expand All @@ -39,6 +37,8 @@ import org.sopt.official.network.model.request.RefreshRequest
import org.sopt.official.network.persistence.SoptDataStore
import org.sopt.official.network.service.RefreshService
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class SoptAuthenticator @Inject constructor(
Expand All @@ -50,6 +50,7 @@ class SoptAuthenticator @Inject constructor(
override fun authenticate(route: Route?, response: Response): Request? {
if (response.code == 401) {
val refreshToken = dataStore.refreshToken
if (refreshToken.isEmpty()) return null
val newTokens = runCatching {
runBlocking {
refreshService.refresh(RefreshRequest(refreshToken))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* MIT License
* Copyright 2024 SOPT - Shout Our Passion Together
* Copyright 2023-2024 SOPT - Shout Our Passion Together
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
package org.sopt.official.feature.mypage.model

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable

@Stable
sealed interface MyPageUiModel {
@Immutable
data class Header(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,21 @@
*/
package org.sopt.official.feature.mypage.model

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import org.sopt.official.auth.model.UserActiveState
import org.sopt.official.feature.mypage.mypage.MyPageAction

@Stable
sealed interface MyPageUiState {

@Immutable
data object UnInitialized : MyPageUiState
data class User(val activeState: UserActiveState) : MyPageUiState
data class Dialog(val action: MyPageAction) : MyPageUiState

@Immutable
data class Authenticated(
val activeState: UserActiveState,
) : MyPageUiState

@Immutable
data object UnAuthenticated : MyPageUiState
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import com.jakewharton.processphoenix.ProcessPhoenix
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.collections.immutable.persistentListOf
import org.sopt.official.auth.model.UserActiveState
Expand Down Expand Up @@ -84,8 +83,8 @@ class MyPageActivity : AppCompatActivity() {
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current

val isAuthenticated by viewModel.userActiveState.collectAsStateWithLifecycle(initialValue = false)
val dialogState by viewModel.dialogState.collectAsStateWithLifecycle()
val myPageState by viewModel.state.collectAsStateWithLifecycle()
val myPageAction by viewModel.action.collectAsStateWithLifecycle()
val scrollState = rememberScrollState()

val serviceSectionItems = remember {
Expand Down Expand Up @@ -156,34 +155,25 @@ class MyPageActivity : AppCompatActivity() {
MyPageUiModel.MyPageItem(
title = "로그인",
onItemClick = {
onBackPressedDispatcher.onBackPressed()
startActivity(navigatorProvider.getAuthActivityIntent())
}
)
)
}

LaunchedEffect(Unit) {
args?.userActiveState?.let {
viewModel.setUserActiveState(MyPageUiState.User(it))
viewModel.setUserActiveState(it)
}
}

LaunchedEffect(viewModel.finish, lifecycleOwner) {
viewModel.finish.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect {
ProcessPhoenix.triggerRebirth(context, navigatorProvider.getAuthActivityIntent())
startActivity(navigatorProvider.getAuthActivityIntent())
}
}

if (dialogState is MyPageUiState.Dialog) {
ShowMyPageDialog(
action = (dialogState as MyPageUiState.Dialog).action,
onDismissRequest = viewModel::onDismiss,
onClearSoptampClick = viewModel::resetSoptamp,
onLogoutClick = viewModel::logOut
)
}

Scaffold(modifier = Modifier
.background(SoptTheme.colors.background)
.fillMaxSize(),
Expand All @@ -204,17 +194,31 @@ class MyPageActivity : AppCompatActivity() {
Spacer(modifier = Modifier.height(20.dp))
MyPageSection(items = serviceSectionItems)
Spacer(modifier = Modifier.height(16.dp))
if (isAuthenticated) {
MyPageSection(items = notificationSectionItems)
Spacer(modifier = Modifier.height(16.dp))
MyPageSection(items = soptampSectionItems)
Spacer(modifier = Modifier.height(16.dp))
MyPageSection(items = etcSectionItems)
} else {
MyPageSection(items = etcLoginSectionItems)
when (myPageState) {
is MyPageUiState.Authenticated -> {
MyPageSection(items = notificationSectionItems)
Spacer(modifier = Modifier.height(16.dp))
MyPageSection(items = soptampSectionItems)
Spacer(modifier = Modifier.height(16.dp))
MyPageSection(items = etcSectionItems)
}

is MyPageUiState.UnAuthenticated -> {
MyPageSection(items = etcLoginSectionItems)
}

is MyPageUiState.UnInitialized -> {}
}
Spacer(modifier = Modifier.height(32.dp))
}
if (myPageAction != null) {
ShowMyPageDialog(
action = myPageAction ?: return@Scaffold,
onDismissRequest = viewModel::closeDialog,
onClearSoptampClick = viewModel::resetSoptamp,
onLogoutClick = viewModel::logOut
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import org.sopt.official.auth.model.UserActiveState
Expand All @@ -54,18 +53,20 @@ class MyPageViewModel @Inject constructor(
private val stampRepository: StampRepository,
) : ViewModel() {

private val _userActiveState = MutableStateFlow<MyPageUiState>(MyPageUiState.UnInitialized)
val userActiveState = _userActiveState.filterIsInstance<MyPageUiState.User>()
.map { it.activeState != UserActiveState.UNAUTHENTICATED }
private val _state: MutableStateFlow<MyPageUiState> = MutableStateFlow(MyPageUiState.UnInitialized)
val state: StateFlow<MyPageUiState> = _state.asStateFlow()

private val _dialogState: MutableStateFlow<MyPageUiState> = MutableStateFlow(MyPageUiState.UnInitialized)
val dialogState: StateFlow<MyPageUiState> = _dialogState.asStateFlow()
private val _action = MutableStateFlow<MyPageAction?>(null)
val action: StateFlow<MyPageAction?> = _action.asStateFlow()

private val _finish = Channel<Unit>()
val finish = _finish.receiveAsFlow()

fun setUserActiveState(new: MyPageUiState) {
_userActiveState.value = new
fun setUserActiveState(activeState: UserActiveState) {
_state.update {
if (activeState == UserActiveState.UNAUTHENTICATED) MyPageUiState.UnAuthenticated
else MyPageUiState.Authenticated(activeState)
}
}

fun logOut() {
Expand All @@ -87,16 +88,16 @@ class MyPageViewModel @Inject constructor(
fun resetSoptamp() {
viewModelScope.launch {
stampRepository.deleteAllStamps()
.onSuccess { closeDialog() }
.onFailure { Timber.e(it) }
}
}

fun showDialogState(action: MyPageAction) {
_dialogState.tryEmit(MyPageUiState.Dialog(action))
_action.update { action }
}

fun onDismiss() {
_dialogState.tryEmit(MyPageUiState.UnInitialized)
fun closeDialog() {
_action.update { null }
}

}

This file was deleted.

Loading