main #25

Merged
andy merged 14 commits from main into pipeline-test 2025-03-08 22:15:23 +03:00
6 changed files with 121 additions and 52 deletions
Showing only changes of commit 09871e8727 - Show all commits

1
.idea/misc.xml generated
View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">

View File

@ -7,5 +7,5 @@ data class GlobalResponse(
@SerializedName("active_currencies") val activeCryptocurrencies: String = "", @SerializedName("active_currencies") val activeCryptocurrencies: String = "",
@SerializedName("total_market_cap_usd") val totalMarketCapUsd: String = "", @SerializedName("total_market_cap_usd") val totalMarketCapUsd: String = "",
@SerializedName("total_24h_volume_usd") val total24hVolumeUsd: String = "", @SerializedName("total_24h_volume_usd") val total24hVolumeUsd: String = "",
@SerializedName("bitcoin_percentage_of_market_cap") val bitcoinPercentageOfMarketCap: String = "" @SerializedName("bitcoin_percentage_of_market_cap") val bitcoinPercentageOfMarketCap: String = "0.0"
) )

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@ -42,28 +43,43 @@ import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLabelComponent
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLineComponent
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLine
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState
import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent
import com.patrykandpatrick.vico.compose.common.component.rememberTextComponent import com.patrykandpatrick.vico.compose.common.component.rememberTextComponent
import com.patrykandpatrick.vico.compose.common.component.shapeComponent import com.patrykandpatrick.vico.compose.common.component.shapeComponent
import com.patrykandpatrick.vico.compose.common.fill import com.patrykandpatrick.vico.compose.common.fill
import com.patrykandpatrick.vico.compose.common.shape.rounded import com.patrykandpatrick.vico.compose.common.shape.rounded
import com.patrykandpatrick.vico.compose.common.vicoTheme
import com.patrykandpatrick.vico.core.cartesian.Zoom import com.patrykandpatrick.vico.core.cartesian.Zoom
import com.patrykandpatrick.vico.core.cartesian.axis.BaseAxis
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.CartesianLayerRangeProvider
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
import com.patrykandpatrick.vico.core.cartesian.decoration.HorizontalLine import com.patrykandpatrick.vico.core.cartesian.decoration.HorizontalLine
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
import com.patrykandpatrick.vico.core.common.Position import com.patrykandpatrick.vico.core.common.Position
import com.patrykandpatrick.vico.core.common.component.LineComponent import com.patrykandpatrick.vico.core.common.component.LineComponent
import com.patrykandpatrick.vico.core.common.component.TextComponent import com.patrykandpatrick.vico.core.common.component.TextComponent
import com.patrykandpatrick.vico.core.common.shape.CorneredShape import com.patrykandpatrick.vico.core.common.shape.CorneredShape
import ru.vendetti.bitcoin_summarizer.ui.theme.BitcoinSummarizerTheme import ru.vendetti.bitcoin_summarizer.ui.theme.BitcoinSummarizerTheme
import ru.vendetti.bitcoin_summarizer.ui.theme.EnglishViolet
import ru.vendetti.bitcoin_summarizer.ui.theme.Flame
import ru.vendetti.bitcoin_summarizer.ui.theme.Green2
import java.text.DateFormat import java.text.DateFormat
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Date
import kotlin.math.roundToInt
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -76,7 +92,7 @@ class MainActivity : ComponentActivity() {
} }
} }
@SuppressLint("MutableCollectionMutableState") @SuppressLint("MutableCollectionMutableState", "SimpleDateFormat")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Preview @Preview
@Composable @Composable
@ -109,15 +125,24 @@ fun CryptoScreen() {
LaunchedEffect(fearGreedDataList) { LaunchedEffect(fearGreedDataList) {
modelProducer.runTransaction { modelProducer.runTransaction {
var numberValues = Array<Int>(fearGreedDataList.count()) { index -> fearGreedDataList[index].value.toInt() } var numberValues = Array<Int>(fearGreedDataList.count()) {
index ->
fearGreedDataList[fearGreedDataList.count() - index - 1]
.value.toInt()
}
if(numberValues.isEmpty()) if(numberValues.isEmpty())
numberValues = Array<Int>(1) {0} numberValues = Array<Int>(1) {0}
lineSeries { series(numberValues.toList()) } lineSeries { series(numberValues.toList()) }
} }
} }
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
val zoomState = rememberVicoZoomState(initialZoom = Zoom.x(fearGreedIndexDaysCount.toDouble())) val zoomState = rememberVicoZoomState(
zoomEnabled = false,
initialZoom = Zoom.x(fearGreedIndexDaysCount.toDouble()))
// Отображаем результаты на странице // Отображаем результаты на странице
Scaffold ( Scaffold (
modifier = Modifier modifier = Modifier
@ -126,8 +151,11 @@ fun CryptoScreen() {
topBar = { topBar = {
MediumTopAppBar( MediumTopAppBar(
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer, containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.primary, scrolledContainerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.onPrimary,
navigationIconContentColor = MaterialTheme.colorScheme.onPrimary,
actionIconContentColor = MaterialTheme.colorScheme.onPrimary,
), ),
title = { title = {
Text( Text(
@ -159,7 +187,7 @@ fun CryptoScreen() {
{ innerPadding -> { innerPadding ->
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .background(Color.Transparent)
.padding(innerPadding) .padding(innerPadding)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
@ -171,27 +199,44 @@ fun CryptoScreen() {
CartesianChartHost( CartesianChartHost(
zoomState = zoomState, zoomState = zoomState,
chart = rememberCartesianChart( chart = rememberCartesianChart(
rememberLineCartesianLayer(), rememberLineCartesianLayer(
lineProvider = LineCartesianLayer.LineProvider.series(
vicoTheme.lineCartesianLayerColors.map{
_ ->
LineCartesianLayer
.rememberLine(
LineCartesianLayer.LineFill.single(
fill(MaterialTheme.colorScheme.onPrimary)
)
)
}
),
rangeProvider = remember { CartesianLayerRangeProvider.fixed(minY = 0.0, maxY = 100.0)}
),
startAxis = VerticalAxis.rememberStart( startAxis = VerticalAxis.rememberStart(
titleComponent = rememberTextComponent(), title = "FGI",
title = "FGI" titleComponent = rememberTextComponent(MaterialTheme.colorScheme.onPrimary),
line = rememberAxisLineComponent(fill(MaterialTheme.colorScheme.onPrimary)),
label = rememberAxisLabelComponent(MaterialTheme.colorScheme.onPrimary)
), ),
bottomAxis = HorizontalAxis.rememberBottom( bottomAxis = HorizontalAxis.rememberBottom(
titleComponent = rememberTextComponent(), title = "last $fearGreedIndexDaysCount days",
title = "last $fearGreedIndexDaysCount days" titleComponent = rememberTextComponent(MaterialTheme.colorScheme.onPrimary),
line = rememberAxisLineComponent(fill(MaterialTheme.colorScheme.onPrimary)),
label = rememberAxisLabelComponent(MaterialTheme.colorScheme.onPrimary)
), ),
decorations = listOf( decorations = listOf(
remember { remember {
HorizontalLine( HorizontalLine(
y = { 15.toDouble() }, y = { 25.toDouble() },
line = LineComponent(fill(Color.Red), 2f), line = LineComponent(fill(Flame), 2f),
labelComponent = TextComponent( labelComponent = TextComponent(
background = background =
shapeComponent( shapeComponent(
fill(Color.Red), fill(Flame),
CorneredShape.rounded( CorneredShape.rounded(
bottomLeft = 4.dp, topLeft = 4.dp,
bottomRight = 4.dp topRight = 4.dp
) )
), ),
), ),
@ -201,12 +246,12 @@ fun CryptoScreen() {
}, },
remember { remember {
HorizontalLine( HorizontalLine(
y = { 60.toDouble() }, y = { 70.toDouble() },
line = LineComponent(fill(Color.Green), 2f), line = LineComponent(fill(Green2), 2f),
labelComponent = TextComponent( labelComponent = TextComponent(
background = background =
shapeComponent( shapeComponent(
fill(Color.Green), fill(Green2),
CorneredShape.rounded( CorneredShape.rounded(
bottomLeft = 4.dp, bottomLeft = 4.dp,
bottomRight = 4.dp bottomRight = 4.dp
@ -229,15 +274,23 @@ fun CryptoScreen() {
.align(alignment = Alignment.CenterHorizontally), .align(alignment = Alignment.CenterHorizontally),
fontSize = 24.sp fontSize = 24.sp
) )
Text("Текущая цена: \n ${bitcoinTicker.priceUsd}\n") val formatter = DecimalFormat("0.00")
Text("Суточный оборот: \n ${bitcoinTicker.volume24hUsd}\n") Text("Текущая цена: \n \$ ${formatter.format(bitcoinTicker.priceUsd.toFloat())}\n")
Text("Капитализация: \n ${bitcoinTicker.marketCapUsd}\n") Text("Суточный оборот: \n \$ ${bitcoinTicker.volume24hUsd}\n")
Text("Капитализация: \n \$ ${bitcoinTicker.marketCapUsd}\n")
Text( Text(
"Изменение курса за: " + "Изменение курса за: " +
"\n Сутки: ${bitcoinTicker.percentChange24h} " + "\n Сутки: ${formatter.format(bitcoinTicker.percentChange24h.toFloat())}% " +
"\n Неделю: ${bitcoinTicker.percentChange7d}\n" "\n Неделю: ${formatter.format(bitcoinTicker.percentChange7d.toFloat())}%\n"
) )
Text("Дата последнего обновления: \n ${bitcoinTicker.lastUpdated}\n")
var humanDate = ""
if(bitcoinTicker.lastUpdated.isNotEmpty())
humanDate = DateTimeFormatter.ISO_INSTANT
.format(java.time.Instant.ofEpochSecond(bitcoinTicker.lastUpdated.toLong()))
Text("Дата последнего обновления: \n ${humanDate}\n")
HorizontalDivider(thickness = 2.dp) HorizontalDivider(thickness = 2.dp)
Text( Text(
@ -246,10 +299,10 @@ fun CryptoScreen() {
.align(alignment = Alignment.CenterHorizontally), .align(alignment = Alignment.CenterHorizontally),
fontSize = 24.sp fontSize = 24.sp
) )
Text("Общая капитализация крипторынка: \n ${globalData.totalMarketCapUsd}\n") Text("Общая капитализация крипторынка: \n \$ ${globalData.totalMarketCapUsd}\n")
Text("Всего видов криптовалют: \n ${globalData.activeCryptocurrencies}\n") Text("Всего видов криптовалют: \n ${globalData.activeCryptocurrencies}\n")
Text("Суточный оборот других криптовалют: \n ${globalData.total24hVolumeUsd}\n") Text("Суточный оборот других криптовалют: \n \$ ${globalData.total24hVolumeUsd}\n")
Text("Процент доминации Биткоина: \n ${globalData.bitcoinPercentageOfMarketCap}\n") Text("Процент доминации Биткоина: \n ${formatter.format(globalData.bitcoinPercentageOfMarketCap.toFloat())}%\n")
} }
} }
} }

View File

@ -11,15 +11,15 @@ data class TickerData(
val name: String = "", val name: String = "",
val symbol: String = "", val symbol: String = "",
val rank: String = "", val rank: String = "",
@SerializedName("price_usd") val priceUsd: String = "", @SerializedName("price_usd") val priceUsd: String = "0.0",
@SerializedName("price_btc") val priceBtc: String = "", @SerializedName("price_btc") val priceBtc: String = "0.0",
@SerializedName("24h_volume_usd") val volume24hUsd: String = "", @SerializedName("24h_volume_usd") val volume24hUsd: String = "0",
@SerializedName("market_cap_usd") val marketCapUsd: String = "", @SerializedName("market_cap_usd") val marketCapUsd: String = "0",
@SerializedName("available_supply") val availableSupply: String = "", @SerializedName("available_supply") val availableSupply: String = "0",
@SerializedName("total_supply") val totalSupply: String = "", @SerializedName("total_supply") val totalSupply: String = "0",
@SerializedName("max_supply") val maxSupply: String? = "", @SerializedName("max_supply") val maxSupply: String? = "0",
@SerializedName("percent_change_1h") val percentChange1h: String = "", @SerializedName("percent_change_1h") val percentChange1h: String = "0",
@SerializedName("percent_change_24h") val percentChange24h: String = "", @SerializedName("percent_change_24h") val percentChange24h: String = "0.0",
@SerializedName("percent_change_7d") val percentChange7d: String = "", @SerializedName("percent_change_7d") val percentChange7d: String = "0.0",
@SerializedName("last_updated") val lastUpdated: String = "" @SerializedName("last_updated") val lastUpdated: String = ""
) )

View File

@ -9,3 +9,11 @@ val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4) val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71) val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260) val Pink40 = Color(0xFF7D5260)
val EnglishViolet = Color(0xFF44355B)
val DarkPurple = Color(0xFF31263E)
val RaisinBlack = Color(0xFF221E22)
val HunyadiYellow = Color(0xFFECA72C)
val Flame = Color(0xFFEE5622)
val Green2 = Color(0xFFB1E434)

View File

@ -9,28 +9,37 @@ import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme( private val DarkColorScheme = darkColorScheme(
primary = Purple80, primary = RaisinBlack,
secondary = PurpleGrey80, secondary = DarkPurple,
tertiary = Pink80 tertiary = EnglishViolet,
// Other default colors to override
background = DarkPurple,
surface = Color(0xFFFFFBFE),
onPrimary = HunyadiYellow,
onSecondary = HunyadiYellow,
onTertiary = HunyadiYellow,
onBackground = HunyadiYellow,
onSurface = Color(0xFF1C1B1F),
) )
private val LightColorScheme = lightColorScheme( private val LightColorScheme = lightColorScheme(
primary = Purple40, primary = HunyadiYellow,
secondary = PurpleGrey40, secondary = Flame,
tertiary = Pink40 tertiary = EnglishViolet,
/* Other default colors to override // Other default colors to override
background = Color(0xFFFFFBFE), background = Color.White,
surface = Color(0xFFFFFBFE), surface = Color(0xFFFFFBFE),
onPrimary = Color.White, onPrimary = RaisinBlack,
onSecondary = Color.White, onSecondary = Color.White,
onTertiary = Color.White, onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F), onBackground = RaisinBlack,
onSurface = Color(0xFF1C1B1F), onSurface = Color(0xFF1C1B1F),
*/
) )
@Composable @Composable