This commit is contained in:
AnnZhimol 2023-10-27 23:54:55 +04:00
parent 742f6e5bbc
commit 783537d2ae
55 changed files with 2541 additions and 818 deletions

2
.idea/compiler.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" /> <bytecodeTargetLevel target="11" />
</component> </component>
</project> </project>

View File

@ -7,11 +7,11 @@
<deviceKey> <deviceKey>
<Key> <Key>
<type value="VIRTUAL_DEVICE_PATH" /> <type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\ankav\.android\avd\Pixel_6_API_31.avd" /> <value value="C:\Users\ankav\.android\avd\Pixel_6_API_31_2.avd" />
</Key> </Key>
</deviceKey> </deviceKey>
</Target> </Target>
</targetSelectedWithDropDown> </targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-03T08:08:19.409182700Z" /> <timeTargetWasSelectedWithDropDown value="2023-10-27T17:41:35.449717700Z" />
</component> </component>
</project> </project>

2
.idea/gradle.xml generated
View File

@ -7,7 +7,7 @@
<option name="testRunner" value="GRADLE" /> <option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="corretto-17" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

2
.idea/kotlinc.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.10" /> <option name="version" value="1.8.20" />
</component> </component>
</project> </project>

2
.idea/misc.xml generated
View File

@ -1,6 +1,6 @@
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,5 +1,6 @@
plugins { plugins {
id("com.android.application") id("com.android.application")
id("com.google.devtools.ksp")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
} }
@ -30,17 +31,17 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_11
} }
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = "11"
} }
buildFeatures { buildFeatures {
compose = true compose = true
} }
composeOptions { composeOptions {
kotlinCompilerExtensionVersion = "1.4.3" kotlinCompilerExtensionVersion = "1.4.5"
} }
packaging { packaging {
resources { resources {
@ -48,6 +49,9 @@ android {
} }
} }
} }
kotlin {
jvmToolchain(11)
}
dependencies { dependencies {
@ -71,5 +75,10 @@ dependencies {
implementation("androidx.compose.material:material-icons-extended") implementation("androidx.compose.material:material-icons-extended")
implementation("androidx.navigation:navigation-compose:2.6.0") implementation("androidx.navigation:navigation-compose:2.6.0")
implementation("androidx.navigation:navigation-compose:2.4.0-alpha10") implementation("androidx.navigation:navigation-compose:2.4.0-alpha10")
val room_version = "2.5.2"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
ksp("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
} }

View File

@ -5,10 +5,10 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.pmulabs.designElem.SearchViewModel
import com.example.pmulabs.designElem.SharedViewModel
import com.example.pmulabs.graphs.RootNavigationGraph import com.example.pmulabs.graphs.RootNavigationGraph
import com.example.pmulabs.ui.theme.PMULabsTheme import com.example.pmulabs.ui.theme.PMULabsTheme
import com.example.pmulabs.viewModels.SearchViewModel
import com.example.pmulabs.viewModels.SharedViewModel
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private val searchViewModel: SearchViewModel by viewModels() private val searchViewModel: SearchViewModel by viewModels()

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.basecomponents.navigate
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -28,7 +28,6 @@ import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
@Composable @Composable
fun BottomBar(navController: NavHostController){ fun BottomBar(navController: NavHostController){

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.basecomponents.navigate
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth

View File

@ -1,191 +0,0 @@
package com.example.pmulabs.designElem
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
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.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.pmulabs.R
import com.example.pmulabs.models.Article
import com.example.pmulabs.repository.CommentRepository
import com.example.pmulabs.repository.TegRepository
import java.text.SimpleDateFormat
@Composable
fun ArticleItem(article: Article,modifier: Modifier = Modifier,onArticleClick: () -> Unit) {
val tagRepository= TegRepository()
val getAllData= tagRepository.getAllData()
val commRepository= CommentRepository()
val countComm= commRepository.getCountComment(article.id)
val formatter = SimpleDateFormat("dd.MM.YY")
val publishDate=formatter.format(article.publishDate)
var tagName=""
getAllData.forEach{teg ->
if(article.tagId == teg.id){
tagName=teg.title
}
}
Card(
colors = CardDefaults.outlinedCardColors(
containerColor = Color.White,
contentColor = Color(0xff423a99)
),
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
modifier = modifier
.clip(shape = RoundedCornerShape(5.dp))
.clickable{onArticleClick()}
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 199.dp)
) {
Card(
colors = CardDefaults.outlinedCardColors(
containerColor = Color.White
),
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
content = {},
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 199.dp)
.clip(shape = RoundedCornerShape(5.dp))
.background(color = Color.White)
.border(border = BorderStroke(3.dp, Color(0xffdbdbf1)),
shape = RoundedCornerShape(5.dp)))
LazyRow(
modifier = Modifier
.requiredWidth(width = 387.dp)
.requiredHeight(height = 199.dp)
) {
item {
Image(
painter = painterResource(id = R.drawable.image2),
contentDescription = "image 2",
modifier = Modifier
.requiredWidth(width = 180.dp)
.requiredHeight(height = 199.dp)
.clip(shape = RoundedCornerShape(5.dp))
.border(border = BorderStroke(3.dp, Color(0xffdbdbf1)),
shape = RoundedCornerShape(5.dp)))
}
item {
Column(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 5.dp,
y = 8.dp)
.requiredWidth(width = 201.dp)
.requiredHeight(height = 177.dp)
) {
LazyColumn(
modifier = Modifier
.requiredWidth(width = 201.dp)
.requiredHeight(height = 150.dp)
) {
item {
LazyRow(
modifier = Modifier
.requiredWidth(width = 150.dp)
.requiredHeight(height = 20.dp)
) {
item {
Text(
text = "${publishDate}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp))
}
item {
Text(
text = "#${tagName}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 12.dp,
y = 0.dp))
}
}
}
item {
Text(
text = "${article.title}",
maxLines=4,
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 0.dp,
y = 15.dp)
.requiredWidth(width = 201.dp)
.requiredHeight(height = 100.dp))
}
}
LazyRow(
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 3.dp,
y = 5.dp)
.requiredWidth(width = 80.dp)
.requiredHeight(height = 25.dp)
) {
item {
Row(
modifier = Modifier
.requiredWidth(width = 58.dp)
.requiredHeight(height = 22.dp)
) {
Image(
painter = painterResource(id = R.drawable.ic_comment),
contentDescription = "icon \"heart\"",
modifier = Modifier
.requiredWidth(width = 25.dp)
.requiredHeight(height = 22.dp))
Text(
text = "${countComm}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 5.dp,
y = 1.dp))
}
}
}
}
}
}
}
}
}

View File

@ -1,76 +0,0 @@
package com.example.pmulabs.designElem
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
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.HorizontalDivider
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.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.sp
import com.example.pmulabs.models.Comment
import com.example.pmulabs.repository.UserRepository
@Composable
fun CommentItem(modifier: Modifier = Modifier,comm : Comment) {
val userRep= UserRepository()
val user=userRep.getUserById(comm.userId.toString())
Box(
modifier = modifier
.requiredWidth(width = 376.dp)
.requiredHeight(height = 105.dp)
.offset(
y=10.dp
)
) {
Box(
modifier = Modifier
.requiredWidth(width = 376.dp)
.requiredHeight(height = 87.dp)
.clip(shape = RoundedCornerShape(10.dp))
.background(color = Color.White)
.border(border = BorderStroke(3.dp, Color(0xff423a99)),
shape = RoundedCornerShape(10.dp)))
HorizontalDivider(
thickness=3.dp,
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 1.dp,
y = 31.dp)
.requiredWidth(width = 374.dp), color = Color(0xff423a99)
)
Text(
text = "${user.nickname}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 13.dp,
y = 7.dp))
Text(
text = "${comm.text}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 13.dp,
y = 36.dp))
}
}

View File

@ -1,63 +0,0 @@
package com.example.pmulabs.designElem
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
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.Icon
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.graphics.Color
import androidx.compose.ui.res.painterResource
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.sp
import com.example.pmulabs.R
import com.example.pmulabs.models.Teg
@Composable
fun TagItem(teg: Teg, modifier: Modifier = Modifier,onTagClick: () -> Unit) {
Box(
modifier = modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xFFDBDBF1))
.clickable { onTagClick() }
)
Icon(
painter = painterResource(id = R.drawable.iconhashtag1),
tint= Color(0xff423a99),
contentDescription = "icon \"hashtag 1\"",
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 20.dp,
y = 14.dp)
.requiredWidth(width = 31.dp)
.requiredHeight(height = 29.dp))
Text(
text = "${teg.title}",
color = Color(0xff423a99),
textAlign = TextAlign.Center,
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 64.dp,
y = 14.dp))
}
}

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.basecomponents.navigate package com.example.pmulabs.designElem.elem
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.basecomponents.navigate package com.example.pmulabs.designElem.elem
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding

View File

@ -0,0 +1,462 @@
package com.example.pmulabs.designElem.items
import android.util.Log
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
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.fillMaxWidth
import androidx.compose.foundation.layout.height
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.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.ArrowDropUp
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
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.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.toSize
import com.example.pmulabs.R
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick: () -> Unit,sharedViewModel: SharedViewModel) {
val context = LocalContext.current
//список тэгов
val tags = remember { mutableStateListOf<Tag>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getAll().collect { data ->
tags.clear()
tags.addAll(data)
}
}
}
//количество комментариев для статьи
var countComm by rememberSaveable { mutableStateOf(0) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
countComm = article.id?.let {
NewsPortalDatabase.getInstance(context).commentDao().getCountComment(
it
)
}?.toInt() ?: 0
}
}
//текущий пользователь
val argument = sharedViewModel.argument.value
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser=data
}
}
}
//формат даты
val formatter = SimpleDateFormat("dd.MM.YY")
val publishDate=formatter.format(article.publishDate)
//список названий тэгов
var tagName=""
var tagsNames= remember { mutableStateListOf<String>() }
tags.forEach{teg ->
if(article.tagId == teg.id){
tagName=teg.title
}
if(!tagsNames.contains(teg.title)) {
tagsNames.add(teg.title)
}
}
//открыто ли диалоговое окно
var openDialog by remember { mutableStateOf(false) }
//переменные article для update
var text by remember { mutableStateOf(article.text) }
var tagId by remember { mutableStateOf(article.tagId) }
var title by remember { mutableStateOf(article.title) }
//переменные для dropdown
var expanded by remember { mutableStateOf(false) }
val suggestions = tagsNames
var selectedText by remember { mutableStateOf(tagName) }
var textfieldSize by remember { mutableStateOf(Size.Zero)}
val icon = if (expanded)
Icons.Filled.ArrowDropUp
else
Icons.Filled.ArrowDropDown
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getTagById(tagId).collect { data ->
selectedText=data.title
}
}
}
//диалоговое окно
if (openDialog) {
AlertDialog(
onDismissRequest = {
openDialog = false
text=article.text
selectedText=tagName
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Edit your article",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
Box() {
OutlinedTextField(
value = selectedText,
onValueChange = { selectedText = it },
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
.onGloballyPositioned { coordinates ->
textfieldSize = coordinates.size.toSize()
},
label = {Text("Select Tag")},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
trailingIcon = {
Icon(icon,"List of tags",
Modifier.clickable { expanded = !expanded })
}
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.width(with(LocalDensity.current){textfieldSize.width.toDp()})
) {
suggestions.forEach { label ->
DropdownMenuItem(
text= {Text(text=label)},
onClick = { selectedText = label
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).tagDao().getTagByName(selectedText).collect{ tag ->
tagId=tag?.id.toString().toInt()
}
}}
)
}
}
}
OutlinedTextField(
value = title,
onValueChange = {
title=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Article Title") },
placeholder = { Text("Write title of article...") },
minLines = 3,
maxLines = 3,
)
OutlinedTextField(
value = text,
onValueChange = {
text=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Article Text") },
placeholder = { Text("Write text of article...") },
minLines = 3,
maxLines = 3,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialog = false
article.text=text
article.title=title
tagName=selectedText
Log.d("Tag",tagId.toString())
if(tagId!=null) {
article.tagId = tagId
}
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).articleDao().update(article)
}
},
modifier = Modifier
.padding(start=100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Edit", fontSize = 20.sp)
}
}
}
},
)
}
Card(
colors = CardDefaults.outlinedCardColors(
containerColor = Color.White,
contentColor = Color(0xff423a99)
),
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
modifier = modifier
.clip(shape = RoundedCornerShape(5.dp))
.clickable{onArticleClick()}
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 199.dp)
) {
Card(
colors = CardDefaults.outlinedCardColors(
containerColor = Color.White
),
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
content = {},
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 199.dp)
.clip(shape = RoundedCornerShape(5.dp))
.background(color = Color.White)
.border(border = BorderStroke(3.dp, Color(0xffdbdbf1)),
shape = RoundedCornerShape(5.dp)))
LazyRow(
modifier = Modifier
.requiredWidth(width = 387.dp)
.requiredHeight(height = 199.dp)
) {
item {
Column(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(x = 15.dp,
y = 8.dp)
.requiredWidth(width = 351.dp)
.requiredHeight(height = 177.dp)
) {
LazyColumn(
modifier = Modifier
.requiredWidth(width = 351.dp)
.requiredHeight(height = 150.dp)
) {
item {
LazyRow(
modifier = Modifier
.requiredWidth(width = 351.dp)
.requiredHeight(height = 20.dp)
) {
item {
Text(
text = "${publishDate}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp))
}
item {
Text(
text = "#${tagName}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 12.dp,
y = 0.dp))
}
item{
if(getUser?.id==article.userId) {
Icon(
modifier=Modifier
.align(Alignment.End)
.offset(x = 20.dp,
y = 0.dp)
.requiredHeight(30.dp)
.clickable {
openDialog=true
},
imageVector = Icons.Filled.Edit,
contentDescription = "Update Icon",
tint = Color(0xff423a99)
)
Icon(
modifier=Modifier
.align(Alignment.End)
.offset(x = 20.dp,
y = 0.dp)
.requiredHeight(30.dp)
.clickable {
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).articleDao().delete(article)
}
},
imageVector = Icons.Filled.Close,
contentDescription = "Delete Icon",
tint = Color(0xff423a99)
)
}
}
}
}
item {
Text(
text = "${article.title}",
maxLines=4,
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 0.dp,
y = 15.dp)
.requiredWidth(width = 351.dp)
.requiredHeight(height = 100.dp))
}
}
LazyRow(
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 3.dp,
y = 5.dp)
.requiredWidth(width = 80.dp)
.requiredHeight(height = 25.dp)
) {
item {
Row(
modifier = Modifier
.requiredWidth(width = 58.dp)
.requiredHeight(height = 22.dp)
) {
Image(
painter = painterResource(id = R.drawable.ic_comment),
contentDescription = "icon \"heart\"",
modifier = Modifier
.requiredWidth(width = 25.dp)
.requiredHeight(height = 22.dp))
Text(
text = "${countComm}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 17.sp),
modifier = Modifier
//.align(alignment = Alignment.TopStart)
.offset(x = 5.dp,
y = 1.dp))
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,207 @@
package com.example.pmulabs.designElem.items
import androidx.compose.foundation.background
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.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CommentItem(modifier: Modifier = Modifier,comm : Comment,sharedViewModel: SharedViewModel) {
val context = LocalContext.current
var user by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(comm.userId).collect { data ->
user=data
}
}
}
val argument = sharedViewModel.argument.value
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser=data
}
}
}
var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf(comm.text) }
if (openDialog) {
AlertDialog(
onDismissRequest = {
openDialog = false
text=comm.text
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Edit your comment",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
OutlinedTextField(
value = text,
onValueChange = {
text=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Comment") },
placeholder = { Text("Write comment...") },
minLines = 3,
maxLines = 3,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialog = false
comm.text=text
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).commentDao().update(comm)
}
},
modifier = Modifier
.padding(start=100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Edit", fontSize = 20.sp)
}
}
}
},
)
}
Row(
modifier = Modifier
.padding(3.dp)
.fillMaxWidth()
.background(Color.White)
)
{
Column(
modifier= Modifier
.padding(start = 10.dp,top=10.dp)
) {
Row() {
Text(
text = "${user?.nickname}",
color = Color(0xff423a99),
style = TextStyle(
textDecoration = TextDecoration.Underline,
fontSize = 17.sp,
fontWeight = FontWeight.Bold
),
)
if(getUser?.id==comm.userId) {
Icon(
modifier=Modifier
.requiredHeight(20.dp)
.clickable {
openDialog=true
},
imageVector = Icons.Filled.Edit,
contentDescription = "Update Icon",
tint = Color(0xff423a99)
)
Icon(
modifier=Modifier
.requiredHeight(20.dp)
.clickable {
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).commentDao().delete(comm)
}
},
imageVector = Icons.Filled.Close,
contentDescription = "Delete Icon",
tint = Color(0xff423a99)
)
}
}
Text(
text = "${comm.text}",
color = Color(0xff423a99),
style = TextStyle(fontSize = 15.sp, fontWeight = FontWeight.Bold),
)
Spacer(modifier = Modifier.padding(10.dp))
}
}
}

View File

@ -0,0 +1,220 @@
package com.example.pmulabs.designElem.items
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.fillMaxWidth
import androidx.compose.foundation.layout.height
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.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.res.painterResource
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.sp
import com.example.pmulabs.R
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit,sharedViewModel: SharedViewModel) {
val context = LocalContext.current
val argument = sharedViewModel.argument.value
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser = data
}
}
}
var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf(teg.title) }
if (openDialog) {
AlertDialog(
onDismissRequest = {
openDialog = false
text = teg.title
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Edit your tag",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
OutlinedTextField(
value = text,
onValueChange = {
text = it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Tag") },
placeholder = { Text("Write tag...") },
minLines = 3,
maxLines = 3,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialog = false
teg.title = text
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).tagDao().update(teg)
}
},
modifier = Modifier
.padding(start = 100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Edit", fontSize = 20.sp)
}
}
}
},
)
}
Box(
modifier = modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xFFDBDBF1))
.clickable { onTagClick() }
)
Icon(
painter = painterResource(id = R.drawable.iconhashtag1),
tint = Color(0xff423a99),
contentDescription = "icon \"hashtag 1\"",
modifier = Modifier
.offset(
x = 20.dp,
y = 14.dp
)
.requiredWidth(width = 31.dp)
.requiredHeight(height = 29.dp)
)
Text(
text = "${teg.title}",
color = Color(0xff423a99),
textAlign = TextAlign.Center,
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.offset(
x = 64.dp,
y = 14.dp
)
)
if (getUser?.id == teg.userId) {
Icon(
modifier = Modifier
.requiredHeight(40.dp)
.offset(
x = 290.dp,
y = 9.dp
)
.clickable {
openDialog = true
},
imageVector = Icons.Filled.Edit,
contentDescription = "Update Icon",
tint = Color(0xff423a99)
)
Icon(
modifier = Modifier
.requiredHeight(40.dp)
.offset(
x = 320.dp,
y = 9.dp
)
.clickable {
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).tagDao().delete(teg)
}
},
imageVector = Icons.Filled.Close,
contentDescription = "Delete Icon",
tint = Color(0xff423a99)
)
}
}
}

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.designElem.statDesign
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View File

@ -1,19 +1,14 @@
package com.example.pmulabs.designElem package com.example.pmulabs.designElem.statDesign
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
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

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.designElem.statDesign
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View File

@ -5,10 +5,10 @@ import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.navigation import androidx.navigation.navigation
import com.example.pmulabs.designElem.SharedViewModel import com.example.pmulabs.screensMobile.authScreens.EntryScreen
import com.example.pmulabs.screensMobile.EntryScreen import com.example.pmulabs.screensMobile.authScreens.RegisterScreen
import com.example.pmulabs.screensMobile.RegisterScreen import com.example.pmulabs.screensMobile.authScreens.SplashScreen
import com.example.pmulabs.screensMobile.SplashScreen import com.example.pmulabs.viewModels.SharedViewModel
fun NavGraphBuilder.authNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){ fun NavGraphBuilder.authNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){
navigation( navigation(
@ -22,7 +22,7 @@ fun NavGraphBuilder.authNavGraph(navController: NavHostController,sharedViewMode
EntryScreen(navController = navController, Modifier,sharedViewModel) EntryScreen(navController = navController, Modifier,sharedViewModel)
} }
composable(route=AuthScreen.Register.route){ composable(route=AuthScreen.Register.route){
RegisterScreen(navController = navController, Modifier) RegisterScreen(navController = navController, Modifier,sharedViewModel)
} }
} }
} }

View File

@ -12,16 +12,16 @@ import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.basecomponents.navigate.CALENDAR_ARGUMENT_DATE import com.example.pmulabs.basecomponents.navigate.CALENDAR_ARGUMENT_DATE
import com.example.pmulabs.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY import com.example.pmulabs.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY
import com.example.pmulabs.basecomponents.navigate.SEARCH_ARGUMENT_TEXT import com.example.pmulabs.basecomponents.navigate.SEARCH_ARGUMENT_TEXT
import com.example.pmulabs.designElem.SharedViewModel
import com.example.pmulabs.screensMobile.ArticlePageScreen import com.example.pmulabs.screensMobile.ArticlePageScreen
import com.example.pmulabs.screensMobile.CalendarScreen
import com.example.pmulabs.screensMobile.CoopScreen import com.example.pmulabs.screensMobile.CoopScreen
import com.example.pmulabs.screensMobile.InfoScreen import com.example.pmulabs.screensMobile.InfoScreen
import com.example.pmulabs.screensMobile.MainScreen import com.example.pmulabs.screensMobile.MainScreen
import com.example.pmulabs.screensMobile.ProfileScreen import com.example.pmulabs.screensMobile.ProfileScreen
import com.example.pmulabs.screensMobile.SearchByTagScreen
import com.example.pmulabs.screensMobile.SearchScreen
import com.example.pmulabs.screensMobile.TagsScreen import com.example.pmulabs.screensMobile.TagsScreen
import com.example.pmulabs.screensMobile.filterScreens.CalendarScreen
import com.example.pmulabs.screensMobile.filterScreens.SearchByTagScreen
import com.example.pmulabs.screensMobile.filterScreens.SearchScreen
import com.example.pmulabs.viewModels.SharedViewModel
@Composable @Composable
fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){
@ -33,7 +33,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
composable( composable(
route=BottomBarScreen.Main.route route=BottomBarScreen.Main.route
){ ){
MainScreen(navController,Modifier) MainScreen(navController,Modifier,sharedViewModel)
} }
composable( composable(
route=BottomBarScreen.SearchByTag.route, route=BottomBarScreen.SearchByTag.route,
@ -41,7 +41,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
SearchByTagScreen(navController,Modifier) SearchByTagScreen(navController,Modifier,sharedViewModel)
} }
composable( composable(
route=BottomBarScreen.ArticlePage.route, route=BottomBarScreen.ArticlePage.route,
@ -49,7 +49,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
ArticlePageScreen(navController,Modifier) ArticlePageScreen(navController,Modifier,sharedViewModel)
} }
composable( composable(
route=BottomBarScreen.Search.route, route=BottomBarScreen.Search.route,
@ -57,7 +57,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
SearchScreen(navController,Modifier) SearchScreen(navController,Modifier,sharedViewModel)
} }
composable( composable(
route=BottomBarScreen.Calendar.route, route=BottomBarScreen.Calendar.route,
@ -65,7 +65,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
CalendarScreen(navController,Modifier) CalendarScreen(navController,Modifier,sharedViewModel)
} }
composable(route=BottomBarScreen.Profile.route){ composable(route=BottomBarScreen.Profile.route){
ProfileScreen(navController,Modifier,sharedViewModel) ProfileScreen(navController,Modifier,sharedViewModel)
@ -77,7 +77,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
CoopScreen(navController,Modifier) CoopScreen(navController,Modifier)
} }
composable(route=BottomBarScreen.Categories.route){ composable(route=BottomBarScreen.Categories.route){
TagsScreen(navController,Modifier) TagsScreen(navController,Modifier,sharedViewModel)
} }
} }
} }

View File

@ -6,14 +6,14 @@ import androidx.navigation.NavType
import androidx.navigation.compose.NavHost 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.pmulabs.designElem.SearchViewModel
import com.example.pmulabs.designElem.SharedViewModel
import com.example.pmulabs.screensMobile.LoadScreen import com.example.pmulabs.screensMobile.LoadScreen
import com.example.pmulabs.viewModels.SearchViewModel
import com.example.pmulabs.viewModels.SharedViewModel
const val USERID_ARGUMENT="userId" const val USERID_ARGUMENT="userId"
@Composable @Composable
fun RootNavigationGraph(navController: NavHostController,searchViewModel: SearchViewModel, sharedViewModel: SharedViewModel){ fun RootNavigationGraph(navController: NavHostController, searchViewModel: SearchViewModel, sharedViewModel: SharedViewModel){
NavHost( NavHost(
navController=navController, navController=navController,
route = Graph.ROOT, route = Graph.ROOT,

View File

@ -1,11 +0,0 @@
package com.example.pmulabs.models
import java.util.Date
data class Article(
val id: Int,
val title: String,
val text: String,
val publishDate: Date,
val tagId: Int
)

View File

@ -1,8 +0,0 @@
package com.example.pmulabs.models
data class Comment(
val id: Int,
val userId: Int,
val text: String,
val articleId: Int
)

View File

@ -1,6 +0,0 @@
package com.example.pmulabs.models
data class Teg(
val id: Int,
val title: String,
)

View File

@ -1,9 +0,0 @@
package com.example.pmulabs.models
data class User(
val id: Int,
val nickname: String,
val email: String,
val password: String,
val role: String
)

View File

@ -1,70 +0,0 @@
package com.example.pmulabs.repository
import com.example.pmulabs.models.Article
import java.util.Date
class ArticleRepository {
fun getArticleById(articleId : String): Article {
return getAllData()[articleId.toInt()]
}
fun getAllData(): List<Article>{
return listOf(
Article(
id=0,
title = "Заголовок 1",
text = "Текст статьи с заголовком 1",
publishDate = Date(2023,5,22),
tagId=5
),
Article(
id=1,
title = "Заголовок 2",
text = "Текст статьи с заголовком 2",
publishDate = Date(2022,11,13),
tagId=1
),
Article(
id=2,
title = "Заголовок 3",
text = "Текст статьи с заголовком 3",
publishDate = Date(2023,5,4),
tagId=0
),
Article(
id=3,
title = "Заголовок 4",
text = "Текст статьи с заголовком 4",
publishDate = Date(2023,2,14),
tagId=2
),
Article(
id=4,
title = "Заголовок 5",
text = "Текст статьи с заголовком 5",
publishDate = Date(2023,0,19),
tagId=3
),
Article(
id=5,
title = "Заголовок 6",
text = "Текст статьи с заголовком 6",
publishDate = Date(2023,5,22),
tagId=3
),
Article(
id=6,
title = "Заголовок 7",
text = "Текст статьи с заголовком 7",
publishDate = Date(2023,0,19),
tagId=4
),
Article(
id=7,
title = "Заголовок 8",
text = "Текст статьи с заголовком 8",
publishDate = Date(2022,11,13),
tagId=5
)
)
}
}

View File

@ -1,86 +0,0 @@
package com.example.pmulabs.repository
import com.example.pmulabs.models.Comment
class CommentRepository {
fun getCountComment(articleId: Int): Int {
var count=0;
getAllData().forEach{
comm ->
if(comm.articleId==articleId){
count++
}
}
return count
}
fun getAllData(): List<Comment>{
return listOf(
Comment(
id=0,
text = "Текст комментария 1",
userId = 0,
articleId = 7
),
Comment(
id=1,
text = "Текст комментария 2",
userId = 1,
articleId = 1
),
Comment(
id=2,
text = "Текст комментария 3",
userId = 2,
articleId = 2
),
Comment(
id=3,
text = "Текст комментария 4",
userId = 0,
articleId = 3
),
Comment(
id=4,
text = "Текст комментария 5",
userId = 1,
articleId = 0
),
Comment(
id=5,
text = "Текст комментария 6",
userId = 2,
articleId = 4
),
Comment(
id=6,
text = "Текст комментария 7",
userId = 0,
articleId = 5
),
Comment(
id=7,
text = "Текст комментария 8",
userId = 1,
articleId = 6
),
Comment(
id=8,
text = "Текст комментария 9",
userId = 2,
articleId = 0
),
Comment(
id=9,
text = "Текст комментария 10",
userId = 0,
articleId = 1
),
Comment(
id=10,
text = "Текст комментария 11",
userId = 1,
articleId = 2
),
)
}
}

View File

@ -1,37 +0,0 @@
package com.example.pmulabs.repository
import com.example.pmulabs.models.Teg
class TegRepository {
fun getTagById(tagId : String): Teg {
return getAllData()[tagId.toInt()]
}
fun getAllData(): List<Teg>{
return listOf(
Teg(
id=0,
title = "Тег_1"
),
Teg(
id=1,
title = "Тег_2"
),
Teg(
id=2,
title = "Тег_3"
),
Teg(
id=3,
title = "Тег_4"
),
Teg(
id=4,
title = "Тег_5"
),
Teg(
id=5,
title = "Тег_6"
),
)
}
}

View File

@ -1,48 +0,0 @@
package com.example.pmulabs.repository
import com.example.pmulabs.models.Comment
import com.example.pmulabs.models.User
class UserRepository {
val commRepository=CommentRepository()
val getAlDataComm=commRepository.getAllData()
fun getAllData(): List<User>{
return listOf(
User(
id=0,
nickname = "LatinMisha",
email = "llmisha@gmail.com",
password = "user1",
role = "user"
),
User(
id=1,
nickname = "Kasablanka",
email = "kasyul@gmail.com",
password = "user2",
role = "user"
),
User(
id=2,
nickname = "Ilonherber",
email = "ihlon82@gmail.com",
password = "user3",
role = "user"
)
)
}
fun getUserById(userId : String): User {
return getAllData()[userId.toInt()]
}
fun getUserComm(userId : String): List<Comment> {
val list = mutableListOf<Comment>()
for (comm in getAlDataComm) {
if (comm.userId == userId.toInt()) {
list.add(comm)
}
}
return list
}
}

View File

@ -0,0 +1,27 @@
package com.example.pmulabs.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.pmulabs.room.models.Article
import kotlinx.coroutines.flow.Flow
@Dao
interface ArticleDao {
@Query("select * from article ORDER BY publish_date ASC")
fun getAll(): Flow<List<Article>>
@Query("select * from article where article.id = :idArticle")
fun getArticleById(idArticle: Int): Flow<Article>
@Insert
suspend fun insert(article: Article)
@Update
suspend fun update(article: Article)
@Delete
suspend fun delete(article: Article)
}

View File

@ -0,0 +1,27 @@
package com.example.pmulabs.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.pmulabs.room.models.Comment
import kotlinx.coroutines.flow.Flow
@Dao
interface CommentDao {
@Query("select * from comment ORDER BY id DESC")
fun getAll(): Flow<List<Comment>>
@Query("select COUNT(*) from comment WHERE comment.text!='' AND comment.article_id= :idArticle")
fun getCountComment(idArticle : Int) : Int
@Insert
suspend fun insert(comment: Comment)
@Update
suspend fun update(comment: Comment)
@Delete
suspend fun delete(comment: Comment)
}

View File

@ -0,0 +1,30 @@
package com.example.pmulabs.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.pmulabs.room.models.Tag
import kotlinx.coroutines.flow.Flow
@Dao
interface TagDao {
@Query("select * from tag")
fun getAll(): Flow<List<Tag>>
@Query("select * from tag where tag.id = :idTag")
fun getTagById(idTag: Int): Flow<Tag>
@Query("select * from tag where tag.title = :nameTag")
fun getTagByName(nameTag: String): Flow<Tag>
@Insert
suspend fun insert(tag: Tag)
@Update
suspend fun update(tag: Tag)
@Delete
suspend fun delete(tag: Tag)
}

View File

@ -0,0 +1,39 @@
package com.example.pmulabs.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.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
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 comment WHERE comment.text!='' AND comment.user_id= :idUser")
fun getUserComms(idUser: Int): Flow<List<Comment>>
@Query("select * from article WHERE article.text!='' AND article.user_id= :idUser")
fun getUserArticles(idUser: Int): Flow<List<Article>>
@Query("select * from tag WHERE tag.title!='' AND tag.user_id= :idUser")
fun getUserTags(idUser: Int): Flow<List<Tag>>
@Insert
suspend fun insert(user: User)
@Update
suspend fun update(user: User)
@Delete
suspend fun delete(user: User)
}

View File

@ -0,0 +1,119 @@
package com.example.pmulabs.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.pmulabs.room.dao.ArticleDao
import com.example.pmulabs.room.dao.CommentDao
import com.example.pmulabs.room.dao.TagDao
import com.example.pmulabs.room.dao.UserDao
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.Date
@Database(entities = [User::class, Tag::class, Comment::class, Article::class], version = 5, exportSchema = false)
abstract class NewsPortalDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun tagDao(): TagDao
abstract fun commentDao(): CommentDao
abstract fun articleDao(): ArticleDao
companion object {
private const val DB_NAME: String = "news-portal"
@Volatile
private var INSTANCE: NewsPortalDatabase? = null
private suspend fun populateDatabase() {
INSTANCE?.let { database ->
val userDao = database.userDao()
val user1 = User(1, "LatinMisha","llmisha@gmail.com","user1","user")
val user2 = User(2, "Kasablanka","kasyul@gmail.com","user2","user")
val user3 = User(3, "Ilonherber","ihlon82@gmail.com","user3","user")
userDao.insert(user1)
userDao.insert(user2)
userDao.insert(user3)
val tagDao = database.tagDao()
val tag1 = Tag(1, "Тег_1",2)
val tag2 = Tag(2, "Тег_2",1)
val tag3 = Tag(3, "Тег_3",3)
val tag4 = Tag(4, "Тег_4",2)
val tag5 = Tag(5, "Тег_5",1)
val tag6 = Tag(6, "Тег_6",3)
tagDao.insert(tag1)
tagDao.insert(tag2)
tagDao.insert(tag3)
tagDao.insert(tag4)
tagDao.insert(tag5)
tagDao.insert(tag6)
val articleDao = database.articleDao()
val article1 = Article(1, "Заголовок 1","Текст статьи с заголовком 1", Date(2023,5,22).time,1,6)
val article2 = Article(2, "Заголовок 2","Текст статьи с заголовком 2", Date(2022,11,13).time,3,2)
val article3 = Article(3, "Заголовок 3","Текст статьи с заголовком 3", Date(2023,5,4).time,2,1)
val article4 = Article(4, "Заголовок 4","Текст статьи с заголовком 4", Date(2023,2,14).time,3,3)
val article5 = Article(5, "Заголовок 5","Текст статьи с заголовком 5", Date(2023,0,19).time,1,4)
val article6 = Article(6, "Заголовок 6","Текст статьи с заголовком 6", Date(2023,5,22).time,2,4)
val article7 = Article(7, "Заголовок 7","Текст статьи с заголовком 7", Date(2023,0,19).time,3,5)
val article8 = Article(8, "Заголовок 8","Текст статьи с заголовком 8", Date(2022,11,13).time,1,6)
articleDao.insert(article1)
articleDao.insert(article2)
articleDao.insert(article3)
articleDao.insert(article4)
articleDao.insert(article5)
articleDao.insert(article6)
articleDao.insert(article7)
articleDao.insert(article8)
val commentDao = database.commentDao()
val comment1 = Comment(1, "Текст комментария 1",1,8)
val comment2 = Comment(2, "Текст комментария 2",2,2)
val comment3 = Comment(3, "Текст комментария 3",3,3)
val comment4 = Comment(4, "Текст комментария 4",1,4)
val comment5 = Comment(5, "Текст комментария 5",2,1)
val comment6 = Comment(6, "Текст комментария 6",3,4)
val comment7 = Comment(7, "Текст комментария 7",1,6)
val comment8 = Comment(8, "Текст комментария 8",2,7)
val comment9 = Comment(9, "Текст комментария 9",3,1)
val comment10 = Comment(10, "Текст комментария 10",1,2)
val comment11 = Comment(11, "Текст комментария 11",2,3)
commentDao.insert(comment1)
commentDao.insert(comment2)
commentDao.insert(comment3)
commentDao.insert(comment4)
commentDao.insert(comment5)
commentDao.insert(comment6)
commentDao.insert(comment7)
commentDao.insert(comment8)
commentDao.insert(comment9)
commentDao.insert(comment10)
commentDao.insert(comment11)
}
}
fun getInstance(appContext: Context): NewsPortalDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
appContext,
NewsPortalDatabase::class.java,
DB_NAME
)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
populateDatabase()
}
}
})
.build()
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,37 @@
package com.example.pmulabs.room.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
@Entity(tableName = "article",
foreignKeys = [ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["user_id"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
ForeignKey(entity = Tag::class, parentColumns = ["id"], childColumns = ["tag_id"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)])
data class Article(
@PrimaryKey(autoGenerate = true)
val id: Int?,
@ColumnInfo(name = "title")
var title: String,
@ColumnInfo(name = "text")
var text: String,
@ColumnInfo(name = "publish_date")
val publishDate: Long,
@ColumnInfo(name = "user_id")
val userId: Int,
@ColumnInfo(name = "tag_id")
var tagId: Int
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Article
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id ?: -1
}
}

View File

@ -0,0 +1,32 @@
package com.example.pmulabs.room.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
@Entity(tableName = "comment",
foreignKeys = [ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["user_id"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
ForeignKey(entity = Article::class, parentColumns = ["id"], childColumns = ["article_id"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)])
data class Comment(
@PrimaryKey(autoGenerate = true)
val id: Int?,
@ColumnInfo(name = "text")
var text: String,
@ColumnInfo(name = "user_id")
val userId: Int,
@ColumnInfo(name = "article_id")
val articleId: Int
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Comment
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id ?: -1
}
}

View File

@ -0,0 +1,31 @@
package com.example.pmulabs.room.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(tableName = "tag",
foreignKeys = [ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["user_id"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)],
indices = [Index(value = ["title"], unique = true)])
data class Tag(
@PrimaryKey(autoGenerate = true)
val id: Int?,
@ColumnInfo(name = "title")
var title: String,
@ColumnInfo(name = "user_id")
val userId: Int
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Tag
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id ?: -1
}
}

View File

@ -0,0 +1,35 @@
package com.example.pmulabs.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),
Index(value = ["nickname"], unique = true)
])
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int?,
@ColumnInfo(name = "nickname")
var nickname: String,
@ColumnInfo(name = "email")
var email: String,
@ColumnInfo(name = "password")
var password: String,
@ColumnInfo(name = "role")
val role: 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
}
}

View File

@ -1,7 +1,6 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -9,52 +8,107 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable 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.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.res.painterResource import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
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
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.R
import com.example.pmulabs.basecomponents.navigate.ARTICLE_ARGUMENT_KEY import com.example.pmulabs.basecomponents.navigate.ARTICLE_ARGUMENT_KEY
import com.example.pmulabs.basecomponents.navigate.BackButton import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.designElem.CommentItem import com.example.pmulabs.designElem.items.CommentItem
import com.example.pmulabs.repository.ArticleRepository import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.repository.CommentRepository import com.example.pmulabs.room.models.Article
import com.example.pmulabs.repository.TegRepository import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier) { fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) {
val argument = sharedViewModel.argument.value
val context = LocalContext.current
var id=navController.currentBackStackEntry?.arguments?.getString(ARTICLE_ARGUMENT_KEY).toString() var id=navController.currentBackStackEntry?.arguments?.getString(ARTICLE_ARGUMENT_KEY).toString()
val articleRep=ArticleRepository() var textComm by rememberSaveable { mutableStateOf("") }
var article= articleRep.getArticleById("0") var article by remember { mutableStateOf<Article?>(null) }
var tag by remember { mutableStateOf<Tag?>(null) }
var tagId = 0
if (id.toString() != "null") { if (id.toString() != "null") {
article = articleRep.getArticleById(id) LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).articleDao().getArticleById(id.toInt()).collect { data ->
article=data
tagId=data.tagId
NewsPortalDatabase.getInstance(context).tagDao().getTagById(tagId).collect { data ->
tag=data
}
}
}
}
} }
val tegRep=TegRepository()
val teg= tegRep.getTagById(article?.tagId.toString())
val formatter = SimpleDateFormat("dd.MM.YY")
val publishDate=formatter.format(article?.publishDate)
val commRep=CommentRepository() val formatter = SimpleDateFormat("dd.MM.YY")
val allComm=commRep.getAllData() val publishDate=formatter.format(Date(article?.publishDate ?: 0))
val comms = remember { mutableStateListOf<Comment>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).commentDao().getAll().collect { data ->
comms.clear()
comms.addAll(data)
}
}
}
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser=data
}
}
}
LazyColumn( LazyColumn(
contentPadding= PaddingValues(top=105.dp, bottom = 20.dp,start=15.dp,end=15.dp), contentPadding= PaddingValues(top=105.dp, bottom = 50.dp,start=15.dp,end=15.dp),
modifier = modifier modifier = modifier
.requiredWidth(width = 412.dp) .requiredWidth(width = 412.dp)
.requiredHeight(height = 915.dp) .requiredHeight(height = 915.dp)
@ -72,7 +126,7 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
item { item {
Row( Row(
modifier = Modifier modifier = Modifier
.requiredWidth(width = 245.dp) .requiredWidth(width = 350.dp)
.requiredHeight(height = 33.dp) .requiredHeight(height = 33.dp)
.offset( .offset(
y=0.dp y=0.dp
@ -83,11 +137,11 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
color = Color(0xff423a99), color = Color(0xff423a99),
style = MaterialTheme.typography.headlineMedium) style = MaterialTheme.typography.headlineMedium)
Text( Text(
text = "#${teg.title}", text = "#${tag?.title}",
color = Color(0xff423a99), color = Color(0xff423a99),
style = MaterialTheme.typography.headlineMedium, style = MaterialTheme.typography.headlineMedium,
modifier = Modifier modifier = Modifier
.offset(x = 60.dp, .offset(x = 20.dp,
y = 0.dp)) y = 0.dp))
} }
} }
@ -104,17 +158,6 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
.requiredWidth(width = 395.dp)) .requiredWidth(width = 395.dp))
} }
item {
Image(
painter = painterResource(id = R.drawable.image3),
contentDescription = "image 3",
modifier = Modifier
.requiredWidth(width = 412.dp)
.requiredHeight(height = 242.dp)
.offset(
y=0.dp
))
}
item { item {
Text( Text(
text = "${article?.text}", text = "${article?.text}",
@ -135,7 +178,7 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
) )
) { ) {
Text( Text(
text = "Комментарии:", text = "Comments:",
color = Color(0xff423a99), color = Color(0xff423a99),
style = TextStyle( style = TextStyle(
fontSize = 32.sp, fontSize = 32.sp,
@ -149,7 +192,6 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
HorizontalDivider( HorizontalDivider(
thickness=5.dp, thickness=5.dp,
modifier = Modifier modifier = Modifier
.requiredWidth(width = 270.dp)
.border(BorderStroke(3.dp, Color(0xff423a99))), color = Color(0xff423a99) .border(BorderStroke(3.dp, Color(0xff423a99))), color = Color(0xff423a99)
) )
HorizontalDivider( HorizontalDivider(
@ -157,18 +199,71 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
modifier = Modifier modifier = Modifier
.align(alignment = Alignment.TopStart) .align(alignment = Alignment.TopStart)
.border(BorderStroke(3.dp, Color(0xff423a99))) .border(BorderStroke(3.dp, Color(0xff423a99)))
.offset(x = 142.dp, .offset(
y = 53.dp) y = 53.dp), color = Color(0xff423a99)
.requiredWidth(width = 270.dp), color = Color(0xff423a99)
) )
} }
} }
item{ item{
allComm.forEach{ comm -> OutlinedTextField(
if(comm.articleId==article.id) { value = textComm,
CommentItem(comm = comm, modifier = Modifier.offset( y = 10.dp)) onValueChange = {
textComm=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Comment") },
placeholder = { Text("Write comment...") },
minLines = 3,
maxLines = 3,
)
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
if(textComm.isNotEmpty()) {
var newComment =
Comment(null, textComm, getUser?.id.toString().toInt(), id.toInt())
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).commentDao().insert(newComment)
}
textComm = ""
}
},
modifier = Modifier
.padding(start = 230.dp)
.fillMaxWidth(0.9f)
.height(40.dp)
) {
Text(text = "Send", fontSize = 20.sp)
}
}
item{
comms.forEach{ comm ->
if(comm.articleId==article?.id && comm.text!="") {
Spacer(modifier = Modifier.padding(0.dp))
HorizontalDivider(
thickness=3.dp,
modifier = Modifier
.border(BorderStroke(3.dp, Color(0xff423a99))), color = Color(0xff423a99)
)
CommentItem(comm = comm, sharedViewModel = sharedViewModel)
} }
} }
} }
} }
} }

View File

@ -21,46 +21,59 @@ import androidx.compose.material3.TextButton
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.rememberDatePickerState import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.pmulabs.basecomponents.navigate.BottomBar
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.designElem.ArticleItem import com.example.pmulabs.basecomponents.navigate.SearchAppBar
import com.example.pmulabs.designElem.BottomBar import com.example.pmulabs.basecomponents.navigate.TopBar
import com.example.pmulabs.designElem.SearchAppBar import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.designElem.SearchViewModel
import com.example.pmulabs.designElem.SearchWidget
import com.example.pmulabs.designElem.SharedViewModel
import com.example.pmulabs.designElem.TopBar
import com.example.pmulabs.graphs.HomeNavGraph import com.example.pmulabs.graphs.HomeNavGraph
import com.example.pmulabs.repository.ArticleRepository import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SearchViewModel
import com.example.pmulabs.viewModels.SearchWidget
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@Composable @Composable
fun MainScreen(navController: NavController, modifier: Modifier = Modifier){ fun MainScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){
val articleRepository=ArticleRepository()
val getAllData= articleRepository.getAllData()
val context = LocalContext.current
val articles = remember { mutableStateListOf<Article>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).articleDao().getAll().collect { data ->
articles.clear()
articles.addAll(data)
}
}
}
LazyColumn( LazyColumn(
modifier=Modifier modifier=Modifier
.background(Color.White) .background(Color.White)
.fillMaxSize(), .fillMaxSize(),
contentPadding = PaddingValues(top=75.dp, bottom = 70.dp, start = 10.dp,end=10.dp), contentPadding = PaddingValues(top=75.dp, bottom = 70.dp, start = 10.dp,end=10.dp),
verticalArrangement = Arrangement.spacedBy(15.dp)){ verticalArrangement = Arrangement.spacedBy(15.dp)){
items(items = getAllData){ article -> items(items = articles){ article ->
ArticleItem(article = article,onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article, sharedViewModel = sharedViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }
@ -68,7 +81,7 @@ fun MainScreen(navController: NavController, modifier: Modifier = Modifier){
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun LoadScreen(navController: NavHostController=rememberNavController(), searchViewModel: SearchViewModel,sharedViewModel: SharedViewModel){ fun LoadScreen(navController: NavHostController=rememberNavController(), searchViewModel: SearchViewModel, sharedViewModel: SharedViewModel){
val searchWidgetState by searchViewModel.searchWidgetState val searchWidgetState by searchViewModel.searchWidgetState
val searchTextState by searchViewModel.searchTextState val searchTextState by searchViewModel.searchTextState

View File

@ -5,43 +5,418 @@ import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
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.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.ArrowDropUp
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable 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.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
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.compose.ui.unit.toSize
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.R import com.example.pmulabs.R
import com.example.pmulabs.designElem.SharedViewModel import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.repository.UserRepository import com.example.pmulabs.designElem.elem.ValidateEmail
import com.example.pmulabs.designElem.elem.isValidEmail
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Date
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) { fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) {
val argument = sharedViewModel.argument.value val argument = sharedViewModel.argument.value
val userRepository =UserRepository()
var getUser=userRepository.getUserById(argument.toString()) val context = LocalContext.current
var getComms=userRepository.getUserComm(argument.toString())
Log.d("UserId", argument.toString()) var openDialogUser by remember { mutableStateOf(false) }
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var nickname by remember { mutableStateOf("") }
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser = data
email=data.email
password=data.password
nickname=data.nickname
}
}
}
val getComms = remember { mutableStateListOf<Comment>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserComms(argument.toString().toInt()).collect { data ->
getComms.clear()
getComms.addAll(data)
}
}
}
val getArticles = remember { mutableStateListOf<Article>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserArticles(argument.toString().toInt()).collect { data ->
getArticles.clear()
getArticles.addAll(data)
}
}
}
val getTags = remember { mutableStateListOf<Tag>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserTags(argument.toString().toInt()).collect { data ->
getTags.clear()
getTags.addAll(data)
}
}
}
//список тэгов
val tags = remember { mutableStateListOf<Tag>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getAll().collect { data ->
tags.clear()
tags.addAll(data)
}
}
}
//список названий тэгов
var tagsNames= remember { mutableStateListOf<String>() }
tags.forEach{teg ->
if(!tagsNames.contains(teg.title)) {
tagsNames.add(teg.title)
}
}
var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") }
var title by remember { mutableStateOf("") }
var tagId by remember { mutableStateOf(0) }
//переменные для dropdown
var expanded by remember { mutableStateOf(false) }
val suggestions = tagsNames
var selectedText by remember { mutableStateOf("") }
var textfieldSize by remember { mutableStateOf(Size.Zero)}
val icon = if (expanded)
Icons.Filled.ArrowDropUp
else
Icons.Filled.ArrowDropDown
if (openDialog) {
AlertDialog(
onDismissRequest = {
openDialog = false
text=""
title=""
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Add your article",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
Box() {
OutlinedTextField(
value = selectedText,
onValueChange = { selectedText = it },
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
.onGloballyPositioned { coordinates ->
textfieldSize = coordinates.size.toSize()
},
label = {Text("Select Tag")},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
trailingIcon = {
Icon(icon,"List of tags",
Modifier.clickable { expanded = !expanded })
}
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.width(with(LocalDensity.current){textfieldSize.width.toDp()})
) {
suggestions.forEach { label ->
DropdownMenuItem(
text= {Text(text=label)},
onClick = { selectedText = label
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).tagDao().getTagByName(selectedText).collect{ tag ->
tagId=tag?.id.toString().toInt()
}
}}
)
}
}
}
OutlinedTextField(
value = title,
onValueChange = {
title=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Article Title") },
placeholder = { Text("Write title of article...") },
minLines = 3,
maxLines = 3,
)
OutlinedTextField(
value = text,
onValueChange = {
text=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Article Text") },
placeholder = { Text("Write article text...") },
minLines = 3,
maxLines = 3,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialog = false
if(title.isNotEmpty() && text.isNotEmpty() && tagId!=null) {
val newArticle = Article(
null, title, text,
Date().time, getUser?.id.toString().toInt(), tagId
)
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).articleDao()
.insert(newArticle)
}
}
},
modifier = Modifier
.padding(start = 100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Add", fontSize = 20.sp)
}
}
}
},
)
}
if (openDialogUser) {
AlertDialog(
onDismissRequest = {
openDialogUser = false
email=getUser?.email.toString()
password=getUser?.password.toString()
nickname=getUser?.nickname.toString()
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Edit your data",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
ValidateEmail(email, {email=it} )
OutlinedTextField(
value = password,
onValueChange = {
password=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Password") },
placeholder = { Text("Write password...") },
minLines = 1,
maxLines = 1,
)
OutlinedTextField(
value = nickname,
onValueChange = {
nickname=it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Nickname") },
placeholder = { Text("Write nickname...") },
minLines = 1,
maxLines = 1,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialogUser = false
if(password.isNotEmpty() && email.isNotEmpty() && isValidEmail(email) && nickname.isNotEmpty()) {
getUser?.password=password
getUser?.email=email
getUser?.nickname=nickname
CoroutineScope(Dispatchers.IO).launch {
getUser?.let {
NewsPortalDatabase.getInstance(context).userDao()
.update(it)
}
}
}
},
modifier = Modifier
.padding(start = 100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Edit", fontSize = 20.sp)
}
}
}
},
)
}
Log.d("UserId", getUser.toString())
LazyColumn( LazyColumn(
contentPadding= PaddingValues(top=5.dp, bottom = 320.dp),
modifier = modifier modifier = modifier
.requiredWidth(width = 412.dp) .requiredWidth(width = 412.dp)
.requiredHeight(height = 915.dp) .requiredHeight(height = 915.dp)
@ -80,7 +455,7 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
.clip(shape = RoundedCornerShape(15.dp)) .clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xffdbdbf1))) .background(color = Color(0xffdbdbf1)))
Text( Text(
text = "${getUser.nickname}", text = "${getUser?.nickname}",
color = Color(0xff423a99), color = Color(0xff423a99),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = TextStyle( style = TextStyle(
@ -108,7 +483,7 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
.clip(shape = RoundedCornerShape(15.dp)) .clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xffdbdbf1))) .background(color = Color(0xffdbdbf1)))
Text( Text(
text = "${getUser.email}", text = "${getUser?.email}",
color = Color(0xff423a99), color = Color(0xff423a99),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = TextStyle( style = TextStyle(
@ -119,6 +494,64 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
.requiredHeight(height = 44.dp) .requiredHeight(height = 44.dp)
.wrapContentHeight(align = Alignment.CenterVertically)) .wrapContentHeight(align = Alignment.CenterVertically))
} }
Box(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 0.dp,
y = 317.dp
)
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99)))
Text(
text = "Add Article!",
color = Color(0xffdbdbf1),
textAlign = TextAlign.Center,
style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
.wrapContentHeight(align = Alignment.CenterVertically)
.clickable { openDialog = true })
}
Box(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 0.dp,
y = 368.dp
)
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99)))
Text(
text = "Edit my Data",
color = Color(0xffdbdbf1),
textAlign = TextAlign.Center,
style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.requiredWidth(width = 200.dp)
.requiredHeight(height = 44.dp)
.wrapContentHeight(align = Alignment.CenterVertically)
.clickable { openDialogUser = true })
}
} }
} }
item { item {
@ -126,10 +559,10 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
modifier = Modifier modifier = Modifier
.offset( .offset(
x = 9.dp, x = 9.dp,
y = 120.dp y = 220.dp
) )
.requiredWidth(width = 393.dp) .requiredWidth(width = 393.dp)
.requiredHeight(height = 342.dp) .requiredHeight(height = 182.dp)
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
@ -139,12 +572,12 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
y = 27.1240234375.dp y = 27.1240234375.dp
) )
.requiredWidth(width = 393.dp) .requiredWidth(width = 393.dp)
.requiredHeight(height = 315.dp) .requiredHeight(height = 155.dp)
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
.requiredWidth(width = 393.dp) .requiredWidth(width = 393.dp)
.requiredHeight(height = 315.dp) .requiredHeight(height = 155.dp)
.clip(shape = RoundedCornerShape(5.dp)) .clip(shape = RoundedCornerShape(5.dp))
.background(color = Color.White) .background(color = Color.White)
.border( .border(
@ -154,27 +587,55 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
) )
LazyColumn( LazyColumn(
contentPadding = PaddingValues( contentPadding = PaddingValues(
top = 38.dp, top = 28.dp,
bottom = 50.dp, bottom = 0.dp,
start = 30.dp, start = 10.dp,
end = 30.dp end = 10.dp
), ),
verticalArrangement = Arrangement.spacedBy(1.dp) verticalArrangement = Arrangement.spacedBy(1.dp)
) { ) {
items(items = getComms) { comment -> if (!getComms.isEmpty()) {
Text( items(items = getComms) { comment ->
text = "${comment.text}", Spacer(modifier = Modifier.padding(5.dp))
color = Color(0xff423a99), Text(
style = TextStyle( text = "${comment.text}",
fontSize = 15.sp, color = Color(0xff423a99),
fontWeight = FontWeight.Bold style = TextStyle(
), fontSize = 15.sp,
modifier = Modifier fontWeight = FontWeight.Bold
.align(alignment = Alignment.TopStart) ),
) modifier = Modifier
.align(alignment = Alignment.TopStart)
.clickable {
navController.navigate(
BottomBarScreen.ArticlePage.passId(
comment.articleId.toString()
)
)
}
)
Spacer(modifier = Modifier.padding(5.dp))
HorizontalDivider(
thickness=3.dp,
modifier = Modifier
.border(BorderStroke(3.dp, Color(0xffdbdbf1))), color = Color(0xffdbdbf1)
)
}
}
else{
item {
Text(
text = "Комментариев пока нет!",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.align(alignment = Alignment.TopStart)
)
}
} }
} }
@ -192,7 +653,235 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
.clip(shape = RoundedCornerShape(15.dp)) .clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99))) .background(color = Color(0xff423a99)))
Text( Text(
text = "Комментарии:", text = "Comments:",
color = Color.White,
style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 24.dp,
y = 0.dp
)
.requiredWidth(width = 210.dp)
.requiredHeight(height = 54.dp)
.wrapContentHeight(align = Alignment.CenterVertically))
}
}
}
item {
Spacer(modifier = Modifier.padding(10.dp))
Box(
modifier = Modifier
.offset(
x = 9.dp,
y = 220.dp
)
.requiredWidth(width = 393.dp)
.requiredHeight(height = 182.dp)
) {
Box(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 0.dp,
y = 27.1240234375.dp
)
.requiredWidth(width = 393.dp)
.requiredHeight(height = 155.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 155.dp)
.clip(shape = RoundedCornerShape(5.dp))
.background(color = Color.White)
.border(
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
shape = RoundedCornerShape(5.dp)
)
)
LazyColumn(
contentPadding = PaddingValues(
top = 28.dp,
bottom = 0.dp,
start = 10.dp,
end = 10.dp
),
verticalArrangement = Arrangement.spacedBy(1.dp)
) {
if (!getArticles.isEmpty()) {
items(items = getArticles) { article ->
Spacer(modifier = Modifier.padding(5.dp))
Text(
text = "${article.title}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.clickable {
navController.navigate(
BottomBarScreen.ArticlePage.passId(
article.id.toString()
)
)
}
)
Spacer(modifier = Modifier.padding(5.dp))
HorizontalDivider(
thickness=3.dp,
modifier = Modifier
.border(BorderStroke(3.dp, Color(0xffdbdbf1))), color = Color(0xffdbdbf1)
)
}
}
else{
item {
Text(
text = "Статей пока нет!",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.align(alignment = Alignment.TopStart)
)
}
}
}
}
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 54.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 54.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99)))
Text(
text = "Articles:",
color = Color.White,
style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 24.dp,
y = 0.dp
)
.requiredWidth(width = 210.dp)
.requiredHeight(height = 54.dp)
.wrapContentHeight(align = Alignment.CenterVertically))
}
}
}
item {
Spacer(modifier = Modifier.padding(10.dp))
Box(
modifier = Modifier
.offset(
x = 9.dp,
y = 220.dp
)
.requiredWidth(width = 393.dp)
.requiredHeight(height = 182.dp)
) {
Box(
modifier = Modifier
.align(alignment = Alignment.TopStart)
.offset(
x = 0.dp,
y = 27.1240234375.dp
)
.requiredWidth(width = 393.dp)
.requiredHeight(height = 155.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 155.dp)
.clip(shape = RoundedCornerShape(5.dp))
.background(color = Color.White)
.border(
border = BorderStroke(3.dp, Color(0xffdbdbf1)),
shape = RoundedCornerShape(5.dp)
)
)
LazyColumn(
contentPadding = PaddingValues(
top = 28.dp,
bottom = 0.dp,
start = 10.dp,
end = 10.dp
),
verticalArrangement = Arrangement.spacedBy(1.dp)
) {
if (!getTags.isEmpty()) {
items(items = getTags) { tag ->
Spacer(modifier = Modifier.padding(5.dp))
Text(
text = "${tag.title}",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.align(alignment = Alignment.TopStart)
.clickable {navController.navigate(BottomBarScreen.SearchByTag.passId(tag.id.toString()))}
)
Spacer(modifier = Modifier.padding(5.dp))
HorizontalDivider(
thickness=3.dp,
modifier = Modifier
.border(BorderStroke(3.dp, Color(0xffdbdbf1))), color = Color(0xffdbdbf1)
)
}
}
else{
item {
Text(
text = "Тэгов пока нет!",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.align(alignment = Alignment.TopStart)
)
}
}
}
}
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 54.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 393.dp)
.requiredHeight(height = 54.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99)))
Text(
text = "Tags:",
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
fontSize = 17.sp, fontSize = 17.sp,

View File

@ -1,25 +1,162 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement 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.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
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.layout.wrapContentHeight
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.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable 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.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color 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.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.designElem.TagItem import com.example.pmulabs.designElem.items.TagItem
import com.example.pmulabs.repository.TegRepository import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun TagsScreen(navController: NavController, modifier: Modifier = Modifier){ fun TagsScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){
val tegRepository= TegRepository() val context = LocalContext.current
val getAllData= tegRepository.getAllData() val tags = remember { mutableStateListOf<Tag>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getAll().collect { data ->
tags.clear()
tags.addAll(data)
}
}
}
val argument = sharedViewModel.argument.value
var getUser by remember { mutableStateOf<User?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao()
.getUserById(argument.toString().toInt()).collect { data ->
getUser=data
}
}
}
var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") }
if (openDialog) {
AlertDialog(
onDismissRequest = {
openDialog = false
text = ""
},
content = {
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(Color.White)
.padding(16.dp),
) {
Text(
text = "Add your tag",
color = Color(0xff423a99),
style = TextStyle(
fontSize = 20.sp,
),
)
OutlinedTextField(
value = text,
onValueChange = {
text = it
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.White,
focusedIndicatorColor = Color(0xff423a99),
focusedLabelColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99)
),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(10.dp),
label = { Text("Tag") },
placeholder = { Text("Write tag...") },
minLines = 3,
maxLines = 3,
)
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
colors = ButtonColors(
containerColor = Color(0xff423a99),
disabledContainerColor = Color(0xff423a99),
contentColor = Color.White,
disabledContentColor = Color.White
),
onClick = {
openDialog = false
if(text.isNotEmpty()) {
val newTag = Tag(null, text, getUser?.id.toString().toInt())
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).tagDao()
.insert(newTag)
}
}
},
modifier = Modifier
.padding(start = 100.dp)
.fillMaxWidth(0.5f)
.height(40.dp)
) {
Text(text = "Add", fontSize = 20.sp)
}
}
}
},
)
}
LazyColumn( LazyColumn(
modifier= Modifier modifier= Modifier
@ -27,9 +164,41 @@ fun TagsScreen(navController: NavController, modifier: Modifier = Modifier){
.fillMaxSize(), .fillMaxSize(),
contentPadding = PaddingValues(top =75.dp, bottom = 10.dp, start = 25.dp,end=25.dp), contentPadding = PaddingValues(top =75.dp, bottom = 10.dp, start = 25.dp,end=25.dp),
verticalArrangement = Arrangement.spacedBy(15.dp)){ verticalArrangement = Arrangement.spacedBy(15.dp)){
items(items = getAllData){ tag -> item{
Box(
modifier = modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
) {
Box(
modifier = Modifier
.requiredWidth(width = 365.dp)
.requiredHeight(height = 58.dp)
.clip(shape = RoundedCornerShape(15.dp))
.background(color = Color(0xff423a99))
.clickable { openDialog=true }
)
Text(
text = "Add Tag!",
color = Color(0xFFFFFFFF),
textAlign = TextAlign.Center,
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.offset(
x = 135.dp,
y = 14.dp
)
)
}
}
items(items = tags){ tag ->
TagItem( TagItem(
teg = tag, teg = tag,
sharedViewModel = sharedViewModel,
onTagClick = {navController.navigate(BottomBarScreen.SearchByTag.passId(tag.id.toString()))} onTagClick = {navController.navigate(BottomBarScreen.SearchByTag.passId(tag.id.toString()))}
) )
} }

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.authScreens
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -28,8 +28,11 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -38,6 +41,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
@ -46,15 +50,18 @@ import androidx.compose.ui.text.style.TextAlign
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.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.ValidateEmail import com.example.pmulabs.designElem.elem.ValidateEmail
import com.example.pmulabs.basecomponents.navigate.isValidEmail import com.example.pmulabs.designElem.elem.isValidEmail
import com.example.pmulabs.designElem.LeftCircles import com.example.pmulabs.designElem.statDesign.LeftCircles
import com.example.pmulabs.designElem.LogoMobile import com.example.pmulabs.designElem.statDesign.LogoMobile
import com.example.pmulabs.designElem.RightCircles import com.example.pmulabs.designElem.statDesign.RightCircles
import com.example.pmulabs.designElem.SharedViewModel
import com.example.pmulabs.graphs.AuthScreen import com.example.pmulabs.graphs.AuthScreen
import com.example.pmulabs.graphs.Graph import com.example.pmulabs.graphs.Graph
import com.example.pmulabs.repository.UserRepository import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -62,8 +69,16 @@ fun EntryScreen(navController: NavController,modifier: Modifier = Modifier, shar
var emailValue by rememberSaveable { mutableStateOf("") } var emailValue by rememberSaveable { mutableStateOf("") }
var passwordValue by rememberSaveable { mutableStateOf("") } var passwordValue by rememberSaveable { mutableStateOf("") }
val userRepository= UserRepository() val context = LocalContext.current
val getAllData= userRepository.getAllData() val users = remember { mutableStateListOf<User>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao().getAll().collect { data ->
users.clear()
users.addAll(data)
}
}
}
val argument = sharedViewModel.argument.value val argument = sharedViewModel.argument.value
var passwordVisibility by rememberSaveable { mutableStateOf(false) } var passwordVisibility by rememberSaveable { mutableStateOf(false) }
@ -188,7 +203,7 @@ fun EntryScreen(navController: NavController,modifier: Modifier = Modifier, shar
), ),
onClick = { onClick = {
if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) { if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) {
getAllData.forEach { user -> users.forEach { user ->
if (user.password == passwordValue && user.email == emailValue) { if (user.password == passwordValue && user.email == emailValue) {
sharedViewModel.setArgument(user.id.toString()) sharedViewModel.setArgument(user.id.toString())
navController.navigate(route = Graph.passUserId(user.id.toString())) { navController.navigate(route = Graph.passUserId(user.id.toString())) {

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.authScreens
import android.util.Log import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -29,8 +29,11 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -39,6 +42,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
@ -47,24 +51,38 @@ import androidx.compose.ui.text.style.TextAlign
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.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.ValidateEmail import com.example.pmulabs.designElem.elem.ValidateEmail
import com.example.pmulabs.basecomponents.navigate.isValidEmail import com.example.pmulabs.designElem.elem.isValidEmail
import com.example.pmulabs.designElem.LeftCircles import com.example.pmulabs.designElem.statDesign.LeftCircles
import com.example.pmulabs.designElem.LogoMobile import com.example.pmulabs.designElem.statDesign.LogoMobile
import com.example.pmulabs.designElem.RightCircles import com.example.pmulabs.designElem.statDesign.RightCircles
import com.example.pmulabs.graphs.AuthScreen import com.example.pmulabs.graphs.AuthScreen
import com.example.pmulabs.graphs.Graph import com.example.pmulabs.graphs.Graph
import com.example.pmulabs.repository.UserRepository import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier) { fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) {
var emailValue by rememberSaveable { mutableStateOf("") } var emailValue by rememberSaveable { mutableStateOf("") }
var passwordValue by rememberSaveable { mutableStateOf("") } var passwordValue by rememberSaveable { mutableStateOf("") }
var nicknameValue by rememberSaveable { mutableStateOf("") } var nicknameValue by rememberSaveable { mutableStateOf("") }
val userRepository= UserRepository() val context = LocalContext.current
val getAllData= userRepository.getAllData() val users = remember { mutableStateListOf<User>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao().getAll().collect { data ->
users.clear()
users.addAll(data)
}
}
}
var passwordVisibility by rememberSaveable { mutableStateOf(false) } var passwordVisibility by rememberSaveable { mutableStateOf(false) }
val emailRegex = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+".toRegex() val emailRegex = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+".toRegex()
@ -206,14 +224,37 @@ fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier) {
disabledContentColor = Color.White disabledContentColor = Color.White
), ),
onClick = { onClick = {
var isExist = false;
if (passwordValue.isNotEmpty() && isValidEmail(emailValue) && nicknameValue.isNotEmpty()) { if (passwordValue.isNotEmpty() && isValidEmail(emailValue) && nicknameValue.isNotEmpty()) {
if(!isUserExist(passwordValue,emailValue,nicknameValue)){ users.forEach { user ->
navController.navigate(route = Graph.MAIN){ if (user.email == emailValue || user.nickname == nicknameValue) {
popUpTo(Graph.MAIN) Log.d("User already exist. User id: ", user.id.toString())
isExist = true
}
}
if (!isExist) {
var newUser = User(null, nicknameValue, emailValue, passwordValue, "user")
CoroutineScope(Dispatchers.IO).launch {
NewsPortalDatabase.getInstance(context).userDao().insert(newUser)
NewsPortalDatabase.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()
)
)
}
}
}
}
} }
} }
} }
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth(0.5f) .fillMaxWidth(0.5f)
@ -251,21 +292,6 @@ fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier) {
} }
} }
fun isUserExist(passwordValue: String, emailValue: String, nicknameValue: String): Boolean {
val userRepository = UserRepository()
val getAllData = userRepository.getAllData()
if (passwordValue.isNotEmpty() && isValidEmail(emailValue) && nicknameValue.isNotEmpty()) {
getAllData.forEach { user ->
if (user.email == emailValue || user.nickname == nicknameValue) {
Log.d("User already exist. User id: ", user.id.toString())
return true
}
}
}
return false
}
/* /*
@Composable @Composable

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.authScreens
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -22,9 +22,9 @@ import androidx.compose.ui.text.style.TextAlign
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.NavController import androidx.navigation.NavController
import com.example.pmulabs.designElem.LeftCircles import com.example.pmulabs.designElem.statDesign.LeftCircles
import com.example.pmulabs.designElem.LogoMobile import com.example.pmulabs.designElem.statDesign.LogoMobile
import com.example.pmulabs.designElem.RightCircles import com.example.pmulabs.designElem.statDesign.RightCircles
import com.example.pmulabs.graphs.AuthScreen import com.example.pmulabs.graphs.AuthScreen
@Composable @Composable

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.filterScreens
import android.util.Log import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -9,22 +9,37 @@ import androidx.compose.foundation.layout.fillMaxSize
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.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.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.BackButton
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.basecomponents.navigate.CALENDAR_ARGUMENT_DATE import com.example.pmulabs.basecomponents.navigate.CALENDAR_ARGUMENT_DATE
import com.example.pmulabs.designElem.ArticleItem import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.repository.ArticleRepository import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@Composable @Composable
fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier){ fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){
val context = LocalContext.current
val articleRepository= ArticleRepository() val articles = remember { mutableStateListOf<Article>() }
val getAllData= articleRepository.getAllData() LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).articleDao().getAll().collect { data ->
articles.clear()
articles.addAll(data)
}
}
}
var date=navController.currentBackStackEntry?.arguments?.getString(CALENDAR_ARGUMENT_DATE).toString() var date=navController.currentBackStackEntry?.arguments?.getString(CALENDAR_ARGUMENT_DATE).toString()
Log.d("date: ",date) Log.d("date: ",date)
val formatter = SimpleDateFormat("dd-MMMM-YY") val formatter = SimpleDateFormat("dd-MMMM-YY")
@ -39,11 +54,12 @@ fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier)
BackButton(modifier=Modifier BackButton(modifier=Modifier
.clickable { navController.popBackStack()}) .clickable { navController.popBackStack()})
} }
items(items = getAllData){ article -> items(items = articles){ article ->
val publishDate=formatter.format(article.publishDate) val publishDate=formatter.format(article.publishDate)
if(publishDate==date) { if(publishDate==date) {
ArticleItem( ArticleItem(
article = article, article = article,
sharedViewModel=sharedViewModel,
onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))} onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}
) )
} }

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.filterScreens
import android.util.Log import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -9,21 +9,36 @@ import androidx.compose.foundation.layout.fillMaxSize
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.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.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.BackButton
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY import com.example.pmulabs.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY
import com.example.pmulabs.designElem.ArticleItem import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.repository.ArticleRepository import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifier){ fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){
val context = LocalContext.current
val articleRepository= ArticleRepository() val articles = remember { mutableStateListOf<Article>() }
val getAllData= articleRepository.getAllData() LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).articleDao().getAll().collect { data ->
articles.clear()
articles.addAll(data)
}
}
}
var id=navController.currentBackStackEntry?.arguments?.getString(SEARCHBYTAG_ARGUMENT_KEY).toString() var id=navController.currentBackStackEntry?.arguments?.getString(SEARCHBYTAG_ARGUMENT_KEY).toString()
Log.d("id: ",id) Log.d("id: ",id)
@ -36,9 +51,9 @@ fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifie
BackButton(modifier=Modifier BackButton(modifier=Modifier
.clickable { navController.popBackStack()}) .clickable { navController.popBackStack()})
} }
items(items = getAllData){ article -> items(items = articles){ article ->
if(article.tagId.toString()==id) { if(article.tagId.toString()==id) {
ArticleItem(article = article, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article, sharedViewModel = sharedViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.screensMobile package com.example.pmulabs.screensMobile.filterScreens
import android.util.Log import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -9,21 +9,36 @@ import androidx.compose.foundation.layout.fillMaxSize
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.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.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.BackButton
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.basecomponents.navigate.SEARCH_ARGUMENT_TEXT import com.example.pmulabs.basecomponents.navigate.SEARCH_ARGUMENT_TEXT
import com.example.pmulabs.designElem.ArticleItem import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.repository.ArticleRepository import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun SearchScreen(navController: NavController, modifier: Modifier = Modifier){ fun SearchScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){
val context = LocalContext.current
val articleRepository= ArticleRepository() val articles = remember { mutableStateListOf<Article>() }
val getAllData= articleRepository.getAllData() LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).articleDao().getAll().collect { data ->
articles.clear()
articles.addAll(data)
}
}
}
var text=navController.currentBackStackEntry?.arguments?.getString(SEARCH_ARGUMENT_TEXT).toString() var text=navController.currentBackStackEntry?.arguments?.getString(SEARCH_ARGUMENT_TEXT).toString()
Log.d("text: ",text) Log.d("text: ",text)
@ -37,9 +52,9 @@ fun SearchScreen(navController: NavController, modifier: Modifier = Modifier){
BackButton(modifier=Modifier BackButton(modifier=Modifier
.clickable { navController.popBackStack()}) .clickable { navController.popBackStack()})
} }
items(items = getAllData){ article -> items(items = articles){ article ->
if(article.title.contains(text)) { if(article.title.contains(text)) {
ArticleItem(article = article,onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article,sharedViewModel=sharedViewModel,onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }

View File

@ -1,10 +1,9 @@
package com.example.pmulabs.designElem package com.example.pmulabs.viewModels
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.example.pmulabs.screensMobile.MainScreen
class SearchViewModel : ViewModel() { class SearchViewModel : ViewModel() {

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.viewModels
enum class SearchWidget { enum class SearchWidget {
OPENED, OPENED,

View File

@ -1,4 +1,4 @@
package com.example.pmulabs.designElem package com.example.pmulabs.viewModels
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel

View File

@ -2,4 +2,5 @@
plugins { plugins {
id("com.android.application") version "8.1.1" apply false id("com.android.application") version "8.1.1" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false id("org.jetbrains.kotlin.android") version "1.8.10" apply false
id("com.google.devtools.ksp") version "1.8.20-1.0.11" apply false
} }