From e32b4feeef0993f0c1da2bb5343931c153047fc5 Mon Sep 17 00:00:00 2001 From: megboyzz Date: Mon, 23 Sep 2024 01:05:47 +0300 Subject: [PATCH] main funtionality --- .../ru/megboyzz/lks/profile/MainActivity.kt | 2 +- .../java/ru/megboyzz/lks/profile/data/Core.kt | 30 ++++++++++---- .../data/repositories/LksRepositoryImpl.kt | 12 ++++-- .../java/ru/megboyzz/lks/profile/ui/Util.kt | 11 ++++- .../ui/components/SearchBottomComponents.kt | 10 ++--- .../profile/ui/components/SearchComponents.kt | 5 ++- .../lks/profile/ui/model/SearchScreenModel.kt | 15 +++---- .../lks/profile/ui/screens/SearchScreen.kt | 41 ++++++++++++------- .../profile/ui/screens/sub/LongPressMenu.kt | 6 +++ .../ui/screens/sub/SearchBottomScreen.kt | 7 +++- 10 files changed, 93 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt b/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt index 9113a1f..84d197e 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt @@ -31,7 +31,7 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { - MainNavigator(SearchScreen()) + MainNavigator(SignInScreen()) } } } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/data/Core.kt b/app/src/main/java/ru/megboyzz/lks/profile/data/Core.kt index a864d98..568c406 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/data/Core.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/data/Core.kt @@ -1,5 +1,6 @@ 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.LksResponse @@ -17,6 +18,7 @@ private fun Connection.dataMap(vararg pairs: Pair) = this.data(m suspend fun signInLks(username: String, password: String) = withContext(Dispatchers.IO) { val cookies = Jsoup .connect("https://lk.mirea.ru/auth.php?login=yes") + //.userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36") .dataMap( "AUTH_FORM" to "Y", "TYPE" to "AUTH", @@ -35,33 +37,47 @@ suspend fun signInLks(username: String, password: String) = withContext(Dispatch return@withContext mapOf() } -suspend fun fakeConnect(cookies: Cookies) = withContext(Dispatchers.IO) { +fun fakeConnect(cookies: Cookies) { Jsoup .connect("https://lk.mirea.ru/") + //.userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36") .cookies(cookies) .referrer("https://lk.mirea.ru/") .execute() } -suspend fun getPage(payload: LksRequest, cookies: Cookies, page: Int) = withContext(Dispatchers.IO) { +fun getProfilePage(payload: LksRequest, cookies: Cookies, page: Int): Document { val sesid = cookies["BITRIX_SM_UIDH"] + //Log.i("TEXT", "Its begin! 1") fakeConnect(cookies) - Jsoup + //Log.i("TEXT", "Its end! 1") + + //Log.i("TEXT", "Its begin! 2") + val conn = Jsoup .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) .referrer("https://lk.mirea.ru/") - .execute().parse() + .execute() + //Log.i("TEXT", "Its end! 2") + + val doc = conn.parse() + //Log.i("TEXT", "Its end! 3") + + println(doc.body()) + + return doc } fun Document.getTotalPages() = kotlin.runCatching { this.select("body > div.container > div.bx-pagination > div > ul > li:nth-child(6) > a > span").text().toInt() }.getOrNull() ?: 0 -fun Document.findStudentsInPage(): LksResponse { +fun findStudentsInPage(document: Document): LksResponse { - val table = this.select("body > div.container > table > tbody") ?: return LksResponse() + val table = document.select("body > div.container > table > tbody") ?: return LksResponse() val students = table.select("tr").map { @@ -88,7 +104,7 @@ fun Document.findStudentsInPage(): LksResponse { return LksResponse( students = students, - availablePages = this.getTotalPages() + availablePages = document.getTotalPages() ) } \ No newline at end of file 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 f4e1718..f0edfbf 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 @@ -1,8 +1,10 @@ package ru.megboyzz.lks.profile.data.repositories import android.content.SharedPreferences +import android.util.Log import androidx.core.content.edit import ru.megboyzz.lks.profile.data.findStudentsInPage +import ru.megboyzz.lks.profile.data.getProfilePage import ru.megboyzz.lks.profile.data.signInLks import ru.megboyzz.lks.profile.domain.CookiesPrefs import ru.megboyzz.lks.profile.domain.entities.LksRequest @@ -23,7 +25,7 @@ class LksRepositoryImpl @Inject constructor( ): Map = signInLks(username, password) override suspend fun cookiesIsValid(cookie: Map): Boolean { - return true + return false } @@ -47,9 +49,13 @@ class LksRepositoryImpl @Inject constructor( override suspend fun getPage(lksRequest: LksRequest, cookie: Map, pageNumber: Int): Result { - val document = ru.megboyzz.lks.profile.data.getPage(lksRequest, cookie, pageNumber) + Log.i("TEXT", "Its begin doc!") + val document = getProfilePage(lksRequest, cookie, pageNumber) + Log.i("TEXT", "Its begin end!") - val page = document.findStudentsInPage() + Log.i("TEXT", "Its begin!") + val page = findStudentsInPage(document) + Log.i("TEXT", "Its end!") return if(page == LksResponse()) Result.failure(Exception()) 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 fe065c3..31e0f35 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 @@ -1,6 +1,8 @@ package ru.megboyzz.lks.profile.ui +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.Composable @@ -9,11 +11,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import kotlin.concurrent.thread +@OptIn(ExperimentalFoundationApi::class) @Composable -fun Modifier.clickableWithNormalRipple(onClick: () -> Unit) = this.clickable( +fun Modifier.clickableWithNormalRipple( + onClick: () -> Unit = {}, + onLongClick: () -> Unit = {}, +) = this.combinedClickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(bounded = true), - onClick = onClick + onClick = onClick, + onLongClick = onLongClick ) @Composable 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 abead6b..b0f5e9c 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 @@ -224,12 +224,12 @@ fun SearchContextMenu( onClick = { val lksRequest = LksRequest( student = Student( - name = name, - surname = family, - patronymic = surname + name = name.ifEmpty { null }, + surname = family.ifEmpty { null }, + patronymic = surname.ifEmpty { null }, ), - group = group, - department = departamnet + group = group.ifEmpty { null }, + department = departamnet.ifEmpty { null } ) onSearch(lksRequest) bottomSheetNavigator?.hide() 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 bf9a6ba..49d8d7d 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 @@ -60,7 +60,10 @@ fun ProfileCard( shape = RoundedCornerShape(16.dp) ) .defaultMinSize(minWidth = 240.dp) - .clickableWithNormalRipple { toggled =! toggled }, + .clickableWithNormalRipple( + onClick = { toggled =! toggled }, + onLongClick = onLongPress + ), contentAlignment = Alignment.Center ) { Column( diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SearchScreenModel.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SearchScreenModel.kt index e0b6a6e..a500b2d 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SearchScreenModel.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/model/SearchScreenModel.kt @@ -5,6 +5,7 @@ import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.hilt.ScreenModelFactory import cafe.adriel.voyager.navigator.Navigator import dagger.assisted.AssistedFactory +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn @@ -46,19 +47,17 @@ class SearchScreenModel @Inject constructor( update() }*/ - _request.onEach { - update() - }.launchIn(screenModelScope) - } fun nextPage() = screenModelScope.launch { _curPageNumber.emit(_curPageNumber.value++) } - private fun update() = screenModelScope.launch { + fun newSearch(request: LksRequest) = screenModelScope.launch(Dispatchers.IO) { state.emit(UiState.Loading) - val result = lksRepository.getPage(_request.value, cookies, curPageNumber.value) + val repoCookies = lksRepository.restoreCooke() + + val result = lksRepository.getPage(request, repoCookies, curPageNumber.value) if(result.isFailure) { state.emit(UiState.Error("Ошибка :-(")) @@ -72,9 +71,5 @@ class SearchScreenModel @Inject constructor( state.emit(UiState.Idle) } - fun newSearch(request: LksRequest) = screenModelScope.launch { - _request.emit(request) - } - } \ No newline at end of file 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 d809b1a..026a8fb 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,6 +1,9 @@ package ru.megboyzz.lks.profile.ui.screens +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.CircularProgressIndicator @@ -8,6 +11,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +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 @@ -25,31 +29,38 @@ class SearchScreen : Screen { val bottomSheetNavigator = LocalBottomSheetNavigator.current - val screenModel = getScreenModel() + val screenModel = getScreenModel("my_tag") val state by screenModel.state.collectAsState() val list by screenModel.responseList.collectAsState() MainScaffold( - onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen()) } + onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) } ) { - LazyColumn( - contentPadding = PaddingValues(8.dp) + Column ( + modifier = Modifier.padding(it) ) { - item { - when(state) { - is SearchScreenModel.UiState.Loading -> CircularProgressIndicator() - is SearchScreenModel.UiState.Error -> Text(state.status ?: "Ошибка") - SearchScreenModel.UiState.Idle -> {} + 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)) } + ) } - } - items(list.students) { - ProfileCard( - lksStudent = it, - onLongPress = { bottomSheetNavigator.show(LongPressMenu(it)) } - ) } } 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 a461ca0..b86e487 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 @@ -1,5 +1,7 @@ package ru.megboyzz.lks.profile.ui.screens.sub +import android.content.Intent +import android.net.Uri import android.widget.Toast import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext @@ -7,6 +9,7 @@ import cafe.adriel.voyager.core.screen.Screen import ru.megboyzz.lks.profile.domain.entities.LksStudent import ru.megboyzz.lks.profile.ui.components.LongPressCardContextMenu + class LongPressMenu(private val lksStudent: LksStudent) : Screen { @Composable @@ -18,6 +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}")) + browserIntent.`package` = "com.vkontakte.android" + context.startActivity(browserIntent); } diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt index 2bb3d47..39fc0f6 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt @@ -1,17 +1,20 @@ package ru.megboyzz.lks.profile.ui.screens.sub import androidx.compose.runtime.Composable +import cafe.adriel.voyager.core.model.rememberScreenModel 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.model.SearchScreenModel -class SearchBottomScreen : Screen { +class SearchBottomScreen( + private val searchScreenModel: SearchScreenModel +) : Screen { @Composable override fun Content() { - val screenModel = getScreenModel() + val screenModel = rememberScreenModel { searchScreenModel } SearchContextMenu { lksRequest -> screenModel.newSearch(lksRequest) }