feat(cache): Cache users
This commit is contained in:
parent
dd88d4a81a
commit
172f997af6
@ -5,7 +5,7 @@ plugins {
|
|||||||
alias(libs.plugins.androidApplication)
|
alias(libs.plugins.androidApplication)
|
||||||
alias(libs.plugins.jetbrainsKotlinAndroid)
|
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||||
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
|
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
|
||||||
|
id("com.google.devtools.ksp")
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets {
|
secrets {
|
||||||
@ -110,4 +110,8 @@ dependencies {
|
|||||||
implementation(libs.kefirbb)
|
implementation(libs.kefirbb)
|
||||||
|
|
||||||
implementation(libs.acra.http)
|
implementation(libs.acra.http)
|
||||||
|
|
||||||
|
implementation(libs.androidx.room.runtime)
|
||||||
|
implementation(libs.androidx.room.ktx)
|
||||||
|
ksp(libs.androidx.room.compiler)
|
||||||
}
|
}
|
@ -1,13 +1,18 @@
|
|||||||
package ru.sweetbread.unn
|
package ru.sweetbread.unn
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import io.ktor.client.request.forms.submitForm
|
import io.ktor.client.request.forms.submitForm
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.request.header
|
import io.ktor.client.request.header
|
||||||
import io.ktor.client.request.parameter
|
import io.ktor.client.request.parameter
|
||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
import io.ktor.http.parameters
|
import io.ktor.http.parameters
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import ru.sweetbread.unn.db.cacheUser
|
||||||
|
import ru.sweetbread.unn.db.loadUserByBitrixId
|
||||||
import ru.sweetbread.unn.ui.layout.LoginData
|
import ru.sweetbread.unn.ui.layout.LoginData
|
||||||
import ru.sweetbread.unn.ui.layout.client
|
import ru.sweetbread.unn.ui.layout.client
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@ -28,7 +33,8 @@ enum class Type(val s: String) {
|
|||||||
Student("student"),
|
Student("student"),
|
||||||
Group("group"),
|
Group("group"),
|
||||||
Lecturer("lecturer"),
|
Lecturer("lecturer"),
|
||||||
Auditorium("auditorium")
|
Auditorium("auditorium"),
|
||||||
|
Employee("employee")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class LecturerRank(val id: Int) {
|
enum class LecturerRank(val id: Int) {
|
||||||
@ -94,7 +100,7 @@ class User(
|
|||||||
val nameEn: String,
|
val nameEn: String,
|
||||||
val isMale: Boolean,
|
val isMale: Boolean,
|
||||||
val birthday: LocalDate,
|
val birthday: LocalDate,
|
||||||
val avatar: ImageSet
|
val avatar: AvatarSet
|
||||||
)
|
)
|
||||||
|
|
||||||
class Post(
|
class Post(
|
||||||
@ -107,7 +113,7 @@ class Post(
|
|||||||
val content: String
|
val content: String
|
||||||
)
|
)
|
||||||
|
|
||||||
class ImageSet(
|
class AvatarSet(
|
||||||
val original: String,
|
val original: String,
|
||||||
val thumbnail: String,
|
val thumbnail: String,
|
||||||
val small: String
|
val small: String
|
||||||
@ -177,7 +183,7 @@ private suspend fun getMyself(login: String) {
|
|||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||||
),
|
),
|
||||||
avatar = user.getJSONObject("photo").let {
|
avatar = user.getJSONObject("photo").let {
|
||||||
ImageSet(
|
AvatarSet(
|
||||||
it.getString("orig"),
|
it.getString("orig"),
|
||||||
it.getString("thumbnail"),
|
it.getString("thumbnail"),
|
||||||
it.getString("small"),
|
it.getString("small"),
|
||||||
@ -304,10 +310,22 @@ suspend fun getBlogposts(): ArrayList<Post> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getUserByBitrixId(id: Int): User {
|
suspend fun getUserByBitrixId(id: Int): User {
|
||||||
|
var user: User?
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
user = loadUserByBitrixId(id)
|
||||||
|
}
|
||||||
|
user?.let { return user as User }
|
||||||
|
|
||||||
val userId = JSONObject(client.get("$vuzapiURL/user/bx/$id") {
|
val userId = JSONObject(client.get("$vuzapiURL/user/bx/$id") {
|
||||||
header("Cookie", "PHPSESSID=$PHPSESSID")
|
header("Cookie", "PHPSESSID=$PHPSESSID")
|
||||||
}.bodyAsText()).getInt("id")
|
}.bodyAsText()).getInt("id")
|
||||||
return getUser(userId)
|
|
||||||
|
getUser(userId).let { user ->
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
cacheUser(user)
|
||||||
|
}
|
||||||
|
return user
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getUser(id: Int): User {
|
suspend fun getUser(id: Int): User {
|
||||||
@ -317,14 +335,15 @@ suspend fun getUser(id: Int): User {
|
|||||||
}.bodyAsText()
|
}.bodyAsText()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Log.d("type", json.getJSONArray("profiles").getJSONObject(0).getString("type"))
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
unnId = null,
|
unnId = null,
|
||||||
bitrixId = json.getInt("bitrix_id"),
|
bitrixId = json.getInt("bitrix_id"),
|
||||||
userId = json.getInt("id"),
|
userId = json.getInt("id"),
|
||||||
type = when (json.getJSONArray("profiles").getJSONObject(0).getString("type")) {
|
type = if (json.getJSONArray("profiles").getJSONObject(0)
|
||||||
"lecturer" -> Type.Lecturer // ig,,,
|
.getString("type") == "employee"
|
||||||
else -> Type.Student
|
) Type.Employee else Type.Student,
|
||||||
},
|
|
||||||
email = json.getString("email"),
|
email = json.getString("email"),
|
||||||
nameRu = json.getString("fullname"),
|
nameRu = json.getString("fullname"),
|
||||||
nameEn = json.getString("fullname_en"),
|
nameEn = json.getString("fullname_en"),
|
||||||
@ -334,7 +353,7 @@ suspend fun getUser(id: Int): User {
|
|||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||||
),
|
),
|
||||||
avatar = json.getJSONObject("photo").let {
|
avatar = json.getJSONObject("photo").let {
|
||||||
ImageSet(
|
AvatarSet(
|
||||||
it.getString("orig"),
|
it.getString("orig"),
|
||||||
it.getString("thumbnail"),
|
it.getString("thumbnail"),
|
||||||
it.getString("small"),
|
it.getString("small"),
|
||||||
|
9
app/src/main/java/ru/sweetbread/unn/db/DB.kt
Normal file
9
app/src/main/java/ru/sweetbread/unn/db/DB.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package ru.sweetbread.unn.db
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
|
||||||
|
@Database(entities = [UserDB::class], version = 1)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
abstract fun userDao(): UserDao
|
||||||
|
}
|
101
app/src/main/java/ru/sweetbread/unn/db/UserDB.kt
Normal file
101
app/src/main/java/ru/sweetbread/unn/db/UserDB.kt
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package ru.sweetbread.unn.db
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.AvatarSet
|
||||||
|
import ru.sweetbread.unn.Type
|
||||||
|
import ru.sweetbread.unn.User
|
||||||
|
import ru.sweetbread.unn.ui.layout.db
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class UserDB(
|
||||||
|
@PrimaryKey val userId: Int,
|
||||||
|
@ColumnInfo val unnId: Int?,
|
||||||
|
@ColumnInfo val bitrixId: Int,
|
||||||
|
@ColumnInfo val type: Type,
|
||||||
|
@ColumnInfo val email: String,
|
||||||
|
@ColumnInfo val nameRu: String,
|
||||||
|
@ColumnInfo val nameEn: String,
|
||||||
|
@ColumnInfo val isMale: Boolean,
|
||||||
|
@ColumnInfo val birthday: String,
|
||||||
|
@ColumnInfo val origAvatar: String,
|
||||||
|
@ColumnInfo val thumbAvatar: String,
|
||||||
|
@ColumnInfo val smallAvatar: String,
|
||||||
|
@ColumnInfo val expiredAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Query("SELECT * FROM userDB WHERE bitrixId = :bitrixId LIMIT 1")
|
||||||
|
fun getUserByBitrix(bitrixId: Int): UserDB?
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
fun insert(user: UserDB)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(user: UserDB)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun cacheUser(user: User) {
|
||||||
|
try {
|
||||||
|
db.userDao().insert(
|
||||||
|
UserDB(
|
||||||
|
user.userId,
|
||||||
|
user.unnId,
|
||||||
|
user.bitrixId,
|
||||||
|
user.type,
|
||||||
|
user.email,
|
||||||
|
user.nameRu,
|
||||||
|
user.nameEn,
|
||||||
|
user.isMale,
|
||||||
|
user.birthday.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
||||||
|
user.avatar.original,
|
||||||
|
user.avatar.thumbnail,
|
||||||
|
user.avatar.small,
|
||||||
|
LocalDateTime.now().plusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadUserByBitrixId(bitrixId: Int): User? {
|
||||||
|
val user = db.userDao().getUserByBitrix(bitrixId)
|
||||||
|
Log.d("UserDB", user?.nameEn ?: "None")
|
||||||
|
if (user == null) return null
|
||||||
|
if (LocalDateTime.parse(
|
||||||
|
user.expiredAt,
|
||||||
|
DateTimeFormatter.ISO_LOCAL_DATE_TIME
|
||||||
|
) < LocalDateTime.now()
|
||||||
|
) {
|
||||||
|
db.userDao().delete(user)
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return User(
|
||||||
|
user.unnId,
|
||||||
|
user.bitrixId,
|
||||||
|
user.userId,
|
||||||
|
user.type,
|
||||||
|
user.email,
|
||||||
|
user.nameRu,
|
||||||
|
user.nameEn,
|
||||||
|
user.isMale,
|
||||||
|
LocalDate.parse(user.birthday, DateTimeFormatter.ISO_LOCAL_DATE),
|
||||||
|
AvatarSet(
|
||||||
|
user.origAvatar,
|
||||||
|
user.thumbAvatar,
|
||||||
|
user.smallAvatar
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import org.kefirsf.bb.BBProcessorFactory
|
import org.kefirsf.bb.BBProcessorFactory
|
||||||
import org.kefirsf.bb.TextProcessor
|
import org.kefirsf.bb.TextProcessor
|
||||||
import ru.sweetbread.unn.ImageSet
|
import ru.sweetbread.unn.AvatarSet
|
||||||
import ru.sweetbread.unn.Post
|
import ru.sweetbread.unn.Post
|
||||||
import ru.sweetbread.unn.R
|
import ru.sweetbread.unn.R
|
||||||
import ru.sweetbread.unn.Type
|
import ru.sweetbread.unn.Type
|
||||||
@ -73,7 +73,7 @@ val defUser = User(
|
|||||||
"Jon Sigma Omega",
|
"Jon Sigma Omega",
|
||||||
true,
|
true,
|
||||||
LocalDate.now(),
|
LocalDate.now(),
|
||||||
ImageSet(
|
AvatarSet(
|
||||||
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
|
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
|
||||||
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
|
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg",
|
||||||
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg"
|
"https://upload.wikimedia.org/wikipedia/ru/thumb/9/94/%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg/500px-%D0%93%D0%B8%D0%B3%D0%B0%D1%87%D0%B0%D0%B4.jpg"
|
||||||
|
@ -25,6 +25,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import androidx.room.Room
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.plugins.HttpRequestRetry
|
import io.ktor.client.plugins.HttpRequestRetry
|
||||||
import io.ktor.client.plugins.HttpTimeout
|
import io.ktor.client.plugins.HttpTimeout
|
||||||
@ -32,6 +33,7 @@ import io.ktor.client.plugins.cache.HttpCache
|
|||||||
import io.ktor.client.plugins.logging.LogLevel
|
import io.ktor.client.plugins.logging.LogLevel
|
||||||
import io.ktor.client.plugins.logging.Logger
|
import io.ktor.client.plugins.logging.Logger
|
||||||
import io.ktor.client.plugins.logging.Logging
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import ru.sweetbread.unn.db.AppDatabase
|
||||||
import ru.sweetbread.unn.ui.composes.Blogposts
|
import ru.sweetbread.unn.ui.composes.Blogposts
|
||||||
import ru.sweetbread.unn.ui.composes.Schedule
|
import ru.sweetbread.unn.ui.composes.Schedule
|
||||||
import ru.sweetbread.unn.ui.theme.UNNTheme
|
import ru.sweetbread.unn.ui.theme.UNNTheme
|
||||||
@ -59,10 +61,18 @@ val client = HttpClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDatabase
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
db = Room.databaseBuilder(
|
||||||
|
applicationContext,
|
||||||
|
AppDatabase::class.java, "database"
|
||||||
|
).build()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
UNNTheme {
|
UNNTheme {
|
||||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.androidApplication) apply false
|
alias(libs.plugins.androidApplication) apply false
|
||||||
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
||||||
|
id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
@ -24,6 +24,7 @@ lifecycleLivedataKtx = "2.7.0"
|
|||||||
lifecycleViewmodelKtx = "2.7.0"
|
lifecycleViewmodelKtx = "2.7.0"
|
||||||
activity = "1.8.2"
|
activity = "1.8.2"
|
||||||
navigationCompose = "2.7.7"
|
navigationCompose = "2.7.7"
|
||||||
|
roomRuntime = "2.6.1"
|
||||||
secretsGradlePlugin = "2.0.1"
|
secretsGradlePlugin = "2.0.1"
|
||||||
splittiesFunPackAndroidBaseWithViewsDsl = "3.0.0"
|
splittiesFunPackAndroidBaseWithViewsDsl = "3.0.0"
|
||||||
kefirbb = "1.5"
|
kefirbb = "1.5"
|
||||||
@ -34,6 +35,9 @@ androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref =
|
|||||||
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "coreSplashscreen" }
|
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "coreSplashscreen" }
|
||||||
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
|
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
|
||||||
|
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomRuntime" }
|
||||||
|
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomRuntime" }
|
||||||
|
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" }
|
||||||
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
|
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
|
||||||
compose = { module = "com.kizitonwose.calendar:compose", version.ref = "compose" }
|
compose = { module = "com.kizitonwose.calendar:compose", version.ref = "compose" }
|
||||||
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
|
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user