diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/CoinItem.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/CoinItem.kt new file mode 100644 index 00000000..1eba485c --- /dev/null +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/CoinItem.kt @@ -0,0 +1,156 @@ +package co.nimblehq.compose.crypto.ui.screens.home + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.KeyboardArrowUp +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.constraintlayout.compose.Dimension +import androidx.compose.ui.tooling.preview.Preview +import androidx.constraintlayout.compose.ConstraintLayout +import co.nimblehq.compose.crypto.R +import co.nimblehq.compose.crypto.ui.theme.Color.FireOpal +import co.nimblehq.compose.crypto.ui.theme.Color.GuppieGreen +import co.nimblehq.compose.crypto.ui.theme.ComposeTheme +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp12 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp16 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp22 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp25 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp4 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp60 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp8 +import co.nimblehq.compose.crypto.ui.theme.Style +import co.nimblehq.compose.crypto.ui.theme.Style.coinItemColor +import co.nimblehq.compose.crypto.ui.theme.Style.coinNameColor +import co.nimblehq.compose.crypto.ui.theme.Style.textColor + +@Suppress("FunctionNaming", "LongMethod") +@Composable +fun CoinItem( + isPositiveNumber: Boolean = false /* TODO Update value to Object on Integrate ticket */ +) { + ConstraintLayout( + modifier = Modifier + .wrapContentWidth() + .clip(RoundedCornerShape(Dp12)) + .background(color = MaterialTheme.colors.coinItemColor) + .padding(horizontal = Dp8, vertical = Dp8) + ) { + val ( + logo, + coinSymbol, + coinName, + price, + icon, + priceChange + ) = createRefs() + + Image( + modifier = Modifier + .size(Dp60) + .padding(end = Dp16) + .constrainAs(logo) { + top.linkTo(coinSymbol.top) + bottom.linkTo(coinName.bottom) + start.linkTo(parent.start) + }, + // TODO: Remove dummy image when work on Integrate. + painter = painterResource(id = R.drawable.ic_btc_bitcoin), + contentDescription = null + ) + + Text( + modifier = Modifier + .constrainAs(coinSymbol) { + top.linkTo(parent.top) + start.linkTo(logo.end) + }, + // TODO: Remove dummy value when work on Integrate. + text = "BTC", + color = MaterialTheme.colors.textColor, + style = Style.semiBold16() + ) + + Text( + modifier = Modifier + .padding(top = Dp4) + .constrainAs(coinName) { + start.linkTo(coinSymbol.start) + top.linkTo(coinSymbol.bottom) + width = Dimension.preferredWrapContent + }, + // TODO: Remove dummy value when work on Integrate. + text = "Bitcoin", + color = MaterialTheme.colors.coinNameColor, + style = Style.medium14() + ) + + Text( + modifier = Modifier + .padding(top = Dp22) + .constrainAs(price) { + start.linkTo(logo.start) + top.linkTo(coinName.bottom) + width = Dimension.preferredWrapContent + }, + // TODO: Remove dummy value when work on Integrate. + text = stringResource(R.string.coin_currency, "24,209"), + color = MaterialTheme.colors.textColor, + style = Style.semiBold16() + ) + + Icon( + modifier = Modifier + .padding(start = Dp25) + .constrainAs(icon) { + start.linkTo(price.end) + top.linkTo(priceChange.top) + bottom.linkTo(priceChange.bottom) + width = Dimension.preferredWrapContent + }, + imageVector = if (isPositiveNumber) Icons.Filled.KeyboardArrowUp else Icons.Filled.KeyboardArrowDown, + tint = if (isPositiveNumber) GuppieGreen else FireOpal, + contentDescription = null + ) + + Text( + modifier = Modifier + .constrainAs(priceChange) { + start.linkTo(icon.end) + bottom.linkTo(parent.bottom) + width = Dimension.preferredWrapContent + }, + // TODO: Remove dummy value when work on Integrate. + text = stringResource(R.string.coin_profit_percent, "6.21"), + style = if (isPositiveNumber) Style.guppieGreenMedium16() else Style.fireOpalGreenMedium16() + ) + } +} + +@Suppress("FunctionNaming") +@Composable +@Preview +fun CoinItemPreview() { + ComposeTheme { + CoinItem() + } +} + +@Suppress("FunctionNaming") +@Composable +@Preview +fun CoinItemPreviewDark() { + ComposeTheme(darkTheme = true) { + CoinItem() + } +} diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/HomeScreen.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/HomeScreen.kt index 84b21a33..e8b271ec 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/HomeScreen.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/HomeScreen.kt @@ -1,6 +1,8 @@ package co.nimblehq.compose.crypto.ui.screens.home +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyRow import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -13,22 +15,28 @@ import co.nimblehq.compose.crypto.R import co.nimblehq.compose.crypto.ui.theme.ComposeTheme import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp16 import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp40 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp52 import co.nimblehq.compose.crypto.ui.theme.Style -import co.nimblehq.compose.crypto.ui.theme.Style.titleHome +import co.nimblehq.compose.crypto.ui.theme.Style.textColor +@Suppress("FunctionNaming", "LongMethod") @Composable fun HomeScreen() { Surface { ConstraintLayout( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = Dp16) + modifier = Modifier.fillMaxSize() ) { - val (title, portfolioCard) = createRefs() + val ( + title, + portfolioCard, + myCoinsTitle, + seeAll, + myCoins + ) = createRefs() Text( modifier = Modifier - .padding(start = Dp16, top = Dp16, end = Dp16) + .padding(top = Dp16) .constrainAs(title) { top.linkTo(parent.top) linkTo(start = parent.start, end = parent.end) @@ -37,18 +45,60 @@ fun HomeScreen() { text = stringResource(id = R.string.home_title), textAlign = TextAlign.Center, style = Style.semiBold24(), - color = MaterialTheme.colors.titleHome + color = MaterialTheme.colors.textColor ) PortfolioCard( - modifier = Modifier.constrainAs(portfolioCard) { - top.linkTo(title.bottom, margin = Dp40) - } + modifier = Modifier + .constrainAs(portfolioCard) { + top.linkTo(title.bottom, margin = Dp40) + } + .padding(horizontal = Dp16) ) + + Text( + modifier = Modifier + .constrainAs(myCoinsTitle) { + top.linkTo(portfolioCard.bottom, margin = Dp52) + start.linkTo(parent.start) + width = Dimension.preferredWrapContent + } + .padding(start = Dp16), + text = stringResource(id = R.string.home_my_coins_title), + style = Style.medium16(), + color = MaterialTheme.colors.textColor + ) + + SeeAll( + modifier = Modifier + .clickable(onClick = { /* TODO: Update on Integrate ticket */ }) + .constrainAs(seeAll) { + top.linkTo(myCoinsTitle.top) + end.linkTo(parent.end) + width = Dimension.preferredWrapContent + } + .padding(end = Dp16) + ) + + LazyRow( + modifier = Modifier + .fillMaxWidth() + .constrainAs(myCoins) { + top.linkTo(myCoinsTitle.bottom, margin = Dp16) + }, + contentPadding = PaddingValues(horizontal = Dp16), + horizontalArrangement = Arrangement.spacedBy(Dp16), + ) { + // TODO: Remove dummy value when work on Integrate. + item { CoinItem() } + item { CoinItem(true) } + item { CoinItem() } + } } } } +@Suppress("FunctionNaming") @Composable @Preview fun HomeScreenPreview() { @@ -57,6 +107,7 @@ fun HomeScreenPreview() { } } +@Suppress("FunctionNaming") @Composable @Preview fun HomeScreenPreviewDark() { diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/PortfolioCard.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/PortfolioCard.kt index 21a7c820..f06d9760 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/PortfolioCard.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/PortfolioCard.kt @@ -27,6 +27,7 @@ import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp40 import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp8 import co.nimblehq.compose.crypto.ui.theme.Style +@Suppress("FunctionNaming", "LongMethod") @Composable fun PortfolioCard( modifier: Modifier @@ -40,6 +41,7 @@ fun PortfolioCard( colors = listOf(Color.MetallicSeaweed, Color.TiffanyBlue), ) ) + .padding(horizontal = Dp16, vertical = Dp16) ) { val ( totalCoinsLabel, @@ -51,7 +53,6 @@ fun PortfolioCard( Text( modifier = Modifier - .padding(top = Dp16, start = Dp16) .constrainAs(totalCoinsLabel) { start.linkTo(parent.start) }, @@ -61,18 +62,16 @@ fun PortfolioCard( Text( modifier = Modifier - .padding(horizontal = Dp16) .constrainAs(totalCoins) { top.linkTo(totalCoinsLabel.bottom, margin = Dp8) }, // TODO: Remove dummy value when work on Integrate. - text = stringResource(R.string.portfolio_card_total_coin, "7,273,291"), + text = stringResource(R.string.coin_currency, "7,273,291"), style = Style.whiteSemiBold24() ) Text( modifier = Modifier - .padding(start = Dp16) .constrainAs(todayProfitLabel) { top.linkTo(totalCoins.bottom, margin = Dp40) }, @@ -82,18 +81,16 @@ fun PortfolioCard( Text( modifier = Modifier - .padding(start = Dp16, bottom = Dp16) .constrainAs(todayProfit) { top.linkTo(todayProfitLabel.bottom, margin = Dp8) }, // TODO: Remove dummy value when work on Integrate. - text = stringResource(R.string.portfolio_card_today_profit, "193,280"), + text = stringResource(R.string.coin_currency, "193,280"), style = Style.whiteSemiBold24() ) Button( modifier = Modifier - .padding(start = Dp16, end = Dp16, bottom = Dp16) .shadow(elevation = Dp0) .constrainAs(profitPercent) { linkTo(top = todayProfitLabel.top, bottom = todayProfit.bottom) @@ -113,13 +110,14 @@ fun PortfolioCard( ) Text( // TODO: Remove dummy value when work on Integrate. - text = stringResource(R.string.portfolio_card_profit_percent, 2.41), + text = stringResource(R.string.coin_profit_percent, "2.41"), style = Style.medium16() ) } } } +@Suppress("FunctionNaming") @Composable @Preview fun PortfolioCardPreview() { diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/SeeAll.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/SeeAll.kt new file mode 100644 index 00000000..9220a716 --- /dev/null +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/home/SeeAll.kt @@ -0,0 +1,53 @@ +package co.nimblehq.compose.crypto.ui.screens.home + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowForward +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import co.nimblehq.compose.crypto.R +import co.nimblehq.compose.crypto.ui.theme.Color +import co.nimblehq.compose.crypto.ui.theme.ComposeTheme +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp14 +import co.nimblehq.compose.crypto.ui.theme.Dimension.Dp8 +import co.nimblehq.compose.crypto.ui.theme.Style + +@Suppress("FunctionNaming") +@Composable +fun SeeAll( + modifier: Modifier +) { + Row(modifier = modifier) { + Text( + modifier = Modifier.padding(end = Dp8), + text = stringResource(id = R.string.home_my_coins_see_all), + style = Style.tiffanyBlueMedium14() + ) + Icon( + modifier = Modifier + .size(Dp14) + .align(Alignment.CenterVertically), + imageVector = Icons.Filled.ArrowForward, + tint = Color.TiffanyBlue, + contentDescription = null + ) + } +} + +@Suppress("FunctionNaming") +@Composable +@Preview +fun SeeAllPreview() { + ComposeTheme { + SeeAll( + modifier = Modifier + ) + } +} diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/to_be_removed/TitleBar.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/to_be_removed/TitleBar.kt index d1f40dbd..28332ef5 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/to_be_removed/TitleBar.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/screens/to_be_removed/TitleBar.kt @@ -16,7 +16,6 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import co.nimblehq.compose.crypto.ui.theme.Dimension -@Suppress("LongMethod") @ExperimentalComposeUiApi @Composable fun TitleBar( diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Color.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Color.kt index 788842ac..ade2ea6b 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Color.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Color.kt @@ -5,7 +5,6 @@ import androidx.compose.ui.graphics.Color @Suppress("MagicNumber") object Color { val BlueFreeSpeech = Color(0xFF3F51B5) - val AlmostWhite = Color(0xFFDFE4EA) val White = Color.White val MetallicSeaweed = Color(0xFF028090) val TiffanyBlue = Color(0xFF00BFB2) @@ -13,4 +12,9 @@ object Color { val GuppieGreen = Color(0xFF10DC78) val DarkJungleGreen = Color(0xFF141B29) val LightSilver = Color(0xFFD6D7D8) + val Quartz = Color(0xFF484D58) + val QuartzAlpha20 = Quartz.copy(alpha = 0.2f) + val Cultured = Color(0xFFEEEEEE) + val FireOpal = Color(0xFFF15950) + val SonicSilver = Color(0xFF70747C) } diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Dimension.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Dimension.kt index 76f54952..abf7cc37 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Dimension.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Dimension.kt @@ -8,9 +8,13 @@ object Dimension { val Dp4 = 4.dp val Dp8 = 8.dp val Dp12 = 12.dp + val Dp14 = 14.dp val Dp16 = 16.dp val Dp20 = 20.dp + val Dp22 = 22.dp val Dp24 = 24.dp + val Dp25 = 25.dp val Dp40 = 40.dp val Dp52 = 52.dp + val Dp60 = 60.dp } diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Style.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Style.kt index 036cdb67..acb3799d 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Style.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Style.kt @@ -5,26 +5,65 @@ import androidx.compose.ui.graphics.Color import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color.Companion.White import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight +import co.nimblehq.compose.crypto.R import co.nimblehq.compose.crypto.ui.theme.Color.DarkJungleGreen +import co.nimblehq.compose.crypto.ui.theme.Color.FireOpal +import co.nimblehq.compose.crypto.ui.theme.Color.GuppieGreen import co.nimblehq.compose.crypto.ui.theme.Color.LightSilver +import co.nimblehq.compose.crypto.ui.theme.Color.QuartzAlpha20 +import co.nimblehq.compose.crypto.ui.theme.Color.SonicSilver +import co.nimblehq.compose.crypto.ui.theme.Color.TiffanyBlue +import co.nimblehq.compose.crypto.ui.theme.TextDimension.Sp14 import co.nimblehq.compose.crypto.ui.theme.TextDimension.Sp16 import co.nimblehq.compose.crypto.ui.theme.TextDimension.Sp24 object Style { - val Colors.titleHome: Color + private val textStyle = TextStyle( + fontFamily = FontFamily( + Font(R.font.inter_medium, FontWeight.Medium), + Font(R.font.inter_semi_bold, FontWeight.SemiBold) + ) + ) + + val Colors.textColor: Color @Composable get() = if (isLight) DarkJungleGreen else White + val Colors.coinItemColor: Color + @Composable + get() = if (isLight) White else QuartzAlpha20 + + val Colors.coinNameColor: Color + @Composable + get() = if (isLight) SonicSilver else LightSilver + + @Composable + fun medium14() = textStyle.copy(fontWeight = FontWeight.Medium, fontSize = Sp14) + @Composable - fun medium16() = TextStyle(fontWeight = FontWeight.Medium, fontSize = Sp16) + fun tiffanyBlueMedium14() = medium14().copy(color = TiffanyBlue) + + @Composable + fun medium16() = textStyle.copy(fontWeight = FontWeight.Medium, fontSize = Sp16) @Composable fun lightSilverMedium16() = medium16().copy(color = LightSilver) @Composable - fun semiBold24() = TextStyle(fontWeight = FontWeight.SemiBold, fontSize = Sp24) + fun guppieGreenMedium16() = medium16().copy(color = GuppieGreen) + + @Composable + fun fireOpalGreenMedium16() = medium16().copy(color = FireOpal) + + @Composable + fun semiBold16() = textStyle.copy(fontWeight = FontWeight.SemiBold, fontSize = Sp16) + + @Composable + fun semiBold24() = textStyle.copy(fontWeight = FontWeight.SemiBold, fontSize = Sp24) @Composable fun whiteSemiBold24() = semiBold24().copy(color = White) diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/TextDimension.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/TextDimension.kt index 6a574b74..abec2d59 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/TextDimension.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/TextDimension.kt @@ -4,6 +4,7 @@ import androidx.compose.ui.unit.sp @Suppress("MagicNumber") object TextDimension { + val Sp14 = 14.sp val Sp16 = 16.sp val Sp24 = 24.sp } diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Theme.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Theme.kt index 07bb69ad..fdf67922 100644 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Theme.kt +++ b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Theme.kt @@ -5,18 +5,23 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.darkColors import androidx.compose.material.lightColors import androidx.compose.runtime.Composable -import co.nimblehq.compose.crypto.ui.theme.Color.AlmostWhite +import co.nimblehq.compose.crypto.ui.theme.Color.Cultured import co.nimblehq.compose.crypto.ui.theme.Color.BlueFreeSpeech +import co.nimblehq.compose.crypto.ui.theme.Color.DarkJungleGreen +@Suppress("MatchingDeclarationName") object Palette { val ComposeLightPalette = lightColors( primary = BlueFreeSpeech, - background = AlmostWhite + surface = Cultured ) - val ComposeDarkPalette = darkColors() + val ComposeDarkPalette = darkColors( + surface = DarkJungleGreen + ) } +@Suppress("FunctionNaming") @Composable fun ComposeTheme( darkTheme: Boolean = isSystemInDarkTheme(), @@ -30,7 +35,6 @@ fun ComposeTheme( MaterialTheme( colors = colors, - typography = Typography.ComposeTypography, shapes = Shape.ComposeShapes, content = content ) diff --git a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Typography.kt b/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Typography.kt deleted file mode 100644 index ad7515b9..00000000 --- a/app/src/main/java/co/nimblehq/compose/crypto/ui/theme/Typography.kt +++ /dev/null @@ -1,18 +0,0 @@ -package co.nimblehq.compose.crypto.ui.theme - -import androidx.compose.material.Typography -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import co.nimblehq.compose.crypto.R - -object Typography { - private val InterFontFamily = FontFamily( - Font(R.font.inter_medium, FontWeight.Medium), - Font(R.font.inter_semi_bold, FontWeight.SemiBold) - ) - - val ComposeTypography = Typography( - defaultFontFamily = InterFontFamily - ) -} diff --git a/app/src/main/res/drawable/ic_btc_bitcoin.png b/app/src/main/res/drawable/ic_btc_bitcoin.png new file mode 100644 index 00000000..3a311de9 Binary files /dev/null and b/app/src/main/res/drawable/ic_btc_bitcoin.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a7e7bb47..ac01adf6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,10 +4,12 @@ Unexpected error Trade Now and Get\nYour Life + My Coins 😎 + see all Total Coins - $%s Today\'s Profit - $%s - %1$s%% + + $%s + %1$s%%