diff --git a/app/src/main/java/ru/megboyzz/lks/profile/data/repositories/LksRepositoryImpl.kt b/app/src/main/java/ru/megboyzz/lks/profile/data/repositories/LksRepositoryImpl.kt index f0edfbf..f724b72 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/data/repositories/LksRepositoryImpl.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/data/repositories/LksRepositoryImpl.kt @@ -25,7 +25,18 @@ class LksRepositoryImpl @Inject constructor( ): Map = signInLks(username, password) override suspend fun cookiesIsValid(cookie: Map): 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() } diff --git a/app/src/main/java/ru/megboyzz/lks/profile/domain/entities/LksRequest.kt b/app/src/main/java/ru/megboyzz/lks/profile/domain/entities/LksRequest.kt index 771aae3..8e09c6c 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/domain/entities/LksRequest.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/domain/entities/LksRequest.kt @@ -12,5 +12,5 @@ data class LksRequest( * Метод для получения пути после https://lk.mirea.ru/staff/students? ... */ fun getSubmitUrlPath(sesid: String) = - "sessid=$sesid&findname=${student}&findgroup=${group ?: ""}&finddepartment=${department ?: ""}&submit-filter=Найти" + "sessid=$sesid&findname=${student ?: ""}&findgroup=${group ?: ""}&finddepartment=${department ?: ""}&submit-filter=Найти" } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt index 31e0f35..7463f33 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.Dp import kotlin.concurrent.thread @OptIn(ExperimentalFoundationApi::class) diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt index 983bf38..caddf38 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt @@ -7,6 +7,7 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator +import cafe.adriel.voyager.transitions.SlideTransition import ru.megboyzz.lks.profile.ui.screens.SearchScreen @Composable @@ -14,7 +15,8 @@ fun MainNavigator(screen: Screen) { BottomSheetNavigator( sheetShape = RoundedCornerShape(12.dp) ) { - - Navigator(screen) + Navigator(screen) { + SlideTransition(it) + } } } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt index b0f5e9c..31d8521 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt @@ -40,6 +40,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.onSizeChanged @@ -264,7 +265,7 @@ fun ContextMenuButton( Box( modifier = Modifier .padding(8.dp) - .clickableWithNormalRipple(onClick) + .clickableWithNormalRipple(onClick = onClick) ) { Row( modifier = Modifier.fillMaxWidth(), @@ -278,7 +279,8 @@ fun ContextMenuButton( ) { Icon( painter = icon, - contentDescription = null + contentDescription = null, + tint = Color.Unspecified ) Text(text = label) } diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchComponents.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchComponents.kt index 49d8d7d..18fddf1 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchComponents.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchComponents.kt @@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth 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.material.icons.Icons import androidx.compose.material.icons.filled.Search @@ -35,6 +37,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +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 @@ -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.LksStudent import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple +import ru.megboyzz.lks.profile.ui.screens.sub.LongPressMenu import ru.megboyzz.lks.profile.ui.theme.MainTheme @Composable @@ -60,14 +64,17 @@ fun ProfileCard( shape = RoundedCornerShape(16.dp) ) .defaultMinSize(minWidth = 240.dp) + .clip(RoundedCornerShape(16.dp)) .clickableWithNormalRipple( - onClick = { toggled =! toggled }, - onLongClick = onLongPress + onClick = { toggled = !toggled }, + onLongClick = onLongPress, ), contentAlignment = Alignment.Center ) { Column( - modifier = Modifier.fillMaxWidth().padding(12.dp), + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(8.dp) ) { @@ -80,7 +87,9 @@ fun ProfileCard( AnimatedVisibility(toggled) { Column( - modifier = Modifier.padding(top = 4.dp).fillMaxWidth(), + modifier = Modifier + .padding(top = 4.dp) + .fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalAlignment = Alignment.CenterHorizontally ) { @@ -166,4 +175,26 @@ private fun Main() { } } +} + + +@Composable +fun CardsColumn( + modifier: Modifier = Modifier, + lksStudents: List, + onLongPress: (LksStudent) -> Unit +) { + Column(modifier) { + LazyColumn( + contentPadding = PaddingValues(12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + items(lksStudents) { student -> + ProfileCard( + lksStudent = student, + onLongPress = { onLongPress(student) } + ) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SharedComponets.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SharedComponets.kt new file mode 100644 index 0000000..f1ca264 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SharedComponets.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SignInScreenModel.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SignInScreenModel.kt index e65a9d0..f1937f3 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SignInScreenModel.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SignInScreenModel.kt @@ -37,14 +37,19 @@ class SignInScreenModel @AssistedInject constructor( val state = MutableStateFlow(SignInState.Idle) + private val _loadingScreen = MutableStateFlow(false) + val loadingScreen = _loadingScreen.asStateFlow() + private var cookie: Map = mapOf() init { - screenModelScope.launch { + screenModelScope.launch(Dispatchers.IO) { + _loadingScreen.emit(true) cookie = lksRepository.restoreCooke() if(lksRepository.cookiesIsValid(cookie)) navigator.push(SearchScreen()) + _loadingScreen.emit(false) } state.onEach { diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SearchScreen.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SearchScreen.kt index 026a8fb..d8f78d6 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SearchScreen.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SearchScreen.kt @@ -1,8 +1,10 @@ package ru.megboyzz.lks.profile.ui.screens import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items @@ -11,12 +13,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.hilt.getScreenModel 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.ProfileCard import ru.megboyzz.lks.profile.ui.model.SearchScreenModel @@ -39,28 +45,15 @@ class SearchScreen : Screen { onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) } ) { - Column ( - modifier = Modifier.padding(it) - ) { - LazyColumn( - contentPadding = PaddingValues(8.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - - 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)) } - ) - } + when (state) { + is SearchScreenModel.UiState.Loading -> LoadingShield("Загрузка челиков") + is SearchScreenModel.UiState.Error -> ErrorShield(state.status) + else -> { + CardsColumn( + modifier = Modifier.padding(it), + lksStudents = list.students, + onLongPress = { student -> bottomSheetNavigator.show(LongPressMenu(student)) } + ) } } diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SignInScreen.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SignInScreen.kt index 83e92b5..ee30be8 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SignInScreen.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/SignInScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.hilt.getScreenModel import cafe.adriel.voyager.navigator.LocalNavigator +import ru.megboyzz.lks.profile.ui.components.LoadingShield import ru.megboyzz.lks.profile.ui.model.SignInScreenModel class SignInScreen : Screen { @@ -35,6 +36,8 @@ class SignInScreen : Screen { val state by viewModel.state.collectAsState() + val loading by viewModel.loadingScreen.collectAsState() + Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center @@ -44,27 +47,33 @@ class SignInScreen : Screen { horizontalAlignment = Alignment.CenterHorizontally ) { - OutlinedTextField( - value = username, - onValueChange = { viewModel.setUsername(it) } - ) + if(loading){ + LoadingShield("Проверка твоих куки файлов :-)") + } else { - OutlinedTextField( - value = password, - onValueChange = { viewModel.setPassword(it) } - ) + OutlinedTextField( + value = username, + onValueChange = { viewModel.setUsername(it) } + ) - OutlinedButton( - onClick = viewModel::signIn - ) { - Text("Войти") - } + OutlinedTextField( + value = password, + onValueChange = { viewModel.setPassword(it) } + ) - when(state) { - is SignInScreenModel.SignInState.Idle -> Text("") - is SignInScreenModel.SignInState.Success -> Text(state.status ?: "") - is SignInScreenModel.SignInState.Loading -> CircularProgressIndicator() - is SignInScreenModel.SignInState.Error -> Text(state.status ?: "Ошибка") + OutlinedButton( + onClick = viewModel::signIn + ) { + Text("Войти") + } + + when (state) { + is SignInScreenModel.SignInState.Idle -> Text("") + is SignInScreenModel.SignInState.Success -> Text(state.status ?: "") + is SignInScreenModel.SignInState.Loading -> CircularProgressIndicator() + is SignInScreenModel.SignInState.Error -> Text(state.status ?: "Ошибка") + else -> {} + } } } diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt index b86e487..d25fb96 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt @@ -21,9 +21,9 @@ class LongPressMenu(private val lksStudent: LksStudent) : Screen { lksStudent = lksStudent ) { 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" - context.startActivity(browserIntent); + context.startActivity(browserIntent) } diff --git a/app/src/main/res/drawable/vk_ic.xml b/app/src/main/res/drawable/vk_ic.xml index 483c2b3..bff801d 100644 --- a/app/src/main/res/drawable/vk_ic.xml +++ b/app/src/main/res/drawable/vk_ic.xml @@ -1,4 +1,5 @@ + android:fillColor="#fff" + tools:ignore="VectorPath" />