Compare commits

..

10 Commits

Author SHA1 Message Date
maxnes3
e247aaddb5 Залил 3 лабу 2023-12-23 11:28:02 +04:00
maxnes3
69175e82f0 Подготовка к 4 лабе(дополнил) 2023-11-25 21:44:25 +04:00
maxnes3
7076d707ea Подготовка к 4 лабе 2023-11-25 21:43:54 +04:00
maxnes3
da844b15f7 CRUD работает 2023-11-25 03:02:32 +04:00
maxnes3
f4fa24f50a БД работает 2023-11-24 21:39:43 +04:00
maxnes3
1d1a0e9be7 ВСЁ на ГИТ 2023-11-24 20:22:29 +04:00
maxnes3
1e3fcaa50f Не работает 2023-11-24 19:45:20 +04:00
maxnes3
31b936fe0e ещё немного осталось 2023-11-16 04:17:27 +04:00
maxnes3
1a3a0d4cd7 Я почти гений 2023-11-16 03:06:38 +04:00
maxnes3
6fc39a2396 Я хорош 2023-11-16 02:01:29 +04:00
24 changed files with 631 additions and 288 deletions

View File

@ -0,0 +1,41 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

View File

@ -3,28 +3,13 @@ package com.example.mobileapp
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.mobileapp.entities.Mail import com.example.mobileapp.components.NavBar
import com.example.mobileapp.entities.MailSingleton import com.example.mobileapp.database.entities.User
import com.example.mobileapp.entities.Story
import com.example.mobileapp.entities.StorySingleton
import com.example.mobileapp.screens.Authorization
import com.example.mobileapp.screens.EditMailScreen
import com.example.mobileapp.screens.EditStoryScreen
import com.example.mobileapp.screens.ListDataScreen
import com.example.mobileapp.screens.ListMailScreen
import com.example.mobileapp.screens.MainScreen
import com.example.mobileapp.screens.Registration
import com.example.mobileapp.screens.SettingsScreen
import com.example.mobileapp.ui.theme.MobileAppTheme import com.example.mobileapp.ui.theme.MobileAppTheme
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ -38,57 +23,31 @@ class MainActivity : ComponentActivity() {
color = MaterialTheme.colorScheme.background color = MaterialTheme.colorScheme.background
) { ) {
val navController = rememberNavController() val navController = rememberNavController()
val mailSingleton = MailSingleton() NavBar(navController = navController)
mailSingleton.addMail(Mail(0, 0, "Дзюнзи Ито", "Выложил новый"))
mailSingleton.addMail(Mail(1, 1, "Стивен Кинг", "Меня отменили в Твиттере"))
mailSingleton.addMail(Mail(0, 0, "Дзюнзи Ито", "Выложил новый"))
mailSingleton.addMail(Mail(1, 1, "Стивен Кинг", "Меня отменили в Твиттере"))
mailSingleton.addMail(Mail(0, 0, "Дзюнзи Ито", "Выложил новый"))
mailSingleton.addMail(Mail(1, 1, "Стивен Кинг", "Меня отменили в Твиттере"))
mailSingleton.addMail(Mail(0, 0, "Дзюнзи Ито", "Выложил новый"))
mailSingleton.addMail(Mail(1, 1, "Стивен Кинг", "Меня отменили в Твиттере"))
val storySingleton = StorySingleton()
storySingleton.addStory(Story(0, "Чужак", "Знаменитая книга стивена кинга", R.drawable.king))
storySingleton.addStory(Story(1, "Переулок", "История ужасов от Дзюнзи Ито", R.drawable.dzun))
storySingleton.addStory(Story(2, "Чужак", "Знаменитая книга стивена кинга", R.drawable.king))
storySingleton.addStory(Story(3, "Переулок", "История ужасов от Дзюнзи Ито", R.drawable.dzun))
AppNavigation(navController = navController)
} }
} }
} }
} }
} }
@Composable class GlobalUser private constructor() {
fun AppNavigation(navController: NavHostController){ private var user: User? = null
NavHost(
navController = navController, startDestination = "authorization" fun setUser(user: User?) {
) { this.user = user
composable("authorization"){
Authorization(navController = navController)
} }
composable("registration"){
Registration(navController = navController) fun getUser(): User? {
return user
} }
composable("main"){
MainScreen(navController = navController) companion object {
private var instance: GlobalUser? = null
fun getInstance(): GlobalUser {
return instance ?: synchronized(this) {
instance ?: GlobalUser().also { instance = it }
} }
composable("listdata"){
ListDataScreen(navController = navController)
}
composable("mail"){
ListMailScreen(navController = navController)
}
composable("settings"){
SettingsScreen(navController = navController)
}
composable("editstory"){
EditStoryScreen(navController = navController)
}
composable("editmail"){
EditMailScreen(navController = navController)
} }
} }
} }

View File

@ -27,18 +27,23 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.example.mobileapp.ui.theme.MobileAppTheme import com.example.mobileapp.ui.theme.MobileAppTheme
val buttonHeightStandard = 72.dp
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun PlaceholderInputField(label: String){ fun PlaceholderInputField(label: String, startValue: String? = null, isSingleLine: Boolean, onTextChanged: (String) -> Unit){
var text = remember { mutableStateOf("") } var text = remember { mutableStateOf("") }
startValue?.let{
text.value = startValue
}
OutlinedTextField( OutlinedTextField(
value = text.value, value = text.value,
onValueChange = { onValueChange = {
text.value = it text.value = it
onTextChanged(it)
}, },
placeholder = { placeholder = {
Text(label) Text(label)
@ -46,18 +51,24 @@ fun PlaceholderInputField(label: String){
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp), .padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp),
shape = RoundedCornerShape(10.dp)) shape = RoundedCornerShape(10.dp),
singleLine = isSingleLine
)
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun PasswordInputField(label: String){ fun PasswordInputField(label: String, startValue: String? = null, onPasswordChanged: (String) -> Unit){
var text = remember { mutableStateOf("") } var text = remember { mutableStateOf("") }
startValue?.let{
text.value = startValue
}
OutlinedTextField( OutlinedTextField(
value = text.value, value = text.value,
onValueChange = { onValueChange = {
text.value = it text.value = it
onPasswordChanged(it)
}, },
placeholder = { placeholder = {
Text(label) Text(label)
@ -92,7 +103,8 @@ fun SearchInputField(){
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 16.dp, start = 16.dp, bottom = 8.dp, end = 16.dp), .padding(top = 16.dp, start = 16.dp, bottom = 8.dp, end = 16.dp),
shape = RoundedCornerShape(10.dp) shape = RoundedCornerShape(10.dp),
singleLine = true
) )
} }
@ -102,7 +114,7 @@ fun IconButton(iconLeft: ImageVector, label: String, backgroundColor: Color, tex
onClick = onClickAction, onClick = onClickAction,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.requiredHeight(64.dp) .requiredHeight(buttonHeightStandard)
.padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp), .padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = backgroundColor containerColor = backgroundColor
@ -134,7 +146,7 @@ fun ActiveButton(label: String, backgroundColor: Color, textColor: Color, onClic
onClick = onClickAction, onClick = onClickAction,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.requiredHeight(64.dp) .requiredHeight(buttonHeightStandard)
.padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp), .padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = backgroundColor containerColor = backgroundColor
@ -155,7 +167,7 @@ fun ActiveButton(label: String, backgroundColor: Color, textColor: Color, onClic
fun PlaceholderTextFieldPreview() { fun PlaceholderTextFieldPreview() {
MobileAppTheme { MobileAppTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
PlaceholderInputField("Email") PlaceholderInputField("Email", null,true, { })
} }
} }
} }

View File

@ -16,57 +16,83 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.mobileapp.R import com.example.mobileapp.R
import com.example.mobileapp.entities.Mail import com.example.mobileapp.database.MobileAppDataBase
import com.example.mobileapp.entities.MailSingleton import com.example.mobileapp.database.entities.Mail
import com.example.mobileapp.entities.Story import com.example.mobileapp.database.entities.Story
import com.example.mobileapp.entities.StorySingleton
import com.example.mobileapp.ui.theme.BackgroundItem2 import com.example.mobileapp.ui.theme.BackgroundItem2
import com.example.mobileapp.ui.theme.ButtonColor1 import com.example.mobileapp.ui.theme.ButtonColor1
import com.example.mobileapp.ui.theme.ButtonColor2 import com.example.mobileapp.ui.theme.ButtonColor2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.Date
val dateFormat = SimpleDateFormat("dd.MM.yyyy")
@Composable @Composable
fun DataListScroll(navController: NavHostController){ fun <T : Any> DataListScroll(navController: NavHostController, dataList: List<T>){
val storySingleton = StorySingleton()
LazyColumn( LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
){ ){
item { item {
addNewListItem(navController, "editstory") when {
dataList.isListOf<Story>() -> addNewListItem(navController, "editstory")
dataList.isListOf<Mail>() -> addNewListItem(navController, "editmail")
}
}
items(dataList){ item ->
when(item){
is Story -> StoryListItem(item = item, navController = navController)
is Mail -> MailListItem(item = item)
} }
items(storySingleton.getStoryList()){ item ->
DataListItem(item = item, navController = navController)
} }
} }
} }
inline fun <reified T> List<*>.isListOf(): Boolean {
return isNotEmpty() && all { it is T }
}
@Composable @Composable
fun DataListItem(item: Story, navController: NavHostController){ fun StoryListItem(item: Story, navController: NavHostController){
val context = LocalContext.current
val isExpanded = remember { val isExpanded = remember {
mutableStateOf(false) mutableStateOf(false)
} }
val showDialog = remember {
mutableStateOf(false)
}
val delete = remember {
mutableStateOf(false)
}
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -88,7 +114,7 @@ fun DataListItem(item: Story, navController: NavHostController){
Row( Row(
verticalAlignment = Alignment.Top verticalAlignment = Alignment.Top
){ ){
Image(painter = painterResource(id = item.cover), Image(bitmap = item.cover.asImageBitmap(),
contentDescription = item.description, contentDescription = item.description,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
@ -98,7 +124,7 @@ fun DataListItem(item: Story, navController: NavHostController){
modifier = Modifier.padding(8.dp) modifier = Modifier.padding(8.dp)
){ ){
Text( Text(
text = item.title, text = "${item.title} | ${dateFormat.format(Date(item.postdate!!))}",
fontSize = 20.sp, fontSize = 20.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
@ -113,12 +139,36 @@ fun DataListItem(item: Story, navController: NavHostController){
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End horizontalArrangement = Arrangement.End
){ ){
DataListItemButton("Изменить", ButtonColor2, Color.White, onClickAction = { navController.navigate("editstory") }) DataListItemButton("Изменить", ButtonColor2, Color.White, onClickAction = {
DataListItemButton("Удалить", Color.Red, Color.White, onClickAction = { }) navController.navigate("editstory/${item.id}")
})
DataListItemButton("Удалить", Color.Red, Color.White, onClickAction = {
showDialog.value = !showDialog.value
})
} }
} }
} }
} }
if(showDialog.value) {
DialogWindow(label = "Подтверждение",
message = "Вы уверены что хотите удалить запись?", onConfirmAction = {
delete.value = !delete.value
showDialog.value = !showDialog.value
}, onDismissAction = {
showDialog.value = !showDialog.value
})
}
if(delete.value) {
LaunchedEffect(Unit){
withContext(Dispatchers.IO){
MobileAppDataBase.getInstance(context).storyDao().delete(item)
}
}
delete.value = !delete.value
navController.navigate("story")
}
} }
@Composable @Composable
@ -139,24 +189,6 @@ fun DataListItemButton(label: String, backgroundColor: Color, textColor: Color,
} }
} }
@Composable
fun MailListScroll(navController: NavHostController){
val mailSingleton = MailSingleton()
LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
){
item {
addNewListItem(navController, "editmail")
}
items(mailSingleton.getMailList()){ item ->
MailListItem(item = item)
}
}
}
@Composable @Composable
fun MailListItem(item: Mail){ fun MailListItem(item: Mail){
val isExpanded = remember { val isExpanded = remember {
@ -194,7 +226,7 @@ fun MailListItem(item: Mail){
modifier = Modifier.padding(8.dp) modifier = Modifier.padding(8.dp)
){ ){
Text( Text(
text = item.username, text = "item.username | ${dateFormat.format(Date(item.postdate!!))}",
fontSize = 20.sp, fontSize = 20.sp,
fontWeight = FontWeight.Bold) fontWeight = FontWeight.Bold)
Text(text = item.message) Text(text = item.message)
@ -264,3 +296,41 @@ fun addNewListItem(navController: NavHostController, destination: String){
} }
} }
} }
@Composable
fun DialogWindow(label: String, message: String, onConfirmAction: () -> Unit, onDismissAction: () -> Unit){
AlertDialog(onDismissRequest = onDismissAction,
title = {
Text(text = label,
fontSize = 20.sp,
fontWeight = FontWeight.Bold)
},
text = {
Text(text = message)
},
confirmButton = {
Button(
onClick = onConfirmAction,
colors = ButtonDefaults.buttonColors(
containerColor = ButtonColor2
),
shape = RoundedCornerShape(5.dp)
) {
Text(text = "Подтвердить",
color = Color.White)
}
},
dismissButton = {
Button(
onClick = onDismissAction,
colors = ButtonDefaults.buttonColors(
containerColor = ButtonColor1
),
shape = RoundedCornerShape(5.dp)
) {
Text(text = "Отмена",
color = Color.Black)
}
}
)
}

View File

@ -1,9 +1,11 @@
package com.example.mobileapp.components package com.example.mobileapp.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
@ -12,14 +14,15 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -30,38 +33,117 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.example.mobileapp.R import com.example.mobileapp.R
import com.example.mobileapp.screens.Authorization
import com.example.mobileapp.screens.EditMailScreen
import com.example.mobileapp.screens.EditStoryScreen
import com.example.mobileapp.screens.EditUserScreen
import com.example.mobileapp.screens.ListDataScreen
import com.example.mobileapp.screens.ListMailScreen
import com.example.mobileapp.screens.MainScreen
import com.example.mobileapp.screens.Registration
import com.example.mobileapp.screens.SettingsScreen
@Composable val navBarItems = listOf(
fun NavBar(navController: NavHostController, itemColorFilter: Color) { NavBarItem(route = "main", label = "Главная", icon = R.drawable.home),
Row( NavBarItem(route = "story", label = "Создание", icon = R.drawable.edit),
modifier = Modifier NavBarItem(route = "mail", label = "Уведомления", icon = R.drawable.mail),
.fillMaxWidth(), NavBarItem(route = "settings", label = "Настройки", icon = R.drawable.settings),
horizontalArrangement = Arrangement.SpaceEvenly, )
verticalAlignment = Alignment.CenterVertically
) {
NavItem(navController = navController, imageId = R.drawable.home,
description = "homeButton", destination = "main", itemColorFilter = itemColorFilter)
NavItem(navController = navController, imageId = R.drawable.edit,
description = "editButton", destination = "listdata", itemColorFilter = itemColorFilter)
NavItem(navController = navController, imageId = R.drawable.mail,
description = "mailButton", destination = "mail", itemColorFilter = itemColorFilter)
NavItem(navController = navController, imageId = R.drawable.settings,
description = "settingsButton", destination = "settings", itemColorFilter = itemColorFilter)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun NavItem(navController: NavHostController, imageId: Int, fun NavBar(navController: NavHostController) {
description: String, destination: String, itemColorFilter: Color){ val bottomBarState = rememberSaveable { (mutableStateOf(false)) }
Image(painter = painterResource(id = imageId),
contentDescription = description, Scaffold(
contentScale = ContentScale.Crop, bottomBar = {
AnimatedVisibility(
visible = bottomBarState.value,
enter = slideInVertically(initialOffsetY = { it }),
exit = slideOutVertically(targetOffsetY = { it }),
content = {
NavigationBar {
navBarItems.forEach{item ->
NavigationBarItem(
icon = {
Image(
painter = painterResource(item.icon),
contentDescription = null,
modifier = Modifier modifier = Modifier
.size(64.dp) .size(40.dp)
.clickable { .padding(bottom = 6.dp)
navController.navigate(destination) )
}, },
colorFilter = ColorFilter.tint(itemColorFilter)) label = {
Text(
text = item.label
)
},
onClick = {
navController.navigate(item.route)
},
selected = false,
modifier = Modifier.fillMaxSize()
)
}
}
}
)
},
modifier = Modifier.background(Color.White)
) {innerPaddings ->
NavHost(
navController = navController,
startDestination = "authorization",
modifier = Modifier.padding(innerPaddings)
) {
composable("authorization"){
bottomBarState.value = false
Authorization(navController = navController)
}
composable("registration"){
bottomBarState.value = false
Registration(navController = navController)
}
composable("main"){
bottomBarState.value = true
MainScreen(navController = navController)
}
composable("story"){
bottomBarState.value = true
ListDataScreen(navController = navController)
}
composable("mail"){
bottomBarState.value = true
ListMailScreen(navController = navController)
}
composable("settings"){
bottomBarState.value = true
SettingsScreen(navController = navController)
}
composable("editstory"){ // Без аргумента
bottomBarState.value = false
EditStoryScreen(navController = navController)
}
composable(
"editstory/{id}",
arguments = listOf(navArgument("id") { type = NavType.IntType }) //С аргументом
) { backStackEntry ->
backStackEntry.arguments?.let {
bottomBarState.value = false
EditStoryScreen(navController = navController, storyId = it.getInt("id"))
}
}
composable("editmail"){ // Без аргумента
bottomBarState.value = false
EditMailScreen(navController = navController)
}
composable("edituser"){
bottomBarState.value = false
EditUserScreen(navController = navController)
}
}
}
} }
@Composable @Composable
@ -74,7 +156,7 @@ fun NavigationButton(navController: NavHostController,
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.requiredHeight(64.dp) .requiredHeight(72.dp)
.padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp), .padding(top = 8.dp, start = 16.dp, bottom = 8.dp, end = 16.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = backgroundColor containerColor = backgroundColor

View File

@ -1,11 +1,13 @@
package com.example.mobileapp.database package com.example.mobileapp.database
import android.content.Context import android.content.Context
import android.graphics.BitmapFactory
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.mobileapp.R
import com.example.mobileapp.database.dao.MailDao import com.example.mobileapp.database.dao.MailDao
import com.example.mobileapp.database.dao.StoryDao import com.example.mobileapp.database.dao.StoryDao
import com.example.mobileapp.database.dao.UserDao import com.example.mobileapp.database.dao.UserDao
@ -25,11 +27,29 @@ abstract class MobileAppDataBase : RoomDatabase() {
abstract fun mailDao(): MailDao abstract fun mailDao(): MailDao
companion object{ companion object{
private const val DB_NAME: String = "mobileApp.db" private const val DB_NAME: String = "my-db"
@Volatile @Volatile
private var INSTANCE: MobileAppDataBase? = null private var INSTANCE: MobileAppDataBase? = null
suspend fun initialDataBase(appContext: Context){
INSTANCE?.let { database ->
val userDao = database.userDao()
userDao.insert(User(id = 1, login = "Дзюнзи Ито", password = "1234", email = "ito@gmail.com"))
userDao.insert(User(id = 2, login = "Стивен Кинг", password = "4321", email = "king@gmail.com"))
val storyDao = database.storyDao()
storyDao.insert(Story(title = "Переулок", description = "История ужасов от Дзюнзи Ито",
cover = BitmapFactory.decodeResource(appContext.resources, R.drawable.dzun), userId = 1))
storyDao.insert(Story(title = "Чужак", description = "Знаменитая книга стивена кинга",
cover = BitmapFactory.decodeResource(appContext.resources, R.drawable.king), userId = 2))
val mailDao = database.mailDao()
mailDao.insert(Mail(message = "Выложил новые страницы", userId = 1))
mailDao.insert(Mail(message = "Меня отменили в Твиттере", userId = 2))
}
}
fun getInstance(appContext: Context): MobileAppDataBase { fun getInstance(appContext: Context): MobileAppDataBase {
return INSTANCE ?: synchronized(this) { return INSTANCE ?: synchronized(this) {
Room.databaseBuilder( Room.databaseBuilder(
@ -41,10 +61,11 @@ abstract class MobileAppDataBase : RoomDatabase() {
override fun onCreate(db: SupportSQLiteDatabase) { override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db) super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
//populateDatabase() initialDataBase(appContext)
} }
} }
}) })
.fallbackToDestructiveMigration()
.build() .build()
.also { INSTANCE = it } .also { INSTANCE = it }
} }

View File

@ -17,6 +17,9 @@ interface StoryDao {
@Query("select * from stories where stories.id = :id") @Query("select * from stories where stories.id = :id")
fun getById(id: Int): Story? fun getById(id: Int): Story?
@Query("select * from stories where stories.user_id = :userId")
fun getByUserId(userId: Int): Flow<List<Story>>
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(story: Story) suspend fun insert(story: Story)

View File

@ -4,6 +4,8 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import androidx.room.TypeConverter import androidx.room.TypeConverter
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.Date
class Converters { class Converters {
@TypeConverter @TypeConverter

View File

@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.util.Date
@Entity( @Entity(
tableName = "mails", tableName = "mails",
@ -19,9 +20,11 @@ import androidx.room.PrimaryKey
) )
data class Mail( data class Mail(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
var id: Int?, val id: Int? = null,
@ColumnInfo(name = "message") @ColumnInfo(name = "message")
val message: String, val message: String,
@ColumnInfo(name = "postdate")
val postdate: Long? = Date().time,
@ColumnInfo(name="user_id") @ColumnInfo(name="user_id")
val userId: Int val userId: Int
){ ){

View File

@ -5,6 +5,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.util.Calendar
import java.util.Date
@Entity( @Entity(
tableName = "stories", tableName = "stories",
@ -20,13 +22,15 @@ import androidx.room.PrimaryKey
) )
data class Story( data class Story(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
val id: Int?, val id: Int? = null,
@ColumnInfo(name = "title") @ColumnInfo(name = "title")
val title: String, val title: String,
@ColumnInfo(name = "description") @ColumnInfo(name = "description")
val description: String, val description: String,
@ColumnInfo(name = "cover") @ColumnInfo(name = "cover")
val cover: Bitmap, val cover: Bitmap,
@ColumnInfo(name = "postdate")
val postdate: Long? = Date().time,
@ColumnInfo(name="user_id") @ColumnInfo(name="user_id")
val userId: Int val userId: Int
){ ){

View File

@ -1,5 +1,6 @@
package com.example.mobileapp.database.entities package com.example.mobileapp.database.entities
import android.graphics.Bitmap
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@ -7,13 +8,15 @@ import androidx.room.PrimaryKey
@Entity(tableName = "users") @Entity(tableName = "users")
data class User( data class User(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
var id: Int?, val id: Int? = null,
@ColumnInfo(name = "login") @ColumnInfo(name = "login")
val login: String, val login: String,
@ColumnInfo(name = "password") @ColumnInfo(name = "password")
val password: String, val password: String,
@ColumnInfo(name = "email") @ColumnInfo(name = "email")
val email: String, val email: String,
@ColumnInfo(name = "photo")
val photo: Bitmap? = null
){ ){
override fun hashCode(): Int { override fun hashCode(): Int {
return id ?: -1 return id ?: -1

View File

@ -1,8 +0,0 @@
package com.example.mobileapp.entities
data class Mail(
val id: Int,
val userId: Int,
val username: String,
val message: String
)

View File

@ -1,15 +0,0 @@
package com.example.mobileapp.entities
class MailSingleton {
companion object {
val mailList: MutableList<Mail> = mutableListOf()
}
fun addMail(mail: Mail) {
mailList.add(mail)
}
fun getMailList(): List<Mail> {
return mailList.toList()
}
}

View File

@ -1,8 +0,0 @@
package com.example.mobileapp.entities
data class Story(
val id: Int,
val title: String,
val description: String,
val cover: Int
)

View File

@ -1,15 +0,0 @@
package com.example.mobileapp.entities
class StorySingleton {
companion object {
val storyList: MutableList<Story> = mutableListOf()
}
fun addStory(story: Story) {
storyList.add(story)
}
fun getStoryList(): List<Story> {
return storyList.toList()
}
}

View File

@ -1,7 +0,0 @@
package com.example.mobileapp.entities
data class User(
val email: String,
val login: String,
val password: String
)

View File

@ -7,10 +7,14 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@ -18,11 +22,26 @@ import com.example.mobileapp.R
import com.example.mobileapp.components.NavigationButton import com.example.mobileapp.components.NavigationButton
import com.example.mobileapp.components.PasswordInputField import com.example.mobileapp.components.PasswordInputField
import com.example.mobileapp.components.PlaceholderInputField import com.example.mobileapp.components.PlaceholderInputField
import com.example.mobileapp.database.MobileAppDataBase
import com.example.mobileapp.database.entities.User
import com.example.mobileapp.ui.theme.ButtonColor1 import com.example.mobileapp.ui.theme.ButtonColor1
import com.example.mobileapp.ui.theme.ButtonColor2 import com.example.mobileapp.ui.theme.ButtonColor2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun Authorization(navController: NavHostController){ fun Authorization(navController: NavHostController){
val context = LocalContext.current
val users = remember { mutableStateListOf<User>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
MobileAppDataBase.getInstance(context).userDao().getAll().collect { data ->
users.clear()
users.addAll(data)
}
}
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -37,8 +56,8 @@ fun Authorization(navController: NavHostController){
.size(512.dp) .size(512.dp)
.padding(8.dp) .padding(8.dp)
.align(Alignment.CenterHorizontally)) .align(Alignment.CenterHorizontally))
PlaceholderInputField(label = "Логин") PlaceholderInputField(label = "Логин", isSingleLine = true, onTextChanged = {})
PasswordInputField(label = "Пароль") PasswordInputField(label = "Пароль", onPasswordChanged = {})
NavigationButton(navController = navController, destination = "main", label = "Вход", NavigationButton(navController = navController, destination = "main", label = "Вход",
backgroundColor = ButtonColor2, textColor = Color.White) backgroundColor = ButtonColor2, textColor = Color.White)
NavigationButton(navController = navController, destination = "registration", label = "Регистрация", NavigationButton(navController = navController, destination = "registration", label = "Регистрация",

View File

@ -1,5 +1,13 @@
package com.example.mobileapp.screens package com.example.mobileapp.screens
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -7,10 +15,16 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@ -19,11 +33,81 @@ import com.example.mobileapp.components.ActiveButton
import com.example.mobileapp.components.NavigationButton import com.example.mobileapp.components.NavigationButton
import com.example.mobileapp.components.PasswordInputField import com.example.mobileapp.components.PasswordInputField
import com.example.mobileapp.components.PlaceholderInputField import com.example.mobileapp.components.PlaceholderInputField
import com.example.mobileapp.database.MobileAppDataBase
import com.example.mobileapp.database.entities.Mail
import com.example.mobileapp.database.entities.Story
import com.example.mobileapp.ui.theme.ButtonColor1 import com.example.mobileapp.ui.theme.ButtonColor1
import com.example.mobileapp.ui.theme.ButtonColor2 import com.example.mobileapp.ui.theme.ButtonColor2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun EditStoryScreen(navController: NavHostController) { fun EditStoryScreen(navController: NavHostController, storyId: Int? = null) {
val context = LocalContext.current
val cover = remember { mutableStateOf<Bitmap>(BitmapFactory.decodeResource(context.resources, R.drawable.editplaceholder)) }
val title = remember { mutableStateOf("") }
val description = remember { mutableStateOf("") }
val imageData = remember { mutableStateOf<Uri?>(null) }
val launcher =
rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {uri: Uri? ->
imageData.value = uri
}
imageData.value?.let {
if (Build.VERSION.SDK_INT < 28) {
cover.value = MediaStore.Images
.Media.getBitmap(context.contentResolver, imageData.value)
} else {
val source = ImageDecoder
.createSource(context.contentResolver, imageData.value!!)
cover.value = ImageDecoder.decodeBitmap(source)
}
}
storyId?.let{
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
val story = MobileAppDataBase.getInstance(context).storyDao().getById(storyId!!)
cover.value = story!!.cover
title.value = story!!.title
description.value = story!!.description
}
}
}
val edit = remember { mutableStateOf(false) }
if (edit.value){
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
storyId?.let {
MobileAppDataBase.getInstance(context).storyDao()
.update(
Story(
id = storyId,
title = title.value,
description = description.value,
cover = cover.value,
userId = 1)
)
} ?: run {
MobileAppDataBase.getInstance(context).storyDao()
.insert(
Story(
title = title.value,
description = description.value,
cover = cover.value,
userId = 1)
)
}
}
}
edit.value = !edit.value
navController.navigate("story")
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -31,23 +115,49 @@ fun EditStoryScreen(navController: NavHostController) {
verticalArrangement = Arrangement.Bottom verticalArrangement = Arrangement.Bottom
) { ) {
Image( Image(
painter = painterResource(id = R.drawable.editplaceholder), bitmap = cover.value.asImageBitmap(),
contentDescription = "editplaceholder", contentDescription = "editplaceholder",
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
.size(512.dp) .size(384.dp)
.padding(8.dp) .padding(8.dp)
.align(Alignment.CenterHorizontally)) .align(Alignment.CenterHorizontally))
PlaceholderInputField(label = "Название") ActiveButton(label = "Выбрать обложку", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
ActiveButton(label = "Выбрать обложку", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {}) launcher.launch("image/*")
PlaceholderInputField(label = "Описание") })
NavigationButton(navController = navController, destination = "listdata", label = "Назад", PlaceholderInputField(label = "Название", isSingleLine = true,
startValue = title.value, onTextChanged = { newName ->
title.value = newName
})
PlaceholderInputField(label = "Описание", isSingleLine = true,
startValue = description.value, onTextChanged = { newDescription ->
description.value = newDescription
})
ActiveButton(label = "Сохранить", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
edit.value = !edit.value
})
NavigationButton(navController = navController, destination = "story", label = "Назад",
backgroundColor = ButtonColor2, textColor = Color.White) backgroundColor = ButtonColor2, textColor = Color.White)
} }
} }
@Composable @Composable
fun EditMailScreen(navController: NavHostController) { fun EditMailScreen(navController: NavHostController) {
val context = LocalContext.current
val message = remember { mutableStateOf("") }
val create = remember { mutableStateOf(false) }
if(create.value){
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
MobileAppDataBase.getInstance(context).mailDao()
.insert(Mail(message = message.value, userId = 2))
}
}
create.value = !create.value
navController.navigate("mail")
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -62,9 +172,76 @@ fun EditMailScreen(navController: NavHostController) {
.size(512.dp) .size(512.dp)
.padding(8.dp) .padding(8.dp)
.align(Alignment.CenterHorizontally)) .align(Alignment.CenterHorizontally))
PlaceholderInputField(label = "Заголовок") PlaceholderInputField(label = "Текс поста", isSingleLine = false, onTextChanged = { newmessage ->
PlaceholderInputField(label = "Текс поста") message.value = newmessage
})
ActiveButton(label = "Сохранить", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
create.value = !create.value
})
NavigationButton(navController = navController, destination = "mail", label = "Назад", NavigationButton(navController = navController, destination = "mail", label = "Назад",
backgroundColor = ButtonColor2, textColor = Color.White) backgroundColor = ButtonColor2, textColor = Color.White)
} }
} }
@Composable
fun EditUserScreen(navController: NavHostController){
val context = LocalContext.current
val photo = remember { mutableStateOf<Bitmap>(BitmapFactory.decodeResource(context.resources, R.drawable.photoplaceholder)) }
val name = remember { mutableStateOf("") }
val password = remember { mutableStateOf("") }
val email = remember { mutableStateOf("") }
val imageData = remember { mutableStateOf<Uri?>(null) }
val launcher =
rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {uri: Uri? ->
imageData.value = uri
}
imageData.value?.let {
if (Build.VERSION.SDK_INT < 28) {
photo.value = MediaStore.Images
.Media.getBitmap(context.contentResolver, imageData.value)
} else {
val source = ImageDecoder
.createSource(context.contentResolver, imageData.value!!)
photo.value = ImageDecoder.decodeBitmap(source)
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 8.dp),
verticalArrangement = Arrangement.Bottom
) {
Image(
bitmap = photo.value.asImageBitmap(),
contentDescription = "editplaceholder",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(384.dp)
.padding(8.dp)
.align(Alignment.CenterHorizontally))
ActiveButton(label = "Выбрать фото", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
launcher.launch("image/*")
})
PlaceholderInputField(label = "Никнейм", isSingleLine = true,
startValue = name.value, onTextChanged = { newName ->
name.value = newName
})
PlaceholderInputField(label = "Пароль", isSingleLine = true,
startValue = password.value, onTextChanged = { newPassword ->
password.value = newPassword
})
PlaceholderInputField(label = "Почта", isSingleLine = true,
startValue = email.value, onTextChanged = { newEmail ->
email.value = newEmail
})
ActiveButton(label = "Сохранить", backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
//edit.value = !edit.value
})
NavigationButton(navController = navController, destination = "story", label = "Назад",
backgroundColor = ButtonColor2, textColor = Color.White)
}
}

View File

@ -8,33 +8,41 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.mobileapp.components.DataListScroll import com.example.mobileapp.components.DataListScroll
import com.example.mobileapp.components.NavBar import com.example.mobileapp.components.NavBar
import com.example.mobileapp.database.MobileAppDataBase
import com.example.mobileapp.database.entities.Story
import com.example.mobileapp.ui.theme.BackgroundItem1 import com.example.mobileapp.ui.theme.BackgroundItem1
import com.example.mobileapp.ui.theme.BackgroundItem2 import com.example.mobileapp.ui.theme.BackgroundItem2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun ListDataScreen(navController: NavHostController){ fun ListDataScreen(navController: NavHostController){
val context = LocalContext.current
val stories = remember { mutableStateListOf<Story>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
MobileAppDataBase.getInstance(context).storyDao().getAll().collect { data ->
stories.clear()
stories.addAll(data)
}
}
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(BackgroundItem1) .background(BackgroundItem1)
) { ) {
Box( DataListScroll(navController, stories)
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(0.9f)
){
DataListScroll(navController)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
NavBar(navController = navController, itemColorFilter = BackgroundItem2)
}
} }
} }

View File

@ -1,40 +1,42 @@
package com.example.mobileapp.screens package com.example.mobileapp.screens
import androidx.compose.foundation.background 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.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.mobileapp.components.MailListScroll import com.example.mobileapp.components.DataListScroll
import com.example.mobileapp.components.NavBar import com.example.mobileapp.database.MobileAppDataBase
import com.example.mobileapp.database.entities.Mail
import com.example.mobileapp.ui.theme.BackgroundItem1 import com.example.mobileapp.ui.theme.BackgroundItem1
import com.example.mobileapp.ui.theme.BackgroundItem2 import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun ListMailScreen(navController: NavHostController){ fun ListMailScreen(navController: NavHostController){
val context = LocalContext.current
val mails = remember { mutableStateListOf<Mail>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
MobileAppDataBase.getInstance(context).mailDao().getAll().collect { data ->
mails.clear()
mails.addAll(data)
}
}
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(BackgroundItem1) .background(BackgroundItem1)
) { ) {
Box( DataListScroll(navController, mails)
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(0.9f)
){
MailListScroll(navController)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
NavBar(navController = navController, itemColorFilter = BackgroundItem2)
}
} }
} }

View File

@ -51,12 +51,5 @@ fun MainScreen(navController: NavHostController) {
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
} }
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
NavBar(navController = navController, itemColorFilter = Color.Black)
}
} }
} }

View File

@ -37,10 +37,10 @@ fun Registration(navController: NavHostController){
.size(384.dp) .size(384.dp)
.padding(8.dp) .padding(8.dp)
.align(Alignment.CenterHorizontally)) .align(Alignment.CenterHorizontally))
PlaceholderInputField(label = "Логин") PlaceholderInputField(label = "Логин", isSingleLine = true, onTextChanged = {})
PlaceholderInputField(label = "Email") PlaceholderInputField(label = "Email", isSingleLine = true, onTextChanged = {})
PasswordInputField(label = "Пароль") PasswordInputField(label = "Пароль", onPasswordChanged = {})
PasswordInputField(label = "Пароль ещё раз") PasswordInputField(label = "Пароль ещё раз", onPasswordChanged = {})
NavigationButton(navController = navController, destination = "main", NavigationButton(navController = navController, destination = "main",
label = "Зарегистрироваться", backgroundColor = ButtonColor2, textColor = Color.White) label = "Зарегистрироваться", backgroundColor = ButtonColor2, textColor = Color.White)
NavigationButton(navController = navController, destination = "authorization", NavigationButton(navController = navController, destination = "authorization",

View File

@ -37,15 +37,10 @@ import com.example.mobileapp.ui.theme.ButtonColor2
fun SettingsScreen(navController: NavHostController){ fun SettingsScreen(navController: NavHostController){
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize(),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(0.9f),
verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
){ ) {
Image( Image(
painter = painterResource(id = R.drawable.settingsplaceholder), painter = painterResource(id = R.drawable.settingsplaceholder),
contentDescription = "settings", contentDescription = "settings",
@ -54,22 +49,24 @@ fun SettingsScreen(navController: NavHostController){
.size(384.dp) .size(384.dp)
.padding(8.dp)) .padding(8.dp))
IconButton(iconLeft = Icons.Default.AccountCircle, label = "Учётная запись", IconButton(iconLeft = Icons.Default.AccountCircle, label = "Учётная запись",
backgroundColor = ButtonColor2, textColor = Color.White, onClickAction = { }) backgroundColor = ButtonColor2, textColor = Color.White, onClickAction = {
navController.navigate("edituser")
})
IconButton(iconLeft = Icons.Default.Face, label = "Внешний вид", IconButton(iconLeft = Icons.Default.Face, label = "Внешний вид",
backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = { }) backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
})
IconButton(iconLeft = Icons.Default.Share, label = "Контакты", IconButton(iconLeft = Icons.Default.Share, label = "Контакты",
backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = { }) backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
})
IconButton(iconLeft = Icons.Default.Info, label = "О приложении", IconButton(iconLeft = Icons.Default.Info, label = "О приложении",
backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = { }) backgroundColor = ButtonColor1, textColor = Color.Black, onClickAction = {
})
IconButton(iconLeft = Icons.Default.ExitToApp, label = "Выйти", IconButton(iconLeft = Icons.Default.ExitToApp, label = "Выйти",
backgroundColor = Color.Red, textColor = Color.White, onClickAction = { }) backgroundColor = Color.Red, textColor = Color.White, onClickAction = {
} navController.navigate("authorization")
Column( })
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
NavBar(navController = navController, itemColorFilter = Color.Black)
}
} }
} }

Binary file not shown.