Лабораторная работа №3: как будто бы готова
This commit is contained in:
parent
a3ef2c1f94
commit
392b9e5c0a
@ -1,6 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
id 'kotlin-kapt'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@ -18,6 +19,10 @@ android {
|
|||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary true
|
useSupportLibrary true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
arguments {arg("room.schemaLocation", "$projectDir/schemas")}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -62,4 +67,8 @@ dependencies {
|
|||||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
|
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
|
||||||
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
|
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
|
||||||
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
|
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
|
||||||
|
|
||||||
|
implementation 'androidx.room:room-runtime:2.5.0' // Библиотека "Room"
|
||||||
|
kapt "androidx.room:room-compiler:2.5.0" // Кодогенератор
|
||||||
|
implementation 'androidx.room:room-ktx:2.5.0'
|
||||||
}
|
}
|
@ -24,7 +24,6 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.navigation.navigation
|
import androidx.navigation.navigation
|
||||||
import com.example.dtf.models.currentUser
|
|
||||||
import com.example.dtf.screens.EditPostScreen
|
import com.example.dtf.screens.EditPostScreen
|
||||||
import com.example.dtf.screens.LoginScreen
|
import com.example.dtf.screens.LoginScreen
|
||||||
import com.example.dtf.screens.NewPostScreen
|
import com.example.dtf.screens.NewPostScreen
|
||||||
|
26
app/src/main/java/com/example/dtf/dao/CategoryDao.kt
Normal file
26
app/src/main/java/com/example/dtf/dao/CategoryDao.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.example.dtf.dao
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.example.dtf.models.*
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface CategoryDao {
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(category: Category)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(category: Category)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(category: Category)
|
||||||
|
|
||||||
|
@Query("select * from category")
|
||||||
|
fun getAll() : Flow<List<Category>>
|
||||||
|
|
||||||
|
@Query("select * from category where category.id = :id")
|
||||||
|
fun getById(id: Int) : Flow<Category>
|
||||||
|
|
||||||
|
@Query("select * from category where category.name = :name")
|
||||||
|
fun getByName(name: String) : Flow<CategoryWithPosts>
|
||||||
|
}
|
26
app/src/main/java/com/example/dtf/dao/CommentDao.kt
Normal file
26
app/src/main/java/com/example/dtf/dao/CommentDao.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.example.dtf.dao
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.example.dtf.models.*
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface CommentDao {
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(comment: Comment)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(comment: Comment)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(comment: Comment)
|
||||||
|
|
||||||
|
@Query("select * from comment")
|
||||||
|
fun getAll() : Flow<List<Comment>>
|
||||||
|
|
||||||
|
@Query("select * from comment where comment.id = :id")
|
||||||
|
fun getById(id: Int) : Flow<Comment>
|
||||||
|
|
||||||
|
@Query("select * from comment where comment.post_id = :postId")
|
||||||
|
fun getByPost(postId: Int) : Flow<List<Comment>>
|
||||||
|
}
|
26
app/src/main/java/com/example/dtf/dao/PostDao.kt
Normal file
26
app/src/main/java/com/example/dtf/dao/PostDao.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.example.dtf.dao
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.example.dtf.models.*
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface PostDao {
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(post: Post)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(post: Post)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(post: Post)
|
||||||
|
|
||||||
|
@Query("select * from post")
|
||||||
|
fun getAll() : Flow<List<Post>>
|
||||||
|
|
||||||
|
@Query("select * from post where post.id = :id")
|
||||||
|
fun getById(id: Int) : Flow<PostWithComments>
|
||||||
|
|
||||||
|
@Query("select * from post where post.category_id = :categoryId")
|
||||||
|
fun getByCategory(categoryId: String) : Flow<Post>
|
||||||
|
}
|
23
app/src/main/java/com/example/dtf/dao/UserDao.kt
Normal file
23
app/src/main/java/com/example/dtf/dao/UserDao.kt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package com.example.dtf.dao
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.example.dtf.models.User
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(user: User)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(user: User)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(user: User)
|
||||||
|
|
||||||
|
@Query("select * from user order by username collate nocase asc")
|
||||||
|
fun getAll() : Flow<List<User>>
|
||||||
|
|
||||||
|
@Query("select * from user where user.id = :id")
|
||||||
|
fun getById(id: Int): User
|
||||||
|
}
|
147
app/src/main/java/com/example/dtf/db/AppDatabase.kt
Normal file
147
app/src/main/java/com/example/dtf/db/AppDatabase.kt
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package com.example.dtf.db
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.*
|
||||||
|
import com.example.dtf.models.Category
|
||||||
|
import com.example.dtf.models.Comment
|
||||||
|
import com.example.dtf.models.Post
|
||||||
|
import com.example.dtf.models.User
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
import com.example.dtf.dao.*
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
@Database(
|
||||||
|
entities = [
|
||||||
|
User::class,
|
||||||
|
Category::class,
|
||||||
|
Post::class,
|
||||||
|
Comment::class
|
||||||
|
],
|
||||||
|
version = 1,
|
||||||
|
exportSchema = false
|
||||||
|
)
|
||||||
|
@TypeConverters(Converter::class)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
abstract fun userDao() : UserDao
|
||||||
|
abstract fun categoryDao() : CategoryDao
|
||||||
|
abstract fun commentDao() : CommentDao
|
||||||
|
abstract fun postDao() : PostDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DB_NAME: String = "news-db"
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: AppDatabase? = null
|
||||||
|
|
||||||
|
private suspend fun populateDatabase() {
|
||||||
|
INSTANCE?.let { database ->
|
||||||
|
val userDao = database.userDao()
|
||||||
|
|
||||||
|
userDao.insert(User(1, "Sheriff", "123456", true))
|
||||||
|
userDao.insert(User(2, "Человек", "123456", true))
|
||||||
|
|
||||||
|
val categoryDao = database.categoryDao()
|
||||||
|
|
||||||
|
categoryDao.insert(Category(1, "Игры"))
|
||||||
|
categoryDao.insert(Category(2, "Кино"))
|
||||||
|
categoryDao.insert(Category(3, "Аниме"))
|
||||||
|
|
||||||
|
val postDao = database.postDao()
|
||||||
|
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
1,
|
||||||
|
"Что не так с half-life 2",
|
||||||
|
"Да всё не так",
|
||||||
|
Date(2023, 10, 22),
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
2,
|
||||||
|
"Я действительно ненавижу фильм про титаник",
|
||||||
|
"Пруфов не будет",
|
||||||
|
Date(2023, 9, 22),
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
3,
|
||||||
|
"\"Госпожа Кагуя\" это переоценённый тайтл",
|
||||||
|
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
|
Date(2023, 9, 22),
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
4,
|
||||||
|
"\"Восхождение в тени\" это переоценённый тайтл",
|
||||||
|
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
|
Date(2023, 9, 22),
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
5,
|
||||||
|
"\"Наруто\" это переоценённый тайтл",
|
||||||
|
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
|
Date(2023, 9, 22),
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
postDao.insert(
|
||||||
|
Post(
|
||||||
|
6,
|
||||||
|
"\"Блич\" это переоценённый тайтл",
|
||||||
|
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
|
Date(2023, 9, 22),
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val commentDao = database.commentDao()
|
||||||
|
|
||||||
|
commentDao.insert(Comment(1, 2, 1, "Пост бред. Начнём с того, что вот эта твоя манера речи клоунская...", Date(2023, 10, 20)))
|
||||||
|
commentDao.insert(Comment(2, 1, 1, "Да какой бред, чел, я всё по факту сказал", Date(2023, 10, 20)))
|
||||||
|
commentDao.insert(Comment(3, 2, 3,"Автора на увольнение", Date(2023, 9, 20)))
|
||||||
|
commentDao.insert(Comment(4, 2, 4,"Автора на увольнение дважды", Date(2023, 9, 20)))
|
||||||
|
commentDao.insert(Comment(5, 2, 5,"Автора на увольнение трижды", Date(2023, 9, 20)))
|
||||||
|
commentDao.insert(Comment(6, 2, 6,"Автора на увольнение четырежды", Date(2023, 9, 20)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInstance(appContext: Context): AppDatabase {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
Room.databaseBuilder(
|
||||||
|
appContext,
|
||||||
|
AppDatabase::class.java,
|
||||||
|
DB_NAME
|
||||||
|
)
|
||||||
|
.addCallback(object : Callback() {
|
||||||
|
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||||
|
super.onCreate(db)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
populateDatabase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
app/src/main/java/com/example/dtf/db/Converter.kt
Normal file
16
app/src/main/java/com/example/dtf/db/Converter.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.example.dtf.db
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
class Converter {
|
||||||
|
@TypeConverter
|
||||||
|
fun fromTimestamp(value: Long?): Date? {
|
||||||
|
return value?.let { Date(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun dateToTimestamp(date: Date?): Long? {
|
||||||
|
return date?.time?.toLong()
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,26 @@
|
|||||||
package com.example.dtf.models
|
package com.example.dtf.models
|
||||||
|
|
||||||
data class Category(
|
import androidx.room.*
|
||||||
val id: Int,
|
|
||||||
val name: String
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getAllCategories() : List<Category> {
|
@Entity(tableName = "category")
|
||||||
return listOf(
|
data class Category(
|
||||||
Category(1, "Игры"),
|
@PrimaryKey(autoGenerate = true)
|
||||||
Category(2, "Кино"),
|
@ColumnInfo
|
||||||
Category(3, "Аниме"),
|
val id: Int?,
|
||||||
)
|
@ColumnInfo
|
||||||
|
val name: String
|
||||||
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as Category
|
||||||
|
|
||||||
|
return id == other.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return id ?: -1
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.example.dtf.models
|
||||||
|
|
||||||
|
import androidx.room.Embedded
|
||||||
|
import androidx.room.Relation
|
||||||
|
|
||||||
|
data class CategoryWithPosts(
|
||||||
|
@Embedded val category: Category,
|
||||||
|
@Relation(parentColumn = "id", entityColumn = "category_id")
|
||||||
|
val posts: List<Post>
|
||||||
|
)
|
@ -1,10 +1,33 @@
|
|||||||
package com.example.dtf.models
|
package com.example.dtf.models
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
@Entity(tableName = "comment")
|
||||||
data class Comment(
|
data class Comment(
|
||||||
val id: Int,
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ColumnInfo
|
||||||
|
val id: Int?,
|
||||||
|
@ColumnInfo(name = "user_id")
|
||||||
val userId: Int,
|
val userId: Int,
|
||||||
|
@ColumnInfo(name = "post_id")
|
||||||
|
val postId: Int,
|
||||||
|
@ColumnInfo
|
||||||
val content: String,
|
val content: String,
|
||||||
|
@ColumnInfo
|
||||||
val date: Date
|
val date: Date
|
||||||
)
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as Comment
|
||||||
|
|
||||||
|
return id == other.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return id ?: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,75 +2,95 @@ package com.example.dtf.models
|
|||||||
|
|
||||||
import androidx.compose.runtime.collection.MutableVector
|
import androidx.compose.runtime.collection.MutableVector
|
||||||
import androidx.compose.runtime.collection.mutableVectorOf
|
import androidx.compose.runtime.collection.mutableVectorOf
|
||||||
|
import androidx.room.*
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
private val posts = listOf(
|
//private val posts = listOf(
|
||||||
Post(
|
// Post(
|
||||||
1,
|
// 1,
|
||||||
"Что не так с half-life 2",
|
// "Что не так с half-life 2",
|
||||||
"Да всё не так",
|
// "Да всё не так",
|
||||||
1,
|
// 1,
|
||||||
mutableVectorOf(
|
// mutableVectorOf(
|
||||||
Comment(1, 2, "Пост бред. Начнём с того, что вот эта твоя манера речи клоунская...", Date(2023, 10, 20)),
|
// Comment(1, 2, "Пост бред. Начнём с того, что вот эта твоя манера речи клоунская...", Date(2023, 10, 20)),
|
||||||
Comment(2, 1, "Да какой бред, чел, я всё по факту сказал", Date(2023, 10, 20))
|
// Comment(2, 1, "Да какой бред, чел, я всё по факту сказал", Date(2023, 10, 20))
|
||||||
),
|
// ),
|
||||||
Date(2023, 10, 22)
|
// Date(2023, 10, 22)
|
||||||
),
|
// ),
|
||||||
Post(
|
// Post(
|
||||||
2,
|
// 2,
|
||||||
"Я действительно ненавижу фильм про титаник",
|
// "Я действительно ненавижу фильм про титаник",
|
||||||
"Пруфов не будет",
|
// "Пруфов не будет",
|
||||||
2,
|
// 2,
|
||||||
mutableVectorOf(Comment(1, 2, "Очередной бред от автора", Date(2023, 9, 20))),
|
// mutableVectorOf(Comment(1, 2, "Очередной бред от автора", Date(2023, 9, 20))),
|
||||||
Date(2023, 9, 22)
|
// Date(2023, 9, 22)
|
||||||
),
|
// ),
|
||||||
Post(
|
// Post(
|
||||||
3,
|
// 3,
|
||||||
"\"Госпожа Кагуя\" это переоценённый тайтл",
|
// "\"Госпожа Кагуя\" это переоценённый тайтл",
|
||||||
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
// "Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
3,
|
// 3,
|
||||||
mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
// mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
||||||
Date(2023, 9, 22)
|
// Date(2023, 9, 22)
|
||||||
),
|
// ),
|
||||||
Post(
|
// Post(
|
||||||
4,
|
// 4,
|
||||||
"\"Восхождение в тени\" это переоценённый тайтл",
|
// "\"Восхождение в тени\" это переоценённый тайтл",
|
||||||
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
// "Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
3,
|
// 3,
|
||||||
mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
// mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
||||||
Date(2023, 9, 22)
|
// Date(2023, 9, 22)
|
||||||
),
|
// ),
|
||||||
Post(
|
// Post(
|
||||||
5,
|
// 5,
|
||||||
"\"Тетрадь смерти\" это переоценённый тайтл",
|
// "\"Тетрадь смерти\" это переоценённый тайтл",
|
||||||
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
// "Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
3,
|
// 3,
|
||||||
mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
// mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
||||||
Date(2023, 9, 22)
|
// Date(2023, 9, 22)
|
||||||
),
|
// ),
|
||||||
Post(
|
// Post(
|
||||||
6,
|
// 6,
|
||||||
"\"Бакуман\" это переоценённый тайтл",
|
// "\"Бакуман\" это переоценённый тайтл",
|
||||||
"Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
// "Я, конечно, не смотрел, но мне так кажется. А всё потому, что там происходит такое, что даже Аристотелю не снилось. А может даже Платону. Об этом можно рассуждать тысячи лет, но я смогу уложиться всего в пару слов. И первое слово - этот тайтл полное днище. Ладно, не слово",
|
||||||
3,
|
// 3,
|
||||||
mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
// mutableVectorOf(Comment(1, 2, "Автора на увольнение", Date(2023, 9, 20))),
|
||||||
Date(2023, 9, 22)
|
// Date(2023, 9, 22)
|
||||||
)
|
// )
|
||||||
)
|
//)
|
||||||
|
|
||||||
|
@Entity(
|
||||||
|
tableName = "post",
|
||||||
|
foreignKeys = [
|
||||||
|
ForeignKey(User::class, ["id"], ["user_id"])
|
||||||
|
]
|
||||||
|
)
|
||||||
data class Post(
|
data class Post(
|
||||||
val id: Int,
|
@PrimaryKey(autoGenerate = true)
|
||||||
var title: String,
|
@ColumnInfo
|
||||||
var content: String,
|
val id: Int?,
|
||||||
val categoryId: Int,
|
@ColumnInfo
|
||||||
val comments: MutableVector<Comment>,
|
val title: String,
|
||||||
|
@ColumnInfo
|
||||||
|
val content: String,
|
||||||
|
@ColumnInfo
|
||||||
val date: Date,
|
val date: Date,
|
||||||
)
|
@ColumnInfo(name = "user_id")
|
||||||
|
val userId: Int,
|
||||||
|
@ColumnInfo(name = "category_id")
|
||||||
|
val categoryId: Int
|
||||||
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
|
||||||
fun getAllPosts() : List<Post> {
|
if (javaClass != other?.javaClass) return false
|
||||||
return posts
|
|
||||||
|
other as Post
|
||||||
|
|
||||||
|
return id == other.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPostsByCategory(categoryId: Int) : List<Post> {
|
override fun hashCode(): Int {
|
||||||
return posts.filter { it.categoryId == categoryId }
|
return id ?: -1
|
||||||
|
}
|
||||||
}
|
}
|
10
app/src/main/java/com/example/dtf/models/PostWithComments.kt
Normal file
10
app/src/main/java/com/example/dtf/models/PostWithComments.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.example.dtf.models
|
||||||
|
|
||||||
|
import androidx.room.Embedded
|
||||||
|
import androidx.room.Relation
|
||||||
|
|
||||||
|
data class PostWithComments(
|
||||||
|
@Embedded val post: Post,
|
||||||
|
@Relation(parentColumn = "id", entityColumn = "post_id")
|
||||||
|
val comments: List<Comment>
|
||||||
|
)
|
@ -1,19 +1,30 @@
|
|||||||
package com.example.dtf.models
|
package com.example.dtf.models
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
|
||||||
|
@Entity(tableName = "user")
|
||||||
data class User(
|
data class User(
|
||||||
val id: Int,
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ColumnInfo
|
||||||
|
val id: Int?,
|
||||||
|
@ColumnInfo
|
||||||
val username: String,
|
val username: String,
|
||||||
|
@ColumnInfo
|
||||||
val password: String,
|
val password: String,
|
||||||
|
@ColumnInfo
|
||||||
val isModerator: Boolean
|
val isModerator: Boolean
|
||||||
)
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
|
||||||
fun getAllUsers() : List<User> {
|
if (javaClass != other?.javaClass) return false
|
||||||
return listOf(
|
|
||||||
User(1, "Sheriff", "123456", true),
|
other as User
|
||||||
User(2, "Shailushaika", "654321", false),
|
|
||||||
)
|
return id == other.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun currentUser() : User {
|
override fun hashCode(): Int {
|
||||||
return getAllUsers()[0]
|
return id ?: -1
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,22 +9,31 @@ import androidx.compose.material.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.ui.*
|
||||||
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.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import com.example.dtf.models.getAllCategories
|
import com.example.dtf.db.AppDatabase
|
||||||
import com.example.dtf.models.getAllPosts
|
|
||||||
import com.example.dtf.utils.ScreenPaths
|
|
||||||
import com.example.dtf.widgets.MyTextField
|
import com.example.dtf.widgets.MyTextField
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun EditPostScreen(postId: Int) {
|
fun EditPostScreen(postId: Int) {
|
||||||
val post = getAllPosts().first {p -> p.id == postId}
|
val context = LocalContext.current
|
||||||
|
|
||||||
val title = remember { mutableStateOf(TextFieldValue(post.title)) }
|
val title = remember { mutableStateOf(TextFieldValue("")) }
|
||||||
val content = remember { mutableStateOf(TextFieldValue(post.content)) }
|
val content = remember { mutableStateOf(TextFieldValue("")) }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
AppDatabase.getInstance(context).postDao().getById(postId).collect { data ->
|
||||||
|
title.value = TextFieldValue(data.post.title)
|
||||||
|
content.value = TextFieldValue(data.post.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState()),
|
modifier = Modifier.verticalScroll(rememberScrollState()),
|
||||||
|
@ -9,18 +9,33 @@ import androidx.compose.material.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.ui.*
|
||||||
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.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import com.example.dtf.models.getAllCategories
|
import com.example.dtf.db.AppDatabase
|
||||||
import com.example.dtf.utils.ScreenPaths
|
import com.example.dtf.models.Category
|
||||||
import com.example.dtf.widgets.MyTextField
|
import com.example.dtf.widgets.MyTextField
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NewPostScreen() {
|
fun NewPostScreen() {
|
||||||
val selectedCategory = remember { mutableStateOf(getAllCategories()[0].name) }
|
val categories = remember { mutableStateListOf<Category>() }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
AppDatabase.getInstance(context).categoryDao().getAll().collect {data ->
|
||||||
|
categories.clear()
|
||||||
|
categories.addAll(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val selectedCategory = remember { mutableStateOf("") }
|
||||||
val expanded = remember { mutableStateOf(false) }
|
val expanded = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val title = remember { mutableStateOf(TextFieldValue()) }
|
val title = remember { mutableStateOf(TextFieldValue()) }
|
||||||
@ -53,7 +68,7 @@ fun NewPostScreen() {
|
|||||||
expanded = expanded.value,
|
expanded = expanded.value,
|
||||||
onDismissRequest = {expanded.value = false}
|
onDismissRequest = {expanded.value = false}
|
||||||
) {
|
) {
|
||||||
getAllCategories().forEach {category ->
|
categories.forEach {category ->
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedCategory.value = category.name
|
selectedCategory.value = category.name
|
||||||
|
@ -5,33 +5,44 @@ import androidx.compose.foundation.*
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
|
||||||
import androidx.compose.material.icons.filled.AddCircle
|
import androidx.compose.material.icons.filled.AddCircle
|
||||||
import androidx.compose.material.icons.filled.ThumbUp
|
import androidx.compose.material.icons.filled.ThumbUp
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.ui.*
|
||||||
import androidx.compose.ui.draw.*
|
import androidx.compose.ui.draw.*
|
||||||
import androidx.compose.ui.geometry.*
|
|
||||||
import androidx.compose.ui.graphics.*
|
import androidx.compose.ui.graphics.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.example.dtf.R
|
import com.example.dtf.db.AppDatabase
|
||||||
import com.example.dtf.models.Comment
|
import com.example.dtf.models.Comment
|
||||||
import com.example.dtf.models.currentUser
|
import com.example.dtf.models.Post
|
||||||
import com.example.dtf.models.getAllCategories
|
import com.example.dtf.models.PostWithComments
|
||||||
import com.example.dtf.models.getAllPosts
|
import com.example.dtf.models.User
|
||||||
import com.example.dtf.models.getAllUsers
|
|
||||||
import com.example.dtf.models.getPostsByCategory
|
|
||||||
import com.example.dtf.utils.ScreenPaths
|
import com.example.dtf.utils.ScreenPaths
|
||||||
import com.example.dtf.widgets.MyTextField
|
import com.example.dtf.widgets.MyTextField
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PostScreen(postId: Int, navController: NavHostController) {
|
fun PostScreen(postId: Int, navController: NavHostController) {
|
||||||
val post = getAllPosts().first {p -> p.id == postId}
|
val post = remember { mutableStateOf(PostWithComments(Post(null, "", "", Date(), -1, -1), listOf())) }
|
||||||
|
|
||||||
|
val user = remember { mutableStateOf(User(-1, "", "", false)) }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
user.value = AppDatabase.getInstance(context).userDao().getById(1)
|
||||||
|
AppDatabase.getInstance(context).postDao().getById(postId).collect {data ->
|
||||||
|
post.value = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val content = remember { mutableStateOf(TextFieldValue("")) }
|
val content = remember { mutableStateOf(TextFieldValue("")) }
|
||||||
|
|
||||||
@ -45,12 +56,12 @@ fun PostScreen(postId: Int, navController: NavHostController) {
|
|||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(10.dp),
|
modifier = Modifier.padding(10.dp),
|
||||||
text = post.title,
|
text = post.value.post.title,
|
||||||
fontSize = 26.sp
|
fontSize = 26.sp
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.fillMaxHeight().padding(10.dp, 0.dp, 10.dp, 0.dp),
|
modifier = Modifier.fillMaxHeight().padding(10.dp, 0.dp, 10.dp, 0.dp),
|
||||||
text = post.content,
|
text = post.value.post.content,
|
||||||
fontSize = 20.sp
|
fontSize = 20.sp
|
||||||
)
|
)
|
||||||
Row(
|
Row(
|
||||||
@ -61,18 +72,18 @@ fun PostScreen(postId: Int, navController: NavHostController) {
|
|||||||
Text(
|
Text(
|
||||||
text = "day.month.year".replace(
|
text = "day.month.year".replace(
|
||||||
"day",
|
"day",
|
||||||
post.date.day.toString()
|
post.value.post.date.day.toString()
|
||||||
).replace(
|
).replace(
|
||||||
"month",
|
"month",
|
||||||
post.date.month.toString()
|
post.value.post.date.month.toString()
|
||||||
).replace(
|
).replace(
|
||||||
"year",
|
"year",
|
||||||
post.date.year.toString()
|
post.value.post.date.year.toString()
|
||||||
),
|
),
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = Color(0xFFCECCCC)
|
color = Color(0xFFCECCCC)
|
||||||
)
|
)
|
||||||
if (currentUser().isModerator) {
|
if (user.value.isModerator) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
navController.navigate(ScreenPaths.EditPost.route.replace("{post}", postId.toString()))
|
navController.navigate(ScreenPaths.EditPost.route.replace("{post}", postId.toString()))
|
||||||
@ -126,7 +137,7 @@ fun PostScreen(postId: Int, navController: NavHostController) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post.comments.forEachReversed {comment ->
|
post.value.comments.reversed().forEach() {comment ->
|
||||||
Comment(comment)
|
Comment(comment)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(60.dp))
|
Spacer(modifier = Modifier.height(60.dp))
|
||||||
@ -135,6 +146,15 @@ fun PostScreen(postId: Int, navController: NavHostController) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Comment(comment: Comment) {
|
private fun Comment(comment: Comment) {
|
||||||
|
val user = remember { mutableStateOf(User(-1, "", "", false)) }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
user.value = AppDatabase.getInstance(context).userDao().getById(comment.userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -148,7 +168,7 @@ private fun Comment(comment: Comment) {
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = getAllUsers().first {u -> u.id == comment.userId}.username,
|
text = user.value.username,
|
||||||
fontSize = 20.sp
|
fontSize = 20.sp
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
|
@ -11,17 +11,39 @@ import androidx.compose.ui.*
|
|||||||
import androidx.compose.ui.draw.*
|
import androidx.compose.ui.draw.*
|
||||||
import androidx.compose.ui.geometry.*
|
import androidx.compose.ui.geometry.*
|
||||||
import androidx.compose.ui.graphics.*
|
import androidx.compose.ui.graphics.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.example.dtf.models.getAllCategories
|
import com.example.dtf.db.AppDatabase
|
||||||
import com.example.dtf.models.getAllPosts
|
import com.example.dtf.models.Category
|
||||||
import com.example.dtf.models.getPostsByCategory
|
import com.example.dtf.models.CategoryWithPosts
|
||||||
import com.example.dtf.utils.ScreenPaths
|
import com.example.dtf.utils.ScreenPaths
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PostsScreen(navController: NavHostController) {
|
fun PostsScreen(navController: NavHostController) {
|
||||||
val currentCategory = remember { mutableStateOf(getAllCategories()[0].name) }
|
val currentCategory = remember { mutableStateOf("") }
|
||||||
|
val categories = remember { mutableListOf<Category> () }
|
||||||
|
val categoryWithPosts = remember { mutableStateOf(CategoryWithPosts(Category(-1, ""), listOf()))}
|
||||||
|
val context = LocalContext.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
AppDatabase.getInstance(context).categoryDao().getAll().collect {data ->
|
||||||
|
currentCategory.value = data.first().name
|
||||||
|
categories.clear()
|
||||||
|
categories.addAll(data)
|
||||||
|
AppDatabase.getInstance(context).categoryDao().getByName(currentCategory.value).collect {data ->
|
||||||
|
categoryWithPosts.value = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -38,7 +60,7 @@ fun PostsScreen(navController: NavHostController) {
|
|||||||
horizontalArrangement = Arrangement.spacedBy(25.dp),
|
horizontalArrangement = Arrangement.spacedBy(25.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Categories(currentCategory)
|
Categories(scope, categoryWithPosts, currentCategory, categories)
|
||||||
}
|
}
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
@ -47,7 +69,9 @@ fun PostsScreen(navController: NavHostController) {
|
|||||||
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
|
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
|
||||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
) {
|
) {
|
||||||
PostsByCategory(navController, currentCategory.value)
|
if (currentCategory.value.isNotEmpty()) {
|
||||||
|
PostsByCategory(navController, categoryWithPosts)
|
||||||
|
}
|
||||||
Spacer(modifier = Modifier.height(60.dp))
|
Spacer(modifier = Modifier.height(60.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,13 +79,20 @@ fun PostsScreen(navController: NavHostController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Categories(categoryState: MutableState<String>) {
|
private fun Categories(scope: CoroutineScope, categoryWithPosts: MutableState<CategoryWithPosts>, categoryState: MutableState<String>, categories: MutableList<Category>) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
getAllCategories().forEach {category ->
|
categories.forEach {category ->
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable {
|
.clickable {
|
||||||
categoryState.value = category.name
|
categoryState.value = category.name
|
||||||
|
scope.launch {
|
||||||
|
AppDatabase.getInstance(context).categoryDao().getByName(categoryState.value).collect { data ->
|
||||||
|
categoryWithPosts.value = data
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
if (category.name == categoryState.value) {
|
if (category.name == categoryState.value) {
|
||||||
@ -82,8 +113,8 @@ private fun Categories(categoryState: MutableState<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PostsByCategory(navController: NavHostController, category: String) {
|
private fun PostsByCategory(navController: NavHostController, categoryWithPosts: MutableState<CategoryWithPosts>) {
|
||||||
getPostsByCategory(getAllCategories().first { c -> c.name == category }.id).forEach { post ->
|
categoryWithPosts.value.posts.forEach { post ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight(0.3f)
|
.fillMaxHeight(0.3f)
|
||||||
|
@ -5,15 +5,31 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.*
|
import androidx.compose.ui.*
|
||||||
import androidx.compose.ui.graphics.*
|
import androidx.compose.ui.graphics.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.example.dtf.models.currentUser
|
import com.example.dtf.db.AppDatabase
|
||||||
|
import com.example.dtf.models.User
|
||||||
import com.example.dtf.utils.ScreenPaths
|
import com.example.dtf.utils.ScreenPaths
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ProfileScreen(navController: NavHostController) {
|
fun ProfileScreen(navController: NavHostController) {
|
||||||
|
val user = remember { mutableStateOf(User(-1, "", "", false)) }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
user.value = AppDatabase.getInstance(context).userDao().getById(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
@ -36,14 +52,14 @@ fun ProfileScreen(navController: NavHostController) {
|
|||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = currentUser().username[0].toString(),
|
text = if (user.value.username.isNotEmpty()) { user.value.username[0].toString() } else {""},
|
||||||
fontSize = 30.sp,
|
fontSize = 30.sp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.fillMaxHeight(0.1f))
|
Spacer(modifier = Modifier.fillMaxHeight(0.1f))
|
||||||
Text(
|
Text(
|
||||||
text = currentUser().username,
|
text = user.value.username,
|
||||||
fontSize = 30.sp,
|
fontSize = 30.sp,
|
||||||
color = Color.White
|
color = Color.White
|
||||||
)
|
)
|
||||||
|
@ -15,20 +15,51 @@ import androidx.compose.material.icons.filled.Edit
|
|||||||
import androidx.compose.material.icons.filled.Home
|
import androidx.compose.material.icons.filled.Home
|
||||||
import androidx.compose.material.icons.filled.Person
|
import androidx.compose.material.icons.filled.Person
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import com.example.dtf.models.currentUser
|
import com.example.dtf.db.AppDatabase
|
||||||
|
import com.example.dtf.models.User
|
||||||
import com.example.dtf.utils.ScreenPaths
|
import com.example.dtf.utils.ScreenPaths
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavBar(navController: NavController) {
|
fun BottomNavBar(navController: NavController) {
|
||||||
|
val user = remember { mutableStateOf(User(-1, "", "", false)) }
|
||||||
|
val buttons = remember { mutableListOf(
|
||||||
|
Triple(ScreenPaths.Posts.route, Icons.Default.Home, "Новости"),
|
||||||
|
Triple(ScreenPaths.Profile.route, Icons.Default.Person, "Профиль")
|
||||||
|
) }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
user.value = AppDatabase.getInstance(context).userDao().getById(1)
|
||||||
|
if (user.value.isModerator) {
|
||||||
|
buttons.clear()
|
||||||
|
buttons.addAll(
|
||||||
|
listOf(
|
||||||
|
Triple(ScreenPaths.Posts.route, Icons.Default.Home, "Новости"),
|
||||||
|
Triple(ScreenPaths.NewPost.route, Icons.Default.Edit, "Создать"),
|
||||||
|
Triple(ScreenPaths.Profile.route, Icons.Default.Person, "Профиль")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BottomNavigation(
|
BottomNavigation(
|
||||||
modifier = Modifier.height(70.dp),
|
modifier = Modifier.height(70.dp),
|
||||||
backgroundColor = Color.White,
|
backgroundColor = Color.White,
|
||||||
@ -38,7 +69,7 @@ fun BottomNavBar(navController: NavController) {
|
|||||||
val currentRoute = navBackStackEntry?.destination?.route
|
val currentRoute = navBackStackEntry?.destination?.route
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
Triple(ScreenPaths.Posts.route, Icons.Default.Home, "Новости"),
|
Triple(ScreenPaths.Posts.route, Icons.Default.Home, "Новости"),
|
||||||
if (currentUser().isModerator) {
|
if (user.value.isModerator) {
|
||||||
Triple(ScreenPaths.NewPost.route, Icons.Default.Edit, "Создать")
|
Triple(ScreenPaths.NewPost.route, Icons.Default.Edit, "Создать")
|
||||||
} else { null },
|
} else { null },
|
||||||
Triple(ScreenPaths.Profile.route, Icons.Default.Person, "Профиль")
|
Triple(ScreenPaths.Profile.route, Icons.Default.Person, "Профиль")
|
||||||
|
Loading…
Reference in New Issue
Block a user