main funtionality
This commit is contained in:
@@ -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) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user