Complete lab
This commit is contained in:
commit
e5adf214b7
37
app/src/main/java/com/example/testapp/MainActivity.kt
Normal file
37
app/src/main/java/com/example/testapp/MainActivity.kt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.example.testapp
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.activity.viewModels
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.graphs.RootNavigationGraph
|
||||||
|
import com.example.testapp.ui.theme.TestAppTheme
|
||||||
|
import org.w3c.dom.Text
|
||||||
|
|
||||||
|
class MainActivity : ComponentActivity() {
|
||||||
|
private val sharedViewModel: SharedViewModel by viewModels()
|
||||||
|
|
||||||
|
@SuppressLint("MissingInflatedId", "SetTextI18n")
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContent {
|
||||||
|
TestAppTheme {
|
||||||
|
RootNavigationGraph(
|
||||||
|
navController = rememberNavController(),
|
||||||
|
sharedViewModel = sharedViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AlertDialogExample(
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onConfirmation: () -> Unit,
|
||||||
|
dialogTitle: String,
|
||||||
|
dialogText: String,
|
||||||
|
) {
|
||||||
|
AlertDialog(
|
||||||
|
title = {
|
||||||
|
Text(text = dialogTitle)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(text = dialogText)
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
onConfirmation()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("Confirm")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
onDismissRequest()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("Dismiss")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
70
app/src/main/java/com/example/testapp/designElem/Btn.kt
Normal file
70
app/src/main/java/com/example/testapp/designElem/Btn.kt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Btn(modifier: Modifier = Modifier, btnConfig: btnConfig) {
|
||||||
|
Button(
|
||||||
|
onClick = btnConfig.onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = btnConfig.color),
|
||||||
|
modifier = modifier
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.Center)
|
||||||
|
.offset(x = btnConfig.offsetX, y = btnConfig.offsetY)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = btnConfig.text,
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class btnConfig(
|
||||||
|
val onClick: () -> Unit = {},
|
||||||
|
val text: String,
|
||||||
|
val color: Color,
|
||||||
|
val offsetX: Dp,
|
||||||
|
val offsetY: Dp
|
||||||
|
)
|
182
app/src/main/java/com/example/testapp/designElem/DealItem.kt
Normal file
182
app/src/main/java/com/example/testapp/designElem/DealItem.kt
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredSize
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DealItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.requiredWidth(width = 356.dp)
|
||||||
|
.requiredHeight(height = 86.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 10.dp,
|
||||||
|
y = 5.dp)
|
||||||
|
.requiredWidth(width = 336.dp)
|
||||||
|
.requiredHeight(height = 131.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color(0xfffafafa))
|
||||||
|
.border(border = BorderStroke(2.dp, Color.White),
|
||||||
|
shape = RoundedCornerShape(8.dp)))
|
||||||
|
Property1ListAvatar(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 10.dp,
|
||||||
|
y = 10.dp), deal, coins)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 201.dp,
|
||||||
|
y = 86.dp)
|
||||||
|
.requiredWidth(width = 130.dp)
|
||||||
|
.requiredHeight(height = 40.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 130.dp)
|
||||||
|
.requiredHeight(height = 40.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color(0xff85c3ff)))
|
||||||
|
Text(
|
||||||
|
text = "${coins.first{ x -> deal.buyerCoinId == x.id }.name} ${deal.countBuy}",
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 21.dp,
|
||||||
|
y = 10.dp)
|
||||||
|
.requiredWidth(width = 87.dp))
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 25.dp,
|
||||||
|
y = 86.dp)
|
||||||
|
.requiredWidth(width = 170.dp)
|
||||||
|
.requiredHeight(height = 40.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 170.dp)
|
||||||
|
.requiredHeight(height = 40.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color(0xff5acb48)))
|
||||||
|
Button(
|
||||||
|
onClick = { },
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color.White),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 52.dp,
|
||||||
|
y = 10.dp)
|
||||||
|
.requiredWidth(width = 66.dp)){ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1ListAvatar(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.requiredWidth(width = 336.dp)
|
||||||
|
.requiredHeight(height = 66.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(start = 12.dp,
|
||||||
|
end = 16.dp,
|
||||||
|
top = 4.dp,
|
||||||
|
bottom = 4.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
) {
|
||||||
|
Avatar(deal = deal, coins = coins)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = coins.first {x -> x.id == deal.sellerCoinId}.name,
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Avatar(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.requiredSize(size = 32.dp)
|
||||||
|
.clip(shape = MaterialTheme.shapes.small)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(color = Color(0xfff9a825)))
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(brush = Brush.linearGradient(
|
||||||
|
0f to Color.White,
|
||||||
|
1f to Color.White,
|
||||||
|
start = Offset(16f, 0f),
|
||||||
|
end = Offset(16f, 32f))))
|
||||||
|
Text(
|
||||||
|
text = coins.first {x -> x.id == deal.sellerCoinId}.shortName(),
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
85
app/src/main/java/com/example/testapp/designElem/DropDown.kt
Normal file
85
app/src/main/java/com/example/testapp/designElem/DropDown.kt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
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.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
data class DropDownConfig<T>(
|
||||||
|
val values: List<T>,
|
||||||
|
var title: String,
|
||||||
|
val onValueChange: (T) -> Unit,
|
||||||
|
val selected: T?
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun <T> DropDown(modifier: Modifier = Modifier, downConfig: DropDownConfig<T>) {
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.clickable { expanded = !expanded }
|
||||||
|
.background(color = Color.Transparent)
|
||||||
|
.border(
|
||||||
|
border = BorderStroke(1.dp, Color.Black),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
)
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 8.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = if (downConfig.selected == null) downConfig.title else downConfig.selected.toString(),
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.43.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false },
|
||||||
|
Modifier.background(color = Color.Transparent),
|
||||||
|
) {
|
||||||
|
downConfig.values.forEach { x ->
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(x.toString()) },
|
||||||
|
onClick = {
|
||||||
|
downConfig.onValueChange(x);
|
||||||
|
expanded = false;
|
||||||
|
downConfig.title = x.toString()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
app/src/main/java/com/example/testapp/designElem/ListItem.kt
Normal file
84
app/src/main/java/com/example/testapp/designElem/ListItem.kt
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ListItem(modifier: Modifier = Modifier, coin : Coin, count: Float) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.requiredWidth(width = 340.dp)
|
||||||
|
.requiredHeight(height = 36.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(end = 12.dp,
|
||||||
|
top = 4.dp,
|
||||||
|
bottom = 4.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 56.dp)
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 40.dp)
|
||||||
|
.requiredHeight(height = 32.dp)
|
||||||
|
.clip(shape = MaterialTheme.shapes.small)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(color = Color(0xfff9a825)))
|
||||||
|
Text(
|
||||||
|
text = coin.shortName(),
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "$count ${coin.name}",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
108
app/src/main/java/com/example/testapp/designElem/NavBar.kt
Normal file
108
app/src/main/java/com/example/testapp/designElem/NavBar.kt
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package com.example.pmulabs.designElem
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.shrinkHorizontally
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.NavigationBar
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.toUpperCase
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavDestination
|
||||||
|
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||||
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
|
import com.example.testapp.navigate.BottomBarScreen
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NavBar(navController: NavHostController){
|
||||||
|
val screens = listOf(
|
||||||
|
BottomBarScreen.Profile,
|
||||||
|
BottomBarScreen.Wallet,
|
||||||
|
BottomBarScreen.Deals,
|
||||||
|
BottomBarScreen.History
|
||||||
|
)
|
||||||
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
|
val currentDestination=navBackStackEntry?.destination
|
||||||
|
val bottomBarDestination=screens.any{ it.route==currentDestination?.route }
|
||||||
|
NavigationBar(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(48.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 5.dp)
|
||||||
|
.background(Color.Transparent),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
if (bottomBarDestination) {
|
||||||
|
screens.forEach { screen ->
|
||||||
|
AddItem(
|
||||||
|
screen = screen,
|
||||||
|
currentDestination = currentDestination,
|
||||||
|
navController = navController
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AddItem(
|
||||||
|
screen: BottomBarScreen,
|
||||||
|
currentDestination: NavDestination?,
|
||||||
|
navController: NavController
|
||||||
|
){
|
||||||
|
val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
|
||||||
|
val background = if (selected) Color(0xff4BB2F9) else Color.Transparent
|
||||||
|
val contentColor = if (selected) Color.White else Color(0xFF4BB2F9)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(40.dp)
|
||||||
|
.background(background)
|
||||||
|
.clickable(onClick = {
|
||||||
|
navController.navigate(screen.route) {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id)
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.requiredWidth(100.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 5.dp, end = 5.dp, top = 8.dp, bottom = 8.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
AnimatedVisibility(visible = true) {
|
||||||
|
Text(
|
||||||
|
text = screen.shortName(),
|
||||||
|
color = contentColor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
|
class SharedViewModel : ViewModel() {
|
||||||
|
val argument = mutableStateOf<String?>(null)
|
||||||
|
val argument_edit = mutableStateOf<Any?>(null)
|
||||||
|
val argument_add_f = mutableStateOf<Any?>(null)
|
||||||
|
val argument_add_c = mutableStateOf<Any?>(null)
|
||||||
|
|
||||||
|
fun setArgumentAdd(arg1: Any, arg2: Any) {
|
||||||
|
argument_add_f.value = arg1
|
||||||
|
argument_add_c.value = arg2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setArgumentEdit(arg: Any) {
|
||||||
|
argument_edit.value = arg
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setArgument(arg: String) {
|
||||||
|
argument.value = arg
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.example.testapp.designElem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Slider
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableDoubleStateOf
|
||||||
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
data class SliderRangeConfig(
|
||||||
|
val start: Float,
|
||||||
|
val end: Float
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SliderWithRange(modifier: Modifier = Modifier,
|
||||||
|
sliderRangeConfig: SliderRangeConfig = SliderRangeConfig(0.0f, 1.0f),
|
||||||
|
onValueChange: (Float) -> Unit = {}
|
||||||
|
) {
|
||||||
|
var value by remember { mutableFloatStateOf(sliderRangeConfig.start) }
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(2.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color.Transparent)
|
||||||
|
.border(
|
||||||
|
border = BorderStroke(1.dp, Color.Black),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
)
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 8.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Slider(
|
||||||
|
value = value,
|
||||||
|
onValueChange = { value = it; onValueChange(value) },
|
||||||
|
onValueChangeFinished = { },
|
||||||
|
valueRange = sliderRangeConfig.start..sliderRangeConfig.end,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 2.dp
|
||||||
|
))
|
||||||
|
Text(
|
||||||
|
text = value.toString(),
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.43.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
29
app/src/main/java/com/example/testapp/graphs/AuthNavGraph.kt
Normal file
29
app/src/main/java/com/example/testapp/graphs/AuthNavGraph.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.example.testapp.graphs
|
||||||
|
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavGraphBuilder
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.navigation
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.screensMobile.EntryScreen
|
||||||
|
import com.example.testapp.screensMobile.RegisterScreen
|
||||||
|
|
||||||
|
fun NavGraphBuilder.authNavGraph(navController: NavHostController, sharedViewModel: SharedViewModel){
|
||||||
|
navigation(
|
||||||
|
route=Graph.AUTHENTICATION,
|
||||||
|
startDestination = AuthScreen.Entry.route
|
||||||
|
){
|
||||||
|
composable(route=AuthScreen.Entry.route){
|
||||||
|
EntryScreen(navController = navController, modifier = Modifier, sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
composable(route=AuthScreen.Register.route){
|
||||||
|
RegisterScreen(navController = navController, modifier = Modifier, sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class AuthScreen(val route: String){
|
||||||
|
object Entry : AuthScreen(route="ENTRY")
|
||||||
|
object Register : AuthScreen(route="REGISTER")
|
||||||
|
}
|
44
app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt
Normal file
44
app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.example.testapp.graphs
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.NavType
|
||||||
|
import androidx.navigation.compose.NavHost
|
||||||
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.navArgument
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.navigate.BottomBarScreen
|
||||||
|
import com.example.testapp.screensMobile.AccountPage
|
||||||
|
import com.example.testapp.screensMobile.CreateDeal
|
||||||
|
import com.example.testapp.screensMobile.DealList
|
||||||
|
import com.example.testapp.screensMobile.History
|
||||||
|
import com.example.testapp.screensMobile.Wallet
|
||||||
|
|
||||||
|
@RequiresApi(34)
|
||||||
|
@Composable
|
||||||
|
fun HomeNavGraph(navController: NavHostController, sharedViewModel: SharedViewModel){
|
||||||
|
NavHost(
|
||||||
|
navController = navController,
|
||||||
|
route = Graph.MAIN,
|
||||||
|
startDestination = BottomBarScreen.Wallet.route
|
||||||
|
){
|
||||||
|
composable(route=BottomBarScreen.Wallet.route){
|
||||||
|
Wallet(sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
composable(route=BottomBarScreen.Profile.route){
|
||||||
|
AccountPage(sharedViewModel = sharedViewModel, navController = navController)
|
||||||
|
}
|
||||||
|
composable(route=BottomBarScreen.Deals.route){
|
||||||
|
DealList(navController = navController, sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
composable(route=BottomBarScreen.CDEAL.route) {
|
||||||
|
CreateDeal(sharedViewModel = sharedViewModel, navController = navController)
|
||||||
|
}
|
||||||
|
composable(route=BottomBarScreen.History.route){
|
||||||
|
History(sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt
Normal file
42
app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.example.testapp.graphs
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
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.navArgument
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.screensMobile.LoadScreen
|
||||||
|
|
||||||
|
const val USERID_ARGUMENT="userId"
|
||||||
|
|
||||||
|
@RequiresApi(34)
|
||||||
|
@Composable
|
||||||
|
fun RootNavigationGraph(navController: NavHostController, sharedViewModel: SharedViewModel){
|
||||||
|
NavHost(
|
||||||
|
navController=navController,
|
||||||
|
route = Graph.ROOT,
|
||||||
|
startDestination = Graph.AUTHENTICATION
|
||||||
|
){
|
||||||
|
authNavGraph(navController=navController,sharedViewModel)
|
||||||
|
composable(route=Graph.MAIN,
|
||||||
|
arguments = listOf(navArgument(USERID_ARGUMENT){
|
||||||
|
type= NavType.StringType
|
||||||
|
})){
|
||||||
|
LoadScreen(sharedViewModel = sharedViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Graph{
|
||||||
|
const val ROOT="root_graph"
|
||||||
|
const val AUTHENTICATION="auth_graph"
|
||||||
|
const val MAIN="main_graph/{$USERID_ARGUMENT}"
|
||||||
|
|
||||||
|
fun passUserId(userId: String): String{
|
||||||
|
return "main_graph/$userId"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.example.testapp.navigate
|
||||||
|
|
||||||
|
sealed class BottomBarScreen(
|
||||||
|
val route: String,
|
||||||
|
val title: String
|
||||||
|
) {
|
||||||
|
object Profile: BottomBarScreen(
|
||||||
|
route = "PROFILE",
|
||||||
|
title = "Account",
|
||||||
|
);
|
||||||
|
object Wallet: BottomBarScreen(
|
||||||
|
route = "WALLET",
|
||||||
|
title = "Wallet"
|
||||||
|
);
|
||||||
|
object Deals: BottomBarScreen(
|
||||||
|
route = "DEALS",
|
||||||
|
title = "Deals"
|
||||||
|
)
|
||||||
|
object History: BottomBarScreen(
|
||||||
|
route = "HISTORY",
|
||||||
|
title = "History"
|
||||||
|
)
|
||||||
|
object CDEAL: BottomBarScreen(
|
||||||
|
route = "CDEAL",
|
||||||
|
title = "CDEAL"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun shortName(): String {
|
||||||
|
return title.uppercase().substring(0, 4)
|
||||||
|
}
|
||||||
|
}
|
21
app/src/main/java/com/example/testapp/room/dao/CoinDao.kt
Normal file
21
app/src/main/java/com/example/testapp/room/dao/CoinDao.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.example.testapp.room.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface CoinDao{
|
||||||
|
@Query("select * from coin")
|
||||||
|
fun getAll(): Flow<List<Coin>>
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(obj: Coin)
|
||||||
|
@Update
|
||||||
|
suspend fun update(obj: Coin)
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(obj: Coin)
|
||||||
|
}
|
24
app/src/main/java/com/example/testapp/room/dao/DealDao.kt
Normal file
24
app/src/main/java/com/example/testapp/room/dao/DealDao.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.testapp.room.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface DealDao{
|
||||||
|
@Query("select * from deal")
|
||||||
|
fun getAll(): Flow<List<Deal>>
|
||||||
|
@Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser")
|
||||||
|
fun getUserDeals(idUser: Int): Flow<List<Deal>>
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(obj: Deal)
|
||||||
|
@Update
|
||||||
|
suspend fun update(obj: Deal)
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(obj: Deal)
|
||||||
|
}
|
29
app/src/main/java/com/example/testapp/room/dao/UserDao.kt
Normal file
29
app/src/main/java/com/example/testapp/room/dao/UserDao.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.example.testapp.room.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import com.example.testapp.room.models.WalletItem
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Query("select * from user")
|
||||||
|
fun getAll(): Flow<List<User>>
|
||||||
|
@Query("select * from user where user.id = :idUser")
|
||||||
|
fun getUserById(idUser: Int): Flow<User>
|
||||||
|
@Query("select * from walletitem where walletitem.userId = :idUser")
|
||||||
|
fun getUserWallet(idUser: Int): Flow<List<WalletItem>>
|
||||||
|
@Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser")
|
||||||
|
fun getUserDeals(idUser: Int): Flow<List<Deal>>
|
||||||
|
@Insert
|
||||||
|
fun insert(obj: User)
|
||||||
|
@Update
|
||||||
|
fun update(obj: User)
|
||||||
|
@Delete
|
||||||
|
fun delete(obj: User)
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.example.testapp.room.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import com.example.testapp.room.models.WalletItem
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface WalletItemDao {
|
||||||
|
@Query("select * from walletitem")
|
||||||
|
fun getAll(): Flow<List<WalletItem>>
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(obj: WalletItem)
|
||||||
|
@Update
|
||||||
|
suspend fun update(obj: WalletItem)
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(obj: WalletItem)
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.example.testapp.room.database
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
import com.example.testapp.room.dao.*
|
||||||
|
import com.example.testapp.room.models.*
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@Database(
|
||||||
|
entities = [User::class, Deal::class, Coin::class, WalletItem::class],
|
||||||
|
version = 2,
|
||||||
|
exportSchema = false)
|
||||||
|
abstract class CryptoDealDb: RoomDatabase() {
|
||||||
|
abstract fun userDao(): UserDao;
|
||||||
|
abstract fun coinDao(): CoinDao;
|
||||||
|
abstract fun dealDao(): DealDao;
|
||||||
|
abstract fun walletItemDao(): WalletItemDao;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DB_NAME: String = "crypto-deal2"
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: CryptoDealDb? = null
|
||||||
|
private suspend fun populateDatabase() {
|
||||||
|
INSTANCE?.let { database ->
|
||||||
|
val userDao = database.userDao();
|
||||||
|
val user1 = User(0, "u11@gmail.com","12345")
|
||||||
|
val user2 = User(1, "u22@gmail.com","12345")
|
||||||
|
val user3 = User(2, "u33@gmail.com","12345")
|
||||||
|
userDao.insert(user1)
|
||||||
|
userDao.insert(user2)
|
||||||
|
userDao.insert(user3)
|
||||||
|
|
||||||
|
val coinDao = database.coinDao();
|
||||||
|
val c1 = Coin(0, "BidCoin");
|
||||||
|
val c2 = Coin(1, "Edhereum");
|
||||||
|
val c3 = Coin(2, "CatCoin");
|
||||||
|
val c4 = Coin(3, "BuzCoin");
|
||||||
|
coinDao.insert(c1);
|
||||||
|
coinDao.insert(c2)
|
||||||
|
coinDao.insert(c3)
|
||||||
|
coinDao.insert(c4)
|
||||||
|
|
||||||
|
val walletItemDao = database.walletItemDao();
|
||||||
|
val wi1 = WalletItem(0, 0, 0.5f);
|
||||||
|
val wi2 = WalletItem(1, 0, 0.6f);
|
||||||
|
val wi3 = WalletItem(3, 0, 0.7f);
|
||||||
|
val wi4 = WalletItem(0, 1, 1000f);
|
||||||
|
val wi5 = WalletItem(3, 1, 10f);
|
||||||
|
val wi6 = WalletItem(2, 1, 1f);
|
||||||
|
walletItemDao.insert(wi1);
|
||||||
|
walletItemDao.insert(wi2);
|
||||||
|
walletItemDao.insert(wi3);
|
||||||
|
walletItemDao.insert(wi4);
|
||||||
|
walletItemDao.insert(wi5);
|
||||||
|
walletItemDao.insert(wi6);
|
||||||
|
|
||||||
|
val dealDao = database.dealDao();
|
||||||
|
val d1 = Deal(0, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST1")
|
||||||
|
val d2 = Deal(1, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST2")
|
||||||
|
dealDao.insert(d1);
|
||||||
|
dealDao.insert(d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInstance(appContext: Context): CryptoDealDb {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
Room.databaseBuilder(
|
||||||
|
appContext,
|
||||||
|
CryptoDealDb::class.java,
|
||||||
|
DB_NAME
|
||||||
|
)
|
||||||
|
.addCallback(object : Callback() {
|
||||||
|
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||||
|
super.onCreate(db)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
populateDatabase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
app/src/main/java/com/example/testapp/room/models/Coin.kt
Normal file
17
app/src/main/java/com/example/testapp/room/models/Coin.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.example.testapp.room.models
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = "coin")
|
||||||
|
class Coin(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val id: Int?,
|
||||||
|
@ColumnInfo(name = "name")
|
||||||
|
val name: String
|
||||||
|
) {
|
||||||
|
fun shortName(): String {
|
||||||
|
return this.name.substring(0, 2)
|
||||||
|
}
|
||||||
|
}
|
22
app/src/main/java/com/example/testapp/room/models/Deal.kt
Normal file
22
app/src/main/java/com/example/testapp/room/models/Deal.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package com.example.testapp.room.models
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class Deal (
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val id: Int?,
|
||||||
|
val sellerId: Int?,
|
||||||
|
val buyerId: Int?,
|
||||||
|
val sellerCoinId: Int,
|
||||||
|
val buyerCoinId: Int,
|
||||||
|
val countSell: Float,
|
||||||
|
val countBuy: Float,
|
||||||
|
val operation: String,
|
||||||
|
var date: Long?,
|
||||||
|
val tip: String,
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
29
app/src/main/java/com/example/testapp/room/models/User.kt
Normal file
29
app/src/main/java/com/example/testapp/room/models/User.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.example.testapp.room.models
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Index
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = "user",
|
||||||
|
indices = [Index(value = ["email"], unique = true)])
|
||||||
|
class User(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val id: Int?,
|
||||||
|
@ColumnInfo(name = "email")
|
||||||
|
var email: String,
|
||||||
|
@ColumnInfo(name = "password")
|
||||||
|
var password: String
|
||||||
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as User
|
||||||
|
if (id != other.id) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return id ?: -1
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.example.testapp.room.models
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.ForeignKey
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(
|
||||||
|
primaryKeys = ["coinId", "userId"],
|
||||||
|
foreignKeys = [
|
||||||
|
ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["userId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
|
||||||
|
ForeignKey(entity = Coin::class, parentColumns = ["id"], childColumns = ["coinId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
class WalletItem (
|
||||||
|
val coinId: Int,
|
||||||
|
val userId: Int,
|
||||||
|
val count: Float
|
||||||
|
)
|
@ -0,0 +1,352 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredSize
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.graphs.AuthScreen
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@SuppressLint("CoroutineCreationDuringComposition")
|
||||||
|
@Composable
|
||||||
|
fun AccountPage(modifier: Modifier = Modifier, sharedViewModel: SharedViewModel, navController: NavController) {
|
||||||
|
val argument = sharedViewModel.argument.value
|
||||||
|
val context = LocalContext.current
|
||||||
|
val users = remember { mutableStateListOf<User>() }
|
||||||
|
var user: User? = null;
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getUserById(argument!!.toInt()).collect { data ->
|
||||||
|
user = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 104.dp
|
||||||
|
)
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(size = 84.dp)
|
||||||
|
) {
|
||||||
|
if (user != null) {
|
||||||
|
Container(
|
||||||
|
name = user!!.email.substring(0, 2),
|
||||||
|
modifier = Modifier.align(alignment = Alignment.TopStart).offset(15.dp, 15.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = 7.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.Start),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = 3.dp)
|
||||||
|
) {
|
||||||
|
if (user != null) {
|
||||||
|
Text(
|
||||||
|
text = user!!.email,
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 17.dp)
|
||||||
|
.requiredHeight(height = 4.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 204.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Property1Switch(modifier = Modifier.padding(vertical = 5.dp))
|
||||||
|
Property1Arrow(modifier = Modifier.padding(vertical = 5.dp))
|
||||||
|
}
|
||||||
|
Property1Clear(navController = navController)
|
||||||
|
Property1(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 24.dp
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1Switch(modifier: Modifier = Modifier) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(
|
||||||
|
start = 12.dp,
|
||||||
|
end = 16.dp,
|
||||||
|
top = 4.dp,
|
||||||
|
bottom = 4.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
) {
|
||||||
|
// Icon(
|
||||||
|
// painter = painterResource(id = R.drawable.sizem),
|
||||||
|
// contentDescription = "IconFavorite",
|
||||||
|
// tint = Color(0xff002033).copy(alpha = 0.35f))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "Enable Notifications",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(weight = 1f)
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
Viewchecked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Container(modifier: Modifier = Modifier, name: String) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.requiredSize(size = 54.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(27.dp))
|
||||||
|
.background(color = Color(0xff4bb2f9))
|
||||||
|
.padding(all = 10.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = name,
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 24.sp,
|
||||||
|
fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Viewchecked(modifier: Modifier = Modifier) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 44.dp)
|
||||||
|
.requiredHeight(height = 24.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(shape = RoundedCornerShape(100.dp))
|
||||||
|
.background(color = Color(0xff4bb2f9)))
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(shape = CircleShape)
|
||||||
|
.background(color = Color.White))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1Arrow(modifier: Modifier = Modifier) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(
|
||||||
|
start = 12.dp,
|
||||||
|
end = 16.dp,
|
||||||
|
top = 4.dp,
|
||||||
|
bottom = 4.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 12.dp)
|
||||||
|
) {
|
||||||
|
// Icon(
|
||||||
|
// painter = painterResource(id = R.drawable.sizem),
|
||||||
|
// contentDescription = "IconFavorite",
|
||||||
|
// tint = Color(0xff002033).copy(alpha = 0.35f))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "Confirm Account",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(weight = 1f)
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1Clear(modifier: Modifier = Modifier, navController: NavController) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.clickable{
|
||||||
|
navController.navigate(route = AuthScreen.Entry.route) {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id)
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(
|
||||||
|
start = 16.dp,
|
||||||
|
end = 16.dp,
|
||||||
|
top = 580.dp,
|
||||||
|
bottom = 20.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.Center)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 0.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Log Out",
|
||||||
|
color = Color(0xffee3f58),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1(modifier: Modifier = Modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(end = 56.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 16.dp)
|
||||||
|
) {
|
||||||
|
// Icon(
|
||||||
|
// painter = painterResource(id = R.drawable.drawer),
|
||||||
|
// contentDescription = "Drawer",
|
||||||
|
// tint = Color(0xff0b1f33))
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Account",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.14.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,415 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
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.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.example.testapp.designElem.DropDown
|
||||||
|
import com.example.testapp.designElem.DropDownConfig
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.navigate.BottomBarScreen
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import com.example.testapp.room.models.WalletItem
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@RequiresApi(34)
|
||||||
|
@Composable
|
||||||
|
fun CreateDeal(modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel,
|
||||||
|
navController: NavHostController) {
|
||||||
|
val argument = sharedViewModel.argument.value
|
||||||
|
val editDeal: Deal? = sharedViewModel.argument_edit.value as? Deal
|
||||||
|
val isEdit = editDeal != null
|
||||||
|
val id = if (isEdit) editDeal?.buyerId else argument?.toInt()
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
val coins = remember { mutableStateListOf<Coin>() }
|
||||||
|
SideEffect() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
CryptoDealDb.getInstance(context).coinDao().getAll().collect { data ->
|
||||||
|
coins.clear()
|
||||||
|
coins.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val wallet = remember { mutableStateListOf<WalletItem>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (id != null) {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getUserWallet(id).collect{data ->
|
||||||
|
wallet.clear();
|
||||||
|
wallet.addAll(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val coinsBuyer = wallet.filter { x -> x.userId == id }.toList()
|
||||||
|
var coinBuyer by rememberSaveable {
|
||||||
|
mutableStateOf(if (isEdit) coins.first{y -> y.id == editDeal?.buyerCoinId }.name else coinsBuyer[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
var buyCount by remember {
|
||||||
|
mutableFloatStateOf(if (isEdit) editDeal?.countBuy!! else 0f)
|
||||||
|
}
|
||||||
|
var tip by remember {
|
||||||
|
mutableStateOf(if (isEdit) editDeal?.tip else "")
|
||||||
|
}
|
||||||
|
|
||||||
|
val coinsSeller = wallet.map { x -> coins.first{y -> y.id == x.coinId}.name }.toList()
|
||||||
|
var coinSeller by rememberSaveable {
|
||||||
|
mutableStateOf(if (isEdit) coins.first{y -> y.id == editDeal?.sellerCoinId }.name else coinsSeller[0])
|
||||||
|
}
|
||||||
|
var sellCount by remember {
|
||||||
|
mutableFloatStateOf(if (isEdit) editDeal?.countSell!! else 0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
.padding(
|
||||||
|
horizontal = 0.dp,
|
||||||
|
vertical = 20.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(1f)
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(
|
||||||
|
horizontal = 17.dp,
|
||||||
|
vertical = 6.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "CREATE DEAL",
|
||||||
|
color = Color.Black,
|
||||||
|
lineHeight = 1.14.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "-",
|
||||||
|
color = Color(0xff4bb2f9),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 0.83.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 24.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {
|
||||||
|
navController.navigate(route = BottomBarScreen.Deals.route)
|
||||||
|
}
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
text = "You",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
DropDown(
|
||||||
|
modifier = Modifier.padding(horizontal = 10.dp),
|
||||||
|
downConfig = DropDownConfig<String>(
|
||||||
|
values = coinsBuyer.map { x -> coins.first{y -> y.id == x.coinId}.name }.toList(),
|
||||||
|
title = "Select coin",
|
||||||
|
onValueChange = { x -> coinBuyer = x },
|
||||||
|
selected = coinBuyer as String
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = buyCount.toString(),
|
||||||
|
onValueChange = {
|
||||||
|
val value = coinsBuyer.first{ x -> coinBuyer == coins.first{y -> y.id == x.coinId} }
|
||||||
|
if (it.toFloatOrNull() != null && it.toFloat() <= value.count) {
|
||||||
|
buyCount = it.toFloat()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Fill count 0 -> ${coinsBuyer.first{ x -> coinBuyer == coins.first{y -> y.id == x.coinId} }.count}",
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.43.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 2.dp
|
||||||
|
))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = tip!!,
|
||||||
|
onValueChange = { tip = it },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Enter tip (up to 100 symbols)",
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.43.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 100.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 2.dp
|
||||||
|
))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
text = "Buyer",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
DropDown(
|
||||||
|
modifier = Modifier.padding(horizontal = 10.dp),
|
||||||
|
downConfig = DropDownConfig<String>(
|
||||||
|
values = coinsSeller.filter { x -> x != (coinBuyer as String) },
|
||||||
|
title = "Select coin",
|
||||||
|
onValueChange = { x -> coinSeller = x },
|
||||||
|
selected = coinSeller
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = sellCount.toString(),
|
||||||
|
onValueChange = { sellCount = it.toFloat() },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Fill count",
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.43.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 2.dp
|
||||||
|
))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
if (isEdit) {
|
||||||
|
val deal = Deal(
|
||||||
|
id = editDeal?.id,
|
||||||
|
sellerId = editDeal?.sellerId,
|
||||||
|
buyerId = id,
|
||||||
|
buyerCoinId = coins.first { x -> x.name == coinBuyer }.id!!,
|
||||||
|
countBuy = buyCount,
|
||||||
|
sellerCoinId = coins.first { x -> x.name == coinSeller }.id!!,
|
||||||
|
countSell = sellCount,
|
||||||
|
tip = tip!!,
|
||||||
|
operation = "Buy",
|
||||||
|
date = null,
|
||||||
|
)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
CryptoDealDb.getInstance(context).dealDao().update(deal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val deal = Deal(
|
||||||
|
id = null,
|
||||||
|
sellerId = null,
|
||||||
|
buyerId = id,
|
||||||
|
buyerCoinId = coins.first { x -> x.name == coinBuyer }.id!!,
|
||||||
|
countBuy = buyCount,
|
||||||
|
sellerCoinId = coins.first { x -> x.name == coinSeller }.id!!,
|
||||||
|
countSell = sellCount,
|
||||||
|
tip = tip!!,
|
||||||
|
operation = "Buy",
|
||||||
|
date = null,
|
||||||
|
)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
CryptoDealDb.getInstance(context).dealDao().insert(deal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navController.navigate(route = BottomBarScreen.Deals.route)
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color(0xff4bb2f9)),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 10.dp, end = 10.dp, top = 30.dp)
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.Center)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 0.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = if (isEdit) "Confirm" else "Create",
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(route = BottomBarScreen.Deals.route)
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color(0xff4bb2f9)),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 10.dp)
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.Center)
|
||||||
|
.offset(
|
||||||
|
x = 0.dp,
|
||||||
|
y = 0.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Cancel",
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(34)
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun Frame20Preview() {
|
||||||
|
val sharedViewModel = SharedViewModel()
|
||||||
|
sharedViewModel.setArgument("0")
|
||||||
|
CreateDeal(Modifier,
|
||||||
|
navController = rememberNavController(),
|
||||||
|
sharedViewModel = sharedViewModel
|
||||||
|
)
|
||||||
|
}
|
367
app/src/main/java/com/example/testapp/screensMobile/DealList.kt
Normal file
367
app/src/main/java/com/example/testapp/screensMobile/DealList.kt
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredSize
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.example.testapp.R
|
||||||
|
import com.example.testapp.designElem.AlertDialogExample
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.graphs.Graph
|
||||||
|
import com.example.testapp.navigate.BottomBarScreen
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import com.example.testapp.room.models.WalletItem
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
@Composable
|
||||||
|
fun DealList(navController: NavHostController,
|
||||||
|
sharedViewModel: SharedViewModel,
|
||||||
|
@SuppressLint("ModifierParameter") modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val argument = sharedViewModel.argument.value
|
||||||
|
val id = argument?.toInt()
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
val deals = remember { mutableStateListOf<Deal>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).dealDao().getAll().collect { data ->
|
||||||
|
deals.clear()
|
||||||
|
deals.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val wallet = remember { mutableStateListOf<WalletItem>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (id != null) {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getUserWallet(id).collect{data ->
|
||||||
|
wallet.clear();
|
||||||
|
wallet.addAll(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val coins = remember { mutableStateListOf<Coin>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).coinDao().getAll().collect { data ->
|
||||||
|
coins.clear()
|
||||||
|
coins.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn (
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
.padding(vertical = 20.dp)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
PropertyDeal(navController = navController)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
deals.filter { x -> x.date == null }.forEach{ x -> Deal(
|
||||||
|
deal = x,
|
||||||
|
coins = coins,
|
||||||
|
modifier = Modifier.padding(vertical = 5.dp),
|
||||||
|
id = id,
|
||||||
|
navController = navController,
|
||||||
|
sharedViewModel = sharedViewModel,
|
||||||
|
wallet = wallet)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
@Composable
|
||||||
|
fun Deal(modifier: Modifier = Modifier,
|
||||||
|
deal: Deal,
|
||||||
|
coins: List<Coin>,
|
||||||
|
id: Int?,
|
||||||
|
navController: NavHostController,
|
||||||
|
sharedViewModel: SharedViewModel,
|
||||||
|
wallet: List<WalletItem>) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.requiredWidth(width = 360.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.background(color = Color(0xffEEEEEE))
|
||||||
|
.padding(
|
||||||
|
start = 10.dp,
|
||||||
|
end = 10.dp,
|
||||||
|
bottom = 10.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 360.dp)
|
||||||
|
.requiredHeight(height = 60.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(horizontal = 22.dp)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(size = 35.dp)
|
||||||
|
.clip(shape = MaterialTheme.shapes.small)
|
||||||
|
.background(
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
0f to Color(0xffffcc7a),
|
||||||
|
1f to Color(0xffe4a031),
|
||||||
|
start = Offset(17.5f, 0f),
|
||||||
|
end = Offset(17.5f, 35f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = coins.first{x -> x.id == deal.buyerCoinId}.shortName(),
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 20.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = deal.countBuy.toString(),
|
||||||
|
color = Color.Black,
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
lineHeight = 1.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 20.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = deal.tip,
|
||||||
|
color = Color(0xffa3abb3),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 40.dp)
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(5.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 360.dp)
|
||||||
|
.requiredHeight(height = 45.dp)
|
||||||
|
.padding(
|
||||||
|
horizontal = 10.dp,
|
||||||
|
vertical = 5.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
if (id != null && id != deal.buyerId) {
|
||||||
|
// val userRepository = UserRepository()
|
||||||
|
// val buyer = deal.buyerId?.let { userRepository.getById(it) }
|
||||||
|
// val seller = userRepository.getById(id)
|
||||||
|
//
|
||||||
|
// val coin = seller.wallet[deal.sellerCoin]
|
||||||
|
// if (coin != null && coin >= deal.countSell) {
|
||||||
|
// if (buyer != null) {
|
||||||
|
// if (buyer.wallet.containsKey(deal.sellerCoin))
|
||||||
|
// buyer.wallet[deal.sellerCoin] = buyer.wallet[deal.sellerCoin]!! + deal.countSell
|
||||||
|
// else buyer.wallet[deal.sellerCoin] = deal.countSell
|
||||||
|
// buyer.wallet[deal.buyerCoin] = buyer.wallet[deal.buyerCoin]!! - deal.countBuy
|
||||||
|
// }
|
||||||
|
// seller.wallet[deal.sellerCoin] = seller.wallet[deal.sellerCoin]!! - deal.countSell
|
||||||
|
// if (seller.wallet.containsKey(deal.buyerCoin))
|
||||||
|
// seller.wallet[deal.buyerCoin] = seller.wallet[deal.buyerCoin]!! + deal.countBuy
|
||||||
|
// else seller.wallet[deal.buyerCoin] = deal.countSell
|
||||||
|
// }
|
||||||
|
// deal.date = LocalDateTime.now()
|
||||||
|
// deal.sellerId = id
|
||||||
|
// DealRepository().update(deal)
|
||||||
|
// navController.navigate(BottomBarScreen.Deals.route) {
|
||||||
|
// popUpTo(navController.graph.findStartDestination().id)
|
||||||
|
// launchSingleTop = true
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
sharedViewModel.setArgumentEdit(deal)
|
||||||
|
sharedViewModel.setArgumentAdd(wallet, coins)
|
||||||
|
navController.navigate(BottomBarScreen.CDEAL.route) {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id)
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color(0xff5acb48)),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.weight(weight = 0.5f)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 168.dp)
|
||||||
|
.requiredHeight(height = 35.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = if (id == deal.buyerId) "Edit" else deal.operation,
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(width = 29.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.weight(weight = 0.5f)
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.background(color = Color(0xff85c3ff))
|
||||||
|
.padding(horizontal = 10.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = coins.first{x -> x.id == deal.sellerCoinId}.shortName(),
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
Text(
|
||||||
|
text = "${deal.countSell}\n",
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 20.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PropertyDeal(modifier: Modifier = Modifier, navController: NavHostController) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(
|
||||||
|
horizontal = 17.dp,
|
||||||
|
vertical = 6.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "CREATE DEAL",
|
||||||
|
color = Color.Black,
|
||||||
|
lineHeight = 1.14.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium))
|
||||||
|
Text(
|
||||||
|
text = "+",
|
||||||
|
color = Color(0xff4bb2f9),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
lineHeight = 0.83.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 24.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {
|
||||||
|
navController.navigate(BottomBarScreen.CDEAL.route) {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id)
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,189 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.testapp.designElem.Btn
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.designElem.btnConfig
|
||||||
|
import com.example.testapp.graphs.AuthScreen
|
||||||
|
import com.example.testapp.graphs.Graph
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
fun isValidEmail(email: String): Boolean {
|
||||||
|
val emailRegex = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+".toRegex()
|
||||||
|
return email.matches(emailRegex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun EntryScreen(navController: NavController,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel) {
|
||||||
|
var emailValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
var passwordValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
val context = LocalContext.current
|
||||||
|
val users = remember { mutableStateListOf<User>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getAll().collect { data ->
|
||||||
|
users.clear()
|
||||||
|
users.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 40.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Sign On",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 24.sp,
|
||||||
|
fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize())
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp, y = 278.dp)
|
||||||
|
.padding(start = 5.dp, end = 5.dp)
|
||||||
|
) {
|
||||||
|
TextField(
|
||||||
|
value = emailValue,
|
||||||
|
onValueChange = { emailValue = it },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Email",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
letterSpacing = 0.2.sp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
placeholder = { Text("Enter email") },
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
TextField(
|
||||||
|
value = passwordValue,
|
||||||
|
onValueChange = { passwordValue = it },
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Password",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
letterSpacing = 0.2.sp))
|
||||||
|
},
|
||||||
|
placeholder = { Text("Enter password") },
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 602.dp)
|
||||||
|
.padding(horizontal = 5.dp,
|
||||||
|
vertical = 5.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Btn(btnConfig = btnConfig(
|
||||||
|
onClick = {
|
||||||
|
if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) {
|
||||||
|
users.forEach { user ->
|
||||||
|
if (user.password == passwordValue && user.email == emailValue) {
|
||||||
|
sharedViewModel.setArgument(user.id.toString())
|
||||||
|
navController.navigate(route = Graph.passUserId(user.id.toString()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
text = "Sign In",
|
||||||
|
color = Color(0xff85c3ff),
|
||||||
|
offsetX = 0.dp,
|
||||||
|
offsetY = 0.dp
|
||||||
|
), modifier = Modifier.fillMaxWidth())
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 656.dp)
|
||||||
|
.padding(horizontal = 5.dp,
|
||||||
|
vertical = 5.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Btn(btnConfig = btnConfig(
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(route = AuthScreen.Register.route)
|
||||||
|
{
|
||||||
|
popUpTo(AuthScreen.Register.route)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = "Sign On",
|
||||||
|
color = Color(0xff85c3f3),
|
||||||
|
offsetX = 0.dp,
|
||||||
|
offsetY = 0.dp
|
||||||
|
), modifier = Modifier.fillMaxWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
206
app/src/main/java/com/example/testapp/screensMobile/History.kt
Normal file
206
app/src/main/java/com/example/testapp/screensMobile/History.kt
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.withStyle
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.Deal
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
@Composable
|
||||||
|
fun History(navController: NavHostController = rememberNavController(),
|
||||||
|
@SuppressLint("ModifierParameter") modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel
|
||||||
|
) {
|
||||||
|
val argument = sharedViewModel.argument.value
|
||||||
|
val id = argument?.toInt()
|
||||||
|
val context = LocalContext.current
|
||||||
|
val deals = remember { mutableStateListOf<Deal>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).dealDao().getAll().collect { data ->
|
||||||
|
deals.clear()
|
||||||
|
deals.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val coins = remember { mutableStateListOf<Coin>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).coinDao().getAll().collect { data ->
|
||||||
|
coins.clear()
|
||||||
|
coins.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var history: List<Deal> = listOf();
|
||||||
|
if (id != null) {
|
||||||
|
history = deals.filter { x -> x.buyerId == id || x.sellerId == id }
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.requiredHeight(height = 720.dp)
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
.padding(vertical = 20.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
PropertyHistory()
|
||||||
|
history.forEach {
|
||||||
|
x -> HistoryCard(deal = x, modifier = Modifier.padding( vertical = 5.dp, horizontal = 5.dp), coins = coins)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryCard(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
|
||||||
|
val status = !(deal.buyerId == null || deal.sellerId == null)
|
||||||
|
val text = if (!status) "In work" else deal.date.toString()
|
||||||
|
val color = if (!status) 0xfff96161 else 0xff5acb48
|
||||||
|
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 150.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(8.dp))
|
||||||
|
.background(color = Color.White)
|
||||||
|
.padding(
|
||||||
|
horizontal = 12.dp,
|
||||||
|
vertical = 5.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = 10.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "-${deal.countSell} ${coins.first{x -> x.id == deal.sellerCoinId}.shortName()}",
|
||||||
|
color = Color(0xfff96161),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
Text(
|
||||||
|
text = "+${deal.countBuy} ${coins.first{x -> x.id == deal.buyerCoinId}.shortName()}",
|
||||||
|
color = Color(0xff5acb48),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(shape = RoundedCornerShape(5.dp))
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
.padding(all = 10.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = deal.tip,
|
||||||
|
color = Color.Black,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
lineHeight = 1.sp,
|
||||||
|
text = buildAnnotatedString {
|
||||||
|
withStyle(style = SpanStyle(
|
||||||
|
color = Color(0xff1e1e1e),
|
||||||
|
fontSize = 16.sp)
|
||||||
|
) {append("Status: ")}
|
||||||
|
withStyle(style = SpanStyle(
|
||||||
|
color = Color(color),
|
||||||
|
fontSize = 16.sp)) {append(text)}},
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentHeight(align = Alignment.CenterVertically))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PropertyHistory(modifier: Modifier = Modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(end = 56.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "HISTORY",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.14.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,260 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.graphs.AuthScreen
|
||||||
|
import com.example.testapp.graphs.Graph
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun RegisterScreen(navController: NavController,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel) {
|
||||||
|
var emailValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
var passwordValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
var passwordConfirmValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
val context = LocalContext.current
|
||||||
|
val users = remember { mutableStateListOf<User>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getAll().collect { data ->
|
||||||
|
users.clear()
|
||||||
|
users.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 40.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Sign On",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 24.sp,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.padding(start = 5.dp, end = 5.dp)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 232.dp)
|
||||||
|
) {
|
||||||
|
TextField(
|
||||||
|
value = emailValue,
|
||||||
|
onValueChange = { emailValue = it },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Email",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
letterSpacing = 0.2.sp))
|
||||||
|
},
|
||||||
|
placeholder = { Text("Enter email") },
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
TextField(
|
||||||
|
value = passwordValue,
|
||||||
|
onValueChange = { passwordValue = it },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Password",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
letterSpacing = 0.2.sp))
|
||||||
|
},
|
||||||
|
placeholder = { Text("Enter password") },
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
TextField(
|
||||||
|
value = passwordConfirmValue,
|
||||||
|
onValueChange = { passwordConfirmValue = it },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Confirm Password",
|
||||||
|
color = Color(0xff66727f),
|
||||||
|
lineHeight = 1.33.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 15.sp,
|
||||||
|
letterSpacing = 0.2.sp))
|
||||||
|
},
|
||||||
|
placeholder = { Text("Confirm password") },
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
letterSpacing = 0.1.sp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
}
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
var isExist = false;
|
||||||
|
if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) {
|
||||||
|
users.forEach { user ->
|
||||||
|
if (user.email == emailValue) {
|
||||||
|
isExist = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isExist) {
|
||||||
|
val newUser = User(null, emailValue, passwordValue)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().insert(newUser)
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getAll()
|
||||||
|
.collect { data ->
|
||||||
|
data.forEach { user ->
|
||||||
|
if ((user.password == passwordValue) && (user.email == emailValue)) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
sharedViewModel.setArgument(user.id.toString())
|
||||||
|
navController.navigate(route = Graph.passUserId(user.id.toString()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 656.dp)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.Top)
|
||||||
|
) {
|
||||||
|
Property1Primary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(route = AuthScreen.Entry.route)
|
||||||
|
{
|
||||||
|
popUpTo(AuthScreen.Entry.route)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
|
||||||
|
contentPadding = PaddingValues(horizontal = 10.dp, vertical = 12.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopStart)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 602.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Sign In",
|
||||||
|
color = Color(0xff4bb2f9),
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Property1Primary(modifier: Modifier = Modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 44.dp)
|
||||||
|
.clip(shape = RoundedCornerShape(10.dp))
|
||||||
|
.background(color = Color(0xff85c3ff))
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.Center)
|
||||||
|
.offset(x = 0.dp,
|
||||||
|
y = 0.dp)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Sign On",
|
||||||
|
color = Color.White,
|
||||||
|
lineHeight = 1.25.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
letterSpacing = 0.1.sp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
156
app/src/main/java/com/example/testapp/screensMobile/Wallet.kt
Normal file
156
app/src/main/java/com/example/testapp/screensMobile/Wallet.kt
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
package com.example.testapp.screensMobile
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.example.pmulabs.designElem.NavBar
|
||||||
|
import com.example.testapp.designElem.ListItem
|
||||||
|
import com.example.testapp.designElem.SharedViewModel
|
||||||
|
import com.example.testapp.graphs.HomeNavGraph
|
||||||
|
import com.example.testapp.room.database.CryptoDealDb
|
||||||
|
import com.example.testapp.room.models.Coin
|
||||||
|
import com.example.testapp.room.models.User
|
||||||
|
import com.example.testapp.room.models.WalletItem
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
@Composable
|
||||||
|
fun Wallet(navController: NavHostController = rememberNavController(),
|
||||||
|
@SuppressLint("ModifierParameter") modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel) {
|
||||||
|
val argument = sharedViewModel.argument.value
|
||||||
|
val id = argument?.toInt()
|
||||||
|
val context = LocalContext.current
|
||||||
|
val users = remember { mutableStateListOf<User>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).userDao().getAll().collect { data ->
|
||||||
|
users.clear()
|
||||||
|
users.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var wallet: List<WalletItem> = listOf()
|
||||||
|
val walletItem = remember { mutableStateListOf<WalletItem>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (id != null) {
|
||||||
|
CryptoDealDb.getInstance(context).walletItemDao().getAll().collect{ data ->
|
||||||
|
walletItem.clear()
|
||||||
|
walletItem.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wallet = walletItem.filter { x -> x.userId == id };
|
||||||
|
|
||||||
|
val coins = remember { mutableStateListOf<Coin>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
CryptoDealDb.getInstance(context).coinDao().getAll().collect { data ->
|
||||||
|
coins.clear()
|
||||||
|
coins.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.background(color = Color(0xfff4f7fb))
|
||||||
|
.padding(vertical = 20.dp)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
PropertyWallet()
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
wallet.forEach { coin ->
|
||||||
|
ListItem(
|
||||||
|
coin = coins.first{ x -> x.id == coin.coinId },
|
||||||
|
count = coin.count,
|
||||||
|
modifier = Modifier.padding( vertical = 5.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(34)
|
||||||
|
@Composable
|
||||||
|
fun LoadScreen(navController: NavHostController = rememberNavController(),
|
||||||
|
@SuppressLint("ModifierParameter") modifier: Modifier = Modifier,
|
||||||
|
sharedViewModel: SharedViewModel) {
|
||||||
|
Scaffold(
|
||||||
|
bottomBar = { NavBar(navController = navController) },
|
||||||
|
) {
|
||||||
|
Modifier
|
||||||
|
.padding(it)
|
||||||
|
HomeNavGraph(navController, sharedViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PropertyWallet(modifier: Modifier = Modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height = 56.dp)
|
||||||
|
.background(color = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(end = 56.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Wallet",
|
||||||
|
color = Color(0xff0b1f33),
|
||||||
|
lineHeight = 1.14.em,
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
app/src/main/java/com/example/testapp/ui/theme/Color.kt
Normal file
11
app/src/main/java/com/example/testapp/ui/theme/Color.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.example.testapp.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
val Purple80 = Color(0xFFD0BCFF)
|
||||||
|
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||||
|
val Pink80 = Color(0xFFEFB8C8)
|
||||||
|
|
||||||
|
val Purple40 = Color(0xFF6650a4)
|
||||||
|
val PurpleGrey40 = Color(0xFF625b71)
|
||||||
|
val Pink40 = Color(0xFF7D5260)
|
70
app/src/main/java/com/example/testapp/ui/theme/Theme.kt
Normal file
70
app/src/main/java/com/example/testapp/ui/theme/Theme.kt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package com.example.testapp.ui.theme
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.darkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
|
import androidx.compose.ui.graphics.toArgb
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
|
||||||
|
private val DarkColorScheme = darkColorScheme(
|
||||||
|
primary = Purple80,
|
||||||
|
secondary = PurpleGrey80,
|
||||||
|
tertiary = Pink80
|
||||||
|
)
|
||||||
|
|
||||||
|
private val LightColorScheme = lightColorScheme(
|
||||||
|
primary = Purple40,
|
||||||
|
secondary = PurpleGrey40,
|
||||||
|
tertiary = Pink40
|
||||||
|
|
||||||
|
/* Other default colors to override
|
||||||
|
background = Color(0xFFFFFBFE),
|
||||||
|
surface = Color(0xFFFFFBFE),
|
||||||
|
onPrimary = Color.White,
|
||||||
|
onSecondary = Color.White,
|
||||||
|
onTertiary = Color.White,
|
||||||
|
onBackground = Color(0xFF1C1B1F),
|
||||||
|
onSurface = Color(0xFF1C1B1F),
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TestAppTheme(
|
||||||
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
|
// Dynamic color is available on Android 12+
|
||||||
|
dynamicColor: Boolean = true,
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
val colorScheme = when {
|
||||||
|
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
|
val context = LocalContext.current
|
||||||
|
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
darkTheme -> DarkColorScheme
|
||||||
|
else -> LightColorScheme
|
||||||
|
}
|
||||||
|
val view = LocalView.current
|
||||||
|
if (!view.isInEditMode) {
|
||||||
|
SideEffect {
|
||||||
|
val window = (view.context as Activity).window
|
||||||
|
window.statusBarColor = colorScheme.primary.toArgb()
|
||||||
|
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialTheme(
|
||||||
|
colorScheme = colorScheme,
|
||||||
|
typography = Typography,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
34
app/src/main/java/com/example/testapp/ui/theme/Type.kt
Normal file
34
app/src/main/java/com/example/testapp/ui/theme/Type.kt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package com.example.testapp.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.material3.Typography
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
// Set of Material typography styles to start with
|
||||||
|
val Typography = Typography(
|
||||||
|
bodyLarge = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.5.sp
|
||||||
|
)
|
||||||
|
/* Other default text styles to override
|
||||||
|
titleLarge = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 22.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.sp
|
||||||
|
),
|
||||||
|
labelSmall = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user