Skip to content

Commit

Permalink
🎨 added a general CardBackgroundSurface to be used across the app to …
Browse files Browse the repository at this point in the history
…display a blurred card background
  • Loading branch information
schachi5000 committed Sep 23, 2024
1 parent ecfab73 commit 71eacbb
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ package net.schacher.mcc.shared.design.compose
import androidx.compose.runtime.Composable

@Composable
expect fun BackHandler(enabled: Boolean, onBack: () -> Unit)
expect fun BackHandler(enabled: Boolean = true, onBack: () -> Unit)
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package net.schacher.mcc.shared.design.compose

import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp

@Composable
fun CardBackgroundBox(
cardCode: String,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit
) {
Box(
modifier = modifier
) {
CardBackgroundImage(
modifier = Modifier.fillMaxWidth(),
background = MaterialTheme.colors.background,
cardCode = cardCode
)

content()
}
}

@Composable
fun CardBackgroundImage(
modifier: Modifier = Modifier.fillMaxWidth(),
background: Color = MaterialTheme.colors.background,
cardCode: String
) {
Box(modifier = modifier.height(340.dp)) {
CardImage(
modifier = Modifier.fillMaxSize()
.blur(30.dp)
.background(MaterialTheme.colors.surface),
cardCode = cardCode,
filterQuality = FilterQuality.Low,
contentScale = ContentScale.Crop,
animationSpec = tween(
durationMillis = 500
),
onLoading = {},
onFailure = {})

Box(
modifier = Modifier.fillMaxSize().background(
Brush.verticalGradient(
colorStops = arrayOf(
0f to background.copy(alpha = 0f),
1f to background.copy(alpha = 1f)
)
)
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import pro.schacher.mcc.BuildConfig
fun CardImage(
cardCode: String,
filterQuality: FilterQuality = FilterQuality.High,
contentDescription: String?,
contentDescription: String? = null,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import net.schacher.mcc.shared.screens.deck.DeckScreen
import net.schacher.mcc.shared.screens.login.LoginScreen
import net.schacher.mcc.shared.screens.main.MainScreen
import net.schacher.mcc.shared.screens.newdeck.NewDeckScreen
import net.schacher.mcc.shared.screens.packselection.PackSelectionScreen
import org.koin.compose.koinInject

@Composable
Expand All @@ -29,8 +30,6 @@ fun AppScreen(
navController: NavController = koinInject(),
onLogInClicked: () -> Unit
) {


NavHost(
navController = navController as NavHostController,
modifier = Modifier.fillMaxSize(),
Expand All @@ -57,6 +56,10 @@ fun AppScreen(
)
}

composable(AppScreen.Packs.route) {
PackSelectionScreen()
}

composable(
route = AppScreen.Deck.route,
arguments = listOf(navArgument("deckId") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,22 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.blur
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import co.touchlab.kermit.Logger
import net.schacher.mcc.shared.design.compose.BackButton
import net.schacher.mcc.shared.design.compose.Card
import net.schacher.mcc.shared.design.compose.CardBackgroundBox
import net.schacher.mcc.shared.design.theme.color
import net.schacher.mcc.shared.localization.label
import net.schacher.mcc.shared.model.Card
import net.schacher.mcc.shared.model.CardType
import net.schacher.mcc.shared.repositories.CardRepository
import org.koin.compose.koinInject

Expand Down Expand Up @@ -74,32 +68,29 @@ fun CardScreen(
modifier: Modifier = Modifier,
onCloseClick: () -> Unit
) {
Logger.i { card.toString() }

Box(
modifier = modifier.statusBarsPadding().background(MaterialTheme.colors.background)
CardBackgroundBox(
cardCode = card.code,
modifier = modifier
) {
Card(
modifier = Modifier.fillMaxWidth().blur(20.dp)
.graphicsLayer { translationY = getTranslationY(card).toPx() }, card = card
Content(
card = card,
onCloseClick = onCloseClick
)
}
}

@Composable
private fun Content(card: Card, onCloseClick: () -> Unit) {
Box(modifier = Modifier.fillMaxSize().statusBarsPadding()) {
Tag(
modifier = Modifier.align(Alignment.TopEnd).padding(16.dp).alpha(0.8f), text = card.code
modifier = Modifier.align(Alignment.TopEnd)
.padding(16.dp)
.alpha(0.8f),
text = card.code
)

Column(
modifier = Modifier.fillMaxSize().background(
Brush.verticalGradient(
colorStops = arrayOf(
0f to MaterialTheme.colors.background.copy(alpha = 0f),
0.15f to MaterialTheme.colors.background.copy(alpha = 0.2f),
0.3f to MaterialTheme.colors.background.copy(alpha = 0.8f),
0.4f to MaterialTheme.colors.background.copy(alpha = 1f),
1f to MaterialTheme.colors.background.copy(alpha = 1f)
)
)
).padding(top = 200.dp, start = 16.dp, end = 16.dp),
modifier = Modifier.fillMaxSize().padding(top = 200.dp, start = 16.dp, end = 16.dp),
horizontalAlignment = Alignment.Start
) {
Text(
Expand Down Expand Up @@ -187,12 +178,6 @@ fun CardScreen(
}
}

private fun getTranslationY(card: Card): Dp = when (card.type) {
CardType.EVENT, CardType.MINION, CardType.VILLAIN, CardType.ENVIRONMENT, CardType.SUPPORT, CardType.UPGRADE, CardType.ALLY, CardType.OBLIGATION, CardType.TREACHERY, CardType.HERO -> (-65).dp

else -> 0.dp
}

@Composable
private fun Tag(
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -228,8 +213,12 @@ private fun String.toAnnotatedString(): AnnotatedString {

// Could be handled more elegantly, but this works for now
val boldStrings = boldRegex.findAll(value).map {
it.value.replace("<b>", "").replace("</b>", "").replace("[", "").replace("]", "")
.replace("per_hero", EMOJI_HERO).replace("per_player", EMOJI_HERO)
it.value.replace("<b>", "")
.replace("</b>", "")
.replace("[", "")
.replace("]", "")
.replace("per_hero", EMOJI_HERO)
.replace("per_player", EMOJI_HERO)
}.toList()

return buildAnnotatedString {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package net.schacher.mcc.shared.screens.deck

import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
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.navigationBarsPadding
import androidx.compose.foundation.layout.padding
Expand All @@ -25,16 +22,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import net.schacher.mcc.shared.design.compose.BackButton
import net.schacher.mcc.shared.design.compose.Card
import net.schacher.mcc.shared.design.compose.CardImage
import net.schacher.mcc.shared.design.compose.CardBackgroundBox
import net.schacher.mcc.shared.design.compose.CardRow
import net.schacher.mcc.shared.design.compose.CardRowEntry
import net.schacher.mcc.shared.design.compose.ConfirmationDialog
Expand Down Expand Up @@ -103,16 +95,12 @@ private fun Content(
onDeleteDeckClick: (Int) -> Unit,
onCardClick: (Card) -> Unit
) {
Box(
CardBackgroundBox(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background)
.background(MaterialTheme.colors.background),
cardCode = deck.hero.code,
) {
BackgroundImage(
modifier = Modifier.fillMaxWidth(),
deck = deck,
)

LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
Spacer(Modifier.statusBarsPadding().height(ContentPadding))
Expand Down Expand Up @@ -190,39 +178,3 @@ private fun Content(
}
}
}

@Composable
private fun BackgroundImage(
modifier: Modifier = Modifier.fillMaxWidth(),
background: Color = MaterialTheme.colors.background,
deck: Deck
) {
Box(
modifier = modifier.height(340.dp)
) {
CardImage(
modifier = Modifier.fillMaxSize()
.blur(30.dp)
.background(MaterialTheme.colors.surface),
cardCode = deck.hero.code,
filterQuality = FilterQuality.Low,
contentDescription = deck.name,
contentScale = ContentScale.Crop,
animationSpec = tween(
durationMillis = 500
),
onLoading = {},
onFailure = {})

Box(
modifier = Modifier.fillMaxSize().background(
Brush.verticalGradient(
colorStops = arrayOf(
0f to background.copy(alpha = 0f),
1f to background.copy(alpha = 1f)
)
)
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import androidx.compose.material.SnackbarHost
import androidx.compose.material.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
Expand All @@ -27,6 +26,7 @@ import marvelchampionscompanion.shared.generated.resources.cards
import marvelchampionscompanion.shared.generated.resources.my_decks
import marvelchampionscompanion.shared.generated.resources.settings
import marvelchampionscompanion.shared.generated.resources.spotlight
import net.schacher.mcc.shared.design.compose.BackHandler
import net.schacher.mcc.shared.design.compose.PagerHeader
import net.schacher.mcc.shared.design.theme.ContentPadding
import net.schacher.mcc.shared.screens.AppScreen
Expand Down Expand Up @@ -57,11 +57,14 @@ fun MainScreen(
viewModel: MainViewModel = koinInject(),
navController: NavController = koinInject(),
) {
val state = viewModel.state.collectAsState()
val scope = rememberCoroutineScope()

val snackbarHostState = remember { SnackbarHostState() }

BackHandler {
viewModel.onLogoutClicked()
}

Scaffold(
modifier = Modifier.fillMaxSize(),
backgroundColor = MaterialTheme.colors.background,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,23 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import net.schacher.mcc.shared.design.compose.BackButton
import net.schacher.mcc.shared.design.theme.DefaultShape
import net.schacher.mcc.shared.model.Pack
import org.koin.compose.koinInject

@Composable
fun PackSelectionScreen(
viewModel: PackSelectionViewModel = koinInject(),
navController: NavController = koinInject()
) {
PackSelectionScreen(
viewModel = viewModel,
onBackPress = { navController.popBackStack() }
)
}

@Composable
fun PackSelectionScreen(
viewModel: PackSelectionViewModel = koinInject(),
Expand Down

0 comments on commit 71eacbb

Please sign in to comment.