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

[Feature/#93] compose loading snackbar #97

Merged
merged 24 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a797ab9
#93 [add] : add snack bar color
chanubc Oct 9, 2024
087ba4e
#93 [hotfix] : λˆ„λ½λœ dtoν•„λ“œ μΆ”κ°€
chanubc Oct 9, 2024
616a35c
Merge branch 'refs/heads/develop' into feature/#93-compose-snackbar
chanubc Oct 10, 2024
7274f02
#93 [add] : add custom drop shadow
chanubc Oct 10, 2024
a7ca426
#93 [add] : add ProgressBackground color
chanubc Oct 10, 2024
b1e0238
#93 [add] : set SnackBarType
chanubc Oct 10, 2024
ff5a46e
#93 [feat] : make custom CircularProgressIndicator
chanubc Oct 10, 2024
e2c4ce7
#93 [chore] : set radius_8 dimes
chanubc Oct 10, 2024
3b3d6a7
#93 [feat] : make custom snackbar with proress indicator and drop shadow
chanubc Oct 10, 2024
2598851
#93 [feat] : adjust SnackbarHost position and elevate with zIndex
chanubc Oct 10, 2024
2d34aff
#93 [refactor] : error message ν•¨μˆ˜ 뢄리
chanubc Oct 10, 2024
d887a0e
#93 [add] : WableSnackBarPopUp μ „μ²΄ν™”λ©΄μœΌλ‘œ κ΅¬ν˜„
chanubc Oct 10, 2024
6fd1f16
#93 [chore] : μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ padding μˆ˜μ •
chanubc Oct 10, 2024
99c885a
#93 [feat] : λ‘œλ”© μŠ€λ‚΅ νŒμ—… state κ΅¬ν˜„
chanubc Oct 11, 2024
5bb747e
#93 [fix] : μŠ€λ‚΅λ°” delay 2μ΄ˆμ„€μ •
chanubc Oct 11, 2024
6c92cb3
#93 [fix] : λ°±λ²„νŠΌμ‹œ μž‘μ—… μ·¨μ†Œ ν—ˆμš©
chanubc Oct 11, 2024
ce594f7
#93 [refacotr] : λ‘œλ”© ν”„λ‘œν•„ state μΆ”κ°€
chanubc Oct 11, 2024
cc704d5
#93 [refactor] : error message둜직 common으둜 이동
chanubc Oct 11, 2024
5e53042
#93 [feat] : profile edit routeμ—μ„œ compose snackbar호좜
chanubc Oct 11, 2024
e374231
#93 [fix] : LOADING_PROFILE λ‘œλ”© 인디케이터 λœ¨λ„λ‘ μˆ˜μ •
chanubc Oct 11, 2024
5cce9c1
#93 [feat] : ν”„λ‘œν•„ νŽΈμ§‘ μ‹œ λ‘œλ”© μŠ€λ‚΅ νŒμ—… κ΅¬ν˜„
chanubc Oct 11, 2024
42a9aa9
#93 [fix] : refresh 만료 ν›„ ν™ˆν™”λ©΄ μ§„μž…μ‹œ 2번 νŒ…κ²¨μ„œ μž¬μ‹œμž‘ λ˜λŠ” 였λ₯˜ ν•΄κ²°
chanubc Oct 11, 2024
5a1afc5
#93 [mod] : refresh μ‹œ toast μΆ”κ°€
chanubc Oct 11, 2024
8ce5458
Merge branch 'refs/heads/develop' into feature/#93-compose-snackbar
chanubc Oct 11, 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: 4 additions & 0 deletions core/common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@
<string name="label_team_lck">LCK</string>

<string name="dummy">testtesttesttesttesttesttesttesttesttesttesttesttesttest</string>

<!-- error message -->
<string name="error_message_network">λ„€νŠΈμ›Œν¬ 연결이 μ›ν™œν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€</string>
<string name="error_message_unknown">μ•Œ 수 μ—†λŠ” 였λ₯˜κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.teamwable.designsystem.component.indicator

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.teamwable.designsystem.theme.WableTheme

@Composable
fun WableCircularIndicator(
modifier: Modifier = Modifier,
size: Dp = 32.dp,
color: Color = WableTheme.colors.info,
strokeWidth: Dp = 2.dp,
trackColor: Color = WableTheme.colors.progressBackground,
) {
CircularProgressIndicator(
modifier = modifier
.size(size)
.padding(5.dp),
color = color,
strokeWidth = strokeWidth,
strokeCap = StrokeCap.Round,
trackColor = trackColor,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.teamwable.designsystem.component.snackbar

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.teamwable.designsystem.R
import com.teamwable.designsystem.component.indicator.WableCircularIndicator
import com.teamwable.designsystem.extension.modifier.dropShadow
import com.teamwable.designsystem.theme.WableTheme
import com.teamwable.designsystem.type.SnackBarType

const val SNACK_BAR_DURATION = 2000L

@Composable
fun WableSnackBar(
modifier: Modifier = Modifier,
message: String = "",
snackBarType: SnackBarType = SnackBarType.ERROR,
onClick: () -> Unit = {},
) {
Box(
modifier = modifier
.padding(horizontal = 18.dp)
.fillMaxWidth()
.border(
width = 1.dp,
color = WableTheme.colors.gray200,
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius_8)),
)
.dropShadow(
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius_8)),
color = Color.Black.copy(alpha = 0.12f),
blur = 4.dp,
offsetX = 0.dp,
offsetY = 2.dp,
spread = 0.dp,
)
.background(
color = WableTheme.colors.gray100.copy(alpha = 0.9f),
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius_8)),
),
contentAlignment = Alignment.CenterStart,
) {
WableSnackBarContent(
snackBarType = snackBarType,
message = message,
)
}
}

@Composable
fun WableSnackBarContent(
snackBarType: SnackBarType,
message: String,
) {
Row(
modifier = Modifier
.padding(vertical = 8.dp, horizontal = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
when (snackBarType) {
SnackBarType.LOADING, SnackBarType.LOADING_PROFILE -> WableCircularIndicator()
else -> WableSnackBarImage(snackBarType)
}
Text(
text = when (snackBarType) {
SnackBarType.LOADING -> stringResource(id = R.string.snackbar_text_loading)
SnackBarType.LOADING_PROFILE -> stringResource(id = R.string.snackbar_text_profile_loading)
else -> message
},
textAlign = TextAlign.Start,
color = WableTheme.colors.black,
style = WableTheme.typography.body03,
modifier = Modifier.padding(start = 6.dp),
)
}
}

@Composable
fun WableSnackBarImage(snackBarType: SnackBarType) {
Image(
painter = painterResource(id = snackBarType.image),
contentDescription = null,
)
}

@Preview(showBackground = true)
@Composable
fun WableButtonDialogPreview() {
WableTheme {
WableSnackBar(
snackBarType = SnackBarType.SUCCESS,
message = "ν”„λ‘œν•„ 사진을 5MB μ΄ν•˜μΈ μ‚¬μ§„μœΌλ‘œ λ°”κΏ”μ£Όμ„Έμš”",
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.teamwable.designsystem.component.snackbar

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
import com.teamwable.designsystem.theme.WableTheme
import com.teamwable.designsystem.type.SnackBarType

@Composable
fun WableSnackBarPopUp(
isVisible: Boolean,
snackBarType: SnackBarType = SnackBarType.LOADING,
onDismissRequest: () -> Unit = {},
) {
if (isVisible) {
Popup(
onDismissRequest = onDismissRequest,
properties = PopupProperties(
focusable = false,
dismissOnBackPress = true,
dismissOnClickOutside = false,
excludeFromSystemGesture = true,
),
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(WableTheme.colors.white.copy(alpha = 0.5f)),
) {
WableSnackBar(
snackBarType = snackBarType,
modifier = Modifier
.fillMaxWidth()
.padding(top = 30.dp),
)
}
}
}
}

@Preview(showBackground = true)
@Composable
fun WableSnackBarPopUpPreview() {
WableTheme {
WableSnackBarPopUp(
isVisible = true,
snackBarType = SnackBarType.LOADING,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.teamwable.designsystem.extension.modifier

import android.graphics.BlurMaskFilter
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.Composable
Expand All @@ -10,7 +11,16 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawOutline
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -46,3 +56,35 @@ fun Modifier.noRippleDebounceClickable(
true
}
}

@Composable
fun Modifier.dropShadow(
shape: Shape,
color: Color = Color.Black.copy(alpha = 0.25f),
blur: Dp = 4.dp,
offsetY: Dp = 4.dp,
offsetX: Dp = 0.dp,
spread: Dp = 0.dp,
) = this.drawBehind {
val spreadPx = spread.toPx()
val shadowSize = Size(size.width + spreadPx, size.height + spreadPx)

val shadowOutline = shape.createOutline(shadowSize, layoutDirection, this)

val paint = Paint().apply {
this.color = color
}

if (blur.toPx() > 0) {
paint.asFrameworkPaint().apply {
maskFilter = BlurMaskFilter(blur.toPx(), BlurMaskFilter.Blur.NORMAL)
}
}

drawIntoCanvas { canvas ->
canvas.save()
canvas.translate(offsetX.toPx() - spreadPx / 2, offsetY.toPx() - spreadPx / 2)
canvas.drawOutline(shadowOutline, paint)
canvas.restore()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ val Warning = Color(0xFFEE9209)
val Error = Color(0xFFF01F1F)
val SystemNavigationBar = Color(0xFFF5F5F5)
val SystemLoginSystemAppBar = Color(0xFFEBE2FD)
val ProgressBackground = Color(0xFFCADFF7)

// Gray Scale
val Black = Color(0xFF0E0E0E)
Expand Down Expand Up @@ -100,6 +101,7 @@ class WableColors(
kdf10: Color,
hle50: Color,
hle10: Color,
progressBackground: Color,
) {
var purple50 by mutableStateOf(purple50)
private set
Expand Down Expand Up @@ -181,6 +183,8 @@ class WableColors(
private set
var hle10 by mutableStateOf(hle10)
private set
var progressBackground by mutableStateOf(progressBackground)
private set

fun copy(): WableColors = WableColors(
purple50,
Expand Down Expand Up @@ -223,6 +227,7 @@ class WableColors(
kdf10,
hle50,
hle10,
progressBackground,
)

fun update(other: WableColors) {
Expand Down Expand Up @@ -266,6 +271,7 @@ class WableColors(
kdf10 = other.kdf10
hle50 = other.hle50
hle10 = other.hle10
progressBackground = other.progressBackground
}
}

Expand Down Expand Up @@ -310,6 +316,7 @@ fun wableLightColors(
kdf10: Color = Kdf10,
hle50: Color = Hle50,
hle10: Color = Hle10,
progressBackground: Color = ProgressBackground,
) = WableColors(
purple50,
purple100,
Expand Down Expand Up @@ -351,4 +358,5 @@ fun wableLightColors(
kdf10,
hle50,
hle10,
progressBackground,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.teamwable.designsystem.type

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.teamwable.designsystem.R

enum class SnackBarType(
@DrawableRes val image: Int = com.teamwable.common.R.drawable.ic_home_toast_success,
@StringRes val message: Int = R.string.empty,
) {
WARNING(image = com.teamwable.common.R.drawable.ic_home_toast_warning),
ERROR(image = com.teamwable.common.R.drawable.ic_home_toast_error),
SUCCESS(image = com.teamwable.common.R.drawable.ic_home_toast_success),
LOADING(message = R.string.snackbar_text_loading),
LOADING_PROFILE(message = R.string.snackbar_text_loading),
}
1 change: 1 addition & 0 deletions core/designsystem/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="radius_8">8dp</dimen>
<dimen name="radius_12">12dp</dimen>
</resources>
4 changes: 4 additions & 0 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@
<!-- 곡톡-->
<string name="empty"> </string>

<!-- μŠ€λ‚΅λ°”-->
<string name="snackbar_text_loading">νšŒμ›κ°€μž…μ΄ 거의 마무리 λ˜μ—ˆμ–΄μš”.\nμž μ‹œλ§Œ κΈ°λ‹€λ €μ£Όμ„Έμš”!</string>
<string name="snackbar_text_profile_loading">ν”„λ‘œν•„ μˆ˜μ •μ΄ 거의 마무리 λ˜μ—ˆμ–΄μš”.\nμž μ‹œλ§Œ κΈ°λ‹€λ €μ£Όμ„Έμš”!</string>

</resources>
Loading