main funtionality

This commit is contained in:
2024-09-23 01:05:47 +03:00
parent 7d3d3517c5
commit e32b4feeef
10 changed files with 93 additions and 46 deletions
@@ -31,7 +31,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
MainNavigator(SearchScreen())
MainNavigator(SignInScreen())
}
}
}
@@ -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<String, String>) = 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<String, String>()
}
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()
)
}
@@ -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<String, String> = signInLks(username, password)
override suspend fun cookiesIsValid(cookie: Map<String, String>): Boolean {
return true
return false
}
@@ -47,9 +49,13 @@ class LksRepositoryImpl @Inject constructor(
override suspend fun getPage(lksRequest: LksRequest, cookie: Map<String, String>, pageNumber: Int): Result<LksResponse> {
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())
@@ -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
@@ -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()
@@ -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(
@@ -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)
}
}
@@ -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<SearchScreenModel>()
val screenModel = getScreenModel<SearchScreenModel>("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)) }
)
}
}
@@ -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);
}
@@ -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<SearchScreenModel>()
val screenModel = rememberScreenModel { searchScreenModel }
SearchContextMenu { lksRequest -> screenModel.newSearch(lksRequest) }