added repositories, partial transfer of business logic to ViewModel files.

This commit is contained in:
AnnZhimol 2023-11-21 15:43:03 +04:00
parent a2add02c8d
commit 41536e89d9
37 changed files with 544 additions and 270 deletions

3
.idea/misc.xml generated
View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="corretto-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">

View File

@ -11,6 +11,7 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.PMULabs" android:theme="@style/Theme.PMULabs"
android:name=".NewsPortalApplication"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"

View File

@ -4,20 +4,22 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.pmulabs.viewModels.CurrentUserViewModel
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.AppViewModelProvider
import com.example.pmulabs.viewModels.SearchViewModel 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()
private val sharedViewModel: SharedViewModel by viewModels() private val currentUserViewModel: CurrentUserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
PMULabsTheme { PMULabsTheme {
RootNavigationGraph(navController = rememberNavController(),searchViewModel, sharedViewModel = sharedViewModel) RootNavigationGraph(navController = rememberNavController(),searchViewModel, currentUserViewModel = viewModel(factory = AppViewModelProvider.Factory))
} }
} }
} }

View File

@ -0,0 +1,14 @@
package com.example.pmulabs
import android.app.Application
import com.example.pmulabs.room.AppContainer
import com.example.pmulabs.room.AppDataContainer
class NewsPortalApplication : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}

View File

@ -1,5 +1,6 @@
package com.example.pmulabs.designElem.items package com.example.pmulabs.designElem.items
import android.annotation.SuppressLint
import android.util.Log import android.util.Log
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
@ -39,12 +40,11 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
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.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.saveable.rememberSaveable import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue 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
@ -52,7 +52,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Size 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.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity 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
@ -60,60 +59,35 @@ 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.compose.ui.unit.toSize import androidx.compose.ui.unit.toSize
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.pmulabs.R 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.Article
import com.example.pmulabs.room.models.Tag import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.ArticleItemViewModel
import kotlinx.coroutines.CoroutineScope import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick: () -> Unit,sharedViewModel: SharedViewModel) { fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick: () -> Unit, articleItemViewModel: ArticleItemViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
articleItemViewModel.setTagList()
//список тэгов //список тэгов
val tags = remember { mutableStateListOf<Tag>() } val tags = mutableStateOf<List<Tag>>(articleItemViewModel.tagList)
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getAll().collect { data ->
tags.clear()
tags.addAll(data)
}
}
}
//количество комментариев для статьи //количество комментариев для статьи
var countComm by rememberSaveable { mutableStateOf(0) } var countComm = remember{mutableStateOf<Int?>(0)}
LaunchedEffect(Unit) { coroutineScope.launch {
withContext(Dispatchers.IO) { countComm.value = articleItemViewModel.getCount(article.id)
countComm = article.id?.let {
NewsPortalDatabase.getInstance(context).commentDao().getCountComment(
it
)
}?.toInt() ?: 0
}
} }
//текущий пользователь //текущий пользователь
val argument = sharedViewModel.argument.value var getUser by remember { mutableStateOf(currentUserViewModel.user) }
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 formatter = SimpleDateFormat("dd.MM.YY")
@ -122,7 +96,7 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
//список названий тэгов //список названий тэгов
var tagName="" var tagName=""
var tagsNames= remember { mutableStateListOf<String>() } var tagsNames= remember { mutableStateListOf<String>() }
tags.forEach{teg -> tags.value.forEach{teg ->
if(article.tagId == teg.id){ if(article.tagId == teg.id){
tagName=teg.title tagName=teg.title
} }
@ -148,14 +122,6 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
else else
Icons.Filled.ArrowDropDown Icons.Filled.ArrowDropDown
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).tagDao().getTagById(tagId).collect { data ->
selectedText=data.title
}
}
}
//диалоговое окно //диалоговое окно
if (openDialog) { if (openDialog) {
AlertDialog( AlertDialog(
@ -211,11 +177,10 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
DropdownMenuItem( DropdownMenuItem(
text= {Text(text=label)}, text= {Text(text=label)},
onClick = { selectedText = label onClick = { selectedText = label
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).tagDao().getTagByName(selectedText).collect{ tag -> tagId= articleItemViewModel.getTagByName(selectedText).id!!
tagId=tag?.id.toString().toInt() }
} }
}}
) )
} }
} }
@ -282,8 +247,8 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
if(tagId!=null) { if(tagId!=null) {
article.tagId = tagId article.tagId = tagId
} }
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).articleDao().update(article) articleItemViewModel.updateArticle(article)
} }
}, },
modifier = Modifier modifier = Modifier
@ -392,8 +357,8 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
y = 0.dp) y = 0.dp)
.requiredHeight(30.dp) .requiredHeight(30.dp)
.clickable { .clickable {
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).articleDao().delete(article) articleItemViewModel.deleteArticle(article)
} }
}, },
imageVector = Icons.Filled.Close, imageVector = Icons.Filled.Close,
@ -441,7 +406,7 @@ fun ArticleItem(article: Article, modifier: Modifier = Modifier, onArticleClick:
.requiredWidth(width = 25.dp) .requiredWidth(width = 25.dp)
.requiredHeight(height = 22.dp)) .requiredHeight(height = 22.dp))
Text( Text(
text = "${countComm}", text = "${countComm.value}",
color = Color(0xff423a99), color = Color(0xff423a99),
style = TextStyle( style = TextStyle(
fontSize = 17.sp), fontSize = 17.sp),

View File

@ -1,5 +1,6 @@
package com.example.pmulabs.designElem.items package com.example.pmulabs.designElem.items
import android.annotation.SuppressLint
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -24,57 +25,44 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
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.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
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.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.TextDecoration import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.pmulabs.room.database.NewsPortalDatabase import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.pmulabs.room.models.Comment import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.User import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import kotlinx.coroutines.CoroutineScope import com.example.pmulabs.viewModels.CommentItemViewModel
import kotlinx.coroutines.Dispatchers import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@SuppressLint("CoroutineCreationDuringComposition", "UnrememberedMutableState")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun CommentItem(modifier: Modifier = Modifier,comm : Comment,sharedViewModel: SharedViewModel) { fun CommentItem(modifier: Modifier = Modifier, comm : Comment,commentItemViewModel: CommentItemViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
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 getUser by remember { mutableStateOf(currentUserViewModel.user) }
var openDialog by remember { mutableStateOf(false) } var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf(comm.text) } var text by remember { mutableStateOf(comm.text) }
val coroutineScope = rememberCoroutineScope()
commentItemViewModel.getUsersByArticle(comm.articleId)
var users by mutableStateOf(commentItemViewModel.userListByArticle)
var user by mutableStateOf<User?>(null)
for(item in users){
if(comm.userId==item.id){
user=item
}
}
if (openDialog) { if (openDialog) {
AlertDialog( AlertDialog(
@ -131,8 +119,8 @@ fun CommentItem(modifier: Modifier = Modifier,comm : Comment,sharedViewModel: Sh
onClick = { onClick = {
openDialog = false openDialog = false
comm.text=text comm.text=text
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).commentDao().update(comm) commentItemViewModel.updateComment(comm)
} }
}, },
modifier = Modifier modifier = Modifier
@ -169,7 +157,6 @@ fun CommentItem(modifier: Modifier = Modifier,comm : Comment,sharedViewModel: Sh
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
), ),
) )
if(getUser?.id==comm.userId) { if(getUser?.id==comm.userId) {
Icon( Icon(
modifier=Modifier modifier=Modifier
@ -185,8 +172,8 @@ fun CommentItem(modifier: Modifier = Modifier,comm : Comment,sharedViewModel: Sh
modifier=Modifier modifier=Modifier
.requiredHeight(20.dp) .requiredHeight(20.dp)
.clickable { .clickable {
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).commentDao().delete(comm) commentItemViewModel.deleteComment(comm)
} }
}, },
imageVector = Icons.Filled.Close, imageVector = Icons.Filled.Close,

View File

@ -26,49 +26,36 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
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.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
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.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.lifecycle.viewmodel.compose.viewModel
import com.example.pmulabs.R 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.Tag
import com.example.pmulabs.room.models.User import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.CoroutineScope import com.example.pmulabs.viewModels.TagItemViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit,sharedViewModel: SharedViewModel) { fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit, viewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), tagViewModel: TagItemViewModel =viewModel(factory = AppViewModelProvider.Factory)) {
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 getUser by remember { mutableStateOf(viewModel.user) }
var openDialog by remember { mutableStateOf(false) } var openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf(teg.title) } var text by remember { mutableStateOf(teg.title) }
val coroutineScope = rememberCoroutineScope()
if (openDialog) { if (openDialog) {
AlertDialog( AlertDialog(
@ -125,8 +112,8 @@ fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit,shar
onClick = { onClick = {
openDialog = false openDialog = false
teg.title = text teg.title = text
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).tagDao().update(teg) tagViewModel.updateTag(teg)
} }
}, },
modifier = Modifier modifier = Modifier
@ -207,8 +194,8 @@ fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit,shar
y = 9.dp y = 9.dp
) )
.clickable { .clickable {
CoroutineScope(Dispatchers.IO).launch { coroutineScope.launch {
NewsPortalDatabase.getInstance(context).tagDao().delete(teg) tagViewModel.deleteTag(teg)
} }
}, },
imageVector = Icons.Filled.Close, imageVector = Icons.Filled.Close,
@ -218,3 +205,4 @@ fun TagItem(teg: Tag, modifier: Modifier = Modifier, onTagClick: () -> Unit,shar
} }
} }
} }

View File

@ -8,9 +8,9 @@ import androidx.navigation.navigation
import com.example.pmulabs.screensMobile.authScreens.EntryScreen import com.example.pmulabs.screensMobile.authScreens.EntryScreen
import com.example.pmulabs.screensMobile.authScreens.RegisterScreen import com.example.pmulabs.screensMobile.authScreens.RegisterScreen
import com.example.pmulabs.screensMobile.authScreens.SplashScreen import com.example.pmulabs.screensMobile.authScreens.SplashScreen
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.CurrentUserViewModel
fun NavGraphBuilder.authNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){ fun NavGraphBuilder.authNavGraph(navController: NavHostController, currentUserViewModel: CurrentUserViewModel){
navigation( navigation(
route=Graph.AUTHENTICATION, route=Graph.AUTHENTICATION,
startDestination = AuthScreen.Splash.route startDestination = AuthScreen.Splash.route
@ -19,10 +19,10 @@ fun NavGraphBuilder.authNavGraph(navController: NavHostController,sharedViewMode
SplashScreen(navController = navController, Modifier) SplashScreen(navController = navController, Modifier)
} }
composable(route=AuthScreen.Entry.route){ composable(route=AuthScreen.Entry.route){
EntryScreen(navController = navController, Modifier,sharedViewModel) EntryScreen(navController = navController, Modifier,currentUserViewModel)
} }
composable(route=AuthScreen.Register.route){ composable(route=AuthScreen.Register.route){
RegisterScreen(navController = navController, Modifier,sharedViewModel) RegisterScreen(navController = navController, Modifier,currentUserViewModel)
} }
} }
} }

View File

@ -2,6 +2,7 @@ package com.example.pmulabs.graphs
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.NavType import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
@ -12,6 +13,7 @@ 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.viewModels.CurrentUserViewModel
import com.example.pmulabs.screensMobile.ArticlePageScreen import com.example.pmulabs.screensMobile.ArticlePageScreen
import com.example.pmulabs.screensMobile.CoopScreen import com.example.pmulabs.screensMobile.CoopScreen
import com.example.pmulabs.screensMobile.InfoScreen import com.example.pmulabs.screensMobile.InfoScreen
@ -21,10 +23,10 @@ import com.example.pmulabs.screensMobile.TagsScreen
import com.example.pmulabs.screensMobile.filterScreens.CalendarScreen import com.example.pmulabs.screensMobile.filterScreens.CalendarScreen
import com.example.pmulabs.screensMobile.filterScreens.SearchByTagScreen import com.example.pmulabs.screensMobile.filterScreens.SearchByTagScreen
import com.example.pmulabs.screensMobile.filterScreens.SearchScreen import com.example.pmulabs.screensMobile.filterScreens.SearchScreen
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
@Composable @Composable
fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewModel){ fun HomeNavGraph(navController: NavHostController, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
NavHost( NavHost(
navController = navController, navController = navController,
route = Graph.MAIN, route = Graph.MAIN,
@ -33,7 +35,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
composable( composable(
route=BottomBarScreen.Main.route route=BottomBarScreen.Main.route
){ ){
MainScreen(navController,Modifier,sharedViewModel) MainScreen(navController,Modifier,currentUserViewModel)
} }
composable( composable(
route=BottomBarScreen.SearchByTag.route, route=BottomBarScreen.SearchByTag.route,
@ -41,7 +43,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
SearchByTagScreen(navController,Modifier,sharedViewModel) SearchByTagScreen(navController,Modifier,currentUserViewModel)
} }
composable( composable(
route=BottomBarScreen.ArticlePage.route, route=BottomBarScreen.ArticlePage.route,
@ -49,7 +51,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
ArticlePageScreen(navController,Modifier,sharedViewModel) ArticlePageScreen(navController,Modifier,currentUserViewModel)
} }
composable( composable(
route=BottomBarScreen.Search.route, route=BottomBarScreen.Search.route,
@ -57,7 +59,7 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
SearchScreen(navController,Modifier,sharedViewModel) SearchScreen(navController,Modifier,currentUserViewModel)
} }
composable( composable(
route=BottomBarScreen.Calendar.route, route=BottomBarScreen.Calendar.route,
@ -65,10 +67,10 @@ fun HomeNavGraph(navController: NavHostController,sharedViewModel: SharedViewMod
type= NavType.StringType type= NavType.StringType
}) })
){ ){
CalendarScreen(navController,Modifier,sharedViewModel) CalendarScreen(navController,Modifier,currentUserViewModel)
} }
composable(route=BottomBarScreen.Profile.route){ composable(route=BottomBarScreen.Profile.route){
ProfileScreen(navController,Modifier,sharedViewModel) ProfileScreen(navController,Modifier,currentUserViewModel)
} }
composable(route=BottomBarScreen.Info.route){ composable(route=BottomBarScreen.Info.route){
InfoScreen(navController,Modifier) InfoScreen(navController,Modifier)
@ -77,7 +79,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,sharedViewModel) TagsScreen(navController,Modifier,currentUserViewModel)
} }
} }
} }

View File

@ -1,30 +1,32 @@
package com.example.pmulabs.graphs package com.example.pmulabs.graphs
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.NavType 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.viewModels.CurrentUserViewModel
import com.example.pmulabs.screensMobile.LoadScreen import com.example.pmulabs.screensMobile.LoadScreen
import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SearchViewModel 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, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
NavHost( NavHost(
navController=navController, navController=navController,
route = Graph.ROOT, route = Graph.ROOT,
startDestination = Graph.AUTHENTICATION startDestination = Graph.AUTHENTICATION
){ ){
authNavGraph(navController=navController,sharedViewModel) authNavGraph(navController=navController,currentUserViewModel)
composable(route=Graph.MAIN, composable(route=Graph.MAIN,
arguments = listOf(navArgument(USERID_ARGUMENT){ arguments = listOf(navArgument(USERID_ARGUMENT){
type= NavType.StringType type= NavType.StringType
})){ })){
LoadScreen(searchViewModel = searchViewModel, sharedViewModel = sharedViewModel) LoadScreen(searchViewModel = searchViewModel, currentUserViewModel = currentUserViewModel)
} }
} }
} }

View File

@ -0,0 +1,38 @@
package com.example.pmulabs.room
import android.content.Context
import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.repository.ArticleRepository
import com.example.pmulabs.room.repository.CommentRepository
import com.example.pmulabs.room.repository.OfflineArticleRepository
import com.example.pmulabs.room.repository.OfflineCommentRepository
import com.example.pmulabs.room.repository.OfflineTagRepository
import com.example.pmulabs.room.repository.OfflineUserRepository
import com.example.pmulabs.room.repository.TagRepository
import com.example.pmulabs.room.repository.UserRepository
interface AppContainer {
val userRepository: UserRepository
val articleRepository: ArticleRepository
val tagRepository: TagRepository
val commentRepository: CommentRepository
}
class AppDataContainer(private val context: Context) : AppContainer {
override val userRepository: UserRepository by lazy {
OfflineUserRepository(NewsPortalDatabase.getInstance(context).userDao())
}
override val articleRepository: ArticleRepository by lazy {
OfflineArticleRepository(NewsPortalDatabase.getInstance(context).articleDao())
}
override val tagRepository: TagRepository by lazy {
OfflineTagRepository(NewsPortalDatabase.getInstance(context).tagDao())
}
override val commentRepository: CommentRepository by lazy {
OfflineCommentRepository(NewsPortalDatabase.getInstance(context).commentDao())
}
companion object {
const val TIMEOUT = 5000L
}
}

View File

@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface ArticleDao { interface ArticleDao {
@Query("select * from article ORDER BY publish_date ASC") @Query("select * from article")
fun getAll(): Flow<List<Article>> fun getAll(): Flow<List<Article>>
@Query("select * from article where article.id = :idArticle") @Query("select * from article where article.id = :idArticle")

View File

@ -10,11 +10,11 @@ import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface CommentDao { interface CommentDao {
@Query("select * from comment ORDER BY id DESC") @Query("select * from comment")
fun getAll(): Flow<List<Comment>> fun getAll(): Flow<List<Comment>>
@Query("select COUNT(*) from comment WHERE comment.text!='' AND comment.article_id= :idArticle") @Query("select COUNT(*) from comment WHERE comment.text!='' AND comment.article_id= :idArticle")
fun getCountComment(idArticle : Int) : Int fun getCountComment(idArticle : Int?) : Int
@Insert @Insert
suspend fun insert(comment: Comment) suspend fun insert(comment: Comment)

View File

@ -17,7 +17,7 @@ interface UserDao {
fun getAll(): Flow<List<User>> fun getAll(): Flow<List<User>>
@Query("select * from user where user.id = :idUser") @Query("select * from user where user.id = :idUser")
fun getUserById(idUser: Int): Flow<User> fun getUserById(idUser: Int?): Flow<User>
@Query("select * from comment WHERE comment.text!='' AND comment.user_id= :idUser") @Query("select * from comment WHERE comment.text!='' AND comment.user_id= :idUser")
fun getUserComms(idUser: Int): Flow<List<Comment>> fun getUserComms(idUser: Int): Flow<List<Comment>>

View File

@ -0,0 +1,12 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.models.Article
import kotlinx.coroutines.flow.Flow
interface ArticleRepository {
suspend fun insertArticle(article: Article)
suspend fun updateArticle(article: Article)
suspend fun deleteArticle(article: Article)
fun getAllArticles(): Flow<List<Article>>
fun getArticleById(idArticle: Int): Flow<Article>
}

View File

@ -0,0 +1,12 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.models.Comment
import kotlinx.coroutines.flow.Flow
interface CommentRepository {
suspend fun insertComment(comment: Comment)
suspend fun updateComment(comment: Comment)
suspend fun deleteComment(comment: Comment)
fun getAllComments(): Flow<List<Comment>>
fun getCountComment(idArticle : Int?) : Int
}

View File

@ -0,0 +1,13 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.dao.ArticleDao
import com.example.pmulabs.room.models.Article
import kotlinx.coroutines.flow.Flow
class OfflineArticleRepository(private val articleDao: ArticleDao) : ArticleRepository {
override suspend fun insertArticle(article: Article) = articleDao.insert(article)
override suspend fun updateArticle(article: Article) = articleDao.update(article)
override suspend fun deleteArticle(article: Article) = articleDao.delete(article)
override fun getAllArticles(): Flow<List<Article>> = articleDao.getAll()
override fun getArticleById(idArticle: Int): Flow<Article> = articleDao.getArticleById(idArticle)
}

View File

@ -0,0 +1,13 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.dao.CommentDao
import com.example.pmulabs.room.models.Comment
import kotlinx.coroutines.flow.Flow
class OfflineCommentRepository(private val commentDao: CommentDao) : CommentRepository {
override suspend fun insertComment(comment: Comment) = commentDao.insert(comment)
override suspend fun updateComment(comment: Comment) = commentDao.update(comment)
override suspend fun deleteComment(comment: Comment) = commentDao.delete(comment)
override fun getAllComments(): Flow<List<Comment>> = commentDao.getAll()
override fun getCountComment(idArticle : Int?) : Int = commentDao.getCountComment(idArticle)
}

View File

@ -0,0 +1,14 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.dao.TagDao
import com.example.pmulabs.room.models.Tag
import kotlinx.coroutines.flow.Flow
class OfflineTagRepository(private val tagDao: TagDao) : TagRepository {
override suspend fun insertTag(tag: Tag) = tagDao.insert(tag)
override suspend fun updateTag(tag: Tag) = tagDao.update(tag)
override suspend fun deleteTag(tag: Tag) = tagDao.delete(tag)
override fun getAllTags(): Flow<List<Tag>> = tagDao.getAll()
override fun getTagById(idTag: Int): Flow<Tag> = tagDao.getTagById(idTag)
override fun getTagByName(nameTag: String): Flow<Tag> = tagDao.getTagByName(nameTag)
}

View File

@ -0,0 +1,19 @@
package com.example.pmulabs.room.repository
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.flow.Flow
class OfflineUserRepository(private val userDao: UserDao) : UserRepository {
override suspend fun insertUser(user: User) = userDao.insert(user)
override suspend fun updateUser(user: User) = userDao.update(user)
override suspend fun deleteUser(user: User) = userDao.delete(user)
override fun getAllUsers(): Flow<List<User>> = userDao.getAll()
override fun getUserById(idUser: Int?): Flow<User> = userDao.getUserById(idUser)
override fun getUserComms(idUser: Int): Flow<List<Comment>> = userDao.getUserComms(idUser)
override fun getUserArticles(idUser: Int): Flow<List<Article>> = userDao.getUserArticles(idUser)
override fun getUserTags(idUser: Int): Flow<List<Tag>> = userDao.getUserTags(idUser)
}

View File

@ -0,0 +1,13 @@
package com.example.pmulabs.room.repository
import com.example.pmulabs.room.models.Tag
import kotlinx.coroutines.flow.Flow
interface TagRepository {
suspend fun insertTag(tag: Tag)
suspend fun updateTag(tag: Tag)
suspend fun deleteTag(tag: Tag)
fun getAllTags(): Flow<List<Tag>>
fun getTagById(idTag: Int): Flow<Tag>
fun getTagByName(nameTag: String): Flow<Tag>
}

View File

@ -0,0 +1,18 @@
package com.example.pmulabs.room.repository
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
interface UserRepository {
suspend fun insertUser(user: User)
suspend fun updateUser(user: User)
suspend fun deleteUser(user: User)
fun getAllUsers(): Flow<List<User>>
fun getUserById(idUser: Int?): Flow<User>
fun getUserComms(idUser: Int): Flow<List<Comment>>
fun getUserArticles(idUser: Int): Flow<List<Article>>
fun getUserTags(idUser: Int): Flow<List<Tag>>
}

View File

@ -42,6 +42,7 @@ 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.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.basecomponents.navigate.ARTICLE_ARGUMENT_KEY import com.example.pmulabs.basecomponents.navigate.ARTICLE_ARGUMENT_KEY
import com.example.pmulabs.designElem.elem.BackButton import com.example.pmulabs.designElem.elem.BackButton
@ -51,7 +52,8 @@ import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Comment import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -61,8 +63,8 @@ import java.util.Date
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) { fun ArticlePageScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val argument = sharedViewModel.argument.value val argument = currentUserViewModel.argument.value
val context = LocalContext.current val context = LocalContext.current
var id=navController.currentBackStackEntry?.arguments?.getString(ARTICLE_ARGUMENT_KEY).toString() var id=navController.currentBackStackEntry?.arguments?.getString(ARTICLE_ARGUMENT_KEY).toString()
@ -260,7 +262,7 @@ fun ArticlePageScreen(navController: NavController,modifier: Modifier = Modifier
modifier = Modifier modifier = Modifier
.border(BorderStroke(3.dp, Color(0xff423a99))), color = Color(0xff423a99) .border(BorderStroke(3.dp, Color(0xff423a99))), color = Color(0xff423a99)
) )
CommentItem(comm = comm, sharedViewModel = sharedViewModel) CommentItem(comm = comm, currentUserViewModel = currentUserViewModel)
} }
} }

View File

@ -33,6 +33,7 @@ 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.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
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
@ -41,12 +42,13 @@ import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
import com.example.pmulabs.basecomponents.navigate.SearchAppBar import com.example.pmulabs.basecomponents.navigate.SearchAppBar
import com.example.pmulabs.basecomponents.navigate.TopBar import com.example.pmulabs.basecomponents.navigate.TopBar
import com.example.pmulabs.designElem.items.ArticleItem import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.viewModels.CurrentUserViewModel
import com.example.pmulabs.graphs.HomeNavGraph import com.example.pmulabs.graphs.HomeNavGraph
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SearchViewModel import com.example.pmulabs.viewModels.SearchViewModel
import com.example.pmulabs.viewModels.SearchWidget import com.example.pmulabs.viewModels.SearchWidget
import com.example.pmulabs.viewModels.SharedViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -54,7 +56,7 @@ import java.util.Calendar
import java.util.Date import java.util.Date
@Composable @Composable
fun MainScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){ fun MainScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val context = LocalContext.current val context = LocalContext.current
val articles = remember { mutableStateListOf<Article>() } val articles = remember { mutableStateListOf<Article>() }
@ -73,7 +75,7 @@ fun MainScreen(navController: NavController, modifier: Modifier = Modifier,share
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 = articles){ article -> items(items = articles){ article ->
ArticleItem(article = article, sharedViewModel = sharedViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article, currentUserViewModel = currentUserViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }
@ -81,7 +83,7 @@ fun MainScreen(navController: NavController, modifier: Modifier = Modifier,share
@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, currentUserViewModel: CurrentUserViewModel){
val searchWidgetState by searchViewModel.searchWidgetState val searchWidgetState by searchViewModel.searchWidgetState
val searchTextState by searchViewModel.searchTextState val searchTextState by searchViewModel.searchTextState
@ -244,7 +246,7 @@ fun LoadScreen(navController: NavHostController=rememberNavController(), searchV
) { ) {
Modifier Modifier
.padding(it) .padding(it)
HomeNavGraph(navController = navController,sharedViewModel) HomeNavGraph(navController = navController,currentUserViewModel)
} }
} }

View File

@ -60,6 +60,7 @@ 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.compose.ui.unit.toSize
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.R import com.example.pmulabs.R
import com.example.pmulabs.basecomponents.navigate.BottomBarScreen import com.example.pmulabs.basecomponents.navigate.BottomBarScreen
@ -69,8 +70,8 @@ import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Comment import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.Tag import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -79,34 +80,20 @@ import java.util.Date
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) { fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
val argument = sharedViewModel.argument.value
val context = LocalContext.current val context = LocalContext.current
var getUser by remember { mutableStateOf(currentUserViewModel.user) }
var openDialogUser by remember { mutableStateOf(false) } var openDialogUser by remember { mutableStateOf(false) }
var email by remember { mutableStateOf("") } var email by remember { mutableStateOf(getUser?.email) }
var password by remember { mutableStateOf("") } var password by remember { mutableStateOf(getUser?.password) }
var nickname by remember { mutableStateOf("") } var nickname by remember { mutableStateOf(getUser?.nickname) }
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>() } val getComms = remember { mutableStateListOf<Comment>() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao() NewsPortalDatabase.getInstance(context).userDao()
.getUserComms(argument.toString().toInt()).collect { data -> .getUserComms(getUser?.id.toString().toInt()).collect { data ->
getComms.clear() getComms.clear()
getComms.addAll(data) getComms.addAll(data)
} }
@ -117,7 +104,7 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao() NewsPortalDatabase.getInstance(context).userDao()
.getUserArticles(argument.toString().toInt()).collect { data -> .getUserArticles(getUser?.id.toString().toInt()).collect { data ->
getArticles.clear() getArticles.clear()
getArticles.addAll(data) getArticles.addAll(data)
} }
@ -128,7 +115,7 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
NewsPortalDatabase.getInstance(context).userDao() NewsPortalDatabase.getInstance(context).userDao()
.getUserTags(argument.toString().toInt()).collect { data -> .getUserTags(getUser?.id.toString().toInt()).collect { data ->
getTags.clear() getTags.clear()
getTags.addAll(data) getTags.addAll(data)
} }
@ -332,49 +319,53 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
fontSize = 20.sp, fontSize = 20.sp,
), ),
) )
ValidateEmail(email, {email=it} ) email?.let { ValidateEmail(it, {email=it} ) }
OutlinedTextField( password?.let {
value = password, OutlinedTextField(
onValueChange = { value = it,
password=it onValueChange = {
}, password=it
colors = TextFieldDefaults.textFieldColors( },
containerColor = Color.White, colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color(0xff423a99), containerColor = Color.White,
focusedLabelColor = Color(0xff423a99), focusedIndicatorColor = Color(0xff423a99),
unfocusedIndicatorColor = Color(0xff423a99), focusedLabelColor = Color(0xff423a99),
unfocusedLabelColor = Color(0xff423a99) unfocusedIndicatorColor = Color(0xff423a99),
), unfocusedLabelColor = Color(0xff423a99)
modifier = Modifier ),
.fillMaxWidth() modifier = Modifier
.wrapContentHeight() .fillMaxWidth()
.padding(10.dp), .wrapContentHeight()
label = { Text("Password") }, .padding(10.dp),
placeholder = { Text("Write password...") }, label = { Text("Password") },
minLines = 1, placeholder = { Text("Write password...") },
maxLines = 1, minLines = 1,
) maxLines = 1,
OutlinedTextField( )
value = nickname, }
onValueChange = { nickname?.let {
nickname=it OutlinedTextField(
}, value = it,
colors = TextFieldDefaults.textFieldColors( onValueChange = {
containerColor = Color.White, nickname=it
focusedIndicatorColor = Color(0xff423a99), },
focusedLabelColor = Color(0xff423a99), colors = TextFieldDefaults.textFieldColors(
unfocusedIndicatorColor = Color(0xff423a99), containerColor = Color.White,
unfocusedLabelColor = Color(0xff423a99) focusedIndicatorColor = Color(0xff423a99),
), focusedLabelColor = Color(0xff423a99),
modifier = Modifier unfocusedIndicatorColor = Color(0xff423a99),
.fillMaxWidth() unfocusedLabelColor = Color(0xff423a99)
.wrapContentHeight() ),
.padding(10.dp), modifier = Modifier
label = { Text("Nickname") }, .fillMaxWidth()
placeholder = { Text("Write nickname...") }, .wrapContentHeight()
minLines = 1, .padding(10.dp),
maxLines = 1, label = { Text("Nickname") },
) placeholder = { Text("Write nickname...") },
minLines = 1,
maxLines = 1,
)
}
Row( Row(
modifier = Modifier.padding(all = 8.dp), modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
@ -388,10 +379,13 @@ fun ProfileScreen(navController: NavController, modifier: Modifier = Modifier,sh
), ),
onClick = { onClick = {
openDialogUser = false openDialogUser = false
if(password.isNotEmpty() && email.isNotEmpty() && isValidEmail(email) && nickname.isNotEmpty()) { if(password?.isNotEmpty() == true && email?.isNotEmpty() == true && isValidEmail(
getUser?.password=password email!!
getUser?.email=email ) && nickname?.isNotEmpty() == true
getUser?.nickname=nickname ) {
getUser?.password= password as String
getUser?.email= email as String
getUser?.nickname= nickname as String
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
getUser?.let { getUser?.let {
NewsPortalDatabase.getInstance(context).userDao() NewsPortalDatabase.getInstance(context).userDao()

View File

@ -41,13 +41,14 @@ 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.lifecycle.viewmodel.compose.viewModel
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.items.TagItem import com.example.pmulabs.designElem.items.TagItem
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Tag import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.models.User import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -55,7 +56,7 @@ import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun TagsScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){ fun TagsScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val context = LocalContext.current val context = LocalContext.current
val tags = remember { mutableStateListOf<Tag>() } val tags = remember { mutableStateListOf<Tag>() }
@ -68,17 +69,7 @@ fun TagsScreen(navController: NavController, modifier: Modifier = Modifier,share
} }
} }
val argument = sharedViewModel.argument.value var getUser by remember { mutableStateOf(currentUserViewModel.user) }
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 openDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") } var text by remember { mutableStateOf("") }
@ -198,7 +189,7 @@ fun TagsScreen(navController: NavController, modifier: Modifier = Modifier,share
items(items = tags){ tag -> items(items = tags){ tag ->
TagItem( TagItem(
teg = tag, teg = tag,
sharedViewModel = sharedViewModel, viewModel = currentUserViewModel,
onTagClick = {navController.navigate(BottomBarScreen.SearchByTag.passId(tag.id.toString()))} onTagClick = {navController.navigate(BottomBarScreen.SearchByTag.passId(tag.id.toString()))}
) )
} }

View File

@ -49,6 +49,7 @@ import androidx.compose.ui.text.input.VisualTransformation
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.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.designElem.elem.ValidateEmail import com.example.pmulabs.designElem.elem.ValidateEmail
import com.example.pmulabs.designElem.elem.isValidEmail import com.example.pmulabs.designElem.elem.isValidEmail
@ -59,13 +60,14 @@ import com.example.pmulabs.graphs.AuthScreen
import com.example.pmulabs.graphs.Graph import com.example.pmulabs.graphs.Graph
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.User import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import com.example.pmulabs.viewModels.CurrentUserViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun EntryScreen(navController: NavController,modifier: Modifier = Modifier, sharedViewModel: SharedViewModel) { fun EntryScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
var emailValue by rememberSaveable { mutableStateOf("") } var emailValue by rememberSaveable { mutableStateOf("") }
var passwordValue by rememberSaveable { mutableStateOf("") } var passwordValue by rememberSaveable { mutableStateOf("") }
@ -79,7 +81,7 @@ fun EntryScreen(navController: NavController,modifier: Modifier = Modifier, shar
} }
} }
} }
val argument = sharedViewModel.argument.value val argument = currentUserViewModel.argument.value
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()
@ -205,7 +207,7 @@ fun EntryScreen(navController: NavController,modifier: Modifier = Modifier, shar
if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) { if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) {
users.forEach { user -> users.forEach { user ->
if (user.password == passwordValue && user.email == emailValue) { if (user.password == passwordValue && user.email == emailValue) {
sharedViewModel.setArgument(user.id.toString()) currentUserViewModel.setArgument(user.id.toString())
navController.navigate(route = Graph.passUserId(user.id.toString())) { navController.navigate(route = Graph.passUserId(user.id.toString())) {
} }
} }

View File

@ -50,9 +50,11 @@ import androidx.compose.ui.text.input.VisualTransformation
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.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.pmulabs.designElem.elem.ValidateEmail import com.example.pmulabs.designElem.elem.ValidateEmail
import com.example.pmulabs.designElem.elem.isValidEmail import com.example.pmulabs.designElem.elem.isValidEmail
import com.example.pmulabs.viewModels.CurrentUserViewModel
import com.example.pmulabs.designElem.statDesign.LeftCircles import com.example.pmulabs.designElem.statDesign.LeftCircles
import com.example.pmulabs.designElem.statDesign.LogoMobile import com.example.pmulabs.designElem.statDesign.LogoMobile
import com.example.pmulabs.designElem.statDesign.RightCircles import com.example.pmulabs.designElem.statDesign.RightCircles
@ -60,7 +62,7 @@ import com.example.pmulabs.graphs.AuthScreen
import com.example.pmulabs.graphs.Graph import com.example.pmulabs.graphs.Graph
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.User import com.example.pmulabs.room.models.User
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -68,7 +70,7 @@ import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier,sharedViewModel: SharedViewModel) { fun RegisterScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)) {
var emailValue by rememberSaveable { mutableStateOf("") } var emailValue by rememberSaveable { mutableStateOf("") }
var passwordValue by rememberSaveable { mutableStateOf("") } var passwordValue by rememberSaveable { mutableStateOf("") }
@ -242,7 +244,7 @@ fun RegisterScreen(navController: NavController,modifier: Modifier = Modifier,sh
data.forEach { user -> data.forEach { user ->
if (user.password == passwordValue && user.email == emailValue) { if (user.password == passwordValue && user.email == emailValue) {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
sharedViewModel.setArgument(user.id.toString()) currentUserViewModel.setArgument(user.id.toString())
navController.navigate( navController.navigate(
route = Graph.passUserId( route = Graph.passUserId(
user.id.toString() user.id.toString()

View File

@ -16,20 +16,22 @@ 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.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
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.basecomponents.navigate.CALENDAR_ARGUMENT_DATE import com.example.pmulabs.basecomponents.navigate.CALENDAR_ARGUMENT_DATE
import com.example.pmulabs.designElem.elem.BackButton import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.designElem.items.ArticleItem import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.viewModels.CurrentUserViewModel
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@Composable @Composable
fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){ fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val context = LocalContext.current val context = LocalContext.current
val articles = remember { mutableStateListOf<Article>() } val articles = remember { mutableStateListOf<Article>() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -59,7 +61,7 @@ fun CalendarScreen(navController: NavController, modifier: Modifier = Modifier,
if(publishDate==date) { if(publishDate==date) {
ArticleItem( ArticleItem(
article = article, article = article,
sharedViewModel=sharedViewModel, currentUserViewModel=currentUserViewModel,
onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))} onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}
) )
} }

View File

@ -16,19 +16,21 @@ 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.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
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.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY import com.example.pmulabs.basecomponents.navigate.SEARCHBYTAG_ARGUMENT_KEY
import com.example.pmulabs.designElem.elem.BackButton import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.designElem.items.ArticleItem import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.viewModels.CurrentUserViewModel
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@Composable @Composable
fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){ fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val context = LocalContext.current val context = LocalContext.current
val articles = remember { mutableStateListOf<Article>() } val articles = remember { mutableStateListOf<Article>() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -53,7 +55,7 @@ fun SearchByTagScreen(navController: NavController, modifier: Modifier = Modifie
} }
items(items = articles){ article -> items(items = articles){ article ->
if(article.tagId.toString()==id) { if(article.tagId.toString()==id) {
ArticleItem(article = article, sharedViewModel = sharedViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article, currentUserViewModel = currentUserViewModel, onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }

View File

@ -16,19 +16,21 @@ 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.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
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.basecomponents.navigate.SEARCH_ARGUMENT_TEXT import com.example.pmulabs.basecomponents.navigate.SEARCH_ARGUMENT_TEXT
import com.example.pmulabs.designElem.elem.BackButton import com.example.pmulabs.designElem.elem.BackButton
import com.example.pmulabs.designElem.items.ArticleItem import com.example.pmulabs.designElem.items.ArticleItem
import com.example.pmulabs.viewModels.CurrentUserViewModel
import com.example.pmulabs.room.database.NewsPortalDatabase import com.example.pmulabs.room.database.NewsPortalDatabase
import com.example.pmulabs.room.models.Article import com.example.pmulabs.room.models.Article
import com.example.pmulabs.viewModels.SharedViewModel import com.example.pmulabs.viewModels.AppViewModelProvider
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@Composable @Composable
fun SearchScreen(navController: NavController, modifier: Modifier = Modifier,sharedViewModel: SharedViewModel){ fun SearchScreen(navController: NavController, modifier: Modifier = Modifier, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val context = LocalContext.current val context = LocalContext.current
val articles = remember { mutableStateListOf<Article>() } val articles = remember { mutableStateListOf<Article>() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -54,7 +56,7 @@ fun SearchScreen(navController: NavController, modifier: Modifier = Modifier,sha
} }
items(items = articles){ article -> items(items = articles){ article ->
if(article.title.contains(text)) { if(article.title.contains(text)) {
ArticleItem(article = article,sharedViewModel=sharedViewModel,onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))}) ArticleItem(article = article,currentUserViewModel=currentUserViewModel,onArticleClick = {navController.navigate(BottomBarScreen.ArticlePage.passId(article.id.toString()))})
} }
} }
} }

View File

@ -0,0 +1,27 @@
package com.example.pmulabs.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.pmulabs.NewsPortalApplication
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
CurrentUserViewModel(newsPortalApplication().container.userRepository)
}
initializer {
TagItemViewModel(newsPortalApplication().container.tagRepository)
}
initializer {
CommentItemViewModel(newsPortalApplication().container.userRepository,newsPortalApplication().container.commentRepository)
}
initializer {
ArticleItemViewModel(newsPortalApplication().container.tagRepository,newsPortalApplication().container.commentRepository,newsPortalApplication().container.articleRepository)
}
}
}
fun CreationExtras.newsPortalApplication(): NewsPortalApplication =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as NewsPortalApplication)

View File

@ -0,0 +1,46 @@
package com.example.pmulabs.viewModels
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.pmulabs.room.models.Article
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.repository.ArticleRepository
import com.example.pmulabs.room.repository.CommentRepository
import com.example.pmulabs.room.repository.TagRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ArticleItemViewModel(
private val tagRepository: TagRepository,
private val commentRepository: CommentRepository,
private val articleRepository: ArticleRepository
) : ViewModel() {
var tagList by mutableStateOf<List<Tag>>(emptyList())
fun setTagList() {
viewModelScope.launch {
tagList=tagRepository.getAllTags().first()
}
}
suspend fun updateArticle(article: Article) {
articleRepository.updateArticle(article)
}
suspend fun deleteArticle(article: Article) {
articleRepository.deleteArticle(article)
}
suspend fun getTagByName(name: String) : Tag {
return tagRepository.getTagByName(name).first()
}
suspend fun getCount(articleId: Int?): Int = withContext(Dispatchers.IO) {
commentRepository.getCountComment(articleId)
}
}

View File

@ -0,0 +1,57 @@
package com.example.pmulabs.viewModels
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.pmulabs.room.models.Comment
import com.example.pmulabs.room.models.User
import com.example.pmulabs.room.repository.CommentRepository
import com.example.pmulabs.room.repository.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class CommentItemViewModel(
private val userRepository: UserRepository,
private val commentRepository: CommentRepository
) : ViewModel() {
suspend fun updateComment(comment: Comment) {
commentRepository.updateComment(comment)
}
var commentList by mutableStateOf<Flow<List<Comment>>>(commentRepository.getAllComments())
var commListByArticle by mutableStateOf<List<Comment>>(emptyList())
var userListByArticle by mutableStateOf<List<User>>(emptyList())
suspend fun getCount(articleId: Int): Int = withContext(Dispatchers.IO) {
commentRepository.getCountComment(articleId)
}
fun getUsersByArticle(articleId: Int) {
viewModelScope.launch {
val count=getCount(articleId)
for(item in commentList.first()){
if(item.articleId==articleId){
commListByArticle+=item
}
if(commListByArticle.size>count){
commListByArticle -= commListByArticle[commListByArticle.size-1]
}
}
for(item in commListByArticle){
userListByArticle+=userRepository.getUserById(item.userId).first()
if(userListByArticle.size>count){
userListByArticle -= userListByArticle[userListByArticle.size-1]
}
}
}
}
suspend fun deleteComment(comment: Comment) {
commentRepository.deleteComment(comment)
}
}

View File

@ -0,0 +1,28 @@
package com.example.pmulabs.viewModels
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.pmulabs.room.models.User
import com.example.pmulabs.room.repository.UserRepository
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
class CurrentUserViewModel(private val userRepository: UserRepository) : ViewModel(){
val argument = mutableStateOf<String?>(null)
private val userid = mutableStateOf<Int?>(null)
var user by mutableStateOf<User?>(null)
fun setArgument(arg: String) {
argument.value = arg
userid.value = arg.toInt()
viewModelScope.launch {
user = userRepository.getUserById(userid.value)
.filterNotNull()
.first()
}
}
}

View File

@ -1,12 +0,0 @@
package com.example.pmulabs.viewModels
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class SharedViewModel : ViewModel() {
val argument = mutableStateOf<String?>(null)
fun setArgument(arg: String) {
argument.value = arg
}
}

View File

@ -0,0 +1,17 @@
package com.example.pmulabs.viewModels
import androidx.lifecycle.ViewModel
import com.example.pmulabs.room.models.Tag
import com.example.pmulabs.room.repository.TagRepository
class TagItemViewModel(
private val tagRepository: TagRepository
) : ViewModel() {
suspend fun updateTag(tag: Tag) {
tagRepository.updateTag(tag)
}
suspend fun deleteTag(tag: Tag) {
tagRepository.deleteTag(tag)
}
}