Skip to content

Commit

Permalink
Merge pull request #12 from nimblehq/feature/5-implement-ui-my-coins-…
Browse files Browse the repository at this point in the history
…list-on-home-screen

[#5] Implement UI My coins list on home page
  • Loading branch information
hoangnguyen92dn authored Aug 18, 2022
2 parents 2b7f183 + 1c2e973 commit 27aa31b
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -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()
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
Expand All @@ -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() {
Expand All @@ -57,6 +107,7 @@ fun HomeScreenPreview() {
}
}

@Suppress("FunctionNaming")
@Composable
@Preview
fun HomeScreenPreviewDark() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,6 +41,7 @@ fun PortfolioCard(
colors = listOf(Color.MetallicSeaweed, Color.TiffanyBlue),
)
)
.padding(horizontal = Dp16, vertical = Dp16)
) {
val (
totalCoinsLabel,
Expand All @@ -51,7 +53,6 @@ fun PortfolioCard(

Text(
modifier = Modifier
.padding(top = Dp16, start = Dp16)
.constrainAs(totalCoinsLabel) {
start.linkTo(parent.start)
},
Expand All @@ -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)
},
Expand All @@ -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)
Expand All @@ -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() {
Expand Down
Loading

0 comments on commit 27aa31b

Please sign in to comment.