diff --git a/README.md b/README.md
index fa0d054d..430f3f50 100644
--- a/README.md
+++ b/README.md
@@ -59,9 +59,9 @@ Spotify | Instagram Demo | Twitter, Gmail, Youtube
:-------------------------:|:-------------------------: | :-------------------------: | :-------------------------:
 |  |  | 
-Gmail full | Tiktok
-:-------------------------:|:-------------------------:
- | 
+Gmail full | Tiktok | Complete Crypto App Ui
+:-------------------------:|:-------------------------: |:-------------------------:
+ |  | 
### Apps with Api, Retrofit, Room, Flow, Livedata Integration
CryptoApp MVVM | MovieApp MVI | Dating APP DEMO UI | Betty
diff --git a/demos/CryptoAppUi/.gitignore b/demos/CryptoAppUi/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/demos/CryptoAppUi/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/demos/CryptoAppUi/.idea/.gitignore b/demos/CryptoAppUi/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/demos/CryptoAppUi/.idea/.name b/demos/CryptoAppUi/.idea/.name
new file mode 100644
index 00000000..37a31949
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/.name
@@ -0,0 +1 @@
+Crypto App
\ No newline at end of file
diff --git a/demos/CryptoAppUi/.idea/compiler.xml b/demos/CryptoAppUi/.idea/compiler.xml
new file mode 100644
index 00000000..fb7f4a8a
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/.idea/deploymentTargetDropDown.xml b/demos/CryptoAppUi/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000..10f81e3d
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/.idea/gradle.xml b/demos/CryptoAppUi/.idea/gradle.xml
new file mode 100644
index 00000000..a2d7c213
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/.idea/inspectionProfiles/Project_Default.xml b/demos/CryptoAppUi/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..28422375
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/.idea/misc.xml b/demos/CryptoAppUi/.idea/misc.xml
new file mode 100644
index 00000000..4626c32e
--- /dev/null
+++ b/demos/CryptoAppUi/.idea/misc.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/README.md b/demos/CryptoAppUi/README.md
new file mode 100644
index 00000000..c33a87b4
--- /dev/null
+++ b/demos/CryptoAppUi/README.md
@@ -0,0 +1,12 @@
+# CryptoUIJetpackCompose
+
+Complete Crypto App UI Designed using Jetpack Compose
+
+## Preview
+
+
+
+
+## FeedBack
+
+Feel free to for feedback!! Ping me in LinkedIn for some healthy discussions!!
diff --git a/demos/CryptoAppUi/app/.gitignore b/demos/CryptoAppUi/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/demos/CryptoAppUi/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/build.gradle b/demos/CryptoAppUi/app/build.gradle
new file mode 100644
index 00000000..21b77dcf
--- /dev/null
+++ b/demos/CryptoAppUi/app/build.gradle
@@ -0,0 +1,70 @@
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
+
+android {
+ compileSdk 30
+
+ defaultConfig {
+ applicationId "com.rs.crypto"
+ minSdk 21
+ targetSdk 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ useIR = true
+ }
+ buildFeatures {
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion compose_version
+ kotlinCompilerVersion '1.5.10'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.3.0'
+ implementation "androidx.compose.ui:ui:$compose_version"
+ implementation "androidx.compose.material:material:$compose_version"
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.3.0-alpha06'
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
+ debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
+
+// Jetpack Compose Navigation
+ implementation("androidx.navigation:navigation-compose:2.4.0-alpha05")
+// Jetpack Compose extended icons
+ implementation "androidx.compose.material:material-icons-extended:$compose_version"
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/proguard-rules.pro b/demos/CryptoAppUi/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/demos/CryptoAppUi/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/androidTest/java/com/rs/crypto/ExampleInstrumentedTest.kt b/demos/CryptoAppUi/app/src/androidTest/java/com/rs/crypto/ExampleInstrumentedTest.kt
new file mode 100644
index 00000000..091c4cdb
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/androidTest/java/com/rs/crypto/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.rs.crypto
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.srivathsanvenkateswaran.cryptocurrencyapp", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/AndroidManifest.xml b/demos/CryptoAppUi/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..3b60628a
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/MainActivity.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/MainActivity.kt
new file mode 100644
index 00000000..8991643f
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/MainActivity.kt
@@ -0,0 +1,120 @@
+package com.rs.crypto
+
+import android.os.Bundle
+import android.widget.Toast
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import androidx.navigation.*
+import androidx.navigation.compose.rememberNavController
+import com.rs.crypto.composables.*
+import com.rs.crypto.ui.theme.CryptocurrencyAppTheme
+import com.rs.crypto.ui.theme.Purple500
+import com.rs.crypto.utils.NavigationItems
+import com.rs.crypto.utils.Screen
+import kotlinx.coroutines.*
+
+class MainActivity : ComponentActivity() {
+ @ExperimentalMaterialApi
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ CryptocurrencyAppTheme {
+ TradeModelBottomSheet(
+ onButtonClick = {
+ Toast
+ .makeText(this, "Processing transaction...", Toast.LENGTH_LONG)
+ .show()
+ }
+ )
+ }
+ }
+ }
+}
+
+@ExperimentalMaterialApi
+@Composable
+private fun MainActivityContent(
+ coroutineScope: CoroutineScope,
+ modalBottomSheetState: ModalBottomSheetState
+) {
+ val navController = rememberNavController()
+
+ Scaffold(
+ bottomBar = {
+ BottomnavigationBar(
+ onItemSelected = {
+ when (it) {
+ NavigationItems.Home -> navController.navigate(Screen.HomeScreen.route)
+ NavigationItems.Portfolio -> navController.navigate(Screen.PortfolioScreen.route)
+ NavigationItems.Prices -> navController.navigate(Screen.PricesScreen.route)
+ NavigationItems.Settings -> navController.navigate(Screen.SettingsScreen.route)
+ }
+ }
+ )
+ },
+ floatingActionButton = {
+ FloatingActionButton(
+ onClick = {
+ coroutineScope.launch{
+ modalBottomSheetState.show()
+ }
+ },
+ backgroundColor = Purple500,
+ contentColor = Color.White,
+ elevation = FloatingActionButtonDefaults.elevation(defaultElevation = 0.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.transaction),
+ contentDescription = null,
+ modifier = Modifier.size(30.dp)
+ )
+ }
+ },
+ floatingActionButtonPosition = FabPosition.Center,
+ isFloatingActionButtonDocked = true,
+ drawerShape = MaterialTheme.shapes.small,
+ modifier = Modifier.shadow(
+ elevation = 10.dp,
+ shape = RectangleShape
+ )
+ ) {
+ Navigation(navController)
+ }
+}
+
+
+@Composable
+@ExperimentalMaterialApi
+private fun TradeModelBottomSheet(
+ onButtonClick: () -> Unit
+) {
+ val modalBottomSheetState = rememberModalBottomSheetState(
+ initialValue =ModalBottomSheetValue.Hidden
+ )
+
+ val scope = rememberCoroutineScope()
+
+ ModalBottomSheetLayout(
+ sheetState = modalBottomSheetState,
+ sheetContent = {
+ TradeScreen(
+ onButtonClick = {
+ onButtonClick()
+ }
+ )
+ },
+ content = {
+ MainActivityContent(scope, modalBottomSheetState)
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/AllSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/AllSection.kt
new file mode 100644
index 00000000..3e199034
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/AllSection.kt
@@ -0,0 +1,58 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun AllSection(
+ onItemClick: (String) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ ) {
+ Text(
+ text = "Following",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.followingTokens) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ Text(
+ text = "Cryptocurrencies",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.trendingCurrencies) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CoinRateItem.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CoinRateItem.kt
new file mode 100644
index 00000000..5632080b
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CoinRateItem.kt
@@ -0,0 +1,128 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.Text
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.ui.theme.*
+import com.rs.crypto.utils.Constants
+
+
+@Composable
+fun CoinRateItem(
+ currency: TrendingCurrency,
+ onItemClick: (String) -> Unit = {}
+) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ horizontal = Constants.PADDING_SIDE_VALUE.dp,
+ vertical = (Constants.PADDING_SIDE_VALUE / 2).dp
+ )
+ .clickable {
+ onItemClick(currency.currencyCode)
+ }
+ ) {
+ CurrencyInfoSection(currency = currency)
+
+ CoinAmountSection(currency = currency)
+ }
+}
+
+
+@Composable
+fun CurrencyInfoSection(
+ currency: TrendingCurrency,
+ modifier: Modifier = Modifier
+) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = modifier
+ ) {
+ Image(
+ painter = painterResource(id = currency.imageRes),
+ contentDescription = "Transaction image",
+ modifier = Modifier
+ .padding(end = (Constants.PADDING_SIDE_VALUE * 1.5).dp)
+ )
+
+ Column {
+ Text(
+ text = currency.currencyName,
+ style = Typography.h4,
+ )
+
+ Spacer(modifier = Modifier.height(4.dp))
+
+ Text(
+ text = currency.currencyCode,
+ style = Typography.h5,
+ color = Gray
+ )
+ }
+ }
+}
+
+@Composable
+private fun CoinAmountSection(currency: TrendingCurrency) {
+
+ val operator by remember {
+ mutableStateOf(
+ if(currency.changeType == "I") {
+ '+'
+ } else {
+ '-'
+ }
+ )
+ }
+
+ val changesColor by remember {
+ mutableStateOf(
+ if(currency.changeType == "I") {
+ Color.Green
+ } else {
+ Color.Red
+ }
+ )
+ }
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(
+ horizontalAlignment = Alignment.End
+ ) {
+ Text(
+ text = "£${currency.currentPrice}",
+ style = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 16.sp,
+ lineHeight = 22.sp
+ ),
+ color = Color.Black
+ )
+
+ Text(
+ text = "$operator${currency.changes}%",
+ style = TextStyle(
+ fontFamily = RobotoBold,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ color = changesColor
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CryptoSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CryptoSection.kt
new file mode 100644
index 00000000..8bda737e
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/CryptoSection.kt
@@ -0,0 +1,40 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun CryptoSection(
+ onItemClick: (String) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ ) {
+ Text(
+ text = "Cryptocurrencies",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.trendingCurrencies) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/FollowingSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/FollowingSection.kt
new file mode 100644
index 00000000..bc7c129e
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/FollowingSection.kt
@@ -0,0 +1,40 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun FollowingSection(
+ onItemClick: (String) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ ) {
+ Text(
+ text = "Following",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.followingTokens) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/StableCoinsSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/StableCoinsSection.kt
new file mode 100644
index 00000000..08091515
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/StableCoinsSection.kt
@@ -0,0 +1,40 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun StableCoinsSection(
+ onItemClick: (String) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ ) {
+ Text(
+ text = "Stablecoins",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.stableCoins) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/UtilityTokensSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/UtilityTokensSection.kt
new file mode 100644
index 00000000..00bfb660
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/prices_components/UtilityTokensSection.kt
@@ -0,0 +1,40 @@
+package com.rs.crypto.composables.prices_components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun UtilityTokensSection(
+ onItemClick: (String) -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ ) {
+ Text(
+ text = "Utility Tokens",
+ fontSize = 14.sp
+ )
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ LazyColumn {
+ itemsIndexed(items = DummyData.utilityTokens) { index: Int, item: TrendingCurrency ->
+ CoinRateItem(
+ currency = item,
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/BottomNavigationBar.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/BottomNavigationBar.kt
new file mode 100644
index 00000000..6606095f
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/BottomNavigationBar.kt
@@ -0,0 +1,88 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.rs.crypto.ui.theme.*
+import com.rs.crypto.utils.NavigationItems
+
+@Composable
+fun BottomnavigationBar(
+ modifier: Modifier = Modifier,
+ onItemSelected: (NavigationItems) -> Unit
+) {
+
+ val navigationItems = listOf(
+ NavigationItems.Home,
+ NavigationItems.Portfolio,
+ NavigationItems.Transaction,
+ NavigationItems.Prices,
+ NavigationItems.Settings
+ )
+
+ var selectedNavItemIndex by remember {
+ mutableStateOf(0)
+ }
+
+ BottomNavigation(
+ modifier = modifier
+ .shadow(
+ elevation = 10.dp,
+ shape = RectangleShape
+ ),
+ contentColor = Purple500,
+ backgroundColor = Color.White,
+ ) {
+ navigationItems.forEach{
+ var isSelected = selectedNavItemIndex == navigationItems.indexOf(it)
+ BottomNavigationItem(
+ selected = isSelected,
+ onClick = {
+ selectedNavItemIndex = navigationItems.indexOf(it)
+ onItemSelected(it)
+ },
+ icon = {
+ Column(horizontalAlignment = CenterHorizontally) {
+ if (it.name == NavigationItems.Transaction.name) {
+
+ } else {
+ Icon(
+ painter = painterResource(id = it.iconRes),
+ contentDescription = it.name,
+ modifier = Modifier.size(20.dp)
+ )
+ }
+
+ if(isSelected){
+ Text(
+ text = it.name,
+ style = Typography.h5,
+ maxLines = 1
+ )
+ }
+ }
+
+ },
+ selectedContentColor = Purple500,
+ unselectedContentColor = Color.Black
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+fun BottomNavBarPreview() {
+ BottomnavigationBar() {
+
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/CryptoDetailScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/CryptoDetailScreen.kt
new file mode 100644
index 00000000..505a0d8d
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/CryptoDetailScreen.kt
@@ -0,0 +1,304 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.*
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+import com.rs.crypto.R
+import com.rs.crypto.ui.theme.*
+
+@Composable
+fun CryptoDetailScreen(
+ currencyCode: String,
+ onBackArrowPressed: () -> Unit,
+ onButtonClick: (String) -> Unit
+) {
+ val currency = DummyData.trendingCurrencies.find { it.currencyCode == currencyCode }!!
+
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Secondary
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(bottom = 50.dp)
+ ) {
+ TopNavigationRow(onBackArrowPressed = onBackArrowPressed)
+
+ LineChartCardSection(currency = currency)
+
+ BuyCryptoCard(
+ currency = currency,
+ onButtonClick = onButtonClick
+ )
+
+ CurrencyDescriptionCard(currency = currency)
+
+ SetPriceAlertSection()
+ }
+ }
+}
+
+@Composable
+private fun CurrencyDescriptionCard(currency: TrendingCurrency) {
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ shape = MaterialTheme.shapes.medium,
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ Text(
+ text = "About ${currency.currencyName}",
+ style = Typography.h2
+ )
+
+ Spacer(modifier = Modifier.height(2.dp))
+
+ Text(
+ text = "${currency.description}",
+ style = Typography.subtitle2
+ )
+ }
+ }
+}
+
+@Composable
+private fun BuyCryptoCard(
+ currency: TrendingCurrency,
+ onButtonClick: (String) -> Unit
+) {
+ Card(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .fillMaxWidth(),
+ elevation = Constants.ELEVATION_VALUE.dp,
+ shape = MaterialTheme.shapes.medium
+ ) {
+ Column() {
+ CurrencyInfoBuyRow(currency = currency)
+
+ StandardButton(
+ onButtonClick = onButtonClick,
+ currency = currency,
+ buttonText = "Buy"
+ )
+ }
+ }
+}
+
+@Composable
+fun StandardButton(
+ onButtonClick: (String) -> Unit,
+ currency: TrendingCurrency,
+ buttonText: String
+) {
+ Button(
+ onClick = {
+ onButtonClick(currency.currencyCode)
+ },
+ colors = ButtonDefaults.buttonColors(
+ backgroundColor = Secondary
+ ),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ shape = MaterialTheme.shapes.medium
+ ) {
+ Text(
+ text = buttonText,
+ color = Color.White
+ )
+ }
+}
+
+@Composable
+private fun CurrencyInfoBuyRow(currency: TrendingCurrency) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ CurrencyItem(currency = currency)
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(
+ horizontalAlignment = Alignment.End
+ ) {
+ Text(
+ text = "£${DummyData.portfolio.balance}",
+ style = Typography.h2,
+ )
+
+ Text(
+ text = "${currency.wallet.crypto} ${currency.currencyCode}",
+ style = Typography.subtitle2,
+ color = BlueGrey700
+ )
+ }
+
+ Image(
+ painter = painterResource(id = R.drawable.right_arrow),
+ contentDescription = null,
+ modifier = Modifier
+ .clipToBounds()
+ .padding(start = (Constants.PADDING_SIDE_VALUE * 1.5).dp)
+ )
+ }
+ }
+}
+
+@Composable
+private fun LineChartCardSection(currency: TrendingCurrency) {
+ Card(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .fillMaxWidth(),
+ elevation = Constants.ELEVATION_VALUE.dp,
+ shape = MaterialTheme.shapes.medium
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ CardCurrencyInfoSection(currency = currency)
+
+// Insert line chart later
+ Image(
+ painter = painterResource(id = R.drawable.sample_line_chart_image),
+ contentDescription = "Line chart image",
+ modifier = Modifier
+ .fillMaxWidth(),
+ contentScale = ContentScale.FillWidth
+ )
+ }
+ }
+}
+
+@Composable
+private fun CardCurrencyInfoSection(
+ currency: TrendingCurrency
+) {
+ Column() {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ CurrencyItem(currency = currency)
+
+ Column() {
+ ValuesItem(
+ currency = currency,
+ priceModifier = Modifier,
+ currencyPriceStyle = Typography.h2
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun TopNavigationRow(
+ onBackArrowPressed: () -> Unit,
+ isStarNeeded: Boolean = true
+) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .wrapContentHeight()
+ .padding(
+ top = (Constants.ELEVATION_VALUE + Constants.PADDING_SIDE_VALUE).dp,
+ start = (2 * Constants.ELEVATION_VALUE).dp,
+ end = Constants.PADDING_SIDE_VALUE.dp
+ )
+ .fillMaxWidth()
+ ) {
+ BackRowItem(onBackArrowPressed = onBackArrowPressed)
+
+ FavouritesStarItem(isStarNeeded)
+ }
+}
+
+@Composable
+private fun FavouritesStarItem(
+ isStarNeeded: Boolean = true
+) {
+ if (isStarNeeded) {
+ Row() {
+ Image(
+ painter = painterResource(id = R.drawable.star),
+ contentDescription = "favourites start",
+ modifier = Modifier
+ .size(25.dp)
+ )
+ }
+ }
+}
+
+@Composable
+private fun BackRowItem(onBackArrowPressed: () -> Unit) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ imageVector = Icons.Default.ArrowBack,
+ contentDescription = "Go back",
+ tint = Color.White,
+ modifier = Modifier
+ .size(25.dp)
+ .clickable {
+ onBackArrowPressed()
+ }
+ )
+
+ Text(
+ text = "Back",
+ modifier = Modifier
+ .padding(start = 8.dp),
+ style = Typography.h2,
+ color = Color.White
+ )
+ }
+}
+
+@Preview
+@Composable
+fun CyptoDetailScreenPreview() {
+ CryptoDetailScreen(
+ currencyCode = "ETH",
+ onBackArrowPressed = {
+
+ },
+ onButtonClick = {
+
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/HomeScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/HomeScreen.kt
new file mode 100644
index 00000000..92edd8b7
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/HomeScreen.kt
@@ -0,0 +1,530 @@
+package com.rs.crypto.composables
+
+import android.util.Log
+import androidx.compose.foundation.*
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.R
+import com.rs.crypto.models.Transaction
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.ui.theme.*
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun HomeScreen(
+ onCardClick: (String) -> Unit
+) {
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Secondary
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(bottom = 50.dp)
+ ) {
+ HomeScreenContent(onCardClick = onCardClick)
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterialApi::class)
+@Composable
+private fun HomeScreenContent(
+ onCardClick: (String) -> Unit
+) {
+ Box {
+ BannerImage()
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier
+ .fillMaxWidth(0.9f)
+ .align(Alignment.TopCenter)
+ .padding(
+ top = 30.dp,
+ )
+ ) {
+ Icon(
+ Icons.Filled.HorizontalSplit,
+ contentDescription = "More",
+ tint = Color.White
+ )
+
+ BadgeBox(badgeContent = {
+ Text("12")
+ },
+ ){
+ Icon(
+ Icons.Default.Notifications,
+ contentDescription = "Notifications",
+ tint = Color.White
+ )
+ }
+ }
+
+// Image(
+// painter = painterResource(id = R.drawable.notification_white),
+// contentDescription = "Notification",
+// modifier = Modifier
+// .padding(
+// top = 40.dp,
+// end = 25.dp
+// )
+// .align(alignment = Alignment.TopEnd)
+// .clickable {
+// Log.d("HomeScreen", "Notification icon Pressed")
+// }
+// )
+ Box(
+ modifier = Modifier
+ .align(alignment = Alignment.TopCenter)
+ .padding(top = 80.dp)
+ ) {
+ PortfolioBalanceSection()
+ }
+
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ top = 180.dp,
+ )
+ ) {
+ Text(
+ text = "Trending",
+ color = Color.White,
+ style = Typography.h2,
+ modifier = Modifier
+ .padding(start = Constants.PADDING_SIDE_VALUE.dp)
+ )
+
+ Row(
+ modifier = Modifier
+ .horizontalScroll(rememberScrollState())
+ ) {
+// items(items = DummyData.trendingCurrencies) { currency ->
+// Spacer(modifier = Modifier.width(Constants.PADDING_SIDE_VALUE.dp))
+// CurrencyCard(
+// currency = currency,
+// onCardClick = onCardClick
+// )
+// }
+
+ DummyData.trendingCurrencies.forEachIndexed{ index, currency ->
+ if (index == 0) {
+ Spacer(modifier = Modifier.width(Constants.PADDING_SIDE_VALUE.dp))
+ }
+
+ CurrencyCard(
+ currency = currency,
+ onCardClick = onCardClick
+ )
+
+ Spacer(modifier = Modifier.width(Constants.PADDING_SIDE_VALUE.dp))
+ }
+ }
+
+ Spacer(modifier = Modifier.height(Constants.ELEVATION_VALUE.dp))
+
+ SetPriceAlertSection()
+
+ InvestingSafetySection()
+
+ TransactionHistorySection()
+ }
+ }
+}
+
+@Composable
+fun TransactionHistorySection() {
+ Card(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .fillMaxWidth(),
+ ) {
+ Column(
+ modifier = Modifier.background(color = Secondary),
+ ) {
+ Row() {
+ Text(
+ text = "Your Transaction History",
+ style = Typography.h2,
+ color = Color.White,
+ modifier = Modifier.padding(
+ top = Constants.PADDING_SIDE_VALUE.dp,
+ bottom = Constants.PADDING_SIDE_VALUE.dp
+ )
+ )
+ }
+
+ Column(modifier = Modifier.fillMaxWidth()) {
+ DummyData.transactionHistory.forEachIndexed { index, transaction ->
+ TransactionItem(transaction)
+ Divider(
+ modifier = Modifier
+ .padding(
+ top = 5.dp,
+ bottom = if (DummyData.transactionHistory.size - 1 > index) {
+ 5.dp
+ } else {
+ 0.dp
+ }
+ )
+ )
+ }
+ }
+ }
+ }
+}
+
+@Composable
+private fun TransactionItem(transaction: Transaction) {
+ Card(
+ modifier = Modifier.fillMaxWidth()
+ .border(border = BorderStroke(1.dp, Color.White)),
+ elevation = 10.dp,
+ backgroundColor = Secondary
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(
+ vertical = 4.dp,
+ horizontal = 8.dp
+ )
+ .fillMaxWidth()
+
+ ) {
+ TransactionDescriptionSection(transaction)
+
+ TransactionAmountSection(transaction)
+ }
+ }
+}
+
+@Composable
+private fun TransactionAmountSection(
+ transaction: Transaction,
+) {
+ val amountColor = if (transaction.transactionType == "S") {
+ Color.White
+ } else {
+ Green
+ }
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Text(
+ text = "${transaction.amount} ${transaction.currencyCode}",
+ style = Typography.h2,
+ color = amountColor
+ )
+
+ Image(
+ painter = painterResource(id = R.drawable.right_arrow),
+ contentDescription = null,
+ modifier = Modifier
+ .clipToBounds()
+ .padding(start = (Constants.PADDING_SIDE_VALUE * 1.5).dp)
+ )
+ }
+}
+
+@Composable
+private fun TransactionDescriptionSection(transaction: Transaction) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(vertical = Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.transaction),
+ contentDescription = "Transaction image",
+ modifier = Modifier
+ .padding(end = (Constants.PADDING_SIDE_VALUE * 1.5).dp),
+ colorFilter = ColorFilter.tint(color = Color.White)
+ )
+
+ Column {
+ Text(
+ text = transaction.description,
+ style = Typography.h4,
+ color = Color.White
+ )
+
+ Spacer(modifier = Modifier.height(4.dp))
+
+ Text(
+ text = transaction.transactionDate,
+ style = Typography.h5,
+ color = BlueGrey50
+ )
+ }
+ }
+}
+
+@Composable
+private fun InvestingSafetySection() {
+ Card(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ shape = MaterialTheme.shapes.medium,
+ elevation = Constants.ELEVATION_VALUE.dp,
+ backgroundColor = BannerColor
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ verticalArrangement = Arrangement.spacedBy(Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ InvestingSafetyTextItems()
+ }
+ }
+}
+
+@Composable
+private fun InvestingSafetyTextItems() {
+ Text(
+ text = "Investing Safety",
+ color = Color.White,
+ style = Typography.h3
+ )
+
+ Text(
+ text = "It's very difficult to time an investement especially when the market is volatile. Learn how to use dollar cost averaging to you advantage.",
+ color = Color.White,
+ style = Typography.subtitle2,
+ lineHeight = 18.sp
+ )
+
+ Text(
+ text = "Learn More",
+ color = Green,
+ textDecoration = TextDecoration.Underline,
+ style = Typography.h3,
+ modifier = Modifier
+ .clickable {
+ Log.d("HomeScreen", "Learn More clicked")
+ }
+ )
+}
+
+@Composable
+fun SetPriceAlertSection() {
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ shape = MaterialTheme.shapes.medium,
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceEvenly,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .fillMaxWidth()
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.notification_color),
+ contentDescription = "Price Alert Icon"
+ )
+
+ SetPriceAlertTextColumn()
+
+ Image(
+ painter = painterResource(id = R.drawable.right_arrow),
+ contentDescription = null
+ )
+ }
+ }
+}
+
+@Composable
+fun SetPriceAlertTextColumn() {
+ Column() {
+ Text(
+ text = "Set Price Alert",
+ style = Typography.h3
+ )
+ Text(
+ text = "Get notified when your coins are moving",
+ style = Typography.subtitle2,
+ color = Gray
+ )
+ }
+}
+
+@Composable
+private fun CurrencyCard(
+ currency: TrendingCurrency,
+ onCardClick: (String) -> Unit
+) {
+ Card(
+ modifier = Modifier
+ .width(150.dp)
+ .padding(top = Constants.PADDING_SIDE_VALUE.dp)
+ .clickable {
+ onCardClick(currency.currencyCode)
+ },
+ shape = MaterialTheme.shapes.medium,
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(
+ top = 20.dp,
+ start = 20.dp,
+ bottom = 20.dp
+ )
+ ) {
+ CurrencyItem(currency = currency)
+
+ ValuesItem(currency = currency)
+ }
+ }
+}
+
+@Composable
+fun ValuesItem(
+ currency: TrendingCurrency,
+ priceModifier: Modifier = Modifier
+ .padding(top = 20.dp),
+ changesModifier: Modifier = Modifier
+ .padding(top = 5.dp),
+ currencyPriceStyle: TextStyle = Typography.h3,
+ currencyChangesStyle: TextStyle = Typography.h3
+ ) {
+ var changeColor by remember {
+ mutableStateOf(
+ if(currency.changeType == "I") {
+ Green
+ } else {
+ Red
+ }
+ )
+ }
+
+ var changeOperator by remember {
+ mutableStateOf(
+ if(currency.changeType == "I") {
+ "+"
+ } else {
+ "-"
+ }
+ )
+ }
+
+ Text(
+ text = "£${currency.currentPrice}",
+ style = currencyPriceStyle,
+ modifier = priceModifier
+ )
+
+ Text(
+ text = "$changeOperator${currency.changes}%",
+ style = currencyChangesStyle,
+ color = changeColor,
+ modifier = changesModifier
+ )
+}
+
+@Composable
+fun CurrencyItem(
+ currency: TrendingCurrency
+) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Image(
+ painter = painterResource(id = currency.imageRes),
+ contentDescription = currency.currencyName,
+ modifier = Modifier
+ .size(25.dp)
+ )
+
+ Column(
+ modifier = Modifier
+ .padding(start = Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ Text(
+ text = currency.currencyName,
+ style = Typography.h2,
+ color = Color.Black
+ )
+
+ Text(
+ text = currency.currencyCode,
+ style = Typography.subtitle1,
+ color = Gray
+ )
+ }
+ }
+}
+
+@Composable
+public fun PortfolioBalanceSection() {
+ var operator: String = if (DummyData.portfolio.changeType == "I") {
+ "+"
+ } else {
+ "-"
+ }
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ ) {
+ Text(
+ text = "Your Portfolio Balance",
+ style = Typography.h3,
+ color = Color.White
+ )
+ Text(
+ text = "£${DummyData.portfolio.balance}",
+ style = Typography.h1,
+ color = Color.White
+ )
+ Text(
+ text = "$operator${DummyData.portfolio.changes} Last 24 hours",
+ style = Typography.h5,
+ color = Color.White
+ )
+ }
+}
+
+@Composable
+private fun BannerImage() {
+ Image(
+ painter = painterResource(id = R.drawable.banner),
+ contentDescription = null,
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(290.dp),
+ contentScale = ContentScale.Crop
+ )
+}
+
+@Preview
+@Composable
+fun HomeScreenPrev() {
+ HomeScreen() {
+
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/Navigation.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/Navigation.kt
new file mode 100644
index 00000000..62cecd12
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/Navigation.kt
@@ -0,0 +1,104 @@
+package com.rs.crypto
+
+import android.util.Log
+import androidx.compose.runtime.Composable
+import androidx.navigation.NavHostController
+import androidx.navigation.NavType
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.navArgument
+import com.rs.crypto.composables.*
+import com.rs.crypto.utils.Screen
+
+
+@Composable
+fun Navigation(
+ navController: NavHostController
+) {
+ NavHost(
+ navController = navController,
+ startDestination = Screen.HomeScreen.route
+ ) {
+ composable(
+ route = Screen.HomeScreen.route
+ ) {
+ HomeScreen() { currencyCode ->
+ navController.navigate(Screen.CryptoDetailScreen.route + "/$currencyCode")
+ }
+ }
+ composable(
+ route = Screen.CryptoDetailScreen.route + "/{currencyCode}",
+ arguments = listOf(
+ navArgument(name = "currencyCode") {
+ type = NavType.StringType
+ }
+ )
+ ) {
+ val currencyCode = it.arguments?.getString("currencyCode")!!
+ CryptoDetailScreen(
+ currencyCode = currencyCode,
+ onBackArrowPressed = {
+ navController.popBackStack()
+ },
+ onButtonClick = {
+ navController.navigate(route = Screen.TransactionScreen.route + "/$currencyCode")
+ }
+ )
+ }
+ composable(
+ route = Screen.TransactionScreen.route + "/{currencyCode}",
+ arguments = listOf(
+ navArgument(name = "currencyCode") {
+ type = NavType.StringType
+ }
+ )
+ ) {
+ val currencyCode = it.arguments?.getString("currencyCode")!!
+ TransactionScreen(
+ onBackArrowPressed = {
+ navController.popBackStack()
+ },
+ currencyCode = currencyCode,
+ onTradeButtonClick = {
+ Log.d("TransactionScreen", "Trade section coming soon...")
+ }
+ )
+ }
+ composable(
+ route = Screen.SettingsScreen.route
+ ) {
+ SettingsScreen(
+ onBackArrowPressed = {
+ navController.popBackStack()
+ }
+ )
+ }
+ composable(
+ route = Screen.PortfolioScreen.route
+ ) {
+ PortfolioScreen(
+ onBackArrowPressed = {
+ navController.popBackStack()
+ },
+ onCoinSearch = {
+
+ }
+ )
+ }
+ composable(
+ route = Screen.PricesScreen.route
+ ) {
+ PricesScreen(
+ onBackArrowPressed = {
+
+ },
+ onCoinSearch = {
+
+ },
+ onItemClick = { currencyCode ->
+ navController.navigate(Screen.CryptoDetailScreen.route + "/$currencyCode")
+ }
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PortfolioScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PortfolioScreen.kt
new file mode 100644
index 00000000..113e4fd1
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PortfolioScreen.kt
@@ -0,0 +1,280 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Search
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.R
+import com.rs.crypto.composables.prices_components.CurrencyInfoSection
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.ui.theme.*
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun PortfolioScreen(
+ onBackArrowPressed: () -> Unit,
+ onCoinSearch: (String) -> Unit
+) {
+ val currency = DummyData.trendingCurrencies[0]
+
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Secondary
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState()),
+ horizontalAlignment = Alignment.CenterHorizontally
+
+ ) {
+ TopNavigationRow(
+ onBackArrowPressed = onBackArrowPressed,
+ isStarNeeded = false,
+ )
+ Box(
+ modifier = Modifier
+ .padding(vertical = 20.dp)
+ ) {
+ PortfolioBalanceSection()
+ }
+// PortfolioCard()
+
+ SearchField(onCoinSearch = onCoinSearch)
+
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ CurrencySection()
+ }
+ }
+ }
+}
+
+@Composable
+private fun CurrencySection() {
+ Column(
+ modifier = Modifier
+ .padding(
+ top = Constants.PADDING_SIDE_VALUE.dp,
+ start = Constants.PADDING_SIDE_VALUE.dp,
+ end = Constants.PADDING_SIDE_VALUE.dp
+ )
+ ) {
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ DummyData.trendingCurrencies.forEachIndexed { index, currency ->
+ CoinItem(currency = currency)
+ Divider(
+ modifier = Modifier
+ .padding(
+ top = Constants.PADDING_SIDE_VALUE.dp,
+ bottom = if (DummyData.trendingCurrencies.size - 1 > index) {
+ Constants.PADDING_SIDE_VALUE.dp
+ } else {
+ 0.dp
+ }
+ )
+ )
+ }
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ DummyData.trendingCurrencies.forEachIndexed { index, currency ->
+ CoinItem(currency = currency)
+ Divider(
+ modifier = Modifier
+ .padding(
+ top = Constants.PADDING_SIDE_VALUE.dp,
+ bottom = if (DummyData.trendingCurrencies.size - 1 > index) {
+ Constants.PADDING_SIDE_VALUE.dp
+ } else {
+ 0.dp
+ }
+ )
+ )
+ }
+ }
+}
+
+@Composable
+private fun CoinItem(currency: TrendingCurrency) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ CurrencyInfoSection(currency = currency)
+
+ CoinAmountSection(currency = currency)
+ }
+}
+
+
+@Composable
+private fun CoinAmountSection(currency: TrendingCurrency) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(
+ horizontalAlignment = Alignment.End
+ ) {
+ Text(
+ text = "${currency.wallet.crypto}",
+ style = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 16.sp,
+ lineHeight = 22.sp
+ ),
+ color = Color.DarkGray
+ )
+ Text(
+ text = "£${currency.wallet.value}",
+ style = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ color = Gray
+ )
+ }
+
+ Image(
+ painter = painterResource(id = R.drawable.right_arrow),
+ contentDescription = null,
+ modifier = Modifier
+ .clipToBounds()
+ .padding(start = (Constants.PADDING_SIDE_VALUE * 1.5).dp)
+ )
+ }
+}
+
+@Composable
+fun SearchField(
+ onCoinSearch: (String) -> Unit
+) {
+ var textFieldState by remember {
+ mutableStateOf("")
+ }
+ OutlinedTextField(
+ value = textFieldState,
+ onValueChange = {
+ textFieldState = it
+ onCoinSearch(it)
+ },
+ leadingIcon = {
+ Icon(
+ imageVector = Icons.Default.Search,
+ contentDescription = null,
+ tint = Color.White
+ )
+ },
+ label = {
+ Text(text = "Search coins..", color = Color.White)
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ maxLines = 1,
+ textStyle = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ colors = TextFieldDefaults.outlinedTextFieldColors(
+ focusedBorderColor = BlueGrey50,
+ unfocusedBorderColor = BlueGrey50
+ )
+ )
+}
+
+@Composable
+private fun PortfolioCard() {
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ Row(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ PortfolioValueSection()
+
+ Image(
+ painter = painterResource(id = R.drawable.crypto_icon),
+ contentDescription = "crypto icon",
+ modifier = Modifier
+ .size(75.dp)
+ .clip(CircleShape)
+ )
+ }
+ }
+}
+
+@Composable
+private fun PortfolioValueSection() {
+ Column() {
+ Spacer(modifier = Modifier.height(Constants.ELEVATION_VALUE.dp))
+
+ Text(
+ text = "TOTAL PORTFOLIO VALUE",
+ style = Typography.subtitle1,
+ color = Gray
+ )
+
+ Spacer(modifier = Modifier.height(Constants.ELEVATION_VALUE.dp))
+
+ Text(
+ text = "£${DummyData.portfolio.balance}",
+ style = TextStyle(
+ fontFamily = RobotoBold,
+ fontSize = 24.sp,
+ lineHeight = 30.sp
+ )
+ )
+
+ Spacer(modifier = Modifier.height((2 * Constants.ELEVATION_VALUE).dp))
+ }
+}
+
+@Preview
+@Composable
+fun PortfolioScreenPreview() {
+ PortfolioScreen(
+ onBackArrowPressed = {
+
+ },
+ onCoinSearch = {
+
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PricesScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PricesScreen.kt
new file mode 100644
index 00000000..b8635f58
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/PricesScreen.kt
@@ -0,0 +1,148 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.composables.prices_components.*
+import com.rs.crypto.ui.theme.BannerColor
+import com.rs.crypto.ui.theme.Primary
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun PricesScreen(
+ onBackArrowPressed: () -> Unit,
+ onCoinSearch: (String) -> Unit,
+ onItemClick: (String) -> Unit
+) {
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Primary
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(bottom = 50.dp)
+ ) {
+ TopNavigationRow(
+ onBackArrowPressed = onBackArrowPressed,
+ isStarNeeded = false
+ )
+
+ SearchField(onCoinSearch = onCoinSearch)
+
+ var selectedIndex = mutableStateOf(0)
+
+ selectedIndex.value = ChipsRow()
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ when(selectedIndex.value) {
+ 0 -> AllSection(
+ onItemClick = onItemClick
+ )
+ 1 -> FollowingSection(
+ onItemClick = onItemClick
+ )
+ 2 -> CryptoSection(
+ onItemClick = onItemClick
+ )
+ 3 -> UtilityTokensSection(
+ onItemClick = onItemClick
+ )
+ 4 -> StableCoinsSection(
+ onItemClick = onItemClick
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun ChipsRow(): Int {
+ var selectedIndex by remember {
+ mutableStateOf(0)
+ }
+
+ LazyRow() {
+ items(count = DummyData.topChipsName.size) { index ->
+ if (index == 0) {
+ Spacer(modifier = Modifier.width(Constants.PADDING_SIDE_VALUE.dp))
+ }
+
+ SectionChip(
+ text = DummyData.topChipsName[index],
+ isSelected = index == selectedIndex,
+ onClick = {
+ selectedIndex = index
+ }
+ )
+ Spacer(modifier = Modifier.width(Constants.ELEVATION_VALUE.dp))
+ }
+ }
+ return selectedIndex
+}
+
+@Composable
+private fun SectionChip(
+ text: String,
+ isSelected: Boolean = false,
+ onClick: () -> Unit
+) {
+ val cardColor = if(isSelected) {
+ BannerColor
+ } else {
+ Color.White
+ }
+
+ val cardTextColor = if(isSelected) {
+ Color.White
+ } else {
+ Color.Black
+ }
+
+ Card(
+ backgroundColor = cardColor,
+ modifier = Modifier
+ .clip(RoundedCornerShape(50.dp))
+ .clickable(onClick = onClick)
+ ) {
+ Text(
+ text = text,
+ modifier = Modifier
+ .padding(
+ horizontal = Constants.ELEVATION_VALUE.dp,
+ vertical = (Constants.PADDING_SIDE_VALUE / 2).dp,
+ ),
+ color = cardTextColor,
+ fontSize = 14.sp
+ )
+ }
+}
+
+@Preview
+@Composable
+fun PricesScreenPreview() {
+ PricesScreen(
+ onBackArrowPressed = {
+
+ },
+ onCoinSearch = {
+
+ },
+ onItemClick = {
+
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SettingsScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SettingsScreen.kt
new file mode 100644
index 00000000..bfaa8f9a
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SettingsScreen.kt
@@ -0,0 +1,209 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Divider
+import androidx.compose.material.Icon
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.*
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.ui.theme.*
+import com.rs.crypto.R
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun SettingsScreen(
+ onBackArrowPressed: () -> Unit,
+ ) {
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Secondary
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(bottom = 50.dp)
+ ) {
+ TopNavigationRow(
+ onBackArrowPressed = onBackArrowPressed,
+ isStarNeeded = false
+ )
+
+ Spacer(modifier = Modifier.height((2*Constants.PADDING_SIDE_VALUE).dp))
+
+ UserInfoSection()
+
+ SettingsColumn()
+ }
+ }
+}
+
+@Composable
+private fun SettingsColumn() {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Person,
+ text = "Profile"
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Tune,
+ text = "Preferences"
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Notifications,
+ text = "Notifications"
+ )
+
+ Divider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = Constants.PADDING_SIDE_VALUE.dp)
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Security,
+ text = "Security"
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Lock,
+ text = "Privacy"
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Info,
+ text = "About"
+ )
+
+ Divider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = Constants.PADDING_SIDE_VALUE.dp)
+ )
+
+ SettingsItem(
+ iconImageVector = Icons.Default.Logout,
+ text = "Logout"
+ )
+ }
+}
+
+@Composable
+private fun SettingsItem(
+ iconImageVector: ImageVector,
+ text: String
+) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ IconTextRow(
+ iconImageVector = iconImageVector,
+ text = text
+ )
+
+ Image(
+ painter = painterResource(id = R.drawable.right_arrow),
+ contentDescription = null,
+ colorFilter = ColorFilter.tint(color = Color.White),
+ modifier = Modifier
+ .clipToBounds()
+ .padding(horizontal = (Constants.PADDING_SIDE_VALUE * 1.5).dp)
+ .size(Constants.PADDING_SIDE_VALUE.dp)
+ )
+ }
+}
+
+@Composable
+private fun IconTextRow(
+ iconImageVector: ImageVector,
+ text: String
+) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(vertical = Constants.PADDING_SIDE_VALUE.dp)
+ ) {
+ Icon(
+ imageVector = iconImageVector,
+ contentDescription = text,
+ tint = Color.White,
+ modifier = Modifier
+ .size((2*Constants.PADDING_SIDE_VALUE).dp)
+ )
+
+ Spacer(modifier = Modifier.width(Constants.ELEVATION_VALUE.dp))
+
+ Text(
+ text = text,
+ style = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ color = Color.White
+ )
+ }
+}
+
+@Composable
+private fun UserInfoSection() {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = "${DummyData.user.firstName} ${DummyData.user.lastName}",
+ style = Typography.h2,
+ color = Color.White
+ )
+
+ Icon(
+ imageVector = Icons.Default.AccountCircle,
+ contentDescription = "Image",
+ tint = Color.White,
+ modifier = Modifier
+ .size((4 * Constants.PADDING_SIDE_VALUE).dp)
+ )
+ }
+}
+
+@Preview
+@Composable
+fun SettingsScreenPreview() {
+ SettingsScreen(
+ onBackArrowPressed = {
+
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SplashScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SplashScreen.kt
new file mode 100644
index 00000000..a193043c
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/SplashScreen.kt
@@ -0,0 +1,25 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.rs.crypto.R
+
+@Preview(showBackground = true)
+@Composable
+fun SplashScreen() {
+ Box(modifier = Modifier.fillMaxSize()) {
+ Image(
+ painter = painterResource(id = R.drawable.launch_screen),
+ contentDescription = null,
+ modifier = Modifier
+ .fillMaxSize(),
+ contentScale = ContentScale.Crop
+ )
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TradeScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TradeScreen.kt
new file mode 100644
index 00000000..5f8b1419
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TradeScreen.kt
@@ -0,0 +1,148 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.composables.trade_components.LimitSection
+import com.rs.crypto.composables.trade_components.RepeatSection
+import com.rs.crypto.composables.trade_components.TransactSection
+import com.rs.crypto.ui.theme.BannerColor
+import com.rs.crypto.ui.theme.RobotoBold
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun TradeScreen(
+ onButtonClick: () -> Unit
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+
+ var selectedIndex = mutableStateOf(1)
+
+ selectedIndex.value = SectionSelectorRow()
+
+ when(selectedIndex.value) {
+ 0 -> TransactSection()
+ 1 -> RepeatSection()
+ 2 -> LimitSection()
+ }
+
+ Button(
+ onClick = {
+ onButtonClick()
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding((2 * Constants.PADDING_SIDE_VALUE).dp),
+ colors = ButtonDefaults.textButtonColors(
+ backgroundColor = BannerColor
+ ),
+ shape = RoundedCornerShape(25.dp)
+ ) {
+ Text(
+ text = "Trade",
+ color = Color.White
+ )
+ }
+ }
+}
+
+@Composable
+private fun SectionSelectorRow(): Int {
+ var selectedSectionIndex by remember {
+ mutableStateOf(0)
+ }
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .clip(RoundedCornerShape((2 * Constants.ELEVATION_VALUE).dp)),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ DummyData.tradeScreenSections.forEachIndexed { index, sectionName ->
+ SectionCard(
+ isSelected = selectedSectionIndex == index,
+ text = sectionName,
+ modifier = Modifier
+ .weight(1f),
+ onCardClick = {
+ selectedSectionIndex = index
+ }
+ )
+ }
+ }
+
+ return selectedSectionIndex
+}
+
+@Composable
+private fun SectionCard(
+ isSelected: Boolean = false,
+ text: String,
+ modifier: Modifier = Modifier,
+ onCardClick: () -> Unit
+) {
+ val cardColor = if(isSelected) {
+ BannerColor
+ } else {
+ Color.White
+ }
+
+ val cardTextColor = if(isSelected) {
+ Color.White
+ } else {
+ Color.Black
+ }
+
+ Card(
+ backgroundColor = cardColor,
+ modifier = modifier
+ .fillMaxWidth()
+ .clip(RoundedCornerShape((2 * Constants.ELEVATION_VALUE).dp))
+ .clickable(onClick = onCardClick),
+ elevation = 0.dp
+ ) {
+ Text(
+ text = text,
+ modifier = Modifier
+ .padding(
+ vertical = (Constants.PADDING_SIDE_VALUE / 2).dp,
+ ),
+ color = cardTextColor,
+ fontSize = 14.sp,
+ fontFamily = RobotoBold,
+ textAlign = TextAlign.Center
+ )
+ }
+}
+
+@Preview
+@Composable
+fun TradeScreenPreview() {
+ Surface() {
+ TradeScreen(
+ onButtonClick = {
+
+ }
+ )
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TransactionScreen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TransactionScreen.kt
new file mode 100644
index 00000000..0c15e076
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/screen/TransactionScreen.kt
@@ -0,0 +1,115 @@
+package com.rs.crypto.composables
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Card
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.rs.crypto.models.TrendingCurrency
+import com.rs.crypto.ui.theme.BlueGrey700
+import com.rs.crypto.ui.theme.LightGray1
+import com.rs.crypto.ui.theme.Secondary
+import com.rs.crypto.ui.theme.Typography
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun TransactionScreen(
+ currencyCode: String,
+ onBackArrowPressed: () -> Unit,
+ onTradeButtonClick: (String) -> Unit
+) {
+ val currency = DummyData.trendingCurrencies.find { it.currencyCode == currencyCode }!!
+
+ Surface(
+ modifier = Modifier
+ .fillMaxSize(),
+ color = Secondary
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(bottom = 50.dp)
+ ) {
+ TopNavigationRow(
+ onBackArrowPressed = onBackArrowPressed,
+ isStarNeeded = false
+ )
+
+ Card(
+ modifier = Modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .fillMaxWidth(),
+ shape = MaterialTheme.shapes.medium,
+ elevation = Constants.ELEVATION_VALUE.dp
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(
+ top = Constants.PADDING_SIDE_VALUE.dp,
+ start = Constants.PADDING_SIDE_VALUE.dp,
+ end = Constants.PADDING_SIDE_VALUE.dp
+ )
+ ) {
+ CurrencyItem(currency = currency)
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ TransactionCurrencyValueTextSection(currency)
+
+ Spacer(modifier = Modifier.height(Constants.PADDING_SIDE_VALUE.dp))
+
+ StandardButton(
+ onButtonClick = onTradeButtonClick,
+ currency = currency,
+ buttonText = "Trade"
+ )
+ }
+ }
+
+ TransactionHistorySection()
+ }
+ }
+}
+
+@Composable
+private fun TransactionCurrencyValueTextSection(currency: TrendingCurrency) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(
+ text = "%.3f ${currency.currencyCode}".format(currency.wallet.crypto),
+ style = Typography.h2
+ )
+
+ Text(
+ text = "£${DummyData.portfolio.balance}",
+ style = Typography.subtitle2,
+ color = BlueGrey700
+ )
+ }
+}
+
+@Preview
+@Composable
+fun TransactionScreenPreview() {
+ TransactionScreen(
+ onBackArrowPressed = {
+
+ },
+ currencyCode = "ETH",
+ onTradeButtonClick = {
+
+ }
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/LimitSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/LimitSection.kt
new file mode 100644
index 00000000..d64acc39
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/LimitSection.kt
@@ -0,0 +1,52 @@
+package com.rs.crypto.composables.trade_components
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Surface
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.DateRange
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.rs.crypto.ui.theme.LightGray1
+import com.rs.crypto.utils.Constants
+
+@Composable
+fun LimitSection() {
+ TransactSection()
+
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ Column(modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .clip(shape = RoundedCornerShape(4.dp))
+ .background(color = LightGray1)
+ ) {
+ RepeatOptionsItem(
+ iconImageVector = Icons.Default.DateRange,
+ optionName = "Duration",
+ frequency = "Good 'til canceled"
+ )
+ }
+ }
+}
+
+
+@Preview
+@Composable
+fun LimSectionPreview() {
+ Surface() {
+ Column() {
+ LimitSection()
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatOptionsItem.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatOptionsItem.kt
new file mode 100644
index 00000000..3820b200
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatOptionsItem.kt
@@ -0,0 +1,69 @@
+package com.rs.crypto.composables.trade_components
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Icon
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.NavigateNext
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.ui.theme.Gray
+import com.rs.crypto.ui.theme.RobotoRegular
+import com.rs.crypto.utils.Constants
+
+
+@Composable
+fun RepeatOptionsItem(
+ iconImageVector: ImageVector,
+ optionName: String,
+ frequency: String
+) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(10.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ imageVector = iconImageVector,
+ contentDescription = null,
+ tint = Gray
+ )
+
+ Text(
+ text = optionName,
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp
+ )
+ }
+
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(10.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = frequency,
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp
+ )
+
+ Icon(
+ imageVector = Icons.Default.NavigateNext,
+ contentDescription = null,
+ tint = Gray
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatSection.kt
new file mode 100644
index 00000000..f223d094
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/RepeatSection.kt
@@ -0,0 +1,49 @@
+package com.rs.crypto.composables.trade_components
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.rs.crypto.ui.theme.LightGray1
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+@Composable
+fun RepeatSection() {
+ TransactSection()
+
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ Column(modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp)
+ .clip(shape = RoundedCornerShape(4.dp))
+ .background(color = LightGray1)
+ ) {
+ DummyData.repeatOptions.forEachIndexed{ index, repeatOptions ->
+ RepeatOptionsItem(
+ iconImageVector = repeatOptions.iconImageVector,
+ optionName = repeatOptions.optionName,
+ frequency = repeatOptions.frequency
+ )
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+fun RepeatSectionPreview() {
+ Surface() {
+ Column() {
+ RepeatSection()
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/TransactSection.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/TransactSection.kt
new file mode 100644
index 00000000..88cde25c
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/composables/trade_components/TransactSection.kt
@@ -0,0 +1,163 @@
+package com.rs.crypto.composables.trade_components
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ExpandMore
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.composables.prices_components.CurrencyInfoSection
+import com.rs.crypto.ui.theme.Gray
+import com.rs.crypto.ui.theme.RobotoRegular
+import com.rs.crypto.utils.Constants
+import com.rs.crypto.utils.DummyData
+
+
+@Composable
+fun TransactSection() {
+ TradeTextField(
+ label = "From",
+ modifier = Modifier
+ .fillMaxWidth()
+ )
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ CurrencySelectorDropDown(
+ selectedIndex = 0
+ )
+
+ CurrencySelectorDropDown(
+ selectedIndex = 1
+ )
+ }
+
+ TradeTextField(
+ label = "To",
+ modifier = Modifier
+ .fillMaxWidth()
+ )
+}
+
+@Composable
+private fun CurrencySelectorDropDown(
+ selectedIndex: Int
+) {
+ var expandedState by remember {
+ mutableStateOf(false)
+ }
+
+ var dropDownSelectedIndex by remember {
+ mutableStateOf(selectedIndex)
+ }
+
+ Box {
+ Box(
+ modifier = Modifier
+ .border(
+ width = 1.dp,
+ color = Gray,
+ shape = RoundedCornerShape((Constants.ELEVATION_VALUE / 2).dp)
+ )
+ .width(150.dp)
+ .clickable {
+ expandedState = true
+ }
+ ) {
+ Row(
+ modifier = Modifier
+ .padding((Constants.ELEVATION_VALUE / 2).dp)
+ .fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ CurrencyInfoSection(
+ currency = DummyData.trendingCurrencies[dropDownSelectedIndex]
+ )
+
+ Icon(
+ imageVector = Icons.Default.ExpandMore,
+ contentDescription = null,
+ tint = Gray
+ )
+ }
+ }
+
+ DropdownMenu(
+ expanded = expandedState,
+ onDismissRequest = {
+ expandedState = false
+ },
+ modifier = Modifier
+ .width(150.dp)
+ ) {
+ DummyData.trendingCurrencies.forEachIndexed { index, currency ->
+ DropdownMenuItem(onClick = {
+ dropDownSelectedIndex = index
+ expandedState = false
+ }) {
+ CurrencyInfoSection(currency = currency)
+ }
+ }
+ }
+ }
+}
+
+@Composable
+private fun TradeTextField(
+ label: String,
+ modifier: Modifier = Modifier
+) {
+ var textFieldState by remember {
+ mutableStateOf("0")
+ }
+
+ var expanded by remember {
+ mutableStateOf(false)
+ }
+
+ var selectedText by remember {
+ mutableStateOf("")
+ }
+
+ var textfieldSize by remember {
+ mutableStateOf(Size.Zero)
+ }
+
+
+ OutlinedTextField(
+ value = textFieldState,
+ onValueChange = {
+ textFieldState = it
+ },
+ modifier = modifier
+ .padding(Constants.PADDING_SIDE_VALUE.dp),
+ label = {
+ Text(text = label)
+ },
+ colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White),
+ maxLines = 1,
+ textStyle = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/ChartOption.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/ChartOption.kt
new file mode 100644
index 00000000..e48cde4f
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/ChartOption.kt
@@ -0,0 +1,6 @@
+package com.rs.crypto.models
+
+data class ChartOption(
+ val optionId: Int,
+ val label: String
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Portfolio.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Portfolio.kt
new file mode 100644
index 00000000..b1447762
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Portfolio.kt
@@ -0,0 +1,7 @@
+package com.rs.crypto.models
+
+data class Portfolio(
+ val balance: Float,
+ val changes: Float,
+ val changeType: String
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/RepeatOptions.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/RepeatOptions.kt
new file mode 100644
index 00000000..f7ecdd82
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/RepeatOptions.kt
@@ -0,0 +1,9 @@
+package com.rs.crypto.models
+
+import androidx.compose.ui.graphics.vector.ImageVector
+
+data class RepeatOptions(
+ val iconImageVector: ImageVector,
+ val optionName: String,
+ val frequency: String
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Transaction.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Transaction.kt
new file mode 100644
index 00000000..103cdb23
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Transaction.kt
@@ -0,0 +1,10 @@
+package com.rs.crypto.models
+
+data class Transaction(
+ val transactionID: Int,
+ val description: String,
+ val amount: Float,
+ val currencyCode: String,
+ val transactionType: String,
+ val transactionDate: String
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/TrendingCurrency.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/TrendingCurrency.kt
new file mode 100644
index 00000000..15ec824a
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/TrendingCurrency.kt
@@ -0,0 +1,15 @@
+package com.rs.crypto.models
+
+data class TrendingCurrency(
+ val id: Int,
+ val currencyName: String,
+ val currencyCode: String,
+ val imageRes: Int,
+ val currentPrice: Float,
+ val changes: Float,
+ val changeType: String,
+ val description: String,
+ val chartData: List>,
+ val wallet: Wallet,
+ val transactionHistory: List,
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/User.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/User.kt
new file mode 100644
index 00000000..b2b226a8
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/User.kt
@@ -0,0 +1,7 @@
+package com.rs.crypto.models
+
+data class User(
+ val userName: String,
+ val firstName: String,
+ val lastName: String
+)
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Wallet.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Wallet.kt
new file mode 100644
index 00000000..fe7c15ad
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/models/Wallet.kt
@@ -0,0 +1,6 @@
+package com.rs.crypto.models
+
+data class Wallet(
+ val value: Float,
+ val crypto: Float
+)
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Color.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Color.kt
new file mode 100644
index 00000000..947dae49
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Color.kt
@@ -0,0 +1,27 @@
+package com.rs.crypto.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Primary = Color(0xFF7F5DF0)
+val Secondary = Color(0xFF5D2DFD)
+
+val Green = Color(0xFF37E39F)
+val Red = Color(0xFFF9A8BA)
+val Gray = Color(0xFF6A6A6A)
+val LightGray1 = Color(0xFFf5f6fa)
+
+val Yellow200 = Color(0xFFFFF59D)
+val DeepOrange600 = Color(0xFFF4511E)
+val Lime300 = Color(0xFFDCE775)
+val LightGreen500 = Color(0xFF8BC34A)
+val Teal700 = Color(0xFF00796B)
+val Cyan900 = Color(0xFF006064)
+val BlueGrey50 = Color(0xFFECEFF1)
+val BlueGrey300 = Color(0xFF90A4AE)
+val BlueGrey700 = Color(0xFF455A64)
+val Grey900 = Color(0xFF212121)
+
+val Purple500 = Color(0xFF6200EE)
+val PurpleOne = Color(0xFF9C27B0)
+val PurpleTwo = Color(0xFF673AB7)
+val BannerColor = Color(0xFF6449FA)
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Shape.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Shape.kt
new file mode 100644
index 00000000..0331745f
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.rs.crypto.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(8.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Theme.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Theme.kt
new file mode 100644
index 00000000..d708e92c
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Theme.kt
@@ -0,0 +1,34 @@
+package com.rs.crypto.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.unit.dp
+
+private val LightColorPalette = lightColors(
+ primary = Primary,
+ secondary = Secondary
+)
+
+object Theme {
+ val paddingSizeValue = 24.dp
+ val radiusSizeValue = 12.dp
+ val fontSizeValue = 14.dp
+ val baseSizeValue = 8.dp
+}
+
+@Composable
+fun CryptocurrencyAppTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ content: @Composable() () -> Unit
+) {
+ val colors = LightColorPalette
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Type.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Type.kt
new file mode 100644
index 00000000..18cca571
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/ui/theme/Type.kt
@@ -0,0 +1,60 @@
+package com.rs.crypto.ui.theme
+
+import androidx.compose.material.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.unit.sp
+import com.rs.crypto.R
+
+private val RobotoBlack = FontFamily(Font(R.font.roboto_black))
+val RobotoBold = FontFamily(Font(R.font.roboto_bold))
+val RobotoRegular = FontFamily(Font(R.font.roboto_regular))
+
+val Typography = Typography(
+ h1 = TextStyle(
+ fontFamily = RobotoBlack,
+ fontSize = 30.sp,
+ lineHeight = 36.sp
+ ),
+ h2 = TextStyle(
+ fontFamily = RobotoBold,
+ fontSize = 18.sp,
+ lineHeight = 30.sp
+ ),
+ h3 = TextStyle(
+ fontFamily = RobotoBold,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ),
+ h4 = TextStyle(
+ fontFamily = RobotoBold,
+ fontSize = 16.sp,
+ lineHeight = 22.sp
+ ),
+ body1 = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 30.sp,
+ lineHeight = 36.sp
+ ),
+ body2 = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 22.sp,
+ lineHeight = 30.sp
+ ),
+ subtitle1 = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 12.sp,
+ lineHeight = 22.sp
+ ), // Subtitle 1 is body 3
+ subtitle2 = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 14.sp,
+ lineHeight = 22.sp
+ ), // Subtitle 2 is body 4
+ h5 = TextStyle(
+ fontFamily = RobotoRegular,
+ fontSize = 10.sp,
+ lineHeight = 22.sp
+ ), // h5 is body 5
+)
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Constants.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Constants.kt
new file mode 100644
index 00000000..c0e3d6a0
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Constants.kt
@@ -0,0 +1,8 @@
+package com.rs.crypto.utils
+
+class Constants {
+ companion object {
+ const val PADDING_SIDE_VALUE = 12
+ const val ELEVATION_VALUE = 10
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/DummyData.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/DummyData.kt
new file mode 100644
index 00000000..ea68bf19
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/DummyData.kt
@@ -0,0 +1,563 @@
+package com.rs.crypto.utils
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.DateRange
+import androidx.compose.material.icons.filled.Label
+import androidx.compose.material.icons.filled.RepeatOneOn
+import com.rs.crypto.R
+import com.rs.crypto.models.*
+
+object DummyData {
+
+ val repeatOptions = listOf(
+ RepeatOptions(
+ iconImageVector = Icons.Default.RepeatOneOn,
+ optionName = "Repeats",
+ frequency = "Never"
+ ),
+ RepeatOptions(
+ iconImageVector = Icons.Default.DateRange,
+ optionName = "Starts",
+ frequency = "Today"
+ ),
+ RepeatOptions(
+ iconImageVector = Icons.Default.DateRange,
+ optionName = "Ends",
+ frequency = "Never"
+ ),
+ RepeatOptions(
+ iconImageVector = Icons.Default.Label,
+ optionName = "Label",
+ frequency = "Edit label"
+ )
+ )
+
+ val tradeScreenSections = listOf(
+ "Transact",
+ "Repeat",
+ "Limit"
+ )
+
+ val topChipsName = listOf(
+ "All 4 ",
+ "Following 2 ",
+ "Crypto 4 ",
+ "Utility Tokens 1 ",
+ "Stable Coins 2 "
+ )
+
+ val user = User(
+ userName = "DeveloperRahnuma",
+ firstName = "Rahnuma",
+ lastName = "Sharib"
+ )
+
+ val portfolio = Portfolio(
+ balance = 12347.33F,
+ changes = 8.39F,
+ changeType = "I"
+ )
+
+ val trendingCurrencies = listOf(
+ TrendingCurrency(
+ id = 3,
+ currencyName = "Litecoin",
+ currencyCode = "LTC",
+ imageRes = R.drawable.litecoin,
+ currentPrice = 98.33F,
+ changes = 1.73F,
+ changeType = "I",
+ description = "Litecoin is a peer-to-peer cryptocurrency and open-source software project released under the MIT/X11 license. Litecoin was an early bitcoin spinoff or altcoin, starting in October 2011. In technical details, Litecoin is nearly identical to Bitcoin.",
+ chartData = listOf(
+ Pair(1F, 2.6F),
+ Pair(1.5F, 2.2F),
+ Pair(2F, 2F),
+ Pair(2.5F, 2.2F),
+ Pair(3F, 1.6F),
+ Pair(3.5F, 2.1F),
+ Pair(4F, 2.5F)
+ ),
+ wallet = Wallet(
+ value = 13139.23F,
+ crypto = 100.2F
+ ),
+ transactionHistory = listOf(
+ Transaction(
+ transactionID = 1,
+ description = "Sold Litecoin",
+ amount = -2.0034F,
+ currencyCode = "LTC",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 2,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 3,
+ description = "Sold Litecoin",
+ amount = -2.0034F,
+ currencyCode = "LTC",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 4,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 5,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 6,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 7,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 8,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 9,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "LTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ )
+ ),
+ TrendingCurrency(
+ id = 4,
+ currencyName = "Ripple",
+ currencyCode = "XRP",
+ imageRes = R.drawable.ripple,
+ currentPrice = 1.49F,
+ changes = 2.23F,
+ changeType = "D",
+ description = "Ripple is a real-time gross settlement system, currency exchange and remittance network created by Ripple Labs Inc., a US-based technology company.",
+ chartData = listOf(
+ Pair(1F, 2.3F),
+ Pair(1.5F, 2.3F),
+ Pair(2F, 2.5F),
+ Pair(2.5F, 2.1F),
+ Pair(3F, 2.2F),
+ Pair(3.5F, 1.8F),
+ Pair(4F, 2.5F)
+ ),
+ wallet = Wallet(
+ value = 2000.0F,
+ crypto = 6000.0F
+ ),
+ transactionHistory = listOf(
+ Transaction(
+ transactionID = 1,
+ description = "Sold Ripple",
+ amount = -2.0034F,
+ currencyCode = "XRP",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 2,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 3,
+ description = "Sold Ripple",
+ amount = -2.0034F,
+ currencyCode = "XRP",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 4,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 5,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 6,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 7,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 8,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 9,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "XRP",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ )
+ ),
+ TrendingCurrency(
+ id = 1,
+ currencyName = "Bitcoin",
+ currencyCode = "BTC",
+ imageRes = R.drawable.bitcoin,
+ currentPrice = 19598.74F,
+ changes = 18.24F,
+ changeType = "I",
+ description = "Bitcoin is a cryptocurrency invented in 2008 by an unknown person or group of people using the name Satoshi Nakamoto. The currency began use in 2009 when its implementation was released as open-source software.",
+ chartData = listOf(
+ Pair(1F, 2.5F),
+ Pair(1.5F, 2F),
+ Pair(2F, 2.3F),
+ Pair(2.5F, 1.4F),
+ Pair(3F, 1.5F),
+ Pair(3.5F, 2.3F),
+ Pair(4F, 2.8F)
+ ),
+ wallet = Wallet(
+ value = 170435.86F,
+ crypto = 5.1F
+ ),
+ transactionHistory = listOf(
+ Transaction(
+ transactionID = 1,
+ description = "Sold Bitcoin",
+ amount = -2.0034F,
+ currencyCode = "BTC",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 2,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 3,
+ description = "Sold Bitcoin",
+ amount = -2.0034F,
+ currencyCode = "BTC",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 4,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 5,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 6,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 7,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 8,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 9,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "BTC",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ )
+ ),
+ TrendingCurrency(
+ id = 2,
+ currencyName = "Ethereum",
+ currencyCode = "ETH",
+ imageRes = R.drawable.ethereum,
+ currentPrice = 512.03F,
+ changes = 5.12F,
+ changeType = "D",
+ description = "Ethereum is a decentralized, open-source blockchain featuring smart contract functionality. Ether is the native cryptocurrency of the platform. It is the second-largest cryptocurrency by market capitalization, after Bitcoin. Ethereum is the most actively used blockchain.",
+ chartData = listOf(
+ Pair(1F, 2F),
+ Pair(1.5F, 2.3F),
+ Pair(2F, 2F),
+ Pair(2.5F, 2.2F),
+ Pair(3F, 1.5F),
+ Pair(3.5F, 2.1F),
+ Pair(4F, 2.5F)
+ ),
+ wallet = Wallet(
+ value = 18409.24F,
+ crypto = 13.7F
+ ),
+ transactionHistory = listOf(
+ Transaction(
+ transactionID = 1,
+ description = "Sold Ethereum",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 2,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 3,
+ description = "Sold Ethereum",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 4,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 5,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 6,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 7,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 8,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 9,
+ description = "Bought Ethereum",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ )
+ )
+ )
+
+ val followingTokens = listOf(
+ trendingCurrencies[0],
+ trendingCurrencies[1]
+ )
+
+ val utilityTokens = listOf(
+ trendingCurrencies[3]
+ )
+
+ val stableCoins = listOf(
+ trendingCurrencies[1],
+ trendingCurrencies[0]
+ )
+
+ val transactionHistory = listOf(
+ Transaction(
+ transactionID = 1,
+ description = "Sold Bitcoin",
+ amount = -1.3174F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 2,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 3,
+ description = "Sold Bitcoin",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 4,
+ description = "Bought Ripple",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 5,
+ description = "Sold Litecoin",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 6,
+ description = "Bought Litecoin",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 7,
+ description = "Sold Ripple",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 8,
+ description = "Sold Bitcoin",
+ amount = -2.0034F,
+ currencyCode = "ETH",
+ transactionType = "S",
+ transactionDate = "14:20 12 Apr"
+ ),
+ Transaction(
+ transactionID = 9,
+ description = "Bought Bitcoin",
+ amount = 2.0034F,
+ currencyCode = "ETH",
+ transactionType = "B",
+ transactionDate = "14:20 12 Apr"
+ ),
+ )
+
+ val chartOptions = listOf(
+ ChartOption(
+ optionId = 1,
+ label = "1 hr"
+ ),
+ ChartOption(
+ optionId = 2,
+ label = "3 Days"
+ ),
+ ChartOption(
+ optionId = 3,
+ label = "1 Week"
+ ),
+ ChartOption(
+ optionId = 4,
+ label = "1 Month"
+ ),
+ ChartOption(
+ optionId = 5,
+ label = "3 Months"
+ )
+ )
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/NavigationItems.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/NavigationItems.kt
new file mode 100644
index 00000000..95c14a12
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/NavigationItems.kt
@@ -0,0 +1,11 @@
+package com.rs.crypto.utils
+
+import com.rs.crypto.R
+
+sealed class NavigationItems(val route: String, val iconRes: Int, val name: String) {
+ object Home: NavigationItems(route = "home_nav_item", iconRes = R.drawable.home, name = "HOME")
+ object Portfolio: NavigationItems(route = "portfolio_nav_item", iconRes = R.drawable.pie_chart, name = "PORTFOLIO")
+ object Transaction: NavigationItems(route = "transaction_nav_item", iconRes = R.drawable.transaction, name = "")
+ object Prices: NavigationItems(route = "prices_nav_item", iconRes = R.drawable.line_graph, name = "PRICES")
+ object Settings: NavigationItems(route = "settings_nav_item", iconRes = R.drawable.settings, name = "SETTINGS")
+}
diff --git a/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Screen.kt b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Screen.kt
new file mode 100644
index 00000000..5af524d0
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/java/com/rs/crypto/utils/Screen.kt
@@ -0,0 +1,11 @@
+package com.rs.crypto.utils
+
+sealed class Screen(val route: String) {
+ object SettingsScreen: Screen("settings_screen")
+ object HomeScreen: Screen("home_screen")
+ object CryptoDetailScreen: Screen("crypto_detail_screen")
+ object TransactionScreen: Screen("transaction_screen")
+ object PortfolioScreen: Screen("portfolio_screen")
+ object PricesScreen: Screen("prices_screen")
+ object TradeScreen: Screen("trade_screen")
+}
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/demos/CryptoAppUi/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..2b068d11
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable-v24/launch_screen.png b/demos/CryptoAppUi/app/src/main/res/drawable-v24/launch_screen.png
new file mode 100644
index 00000000..30b10347
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable-v24/launch_screen.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/back_arrow.png b/demos/CryptoAppUi/app/src/main/res/drawable/back_arrow.png
new file mode 100644
index 00000000..82c21f73
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/back_arrow.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/banner.png b/demos/CryptoAppUi/app/src/main/res/drawable/banner.png
new file mode 100644
index 00000000..56f6bab0
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/banner.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/bitcoin.png b/demos/CryptoAppUi/app/src/main/res/drawable/bitcoin.png
new file mode 100644
index 00000000..e0c21878
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/bitcoin.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/crypto_icon.png b/demos/CryptoAppUi/app/src/main/res/drawable/crypto_icon.png
new file mode 100644
index 00000000..ddc6710d
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/crypto_icon.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/ethereum.png b/demos/CryptoAppUi/app/src/main/res/drawable/ethereum.png
new file mode 100644
index 00000000..a61c6272
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/ethereum.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/home.png b/demos/CryptoAppUi/app/src/main/res/drawable/home.png
new file mode 100644
index 00000000..cfea3ee0
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/home.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/ic_launcher_background.xml b/demos/CryptoAppUi/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..07d5da9c
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/line_graph.png b/demos/CryptoAppUi/app/src/main/res/drawable/line_graph.png
new file mode 100644
index 00000000..3284a60e
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/line_graph.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/litecoin.png b/demos/CryptoAppUi/app/src/main/res/drawable/litecoin.png
new file mode 100644
index 00000000..54ef713f
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/litecoin.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/notification_color.png b/demos/CryptoAppUi/app/src/main/res/drawable/notification_color.png
new file mode 100644
index 00000000..856817f4
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/notification_color.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/notification_white.png b/demos/CryptoAppUi/app/src/main/res/drawable/notification_white.png
new file mode 100644
index 00000000..28f2108b
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/notification_white.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/pie_chart.png b/demos/CryptoAppUi/app/src/main/res/drawable/pie_chart.png
new file mode 100644
index 00000000..307cf86e
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/pie_chart.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/right_arrow.png b/demos/CryptoAppUi/app/src/main/res/drawable/right_arrow.png
new file mode 100644
index 00000000..5f4cf651
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/right_arrow.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/ripple.png b/demos/CryptoAppUi/app/src/main/res/drawable/ripple.png
new file mode 100644
index 00000000..fc9e4dc9
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/ripple.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/sample_line_chart_image.png b/demos/CryptoAppUi/app/src/main/res/drawable/sample_line_chart_image.png
new file mode 100644
index 00000000..2c1ae809
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/sample_line_chart_image.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/settings.png b/demos/CryptoAppUi/app/src/main/res/drawable/settings.png
new file mode 100644
index 00000000..3f26f4e4
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/settings.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/star.png b/demos/CryptoAppUi/app/src/main/res/drawable/star.png
new file mode 100644
index 00000000..65f3f36f
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/star.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/drawable/transaction.png b/demos/CryptoAppUi/app/src/main/res/drawable/transaction.png
new file mode 100644
index 00000000..f935236d
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/drawable/transaction.png differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_black.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_black.ttf
new file mode 100644
index 00000000..71f01ac2
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_black.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_black_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_black_italic.ttf
new file mode 100644
index 00000000..ec309c78
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_black_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_bold.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_bold.ttf
new file mode 100644
index 00000000..aaf374d2
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_bold.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_bold_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_bold_italic.ttf
new file mode 100644
index 00000000..dcd0f800
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_bold_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold.ttf
new file mode 100644
index 00000000..48dd6353
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold_italic.ttf
new file mode 100644
index 00000000..ad728646
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_bold_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_italic.ttf
new file mode 100644
index 00000000..a232513d
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light.ttf
new file mode 100644
index 00000000..a6e368d4
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light_italic.ttf
new file mode 100644
index 00000000..5b2b6ae0
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_light_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_regular.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_regular.ttf
new file mode 100644
index 00000000..65bf32a1
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_condensed_regular.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_italic.ttf
new file mode 100644
index 00000000..f382c687
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_light.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_light.ttf
new file mode 100644
index 00000000..664e1b2f
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_light.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_light_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_light_italic.ttf
new file mode 100644
index 00000000..b8f52963
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_light_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_medium.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_medium.ttf
new file mode 100644
index 00000000..aa00de0e
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_medium.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_medium_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_medium_italic.ttf
new file mode 100644
index 00000000..67e25f01
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_medium_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_regular.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_regular.ttf
new file mode 100644
index 00000000..3e6e2e76
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_regular.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_thin.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_thin.ttf
new file mode 100644
index 00000000..d262d144
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_thin.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/font/roboto_thin_italic.ttf b/demos/CryptoAppUi/app/src/main/res/font/roboto_thin_italic.ttf
new file mode 100644
index 00000000..63e9f971
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/font/roboto_thin_italic.ttf differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/demos/CryptoAppUi/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/demos/CryptoAppUi/app/src/main/res/values-night/themes.xml b/demos/CryptoAppUi/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..ebd2010f
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/values/colors.xml b/demos/CryptoAppUi/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f8c6127d
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/values/strings.xml b/demos/CryptoAppUi/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..93da9056
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Cryptocurrency App
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/main/res/values/themes.xml b/demos/CryptoAppUi/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..96c061d0
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/main/res/values/themes.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/CryptoAppUi/app/src/test/java/com/rs/crypto/ExampleUnitTest.kt b/demos/CryptoAppUi/app/src/test/java/com/rs/crypto/ExampleUnitTest.kt
new file mode 100644
index 00000000..2127b13e
--- /dev/null
+++ b/demos/CryptoAppUi/app/src/test/java/com/rs/crypto/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.rs.crypto
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/build.gradle b/demos/CryptoAppUi/build.gradle
new file mode 100644
index 00000000..6a79d8ad
--- /dev/null
+++ b/demos/CryptoAppUi/build.gradle
@@ -0,0 +1,21 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ ext {
+ compose_version = '1.0.0'
+ }
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:7.0.0"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/demos/CryptoAppUi/gradle.properties b/demos/CryptoAppUi/gradle.properties
new file mode 100644
index 00000000..98bed167
--- /dev/null
+++ b/demos/CryptoAppUi/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
\ No newline at end of file
diff --git a/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.jar b/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.properties b/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..a3dc9368
--- /dev/null
+++ b/demos/CryptoAppUi/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jul 29 20:15:36 IST 2021
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/demos/CryptoAppUi/gradlew b/demos/CryptoAppUi/gradlew
new file mode 100644
index 00000000..4f906e0c
--- /dev/null
+++ b/demos/CryptoAppUi/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/demos/CryptoAppUi/gradlew.bat b/demos/CryptoAppUi/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/demos/CryptoAppUi/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/demos/CryptoAppUi/settings.gradle b/demos/CryptoAppUi/settings.gradle
new file mode 100644
index 00000000..b9ff4ff6
--- /dev/null
+++ b/demos/CryptoAppUi/settings.gradle
@@ -0,0 +1,10 @@
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ jcenter() // Warning: this repository is going to shut down soon
+ }
+}
+rootProject.name = "Crypto App"
+include ':app'