cutout voyager

This commit is contained in:
2025-02-22 16:48:26 +03:00
parent 11cafec847
commit 7d313e1c64
29 changed files with 78 additions and 280 deletions
+1 -2
View File
@@ -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" />
-1
View File
@@ -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">
-9
View File
@@ -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
View File
@@ -1 +0,0 @@
/build
-45
View File
@@ -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)
}
-21
View File
@@ -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)
}
}
-4
View File
@@ -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
View File
@@ -1 +0,0 @@
/build
-15
View File
@@ -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)
}
-69
View File
@@ -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)
@@ -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,
+9
View File
@@ -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>
-2
View File
@@ -21,5 +21,3 @@ dependencyResolutionManagement {
rootProject.name = "LKS PROFILE" rootProject.name = "LKS PROFILE"
include(":app") include(":app")
include(":app:domain")
include(":app:data")