cutout voyager
This commit is contained in:
Generated
+1
-2
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
@@ -10,8 +11,6 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
<option value="$PROJECT_DIR$/app/data" />
|
|
||||||
<option value="$PROJECT_DIR$/app/domain" />
|
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveExternalAnnotations" value="false" />
|
<option name="resolveExternalAnnotations" value="false" />
|
||||||
|
|||||||
Generated
-1
@@ -1,4 +1,3 @@
|
|||||||
<?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_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
|
|||||||
@@ -63,15 +63,6 @@ dependencies {
|
|||||||
ksp(libs.hilt.android.compiler)
|
ksp(libs.hilt.android.compiler)
|
||||||
|
|
||||||
|
|
||||||
implementation(libs.voyager.navigator)
|
|
||||||
|
|
||||||
implementation(libs.voyager.screenmodel)
|
|
||||||
|
|
||||||
implementation(libs.voyager.bottom.sheet.navigator)
|
|
||||||
|
|
||||||
implementation(libs.voyager.transitions)
|
|
||||||
|
|
||||||
implementation(libs.voyager.hilt)
|
|
||||||
|
|
||||||
implementation(libs.jsoup)
|
implementation(libs.jsoup)
|
||||||
}
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
plugins {
|
|
||||||
alias(libs.plugins.android.library)
|
|
||||||
alias(libs.plugins.kotlin.android)
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "ru.megboyzz.lks.data"
|
|
||||||
compileSdk = 34
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
minSdk = 24
|
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
consumerProguardFiles("consumer-rules.pro")
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
isMinifyEnabled = false
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
|
||||||
implementation(libs.androidx.appcompat)
|
|
||||||
implementation(libs.material)
|
|
||||||
testImplementation(libs.junit)
|
|
||||||
androidTestImplementation(libs.androidx.junit)
|
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
|
||||||
|
|
||||||
implementation(libs.jsoup)
|
|
||||||
}
|
|
||||||
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package ru.megboyzz.lks.data
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
||||||
assertEquals("ru.megboyzz.lks.data.test", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package ru.megboyzz.lks.data
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
class ExampleUnitTest {
|
|
||||||
@Test
|
|
||||||
fun addition_isCorrect() {
|
|
||||||
assertEquals(4, 2 + 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("java-library")
|
|
||||||
alias(libs.plugins.jetbrains.kotlin.jvm)
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
testImplementation(libs.junit)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
import org.junit.Test
|
|
||||||
import ru.megboyzz.lks.domain.entities.Student
|
|
||||||
|
|
||||||
class EntityTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testStudent() {
|
|
||||||
|
|
||||||
val student = Student(
|
|
||||||
surname = "Киц",
|
|
||||||
name = "Михаил",
|
|
||||||
patronymic = "Андреевич"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert(student.toString() == "Киц Михаил Андреевич")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testStudent2() {
|
|
||||||
val student = Student(
|
|
||||||
surname = null,
|
|
||||||
name = "Михаил",
|
|
||||||
patronymic = "Андреевич"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert(student.toString() == "Михаил Андреевич")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testStudent3() {
|
|
||||||
|
|
||||||
val student = Student(
|
|
||||||
surname = "Киц",
|
|
||||||
name = null,
|
|
||||||
patronymic = "Андреевич"
|
|
||||||
)
|
|
||||||
println(student)
|
|
||||||
assert(student.toString() == "Киц Андреевич")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testStudent4() {
|
|
||||||
|
|
||||||
val student = Student(
|
|
||||||
surname = "Киц",
|
|
||||||
name = "Михаил",
|
|
||||||
patronymic = null
|
|
||||||
)
|
|
||||||
|
|
||||||
assert(student.toString() == "Киц Михаил")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testStudent5() {
|
|
||||||
|
|
||||||
val student = Student(
|
|
||||||
surname = null,
|
|
||||||
name = null,
|
|
||||||
patronymic = null
|
|
||||||
)
|
|
||||||
|
|
||||||
assert(student.toString().isEmpty())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -15,9 +15,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
|
||||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import ru.megboyzz.lks.profile.ui.components.MainNavigator
|
import ru.megboyzz.lks.profile.ui.components.MainNavigator
|
||||||
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
package ru.megboyzz.lks.profile.data
|
package ru.megboyzz.lks.profile.data
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.jsoup.Connection
|
import org.jsoup.Connection
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
|
||||||
|
|
||||||
private typealias Cookies = Map<String, String>
|
private typealias Cookies = Map<String, String>
|
||||||
|
|
||||||
@@ -50,23 +48,15 @@ fun getProfilePage(payload: LksRequest, cookies: Cookies, page: Int): Document {
|
|||||||
|
|
||||||
val sesid = cookies["BITRIX_SM_UIDH"]
|
val sesid = cookies["BITRIX_SM_UIDH"]
|
||||||
|
|
||||||
//Log.i("TEXT", "Its begin! 1")
|
|
||||||
fakeConnect(cookies)
|
fakeConnect(cookies)
|
||||||
//Log.i("TEXT", "Its end! 1")
|
|
||||||
|
|
||||||
//Log.i("TEXT", "Its begin! 2")
|
|
||||||
val conn = Jsoup
|
val conn = Jsoup
|
||||||
.connect("https://lk.mirea.ru/staff/students/?${payload.getSubmitUrlPath(sesid ?: "")}&PAGEN_1=$page")
|
.connect("https://lk.mirea.ru/staff/students/?${payload.getSubmitUrlPath(sesid ?: "")}&PAGEN_1=$page")
|
||||||
//.userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36")
|
|
||||||
.cookies(cookies)
|
.cookies(cookies)
|
||||||
.referrer("https://lk.mirea.ru/")
|
.referrer("https://lk.mirea.ru/")
|
||||||
.execute()
|
.execute()
|
||||||
//Log.i("TEXT", "Its end! 2")
|
|
||||||
|
|
||||||
val doc = conn.parse()
|
val doc = conn.parse()
|
||||||
//Log.i("TEXT", "Its end! 3")
|
|
||||||
|
|
||||||
println(doc.body())
|
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
@@ -75,9 +65,9 @@ fun Document.getTotalPages() = kotlin.runCatching {
|
|||||||
this.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span").text().toInt()
|
this.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span").text().toInt()
|
||||||
}.getOrNull() ?: 0
|
}.getOrNull() ?: 0
|
||||||
|
|
||||||
fun findStudentsInPage(document: Document): LksResponse {
|
fun findStudentsInPage(document: Document): LksStudent {
|
||||||
|
|
||||||
val table = document.select("body > div.container > table > tbody") ?: return LksResponse()
|
val table = document.select("body > div.container > table > tbody") ?: return LksStudent()
|
||||||
|
|
||||||
val students = table.select("tr").map {
|
val students = table.select("tr").map {
|
||||||
|
|
||||||
@@ -102,7 +92,7 @@ fun findStudentsInPage(document: Document): LksResponse {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return LksResponse(
|
return LksStudent(
|
||||||
students = students,
|
students = students,
|
||||||
availablePages = document.getTotalPages()
|
availablePages = document.getTotalPages()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import ru.megboyzz.lks.profile.data.getProfilePage
|
|||||||
import ru.megboyzz.lks.profile.data.signInLks
|
import ru.megboyzz.lks.profile.data.signInLks
|
||||||
import ru.megboyzz.lks.profile.domain.CookiesPrefs
|
import ru.megboyzz.lks.profile.domain.CookiesPrefs
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LksRepositoryImpl @Inject constructor(
|
class LksRepositoryImpl @Inject constructor(
|
||||||
@CookiesPrefs
|
@CookiesPrefs
|
||||||
private val sharedPreferences: SharedPreferences
|
private val sharedPreferences: SharedPreferences,
|
||||||
|
|
||||||
) : LksRepository {
|
) : LksRepository {
|
||||||
|
|
||||||
private val cookieNamesKey = "cookie_names"
|
private val cookieNamesKey = "cookie_names"
|
||||||
@@ -30,8 +31,6 @@ class LksRepositoryImpl @Inject constructor(
|
|||||||
|
|
||||||
val document = getProfilePage(LksRequest(), cookie, 1)
|
val document = getProfilePage(LksRequest(), cookie, 1)
|
||||||
|
|
||||||
println(document.body())
|
|
||||||
|
|
||||||
val pages =
|
val pages =
|
||||||
document.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span")
|
document.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span")
|
||||||
.text()
|
.text()
|
||||||
@@ -58,7 +57,7 @@ class LksRepositoryImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getPage(lksRequest: LksRequest, cookie: Map<String, String>, pageNumber: Int): Result<LksResponse> {
|
override suspend fun getPage(lksRequest: LksRequest, cookie: Map<String, String>, pageNumber: Int): Result<LksStudent> {
|
||||||
|
|
||||||
Log.i("TEXT", "Its begin doc!")
|
Log.i("TEXT", "Its begin doc!")
|
||||||
val document = getProfilePage(lksRequest, cookie, pageNumber)
|
val document = getProfilePage(lksRequest, cookie, pageNumber)
|
||||||
@@ -68,7 +67,7 @@ class LksRepositoryImpl @Inject constructor(
|
|||||||
val page = findStudentsInPage(document)
|
val page = findStudentsInPage(document)
|
||||||
Log.i("TEXT", "Its end!")
|
Log.i("TEXT", "Its end!")
|
||||||
|
|
||||||
return if(page == LksResponse())
|
return if(page == LksStudent())
|
||||||
Result.failure(Exception())
|
Result.failure(Exception())
|
||||||
else
|
else
|
||||||
Result.success(page)
|
Result.success(page)
|
||||||
|
|||||||
+4
-4
@@ -1,18 +1,18 @@
|
|||||||
package ru.megboyzz.lks.profile.data.repositories
|
package ru.megboyzz.lks.profile.data.repositories
|
||||||
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.domain.repositories.StudentRepository
|
import ru.megboyzz.lks.profile.domain.repositories.StudentRepository
|
||||||
|
|
||||||
class StudentRepositoryImpl : StudentRepository {
|
class StudentRepositoryImpl : StudentRepository {
|
||||||
override fun getAllFavStudents(): List<LksResponse> {
|
override fun getAllFavStudents(): List<LksStudent> {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addStudent(lksResponse: LksResponse) {
|
override fun likeStudent(lksResponse: LksStudent) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteFormFav(lksResponse: LksResponse) {
|
override fun deleteFormFav(lksResponse: LksStudent) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package ru.megboyzz.lks.profile.domain.entities
|
package ru.megboyzz.lks.profile.domain.entities
|
||||||
|
|
||||||
data class LksResponse(
|
data class LksStudent(
|
||||||
val students: List<LksStudent> = emptyList(),
|
val students: List<LksStudent> = emptyList(),
|
||||||
val availablePages: Int = 0
|
val availablePages: Int = 0
|
||||||
)
|
)
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
package ru.megboyzz.lks.profile.domain.repositories
|
package ru.megboyzz.lks.profile.domain.repositories
|
||||||
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
interface LksRepository {
|
interface LksRepository: Serializable {
|
||||||
|
|
||||||
suspend fun signInAndGetCookies(username: String, password: String): Map<String, String>
|
suspend fun signInAndGetCookies(username: String, password: String): Map<String, String>
|
||||||
|
|
||||||
suspend fun cookiesIsValid(cookie: Map<String, String>): Boolean
|
suspend fun cookiesIsValid(cookie: Map<String, String>): Boolean
|
||||||
|
|
||||||
suspend fun getPage(lksRequest: LksRequest, cookie: Map<String, String>, pageNumber: Int): Result<LksResponse>
|
suspend fun getPage(lksRequest: LksRequest, cookie: Map<String, String>, pageNumber: Int): Result<LksStudent>
|
||||||
|
|
||||||
fun saveCookie(cookie: Map<String, String>)
|
fun saveCookie(cookie: Map<String, String>)
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package ru.megboyzz.lks.profile.domain.repositories
|
package ru.megboyzz.lks.profile.domain.repositories
|
||||||
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
|
|
||||||
interface StudentRepository {
|
interface StudentRepository {
|
||||||
|
|
||||||
fun getAllFavStudents(): List<LksResponse>
|
fun getAllFavStudents(): List<LksStudent>
|
||||||
|
|
||||||
fun addStudent(lksResponse: LksResponse)
|
fun likeStudent(lksResponse: LksStudent)
|
||||||
|
|
||||||
fun deleteFormFav(lksResponse: LksResponse)
|
fun deleteFormFav(lksResponse: LksStudent)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ fun SearchTextField(
|
|||||||
Icons.Filled.KeyboardArrowDown
|
Icons.Filled.KeyboardArrowDown
|
||||||
|
|
||||||
|
|
||||||
Column() {
|
Column {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = value,
|
value = value,
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.components
|
package ru.megboyzz.lks.profile.ui.components
|
||||||
|
|
||||||
import android.provider.ContactsContract.Profile
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.defaultMinSize
|
import androidx.compose.foundation.layout.defaultMinSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -20,9 +16,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Divider
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
@@ -39,22 +33,16 @@ 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.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.megboyzz.lks.profile.MainActivity
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.ui.clickableWithNoEffect
|
import ru.megboyzz.lks.profile.ui.clickableWithNoEffect
|
||||||
import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple
|
import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple
|
||||||
import ru.megboyzz.lks.profile.ui.screens.sub.LongPressMenu
|
|
||||||
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.model
|
package ru.megboyzz.lks.profile.ui.model
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.megboyzz.lks.profile.domain.DefaultCookies
|
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
||||||
|
import java.io.Serializable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SearchScreenModel @Inject constructor(
|
class SearchScreenModel @Inject constructor(
|
||||||
private val lksRepository: LksRepository,
|
private val lksRepository: LksRepository,
|
||||||
@DefaultCookies
|
) : ScreenModel, Serializable {
|
||||||
private val cookies: Map<String, String>
|
|
||||||
) : ScreenModel {
|
init {
|
||||||
|
Log.i(this::class.simpleName, "its new init!")
|
||||||
|
}
|
||||||
|
|
||||||
private val _request = MutableStateFlow(LksRequest())
|
private val _request = MutableStateFlow(LksRequest())
|
||||||
val request = _request.asStateFlow()
|
val request = _request.asStateFlow()
|
||||||
@@ -27,7 +27,7 @@ class SearchScreenModel @Inject constructor(
|
|||||||
private val _curPageNumber = MutableStateFlow(1)
|
private val _curPageNumber = MutableStateFlow(1)
|
||||||
val curPageNumber = _curPageNumber.asStateFlow()
|
val curPageNumber = _curPageNumber.asStateFlow()
|
||||||
|
|
||||||
private val _responseList = MutableStateFlow(LksResponse())
|
private val _responseList = MutableStateFlow(LksStudent())
|
||||||
val responseList = _responseList.asStateFlow()
|
val responseList = _responseList.asStateFlow()
|
||||||
|
|
||||||
sealed class UiState(val status: String? = null) {
|
sealed class UiState(val status: String? = null) {
|
||||||
@@ -48,7 +48,7 @@ class SearchScreenModel @Inject constructor(
|
|||||||
|
|
||||||
suspend fun resetStudents() {
|
suspend fun resetStudents() {
|
||||||
_curPageNumber.value = 1
|
_curPageNumber.value = 1
|
||||||
_responseList.emit(LksResponse())
|
_responseList.emit(LksStudent())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newSearch(request: LksRequest) {
|
fun newSearch(request: LksRequest) {
|
||||||
@@ -70,9 +70,9 @@ class SearchScreenModel @Inject constructor(
|
|||||||
if(result.isFailure)
|
if(result.isFailure)
|
||||||
return UiState.Error("Ошибка :-(")
|
return UiState.Error("Ошибка :-(")
|
||||||
|
|
||||||
val list = result.getOrElse { LksResponse() }
|
val list = result.getOrElse { LksStudent() }
|
||||||
|
|
||||||
val updatedStudents = LksResponse(
|
val updatedStudents = LksStudent(
|
||||||
students = _responseList.value.students + list.students,
|
students = _responseList.value.students + list.students,
|
||||||
availablePages = list.availablePages
|
availablePages = list.availablePages
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.model
|
package ru.megboyzz.lks.profile.ui.model
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import cafe.adriel.voyager.hilt.ScreenModelFactory
|
import cafe.adriel.voyager.hilt.ScreenModelFactory
|
||||||
@@ -7,19 +9,26 @@ import cafe.adriel.voyager.navigator.Navigator
|
|||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import ru.megboyzz.lks.profile.domain.DefaultCookies
|
||||||
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
||||||
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
||||||
|
|
||||||
|
|
||||||
class SignInScreenModel @AssistedInject constructor(
|
class SignInScreenModel @AssistedInject constructor(
|
||||||
|
@ApplicationContext val context: Context,
|
||||||
private val lksRepository: LksRepository,
|
private val lksRepository: LksRepository,
|
||||||
@Assisted private val navigator: Navigator
|
@Assisted private val navigator: Navigator,
|
||||||
|
@DefaultCookies
|
||||||
|
private val defaultCookies: Map<String, String>
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
|
|
||||||
private val _username = MutableStateFlow("")
|
private val _username = MutableStateFlow("")
|
||||||
@@ -42,13 +51,22 @@ class SignInScreenModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private var cookie: Map<String, String> = mapOf()
|
private var cookie: Map<String, String> = mapOf()
|
||||||
|
|
||||||
|
private fun makeSuspendToast(text: String) = screenModelScope.launch(Dispatchers.Main) {
|
||||||
|
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
screenModelScope.launch(Dispatchers.IO) {
|
||||||
_loadingScreen.emit(true)
|
_loadingScreen.emit(true)
|
||||||
cookie = lksRepository.restoreCooke()
|
cookie = lksRepository.restoreCooke()
|
||||||
if(lksRepository.cookiesIsValid(cookie))
|
//if(cookie.isEmpty()) cookie = defaultCookies
|
||||||
|
if(lksRepository.cookiesIsValid(cookie)) {
|
||||||
navigator.push(SearchScreen())
|
navigator.push(SearchScreen())
|
||||||
|
makeSuspendToast("Успех!")
|
||||||
|
}else {
|
||||||
|
makeSuspendToast("Не успех!")
|
||||||
|
}
|
||||||
_loadingScreen.emit(false)
|
_loadingScreen.emit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,12 @@ import cafe.adriel.voyager.hilt.getScreenModel
|
|||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import ru.megboyzz.lks.profile.ui.components.LoadingShield
|
import ru.megboyzz.lks.profile.ui.components.LoadingShield
|
||||||
import ru.megboyzz.lks.profile.ui.model.SignInScreenModel
|
import ru.megboyzz.lks.profile.ui.model.SignInScreenModel
|
||||||
|
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
||||||
|
|
||||||
class SignInScreen : Screen {
|
class SignInScreen : Screen {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() = MainTheme {
|
||||||
|
|
||||||
val navigator = LocalNavigator.current!!
|
val navigator = LocalNavigator.current!!
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ import cafe.adriel.voyager.core.screen.Screen
|
|||||||
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.ui.components.LongPressCardContextMenu
|
import ru.megboyzz.lks.profile.ui.components.LongPressCardContextMenu
|
||||||
import ru.megboyzz.lks.profile.ui.copyToClipboard
|
import ru.megboyzz.lks.profile.ui.copyToClipboard
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
class LongPressMenu(private val lksStudent: LksStudent) : Screen {
|
class LongPressMenu(private val lksStudent: LksStudent) : Screen, Serializable {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
@@ -24,7 +25,7 @@ class LongPressMenu(private val lksStudent: LksStudent) : Screen {
|
|||||||
context.copyToClipboard(lksStudent.studentFullName.toString())
|
context.copyToClipboard(lksStudent.studentFullName.toString())
|
||||||
},
|
},
|
||||||
onCopyGroup = {
|
onCopyGroup = {
|
||||||
context.copyToClipboard(lksStudent.studentFullName.toString())
|
context.copyToClipboard(lksStudent.group.toString())
|
||||||
},
|
},
|
||||||
onGoToVk = {
|
onGoToVk = {
|
||||||
Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@@ -3,16 +3,20 @@ package ru.megboyzz.lks.profile.ui.screens.sub
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
|
import cafe.adriel.voyager.hilt.getScreenModel
|
||||||
import ru.megboyzz.lks.profile.ui.components.SearchContextMenu
|
import ru.megboyzz.lks.profile.ui.components.SearchContextMenu
|
||||||
import ru.megboyzz.lks.profile.ui.model.SearchScreenModel
|
import ru.megboyzz.lks.profile.ui.model.SearchScreenModel
|
||||||
|
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
class SearchBottomScreen(
|
class SearchBottomScreen(
|
||||||
private val searchScreenModel: SearchScreenModel
|
private val searchScreenModel: SearchScreenModel
|
||||||
) : Screen {
|
) : Screen, Serializable {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() = MainTheme {
|
||||||
|
|
||||||
|
//val screenModel = getScreenModel<SearchScreenModel>("my_tag")
|
||||||
val screenModel = rememberScreenModel { searchScreenModel }
|
val screenModel = rememberScreenModel { searchScreenModel }
|
||||||
|
|
||||||
SearchContextMenu { lksRequest -> screenModel.newSearch(lksRequest) }
|
SearchContextMenu { lksRequest -> screenModel.newSearch(lksRequest) }
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ private val DarkColorScheme = darkColorScheme(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val LightColorScheme = lightColorScheme(
|
private val LightColorScheme = lightColorScheme(
|
||||||
primary = Color(0xFF90CAF9), // Голубой с пастельным оттенком
|
primary = Color(0xFF207AEE), // Голубой с пастельным оттенком
|
||||||
secondary = Color(0xFFB3E5FC), // Мягкий голубой
|
secondary = Color(0xFFB3E5FC), // Мягкий голубой
|
||||||
tertiary = Color(0xFFC5CAE9), // Светлый фиолетовый
|
tertiary = Color(0xFFC5CAE9), // Светлый фиолетовый
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ fun MainTheme(
|
|||||||
dynamicColor: Boolean = false, // Отключаем динамические цвета для четкости палитры
|
dynamicColor: Boolean = false, // Отключаем динамические цвета для четкости палитры
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
|
val colorScheme = LightColorScheme
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:pathData="M440,840v-240h80v80h320v80L520,760v80h-80ZM120,760v-80h240v80L120,760ZM280,600v-80L120,520v-80h160v-80h80v240h-80ZM440,520v-80h400v80L440,520ZM600,360v-240h80v80h160v80L680,280v80h-80ZM120,280v-80h400v80L120,280Z"
|
||||||
|
android:fillColor="#e8eaed"/>
|
||||||
|
</vector>
|
||||||
@@ -21,5 +21,3 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
rootProject.name = "LKS PROFILE"
|
rootProject.name = "LKS PROFILE"
|
||||||
include(":app")
|
include(":app")
|
||||||
include(":app:domain")
|
|
||||||
include(":app:data")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user