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

[feat] BadgeCategory UI 구현 #53

Merged
merged 8 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand All @@ -17,6 +18,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.android.bbangzip.R
import org.android.bbangzip.presentation.type.BbangZipShadowType
import org.android.bbangzip.presentation.util.modifier.applyShadows
import org.android.bbangzip.ui.theme.BbangZipTheme
import org.android.bbangzip.ui.theme.defaultBbangZipColors

Expand All @@ -32,7 +35,8 @@ fun TopTailBalloon(
modifier =
modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
.padding(horizontal = horizontalPadding)
.applyShadows(BbangZipShadowType.STRONG, shape = RoundedCornerShape(size = 20.dp)),
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_balloon_tail_up_8),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.android.bbangzip.presentation.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class BadgeCategory(
val name: String,
val categoryName: String,
val isLocked: Boolean,
val imageUrl: String,
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.android.bbangzip.presentation.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class BadgeDetail(
val name: String = "안녕",
val categoryName: String = "안녕",
val imageUrl: String = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
val hashTags: List<String> = listOf("안녕", "안녕"),
val achievementCondition: String = "안녕",
val reward: Int = 50,
val isLocked: Boolean = true,
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.android.bbangzip.presentation.ui.my.mybadgecategory

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.android.bbangzip.presentation.model.BadgeCategory
import org.android.bbangzip.presentation.model.BadgeDetail
import org.android.bbangzip.presentation.util.base.BaseContract

class MyBadgeCategoryContract {
@Parcelize
data class MyBadgeCategoryState(
val badgeCategoryList1: List<BadgeCategory> =
listOf(
BadgeCategory(
name = "Badge 1",
categoryName = "Category 1",
isLocked = true,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
BadgeCategory(
name = "Badge 2",
categoryName = "Category 1",
isLocked = false,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
BadgeCategory(
name = "Badge 3",
categoryName = "Category 1",
isLocked = true,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
),
val badgeCategoryList2: List<BadgeCategory> =
listOf(
BadgeCategory(
name = "Badge 4",
categoryName = "Category 2",
isLocked = true,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
BadgeCategory(
name = "Badge 5",
categoryName = "Category 2",
isLocked = false,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
BadgeCategory(
name = "Badge 6",
categoryName = "Category 2",
isLocked = true,
imageUrl = "https://www.chosun.com/resizer/v2/HRGER65PGPIW36FJOBRNAP2PJM.jpg?auth=9da0c167de2cfb03a5d344ce4098faa669a22d7a2b90cb6a21fdc518b0af3558&width=530&height=757&smart=true",
),
),
val badgeDetailBottomSheetState: Boolean = false,
val badgeDetail: BadgeDetail = BadgeDetail(),
) : BaseContract.State, Parcelable {
override fun toParcelable(): Parcelable = this
}

sealed interface MyBadgeCategoryEvent : BaseContract.Event {
data object Initialize : MyBadgeCategoryEvent

data object OnBackIconClicked : MyBadgeCategoryEvent

data object OnBadgeDetailBottomSheetDismissButtonClicked : MyBadgeCategoryEvent

data object OnBadgeDetailBottomSheetDismissRequest : MyBadgeCategoryEvent

data class OnBadgeCardClicked(val badgeName: String) : MyBadgeCategoryEvent
}

sealed interface MyBadgeCategoryReduce : BaseContract.Reduce {
data class UpdateBadgeCategoryList(
val badgeCategoryList1: List<BadgeCategory>,
val badgeCategoryList2: List<BadgeCategory>,
) : MyBadgeCategoryReduce

data class UpdateBadgeDetailBottomSheetState(val badgeDetailBottomSheetState: Boolean) : MyBadgeCategoryReduce

data class UpdateBadgeDetail(val badgeDetail: BadgeDetail) : MyBadgeCategoryReduce
}

sealed interface MyBadgeCategorySideEffect : BaseContract.SideEffect {
data object NavigateToBack : MyBadgeCategorySideEffect
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.android.bbangzip.presentation.ui.my.mybadgecategory

import android.app.Activity
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.collectLatest
import org.android.bbangzip.ui.theme.BbangZipTheme

@Composable
fun MyBadgeCategoryRoute(
navigateToBack: () -> Unit = {},
viewModel: MyBadgeCategoryViewModel = hiltViewModel(),
) {
val badgeCategoryState by viewModel.uiState.collectAsStateWithLifecycle()
val success by viewModel.success.collectAsStateWithLifecycle(initialValue = false)
val view = LocalView.current
val activity = view.context as Activity

activity.window.statusBarColor = BbangZipTheme.colors.backgroundAccent_FFDAA0.toArgb()

LaunchedEffect(viewModel.uiSideEffect) {
viewModel.uiSideEffect.collectLatest { effect ->
when (effect) {
MyBadgeCategoryContract.MyBadgeCategorySideEffect.NavigateToBack ->
navigateToBack()
}
}
}

when (success) {
true ->
MyBadgeCategoryScreen(
badgeCategoryState = badgeCategoryState,
onBackIconClicked = {
viewModel.setEvent(MyBadgeCategoryContract.MyBadgeCategoryEvent.OnBackIconClicked)
},
onBadgeCardClicked = { badgeName ->
viewModel.setEvent(
MyBadgeCategoryContract.MyBadgeCategoryEvent.OnBadgeCardClicked(
badgeName = badgeName,
),
)
},
onBadgeDetailBottomSheetDismissRequest = {
viewModel.setEvent(MyBadgeCategoryContract.MyBadgeCategoryEvent.OnBadgeDetailBottomSheetDismissRequest)
},
onBadgeDetailBottomSheetDismissButtonClicked = {
viewModel.setEvent(MyBadgeCategoryContract.MyBadgeCategoryEvent.OnBadgeDetailBottomSheetDismissButtonClicked)
},
)

false ->
Text("땡!")
}
}
Loading
Loading