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

Middle qa #22

Merged
merged 11 commits into from
Apr 11, 2024
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion app/src/main/java/univ/earthbreaker/namu/data/ApiFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import univ.earthbreaker.namu.data.service.GrowService
import univ.earthbreaker.namu.data.service.HomeService
import univ.earthbreaker.namu.data.service.MissionService
import univ.earthbreaker.namu.data.service.OpenAIApiService
import java.util.concurrent.TimeUnit

object ApiFactory {
@OptIn(ExperimentalSerializationApi::class)
Expand All @@ -31,7 +32,7 @@ object ApiFactory {
level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
},
).build()
).connectTimeout(10, TimeUnit.MINUTES).readTimeout(10, TimeUnit.MINUTES).build()
}

val retrofitForGrowTreeServer: Retrofit by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import univ.earthbreaker.namu.domain.repository.GrowRepository
import univ.earthbreaker.namu.domain.type.character.CharacterLevel
import univ.earthbreaker.namu.domain.type.character.CharacterType
import univ.earthbreaker.namu.domain.type.grow.GrowCharacterResult
import univ.earthbreaker.namu.util.getErrorMessage
import univ.earthbreaker.namu.util.extension.getErrorMessage

class GrowCharacterUseCase(private val growRepository: GrowRepository = GrowRepositoryImpl()) {
suspend operator fun invoke(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fun CharacterDetailDialog(
AsyncImage(
model = characterDetailDialogState.characterImageURL,
contentDescription = characterDetailDialogState.characterName,
modifier = Modifier.padding(top = 20.dp),
modifier = Modifier.padding(top = 40.dp),
)
Spacer(modifier = Modifier.height(14.dp))
GenderCard(isMale = characterDetailDialogState.isMale)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import univ.earthbreaker.namu.ToFinalCharacterUiModel
import univ.earthbreaker.namu.ToHomeUiModel
import univ.earthbreaker.namu.feature.home.HomeActivity
import univ.earthbreaker.namu.ui.theme.GTTheme
import univ.earthbreaker.namu.util.finishSafely
import univ.earthbreaker.namu.util.extension.finishSafely

class FinalCharacterActivity : ComponentActivity() {
private val viewModel: FinalCharacterViewModel by viewModels()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import univ.earthbreaker.namu.feature.character.growfinal.model.FinalCharacterActions
import univ.earthbreaker.namu.feature.character.growfinal.model.FinalCharacterUiState
import univ.earthbreaker.namu.feature.home.HomeLoadingScreen

@Composable
fun FinalCharacterRoute() {
Expand All @@ -19,7 +18,7 @@ fun FinalCharacterRoute() {
// UI Rendering
when (uiState) {
FinalCharacterUiState.Error -> {}
FinalCharacterUiState.Loading -> HomeLoadingScreen()
FinalCharacterUiState.Loading -> {}
is FinalCharacterUiState.Success -> FinalCharacterScreen(
state = uiState as FinalCharacterUiState.Success,
actions = rememberFinalCharacterActions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ class FinalCharacterViewModel : ViewModel() {
private val _navigateToHome: MutableSharedFlow<Unit> = MutableSharedFlow()
val navigateToHome: SharedFlow<Unit> = _navigateToHome.asSharedFlow()

init {
viewModelScope.launch {
_finalCharacterUiStateFlow.emit(
FinalCharacterUiState.Success(
finalCharacterInfo = FinalCharacterInfo(
backgroundImageURL = "https://namu-bucket.s3.ap-northeast-2.amazonaws.com/default-character/admin_ddf95620-b7b3-482c-836c-aaf0251e28f8_sinensis-bg.png",
characterImageURL = "https://namu-bucket.s3.ap-northeast-2.amazonaws.com/default-character/admin_d6bc4178-b6f5-4bba-b4b2-91aec66e2938_sinensis.png",
messages = listOf("hello", "world"),
characterNo = 0,
),
messageIndex = messageIndex,
),
)
}
}

private fun updateUiState() {
viewModelScope.launch {
_finalCharacterUiStateFlow.emit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import univ.earthbreaker.namu.ToFinalCharacterUiModel
import univ.earthbreaker.namu.feature.character.growfinal.FinalCharacterActivity
import univ.earthbreaker.namu.ui.theme.GTTheme
import univ.earthbreaker.namu.util.ContentUriRequestBody
import univ.earthbreaker.namu.util.finishSafely
import univ.earthbreaker.namu.util.getBase64FromUri
import univ.earthbreaker.namu.util.extension.finishSafely
import univ.earthbreaker.namu.util.extension.getBase64FromUri

class HomeActivity : ComponentActivity() {
private val viewModel: HomeViewModel by viewModels()
Expand Down Expand Up @@ -50,7 +50,7 @@ class HomeActivity : ComponentActivity() {

setContent {
GTTheme {
HomeRoute(viewModel = viewModel, onClickCameraIcon = {
HomeRoute(onClickCameraIcon = {
pickMedia.launch(
PickVisualMediaRequest(PickVisualMedia.ImageOnly),
)
Expand Down

This file was deleted.

28 changes: 22 additions & 6 deletions app/src/main/java/univ/earthbreaker/namu/feature/home/HomeRoute.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,35 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import univ.earthbreaker.namu.feature.home.model.HomeActions
import univ.earthbreaker.namu.feature.home.model.HomeUiState
import univ.earthbreaker.namu.feature.loading.LoadingActions
import univ.earthbreaker.namu.feature.loading.LoadingScreen
import univ.earthbreaker.namu.feature.loading.LoadingViewModel

@Composable
fun HomeRoute(
viewModel: HomeViewModel = viewModel(),
onClickCameraIcon: () -> Unit,
) {
val homeViewModel: HomeViewModel = viewModel()
val loadingViewModel: LoadingViewModel = viewModel()

// State observing and declarations
val uiState by viewModel.homeUiStateFlow.collectAsStateWithLifecycle()
val homeUiState by homeViewModel.homeUiStateFlow.collectAsStateWithLifecycle()

val loadingContent by loadingViewModel.loadingContent.collectAsStateWithLifecycle()

// UI Rendering
when (uiState) {
when (homeUiState) {
HomeUiState.Loading -> {
HomeLoadingScreen()
LoadingScreen(loadingContent, rememberLoadingActions(loadingViewModel))
}

HomeUiState.Error -> {
}

is HomeUiState.Success -> {
HomeScreen(
state = uiState as HomeUiState.Success,
actions = rememberHomeActions(viewModel, onClickCameraIcon = onClickCameraIcon),
state = homeUiState as HomeUiState.Success,
actions = rememberHomeActions(homeViewModel, onClickCameraIcon = onClickCameraIcon),
)
}
}
Expand All @@ -52,3 +59,12 @@ fun rememberHomeActions(viewModel: HomeViewModel, onClickCameraIcon: () -> Unit)
)
}
}

@Composable
fun rememberLoadingActions(viewModel: LoadingViewModel): LoadingActions {
return remember(viewModel) {
LoadingActions(
generateNewLoadingContent = viewModel::getNewLoadingContent,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ class HomeViewModel(

fun growCharacter(characterType: CharacterType) {
viewModelScope.launch {
_homeUiStateFlow.emit(HomeUiState.Loading)

val growCharacterFlow = growCharacterUseCase(
characterLevel = homeInfo.characterLevel,
characterType = characterType,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package univ.earthbreaker.namu.feature.loading

data class LoadingActions(
val generateNewLoadingContent: () -> Unit,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package univ.earthbreaker.namu.feature.loading

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
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.foundation.shape.RoundedCornerShape
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.paint
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import univ.earthbreaker.namu.R
import univ.earthbreaker.namu.compose.noRippleClickable
import univ.earthbreaker.namu.ui.theme.GTTheme

@Composable
fun LoadingScreen(loadingContent: LoadingContent, actions: LoadingActions) {
Box(
modifier = Modifier
.fillMaxSize()
.background(color = GTTheme.colors.bgBlack)
.paint(
painter = painterResource(id = R.drawable.img_background),
contentScale = ContentScale.Crop,
),
contentAlignment = Alignment.Center,
) {
Column(modifier = Modifier.padding(horizontal = 20.dp)) {
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.height(7.dp)
.padding(horizontal = 10.dp)
.clip(shape = RoundedCornerShape(30.dp)),
color = GTTheme.colors.green1,
trackColor = GTTheme.colors.green2,
)
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(
color = GTTheme.colors.white,
shape = RoundedCornerShape(15.dp),
)
.padding(horizontal = 38.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.height(30.dp))
Text(
loadingContent.title,
style = GTTheme.typography.titleSemiBold16,
color = GTTheme.colors.gray8,
)
Spacer(modifier = Modifier.height(50.dp))
Text(
loadingContent.description,
style = GTTheme.typography.detailMedium14,
color = GTTheme.colors.gray6,
)
Spacer(modifier = Modifier.height(30.dp))
Box(
modifier = Modifier
.background(color = GTTheme.colors.green2, RoundedCornerShape(10.dp))
.padding(10.dp)
.noRippleClickable(onClick = actions.generateNewLoadingContent),
) {
Text(
"또 다른 내용 알아보기",
style = GTTheme.typography.detailMedium14,
color = GTTheme.colors.green1,
)
}
Spacer(modifier = Modifier.height(40.dp))
}
}
}
}

@Preview
@Composable
private fun HomeLoadingScreenPreview() {
LoadingScreen(
loadingContent = LoadingContent(
title = "대나무는 나무일까 풀일까?",
description = "사람들이 대나무를 일반적인 나무로 생각하기 쉽지만, 엄밀히 말해 대나무는 나무가 아니다." +
" 대나무는 오래 살고 줄기가 단단해 얼핏 나무로 보이지만, 부피생장을 하지 않고 속이 비어 있다는 점에서 풀에 가깝다.\n" +
"대나무는 생장하기 시작한 후 수십 일 동안 자라고는 더 이상 굵어지지 않고 굳어지기만 한다. 풀줄기가 딱딱해지는 것이다.",
),
actions = LoadingActions { },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package univ.earthbreaker.namu.feature.loading

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class LoadingViewModel : ViewModel() {
private val _loadingContent: MutableStateFlow<LoadingContent> =
MutableStateFlow(RandomLoadingContentGenerator.generateRandomContent())
val loadingContent: StateFlow<LoadingContent> = _loadingContent.asStateFlow()

fun getNewLoadingContent() {
viewModelScope.launch {
_loadingContent.emit(RandomLoadingContentGenerator.generateRandomContent(without = loadingContent.value))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package univ.earthbreaker.namu.feature.loading

object RandomLoadingContentGenerator {
private val loadingContentList: List<LoadingContent> = listOf(
LoadingContent(
title = "대나무는 나무일까 풀일까?",
description = "사람들이 대나무를 일반적인 나무로 생각하기 쉽지만, 엄밀히 말해 대나무는 나무가 아니다." +
" 대나무는 오래 살고 줄기가 단단해 얼핏 나무로 보이지만, 부피생장을 하지 않고 속이 비어 있다는 점에서 풀에 가깝다.\n" +
"대나무는 생장하기 시작한 후 수십 일 동안 자라고는 더 이상 굵어지지 않고 굳어지기만 한다. 풀줄기가 딱딱해지는 것이다.",
),
LoadingContent(
title = "세상에서 가장 키가 큰 나무",
description = "미국의 나무 Hyperion은 현재 살아있는 나무 중 세계에서 가장 키가 큰 나무로, " +
"미국 캘리포니아주 레드우드 국립공원에 있는 세쿼이아이다. 높이가 약 115.61m(379.3피트), 나이는 600년으로 추정되며, " +
"보통 세쿼이아의 수명이 1200년에서 2200년 정도인 것을 볼 때, 아직 아기라고 볼 수 있다.",
),
LoadingContent(
title = "은행나무는 암수 구별이 가능하다 ?!",
description = "은행나무는 암나무와 숫나무가 있다. 이는 앞사귀, 가지 모양, 꽃 모양, 열매의 유무 등의 차이점으로 구분할 수 있다." +
" 예를 들면 열매가 열린 나무는 암그루, 열리지 않으면 수그루로 구별할 수 있다.",
),
LoadingContent(
title = "재산을 가지고 세금을 내는 나무",
description = "예천군에 있는 소나무인 석송령은 인격이 부여된 특이한 존재로 재산을 가지고 재산세를 납부하고 있다.\n" +
"전설에 따르면 이 소나무는 약 600년 전 홍수에 떠내려 오는 것을 지나가던 사람이 건져내어 심은 것이라 한다. " +
"그런데 이 마을의 주민이었던 이수목이라는 사람이 이 나무에 영감을 느끼게 되어 석송령이라는 이름을 지어주고 " +
"자신이 소유한 6,600㎡의 토지를 상속시켜 문서 등기를 마쳤다고 한다.",
),
)

fun generateRandomContent(without: LoadingContent? = null): LoadingContent =
if (without == null) {
loadingContentList.random()
} else {
loadingContentList.minus(without).random()
}
}

data class LoadingContent(
val title: String,
val description: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import univ.earthbreaker.namu.feature.home.HomeActivity
import univ.earthbreaker.namu.util.finishSafely
import univ.earthbreaker.namu.util.extension.finishSafely

class LoginActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down
Loading