-
Notifications
You must be signed in to change notification settings - Fork 7
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
[Feature/#875] fortune amulet TodayFortuneCard API #876
base: feature/873
Are you sure you want to change the base?
Changes from 4 commits
4054429
943f65b
6d0a46c
ec88717
a636466
e12c749
b7c1897
af5b437
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,11 @@ | ||
package org.sopt.official.domain.fortune.usecase | ||
|
||
import org.sopt.official.domain.fortune.model.TodayFortuneCard | ||
import org.sopt.official.domain.fortune.repository.FortuneRepository | ||
import javax.inject.Inject | ||
|
||
class GetTodayFortuneCardUseCase @Inject constructor( | ||
private val fortuneRepository: FortuneRepository, | ||
) { | ||
suspend operator fun invoke(): TodayFortuneCard = fortuneRepository.fetchTodayFortuneCard() | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -26,52 +26,74 @@ package org.sopt.official.feature.fortune.feature.fortuneAmulet | |||||
|
||||||
import androidx.compose.foundation.background | ||||||
import androidx.compose.foundation.layout.Column | ||||||
import androidx.compose.foundation.layout.PaddingValues | ||||||
import androidx.compose.foundation.layout.Spacer | ||||||
import androidx.compose.foundation.layout.fillMaxHeight | ||||||
import androidx.compose.foundation.layout.fillMaxSize | ||||||
import androidx.compose.foundation.layout.fillMaxWidth | ||||||
import androidx.compose.foundation.layout.height | ||||||
import androidx.compose.foundation.layout.padding | ||||||
import androidx.compose.material3.Text | ||||||
import androidx.compose.runtime.Composable | ||||||
import androidx.compose.runtime.getValue | ||||||
import androidx.compose.ui.Alignment | ||||||
import androidx.compose.ui.Modifier | ||||||
import androidx.compose.ui.graphics.Color | ||||||
import androidx.compose.ui.text.SpanStyle | ||||||
import androidx.compose.ui.text.buildAnnotatedString | ||||||
import androidx.compose.ui.text.withStyle | ||||||
import androidx.compose.ui.tooling.preview.Preview | ||||||
import androidx.compose.ui.unit.dp | ||||||
import androidx.hilt.navigation.compose.hiltViewModel | ||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||||||
import org.sopt.official.designsystem.SoptTheme | ||||||
import org.sopt.official.feature.fortune.component.CircleShapeBorderButton | ||||||
import org.sopt.official.feature.fortune.component.UrlImage | ||||||
|
||||||
@Composable | ||||||
internal fun FortuneAmuletRoute( | ||||||
paddingValue: PaddingValues, | ||||||
navigateToHome: () -> Unit, | ||||||
viewModel: FortuneAmuletViewModel = hiltViewModel(), | ||||||
) { | ||||||
FortuneAmuletScreen( | ||||||
paddingValue = paddingValue, | ||||||
navigateToHome = navigateToHome | ||||||
) | ||||||
val state by viewModel.state.collectAsStateWithLifecycle() | ||||||
|
||||||
when { | ||||||
state.isLoading -> { | ||||||
// Loading View | ||||||
} | ||||||
Comment on lines
+60
to
+62
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. 오버레이 깔고 서클 로딩 인디케이터 도는게 제일 이상적일듯? 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. 저도 그렇게 생각합니다! |
||||||
|
||||||
state.isFailure -> { | ||||||
// Error View | ||||||
} | ||||||
|
||||||
else -> { | ||||||
FortuneAmuletScreen( | ||||||
description = state.description, | ||||||
name = state.name, | ||||||
imageColor = state.imageColor, | ||||||
imageUrl = state.imageUrl, | ||||||
navigateToHome = navigateToHome | ||||||
) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
@Composable | ||||||
private fun FortuneAmuletScreen( | ||||||
paddingValue: PaddingValues, | ||||||
description: String, | ||||||
name: String, | ||||||
imageColor: Color, | ||||||
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. 선생님 이게 뭘까요? 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.
Suggested change
카드 설명 텍스트를 이렇게 description으로 받아와서 그리는 방법도 있을 것 같아요. 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. 확장성을 생각한 조언 감사합니다! |
||||||
imageUrl: String, | ||||||
navigateToHome: () -> Unit, | ||||||
) { | ||||||
Column( | ||||||
modifier = Modifier | ||||||
.padding(paddingValue) | ||||||
.fillMaxSize() | ||||||
.background(SoptTheme.colors.background), | ||||||
horizontalAlignment = Alignment.CenterHorizontally | ||||||
) { | ||||||
Spacer(modifier = Modifier.height(12.dp)) | ||||||
|
||||||
Text( | ||||||
text = "어려움을 전부 극복할", // 서버에서 받아온 텍스트 | ||||||
text = description, | ||||||
style = SoptTheme.typography.title16SB, | ||||||
color = SoptTheme.colors.onSurface300, | ||||||
) | ||||||
|
@@ -80,8 +102,8 @@ private fun FortuneAmuletScreen( | |||||
|
||||||
Text( | ||||||
text = buildAnnotatedString { | ||||||
withStyle(style = SpanStyle(color = SoptTheme.colors.attention /* 서버에서 받아온 색상 */)) { | ||||||
append("해결부적") // 서버에서 받아온 텍스트 | ||||||
withStyle(style = SpanStyle(color = imageColor)) { | ||||||
append(name) | ||||||
} | ||||||
withStyle(style = SpanStyle(color = SoptTheme.colors.onBackground)) { | ||||||
append("이 왔솝") | ||||||
|
@@ -92,11 +114,11 @@ private fun FortuneAmuletScreen( | |||||
Spacer(modifier = Modifier.height(34.dp)) | ||||||
|
||||||
UrlImage( | ||||||
url = "https://어쩌구저쩌구/test_fortune_card.png", // 서버에서 받아온 이미지 | ||||||
url = imageUrl, | ||||||
contentDescription = null, | ||||||
modifier = Modifier | ||||||
.padding(horizontal = 33.dp) | ||||||
.fillMaxHeight(0.55f) | ||||||
.fillMaxWidth() | ||||||
) | ||||||
|
||||||
Spacer(modifier = Modifier.weight(1f)) | ||||||
|
@@ -122,7 +144,10 @@ private fun FortuneAmuletScreen( | |||||
fun PreviewFortuneAmuletScreen() { | ||||||
SoptTheme { | ||||||
FortuneAmuletScreen( | ||||||
paddingValue = PaddingValues(16.dp), | ||||||
description = "배고픔을 전부 극복할", | ||||||
name = "맛집부적", | ||||||
imageColor = Color.Blue, | ||||||
imageUrl = "https://sopt-makers.s3.ap-northeast-2.amazonaws.com/mainpage/makers-app-img/test_fortune_card.png", | ||||||
navigateToHome = {} | ||||||
) | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.sopt.official.feature.fortune.feature.fortuneAmulet | ||
|
||
import androidx.compose.ui.graphics.Color | ||
|
||
data class FortuneAmuletState( | ||
val isLoading: Boolean = false, | ||
val isFailure: Boolean = false, | ||
val description: String = "", | ||
val imageColor: Color = Color.White, | ||
val imageUrl: String = "", | ||
val name: String = "", | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.sopt.official.feature.fortune.feature.fortuneAmulet | ||
|
||
import androidx.compose.ui.graphics.Color | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.flow.update | ||
import kotlinx.coroutines.launch | ||
import org.sopt.official.domain.fortune.usecase.GetTodayFortuneCardUseCase | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
internal class FortuneAmuletViewModel @Inject constructor( | ||
getTodayFortuneCardUseCase: GetTodayFortuneCardUseCase, | ||
) : ViewModel() { | ||
private val _state: MutableStateFlow<FortuneAmuletState> = MutableStateFlow(FortuneAmuletState()) | ||
val state: StateFlow<FortuneAmuletState> = _state.asStateFlow() | ||
|
||
init { | ||
viewModelScope.launch { | ||
runCatching { | ||
_state.value = _state.value.copy(isLoading = true) | ||
getTodayFortuneCardUseCase() | ||
}.onSuccess { todayFortuneCard -> | ||
_state.update { | ||
it.copy( | ||
description = todayFortuneCard.description, | ||
imageColor = parseColor(todayFortuneCard.imageColorCode), | ||
imageUrl = todayFortuneCard.imageUrl, | ||
name = todayFortuneCard.name, | ||
isLoading = false | ||
) | ||
} | ||
}.onFailure { | ||
_state.value = _state.value.copy(isFailure = true) | ||
} | ||
} | ||
} | ||
|
||
private fun parseColor(colorCode: String): Color { | ||
val color: Color = try { | ||
Color(android.graphics.Color.parseColor(colorCode)) | ||
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. typealias 써보는건 어떨지? 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. 오호 이건 생각을 못해본 방법이네요! |
||
} catch (e: IllegalArgumentException) { | ||
Color.White | ||
} | ||
|
||
return color | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -29,7 +29,6 @@ import androidx.compose.foundation.background | |||||
import androidx.compose.foundation.clickable | ||||||
import androidx.compose.foundation.layout.Box | ||||||
import androidx.compose.foundation.layout.Column | ||||||
import androidx.compose.foundation.layout.PaddingValues | ||||||
import androidx.compose.foundation.layout.Spacer | ||||||
import androidx.compose.foundation.layout.fillMaxSize | ||||||
import androidx.compose.foundation.layout.fillMaxWidth | ||||||
|
@@ -38,7 +37,7 @@ import androidx.compose.foundation.layout.padding | |||||
import androidx.compose.foundation.shape.RoundedCornerShape | ||||||
import androidx.compose.material3.Text | ||||||
import androidx.compose.runtime.Composable | ||||||
import androidx.compose.runtime.remember | ||||||
import androidx.compose.runtime.saveable.rememberSaveable | ||||||
import androidx.compose.ui.Alignment | ||||||
import androidx.compose.ui.Modifier | ||||||
import androidx.compose.ui.draw.clip | ||||||
|
@@ -55,13 +54,11 @@ import java.util.Locale | |||||
|
||||||
@Composable | ||||||
internal fun HomeRoute( | ||||||
paddingValue: PaddingValues, | ||||||
navigateToFortuneDetail: (String) -> Unit, | ||||||
) { | ||||||
val date = remember { getTodayInfo() } | ||||||
val date = rememberSaveable { getTodayInfo() } | ||||||
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.
Suggested change
이건 어떤가요? 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. 좋은거 같습니다! |
||||||
|
||||||
HomeScreen( | ||||||
paddingValue = paddingValue, | ||||||
date = date, | ||||||
navigateToFortuneDetail = { | ||||||
navigateToFortuneDetail(date) | ||||||
|
@@ -71,13 +68,11 @@ internal fun HomeRoute( | |||||
|
||||||
@Composable | ||||||
private fun HomeScreen( | ||||||
paddingValue: PaddingValues, | ||||||
date: String, | ||||||
navigateToFortuneDetail: () -> Unit = {}, | ||||||
) { | ||||||
Column( | ||||||
modifier = Modifier | ||||||
.padding(paddingValue) | ||||||
.fillMaxSize() | ||||||
.background(SoptTheme.colors.background), | ||||||
horizontalAlignment = Alignment.CenterHorizontally | ||||||
|
@@ -156,7 +151,6 @@ fun getTodayInfo(): String { | |||||
fun HomeScreenPreview() { | ||||||
SoptTheme { | ||||||
HomeScreen( | ||||||
paddingValue = PaddingValues(0.dp), | ||||||
date = getTodayInfo() | ||||||
) | ||||||
} | ||||||
|
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.
단순히 데이터만 패스하는 경우엔 유즈케이스까진 필요 없어보여요 :)