stable login and check cookies

This commit is contained in:
2024-09-29 15:33:39 +03:00
parent e32b4feeef
commit e8ed594b9f
12 changed files with 162 additions and 54 deletions
@@ -25,7 +25,18 @@ class LksRepositoryImpl @Inject constructor(
): Map<String, String> = signInLks(username, password) ): Map<String, String> = signInLks(username, password)
override suspend fun cookiesIsValid(cookie: Map<String, String>): Boolean { override suspend fun cookiesIsValid(cookie: Map<String, String>): Boolean {
return false
if(cookie.isEmpty()) return false
val document = getProfilePage(LksRequest(), cookie, 1)
println(document.body())
val pages =
document.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span")
.text()
return pages.isNotEmpty()
} }
@@ -12,5 +12,5 @@ data class LksRequest(
* Метод для получения пути после https://lk.mirea.ru/staff/students? ... * Метод для получения пути после https://lk.mirea.ru/staff/students? ...
*/ */
fun getSubmitUrlPath(sesid: String) = fun getSubmitUrlPath(sesid: String) =
"sessid=$sesid&findname=${student}&findgroup=${group ?: ""}&finddepartment=${department ?: ""}&submit-filter=Найти" "sessid=$sesid&findname=${student ?: ""}&findgroup=${group ?: ""}&finddepartment=${department ?: ""}&submit-filter=Найти"
} }
@@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp
import kotlin.concurrent.thread import kotlin.concurrent.thread
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@@ -7,6 +7,7 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
import cafe.adriel.voyager.transitions.SlideTransition
import ru.megboyzz.lks.profile.ui.screens.SearchScreen import ru.megboyzz.lks.profile.ui.screens.SearchScreen
@Composable @Composable
@@ -14,7 +15,8 @@ fun MainNavigator(screen: Screen) {
BottomSheetNavigator( BottomSheetNavigator(
sheetShape = RoundedCornerShape(12.dp) sheetShape = RoundedCornerShape(12.dp)
) { ) {
Navigator(screen) {
Navigator(screen) SlideTransition(it)
}
} }
} }
@@ -40,6 +40,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.onSizeChanged
@@ -264,7 +265,7 @@ fun ContextMenuButton(
Box( Box(
modifier = Modifier modifier = Modifier
.padding(8.dp) .padding(8.dp)
.clickableWithNormalRipple(onClick) .clickableWithNormalRipple(onClick = onClick)
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@@ -278,7 +279,8 @@ fun ContextMenuButton(
) { ) {
Icon( Icon(
painter = icon, painter = icon,
contentDescription = null contentDescription = null,
tint = Color.Unspecified
) )
Text(text = label) Text(text = label)
} }
@@ -14,6 +14,8 @@ 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
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
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
@@ -35,6 +37,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@@ -43,6 +46,7 @@ import ru.megboyzz.lks.profile.MainActivity
import ru.megboyzz.lks.profile.domain.entities.LksResponse 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.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
@@ -60,14 +64,17 @@ fun ProfileCard(
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
) )
.defaultMinSize(minWidth = 240.dp) .defaultMinSize(minWidth = 240.dp)
.clip(RoundedCornerShape(16.dp))
.clickableWithNormalRipple( .clickableWithNormalRipple(
onClick = { toggled =! toggled }, onClick = { toggled = !toggled },
onLongClick = onLongPress onLongClick = onLongPress,
), ),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Column( Column(
modifier = Modifier.fillMaxWidth().padding(12.dp), modifier = Modifier
.fillMaxWidth()
.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
@@ -80,7 +87,9 @@ fun ProfileCard(
AnimatedVisibility(toggled) { AnimatedVisibility(toggled) {
Column( Column(
modifier = Modifier.padding(top = 4.dp).fillMaxWidth(), modifier = Modifier
.padding(top = 4.dp)
.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
@@ -167,3 +176,25 @@ private fun Main() {
} }
} }
@Composable
fun CardsColumn(
modifier: Modifier = Modifier,
lksStudents: List<LksStudent>,
onLongPress: (LksStudent) -> Unit
) {
Column(modifier) {
LazyColumn(
contentPadding = PaddingValues(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(lksStudents) { student ->
ProfileCard(
lksStudent = student,
onLongPress = { onLongPress(student) }
)
}
}
}
}
@@ -0,0 +1,52 @@
package ru.megboyzz.lks.profile.ui.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun LoadingShield(title: String? = null) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
CircularProgressIndicator()
if(title != null)
Text(title)
}
}
}
@Composable
fun ErrorShield(title: String? = null) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = Icons.Outlined.Info,
contentDescription = null
)
if(title != null)
Text(title)
}
}
}
@@ -37,14 +37,19 @@ class SignInScreenModel @AssistedInject constructor(
val state = MutableStateFlow<SignInState>(SignInState.Idle) val state = MutableStateFlow<SignInState>(SignInState.Idle)
private val _loadingScreen = MutableStateFlow(false)
val loadingScreen = _loadingScreen.asStateFlow()
private var cookie: Map<String, String> = mapOf() private var cookie: Map<String, String> = mapOf()
init { init {
screenModelScope.launch { screenModelScope.launch(Dispatchers.IO) {
_loadingScreen.emit(true)
cookie = lksRepository.restoreCooke() cookie = lksRepository.restoreCooke()
if(lksRepository.cookiesIsValid(cookie)) if(lksRepository.cookiesIsValid(cookie))
navigator.push(SearchScreen()) navigator.push(SearchScreen())
_loadingScreen.emit(false)
} }
state.onEach { state.onEach {
@@ -1,8 +1,10 @@
package ru.megboyzz.lks.profile.ui.screens package ru.megboyzz.lks.profile.ui.screens
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
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.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -11,12 +13,16 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.hilt.getScreenModel import cafe.adriel.voyager.hilt.getScreenModel
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
import ru.megboyzz.lks.profile.ui.components.CardsColumn
import ru.megboyzz.lks.profile.ui.components.ErrorShield
import ru.megboyzz.lks.profile.ui.components.LoadingShield
import ru.megboyzz.lks.profile.ui.components.MainScaffold import ru.megboyzz.lks.profile.ui.components.MainScaffold
import ru.megboyzz.lks.profile.ui.components.ProfileCard import ru.megboyzz.lks.profile.ui.components.ProfileCard
import ru.megboyzz.lks.profile.ui.model.SearchScreenModel import ru.megboyzz.lks.profile.ui.model.SearchScreenModel
@@ -39,30 +45,17 @@ class SearchScreen : Screen {
onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) } onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) }
) { ) {
Column ( when (state) {
modifier = Modifier.padding(it) is SearchScreenModel.UiState.Loading -> LoadingShield("Загрузка челиков")
) { is SearchScreenModel.UiState.Error -> ErrorShield(state.status)
LazyColumn( else -> {
contentPadding = PaddingValues(8.dp), CardsColumn(
verticalArrangement = Arrangement.spacedBy(4.dp) modifier = Modifier.padding(it),
) { lksStudents = list.students,
onLongPress = { student -> bottomSheetNavigator.show(LongPressMenu(student)) }
item {
when(state) {
is SearchScreenModel.UiState.Loading -> CircularProgressIndicator()
is SearchScreenModel.UiState.Error -> Text(state.status ?: "Ошибка")
SearchScreenModel.UiState.Idle -> { Text("Idle") }
}
}
items(list.students) {
ProfileCard(
lksStudent = it,
onLongPress = { bottomSheetNavigator.show(LongPressMenu(it)) }
) )
} }
} }
}
} }
@@ -17,6 +17,7 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.hilt.getScreenModel 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.model.SignInScreenModel import ru.megboyzz.lks.profile.ui.model.SignInScreenModel
class SignInScreen : Screen { class SignInScreen : Screen {
@@ -35,6 +36,8 @@ class SignInScreen : Screen {
val state by viewModel.state.collectAsState() val state by viewModel.state.collectAsState()
val loading by viewModel.loadingScreen.collectAsState()
Box( Box(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@@ -44,6 +47,10 @@ class SignInScreen : Screen {
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
if(loading){
LoadingShield("Проверка твоих куки файлов :-)")
} else {
OutlinedTextField( OutlinedTextField(
value = username, value = username,
onValueChange = { viewModel.setUsername(it) } onValueChange = { viewModel.setUsername(it) }
@@ -60,11 +67,13 @@ class SignInScreen : Screen {
Text("Войти") Text("Войти")
} }
when(state) { when (state) {
is SignInScreenModel.SignInState.Idle -> Text("") is SignInScreenModel.SignInState.Idle -> Text("")
is SignInScreenModel.SignInState.Success -> Text(state.status ?: "") is SignInScreenModel.SignInState.Success -> Text(state.status ?: "")
is SignInScreenModel.SignInState.Loading -> CircularProgressIndicator() is SignInScreenModel.SignInState.Loading -> CircularProgressIndicator()
is SignInScreenModel.SignInState.Error -> Text(state.status ?: "Ошибка") is SignInScreenModel.SignInState.Error -> Text(state.status ?: "Ошибка")
else -> {}
}
} }
} }
@@ -21,9 +21,9 @@ class LongPressMenu(private val lksStudent: LksStudent) : Screen {
lksStudent = lksStudent lksStudent = lksStudent
) { ) {
Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show()
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://vk.com/search?q=${lksStudent.studentFullName}")) val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://vk.com/search?q=${lksStudent.studentFullName?.split(" ")?.dropLast(1)?.joinToString(" ")}"))
browserIntent.`package` = "com.vkontakte.android" browserIntent.`package` = "com.vkontakte.android"
context.startActivity(browserIntent); context.startActivity(browserIntent)
} }
+3 -1
View File
@@ -1,4 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="48dp" android:width="48dp"
android:height="48dp" android:height="48dp"
android:viewportWidth="48" android:viewportWidth="48"
@@ -8,5 +9,6 @@
android:fillColor="#1976d2"/> android:fillColor="#1976d2"/>
<path <path
android:pathData="M35.937,18.041c0.046,-0.151 0.068,-0.291 0.062,-0.416C35.984,17.263 35.735,17 35.149,17h-2.618c-0.661,0 -0.966,0.4 -1.144,0.801c0,0 -1.632,3.359 -3.513,5.574c-0.61,0.641 -0.92,0.625 -1.25,0.625C26.447,24 26,23.786 26,23.199v-5.185C26,17.32 25.827,17 25.268,17h-4.649C20.212,17 20,17.32 20,17.641c0,0.667 0.898,0.827 1,2.696v3.623C21,24.84 20.847,25 20.517,25c-0.89,0 -2.642,-3 -3.815,-6.932C16.448,17.294 16.194,17 15.533,17h-2.643C12.127,17 12,17.374 12,17.774c0,0.721 0.6,4.619 3.875,9.101C18.25,30.125 21.379,32 24.149,32c1.678,0 1.85,-0.427 1.85,-1.094v-2.972C26,27.133 26.183,27 26.717,27c0.381,0 1.158,0.25 2.658,2c1.73,2.018 2.044,3 3.036,3h2.618c0.608,0 0.957,-0.255 0.971,-0.75c0.003,-0.126 -0.015,-0.267 -0.056,-0.424c-0.194,-0.576 -1.084,-1.984 -2.194,-3.326c-0.615,-0.743 -1.222,-1.479 -1.501,-1.879C32.062,25.36 31.991,25.176 32,25c0.009,-0.185 0.105,-0.361 0.249,-0.607C32.223,24.393 35.607,19.642 35.937,18.041z" android:pathData="M35.937,18.041c0.046,-0.151 0.068,-0.291 0.062,-0.416C35.984,17.263 35.735,17 35.149,17h-2.618c-0.661,0 -0.966,0.4 -1.144,0.801c0,0 -1.632,3.359 -3.513,5.574c-0.61,0.641 -0.92,0.625 -1.25,0.625C26.447,24 26,23.786 26,23.199v-5.185C26,17.32 25.827,17 25.268,17h-4.649C20.212,17 20,17.32 20,17.641c0,0.667 0.898,0.827 1,2.696v3.623C21,24.84 20.847,25 20.517,25c-0.89,0 -2.642,-3 -3.815,-6.932C16.448,17.294 16.194,17 15.533,17h-2.643C12.127,17 12,17.374 12,17.774c0,0.721 0.6,4.619 3.875,9.101C18.25,30.125 21.379,32 24.149,32c1.678,0 1.85,-0.427 1.85,-1.094v-2.972C26,27.133 26.183,27 26.717,27c0.381,0 1.158,0.25 2.658,2c1.73,2.018 2.044,3 3.036,3h2.618c0.608,0 0.957,-0.255 0.971,-0.75c0.003,-0.126 -0.015,-0.267 -0.056,-0.424c-0.194,-0.576 -1.084,-1.984 -2.194,-3.326c-0.615,-0.743 -1.222,-1.479 -1.501,-1.879C32.062,25.36 31.991,25.176 32,25c0.009,-0.185 0.105,-0.361 0.249,-0.607C32.223,24.393 35.607,19.642 35.937,18.041z"
android:fillColor="#fff"/> android:fillColor="#fff"
tools:ignore="VectorPath" />
</vector> </vector>