-
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
[PC-589] 매칭 상태 타이머 ui 적용 #71
Conversation
val valuePickQuestions = profileDataSource.loadValuePickQuestions() | ||
.getOrThrow() | ||
.toDomain() | ||
val valuePickQuestions = profileDataSource.loadValuePickQuestions().getOrThrow().toDomain() | ||
.filter { it.id != UNKNOWN_INT } | ||
|
||
localProfileDataSource.setValuePickQuestions(valuePickQuestions) | ||
} | ||
|
||
override suspend fun loadValueTalkQuestions(): Result<Unit> = suspendRunCatching { | ||
val valueTalkQuestions = profileDataSource.loadValueTalkQuestions() | ||
.getOrThrow() | ||
.toDomain() | ||
val valueTalkQuestions = profileDataSource.loadValueTalkQuestions().getOrThrow().toDomain() | ||
.filter { it.id != UNKNOWN_INT } |
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.
체이닝 메서드를 일렬로 만드신 이유가 있을까용?!
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.
줄정리하다가 자동으로 적용된 거 같아요!
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.
진혁님 고생하셨습니다!!!!!!!!
제가 강제 업데이트랑 탈퇴하기 API 연결해볼게요!!
코멘트 남긴거 반영해주시고 conflict 해결해주세요!!!!!!!!!
override suspend fun loadMyValueTalks(): Result<Unit> = suspendRunCatching { | ||
val valueTalks = profileDataSource.getMyValueTalks() | ||
.getOrThrow() | ||
.toDomain() | ||
val valueTalks = profileDataSource.getMyValueTalks().getOrThrow().toDomain() | ||
|
||
localProfileDataSource.setMyValueTalks(valueTalks) | ||
} | ||
|
||
override suspend fun retrieveMyValueTalks(): Result<List<MyValueTalk>> = | ||
suspendRunCatching { localProfileDataSource.myValueTalks.first() } | ||
override suspend fun retrieveMyValueTalks(): Result<List<MyValueTalk>> = suspendRunCatching { | ||
localProfileDataSource.myValueTalks.firstOrNull() ?: throw Exception() | ||
} | ||
|
||
override suspend fun loadMyValuePicks(): Result<Unit> = suspendRunCatching { | ||
val valuePicks = profileDataSource.getMyValuePicks() | ||
.getOrThrow() | ||
.toDomain() | ||
val valuePicks = profileDataSource.getMyValuePicks().getOrThrow().toDomain() | ||
|
||
localProfileDataSource.setMyValuePicks(valuePicks) | ||
} | ||
|
||
override suspend fun retrieveMyValuePicks(): Result<List<MyValuePick>> = | ||
suspendRunCatching { localProfileDataSource.myValuePicks.first() } | ||
suspendRunCatching { | ||
localProfileDataSource.myValuePicks.firstOrNull() ?: throw Exception() | ||
} |
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.
p2)
firstOrNull()을 하신 이유가 궁금해요!
아마도 DataStore 모듈 내부에서 제가 에러를 스로잉하고 있을거라서 기존 로직으로 두는게 좋을 것 같아요!
만약 에러를 명시하시려면 더 정확한 Exception과 에러 메세지가 필요할 것 같아요!
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.
아 usecase쪽으로 데이터가 안넘어와서 repository쪽 수정하다가 변경한건데 다시 돌려놓는걸 깜빡한 거 같아요! 수정해둘게요!!
override fun observeUserRole(): Flow<UserRole> = localUserDataSource.userRole.map { | ||
UserRole.create(it) | ||
} |
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.
p2)
override suspend fun getUserRole(): Result<UserRole> = suspendRunCatching {
val userRoleString = localUserDataSource.userRole.first()
UserRole.create(userRoleString)
}
getUserRole이라는 메서드가 있어서 불필요한 메서드인 것 같아요.
그리고 해당 데이터는 자주 변경되는 데이터가 아니라서 Stream으로 구독하면 오히려 불필요한 오버헤드인 것 같습니다.
일부로 Flow를 Repository에서 스트림을 끊고 원샷으로 내려준거였어요!
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.
그럼 userRole 갱신은 그냥 껐다가 켜야 할 수 있을 텐데 그렇게 해둘까요?
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.
그럼 userRole 갱신은 그냥 껐다가 켜야 할 수 있을 텐데 그렇게 해둘까요?
Stream이 필요한 화면이 있나요 ?!
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.
stream 없이 갱신할 수 잇을 거 같아요! 수정해둘게요!
result.getOrNull()?.let { rejectReason -> | ||
if (rejectReason.profileStatus == ProfileStatus.APPROVED) { | ||
localUserDataSource.setUserRole(UserRole.USER.name) | ||
} else { | ||
localUserDataSource.setUserRole(UserRole.PENDING.name) | ||
} | ||
} |
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.
null일 때의 처리가 없는데 혹시 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.
명세에는 null에 대한 처리는 없었어요! 그래서 일단 null이 아닐 때만 처리해두고 result 그대로 반환해서 viewmodel에서 errorHelper 로 에러 던져놨어요!
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.
아하, 그런거라면 getOrThrow()는 어떨까요?!
fun getRemainingTimeInSec(startTimeInSec: Long): Long { | ||
val startTimeInMillis = startTimeInSec * 1000 | ||
val zoneId = ZoneId.systemDefault() | ||
val now = ZonedDateTime.ofInstant(Instant.ofEpochMilli(startTimeInMillis), zoneId) | ||
val today10PM = now.withHour(22).withMinute(0).withSecond(0).withNano(0) | ||
val targetTime = if (now.isBefore(today10PM)) today10PM else today10PM.plusDays(1) | ||
return Duration.between(now, targetTime).seconds | ||
} |
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.
p3)
아마 이 부분은 서버에서 한국 TimeZone을 기준으로 돌아갈거라서 systemDefault보다는 Asia/Seoul 명시해주는 것이 좋을 것 같아요~~
1000은 SECOND
라는 상수로 TimeUitll 로 뺴면 좋을 것 같네용
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.
이 부분 로직이 많아서 테스트할만한 것 같은데 너무 조금 오래 걸리겠쭁 ...?!
22시 이전이면 금일 22시를 기준으로, 22시 이후면 다음 날 22시를 기준으로 남은 시간을 설정한다
fun isSmoke(): Boolean = if (smokingStatus == "흡연") true else false | ||
fun isSnsActive(): Boolean = if (snsActivityLevel == "활동") true else false | ||
fun isSmoke(): Boolean = smokingStatus == "흡연" | ||
fun isSnsActive(): Boolean = snsActivityLevel == "활동" |
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.
👍👍👍
data class GetRejectReasonResponse( | ||
val profileStatus: String, | ||
val reasonImage: Boolean, | ||
val reasonValues: Boolean, | ||
) { |
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.
p2)
여기도 다른 DTO처럼 Nullable로 받고 toDomain()에서 Default Value를 줘야할 것 같아요~
getOpponentProfileUseCase().onSuccess { response -> | ||
setState { | ||
copy(nickName = response.nickname) | ||
} | ||
}.onFailure { | ||
errorHelper.sendError(it) | ||
}.also { | ||
setState { copy(isLoading = false) } | ||
} |
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.
nickname만 필요한거라면 다른 네비게이션에서 argument로 들고오는 것은 어떨까요?
++ 만약 호출해야한다면 아래 getContacts()랑 동기적으로 호출해야할 이유가 없는 것 같아요!
launch{}로 감싸서 병렬적으로 호출해도 될 것 같네용
}.onFailure { | ||
if (it is HttpResponseException) { | ||
// 1. 회원가입하고 처음 매칭을 하는데 아직 오후 10시가 안되었을 때 | ||
// 2. 내가 차단했을 때 | ||
// 3. 상대방 아이디가 없어졌을 때 | ||
if (it.status == HttpResponseStatus.NotFound) { | ||
startWaitingTimer() | ||
} | ||
return@onFailure | ||
} | ||
|
||
errorHelper.sendError(it) |
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.
👍👍👍
val hours = totalSeconds / 3600 | ||
val minutes = (totalSeconds % 3600) / 60 | ||
val seconds = totalSeconds % 60 |
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.
p3)
매직 넘버 모두 TimeUitl에 상수화 하면 좋을 것 같아요~
withStyle(style = SpanStyle(color = PieceTheme.colors.subDefault)) { | ||
append("02:32:75") | ||
append(remainTime) |
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.
👍👍👍
private fun initContactInfo() = viewModelScope.launch { | ||
setState { copy(isLoading = true) } | ||
|
||
val opponentProfileDeferred = async { getOpponentProfileUseCase() } | ||
val opponentContactsDeferred = async { matchingRepository.getOpponentContacts() } | ||
|
||
opponentProfileDeferred.await().fold( | ||
onSuccess = { response -> | ||
setState { copy(nickName = response.nickname) } | ||
}, | ||
onFailure = { errorHelper.sendError(it) } | ||
) | ||
|
||
opponentContactsDeferred.await().fold( | ||
onSuccess = { response -> | ||
setState { | ||
copy( | ||
contacts = response, | ||
selectedContact = response.first() | ||
) | ||
} | ||
}, | ||
onFailure = { errorHelper.sendError(it) } | ||
) | ||
|
||
setState { copy(isLoading = false) } |
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.
p3)
조아요~~~ 이제 병렬로 호출되네요.
근데 이제 fold
를 쓰면 가독성이 좀 딸려서
마지막으로 아래와 같이 변경해주고 머지해주세요~~~~
private fun initContactInfo() = viewModelScope.launch {
setState { copy(isLoading = true) }
val opponentProfileDeferred = async {
getOpponentProfileUseCase().onSuccess { response ->
setState { copy(nickName = response.nickname) }
}.onFailure {
errorHelper.sendError(it)
}
}
val opponentContactsDeferred = async {
matchingRepository.getOpponentContacts().onSuccess { response ->
setState {
copy(
contacts = response,
selectedContact = response.first()
)
}
}.onFailure {
errorHelper.sendError(it)
}
}
opponentProfileDeferred.await()
opponentContactsDeferred.await()
setState { copy(isLoading = false) }
}
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.
앗차차 아래 코드가 더 좋을 것 같아요
private fun initContactInfo() = viewModelScope.launch {
setState { copy(isLoading = true) }
val opponentProfileJob = launch {
getOpponentProfileUseCase().onSuccess { response ->
setState { copy(nickName = response.nickname) }
}.onFailure {
errorHelper.sendError(it)
}
}
val opponentContactsJob = launch {
matchingRepository.getOpponentContacts().onSuccess { response ->
setState {
copy(
contacts = response,
selectedContact = response.first()
)
}
}.onFailure {
errorHelper.sendError(it)
}
}
opponentProfileJob.join()
opponentContactsJob.join()
setState { copy(isLoading = false) }
}
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.
👍👍👍👍
1. ⭐️ 변경된 내용
2. 🖼️ 스크린샷(선택)
3. 💡 알게된 부분
4. 📌 이 부분은 꼭 봐주세요!