shit happens
This commit is contained in:
@@ -16,10 +16,12 @@ 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.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
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
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
@@ -31,10 +33,13 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.snapshotFlow
|
||||||
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
|
||||||
@@ -42,6 +47,8 @@ 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
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import ru.megboyzz.lks.profile.MainActivity
|
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
|
||||||
@@ -182,10 +189,37 @@ private fun Main() {
|
|||||||
fun CardsColumn(
|
fun CardsColumn(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
lksStudents: List<LksStudent>,
|
lksStudents: List<LksStudent>,
|
||||||
onLongPress: (LksStudent) -> Unit
|
onLongPress: (LksStudent) -> Unit,
|
||||||
|
onColumnOverflow: suspend () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
val buffer = 1
|
||||||
|
|
||||||
|
var isLoading by remember { mutableStateOf(false) }
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
|
// observe list scrolling
|
||||||
|
val reachedBottom: Boolean by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
val lastVisibleItem = listState.layoutInfo.visibleItemsInfo.lastOrNull()
|
||||||
|
lastVisibleItem?.index != 0 && lastVisibleItem?.index == listState.layoutInfo.totalItemsCount - buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load more if scrolled to bottom
|
||||||
|
LaunchedEffect(reachedBottom) {
|
||||||
|
if (reachedBottom) {
|
||||||
|
isLoading = true
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
onColumnOverflow()
|
||||||
|
}
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
state = listState,
|
||||||
contentPadding = PaddingValues(12.dp),
|
contentPadding = PaddingValues(12.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
@@ -195,6 +229,10 @@ fun CardsColumn(
|
|||||||
onLongPress = { onLongPress(student) }
|
onLongPress = { onLongPress(student) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if(isLoading)
|
||||||
|
item {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,7 @@ package ru.megboyzz.lks.profile.ui.model
|
|||||||
|
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import cafe.adriel.voyager.hilt.ScreenModelFactory
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
|
||||||
import dagger.assisted.AssistedFactory
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -15,7 +13,6 @@ import ru.megboyzz.lks.profile.domain.DefaultCookies
|
|||||||
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
import ru.megboyzz.lks.profile.domain.entities.LksRequest
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
import ru.megboyzz.lks.profile.domain.entities.LksResponse
|
||||||
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
import ru.megboyzz.lks.profile.domain.repositories.LksRepository
|
||||||
import ru.megboyzz.lks.profile.ui.HiltModule.MyFactory
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SearchScreenModel @Inject constructor(
|
class SearchScreenModel @Inject constructor(
|
||||||
@@ -43,30 +40,47 @@ class SearchScreenModel @Inject constructor(
|
|||||||
val state = MutableStateFlow<UiState>(UiState.Idle)
|
val state = MutableStateFlow<UiState>(UiState.Idle)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
/* _curPageNumber.onEach {
|
_curPageNumber.onEach {
|
||||||
update()
|
update(_request.value)
|
||||||
}*/
|
}.launchIn(CoroutineScope(Dispatchers.IO))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nextPage() = screenModelScope.launch { _curPageNumber.emit(_curPageNumber.value++) }
|
fun nextPage() = screenModelScope.launch { _curPageNumber.emit(_curPageNumber.value++) }
|
||||||
|
|
||||||
fun newSearch(request: LksRequest) = screenModelScope.launch(Dispatchers.IO) {
|
fun resetStudents() = screenModelScope.launch {
|
||||||
|
_responseList.emit(LksResponse())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newSearch(request: LksRequest) {
|
||||||
|
screenModelScope.launch(Dispatchers.IO) {
|
||||||
|
resetStudents()
|
||||||
|
update(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun update(request: LksRequest) {
|
||||||
|
|
||||||
state.emit(UiState.Loading)
|
state.emit(UiState.Loading)
|
||||||
|
|
||||||
|
_request.emit(request)
|
||||||
|
|
||||||
val repoCookies = lksRepository.restoreCooke()
|
val repoCookies = lksRepository.restoreCooke()
|
||||||
|
|
||||||
val result = lksRepository.getPage(request, repoCookies, curPageNumber.value)
|
val result = lksRepository.getPage(request, repoCookies, curPageNumber.value)
|
||||||
|
|
||||||
if(result.isFailure) {
|
if(result.isFailure) {
|
||||||
state.emit(UiState.Error("Ошибка :-("))
|
state.emit(UiState.Error("Ошибка :-("))
|
||||||
return@launch
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val list = result.getOrElse { LksResponse() }
|
val list = result.getOrElse { LksResponse() }
|
||||||
|
|
||||||
_responseList.emit(list)
|
val updatedStudents = _responseList.value.copy(
|
||||||
|
students = _responseList.value.students + list.students,
|
||||||
|
availablePages = _responseList.value.availablePages + list.availablePages
|
||||||
|
)
|
||||||
|
|
||||||
|
_responseList.emit(updatedStudents)
|
||||||
|
|
||||||
state.emit(UiState.Idle)
|
state.emit(UiState.Idle)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.screens
|
package ru.megboyzz.lks.profile.ui.screens
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -16,6 +17,7 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.Alignment
|
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.platform.LocalContext
|
||||||
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
|
||||||
@@ -41,6 +43,8 @@ class SearchScreen : Screen {
|
|||||||
|
|
||||||
val list by screenModel.responseList.collectAsState()
|
val list by screenModel.responseList.collectAsState()
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
MainScaffold(
|
MainScaffold(
|
||||||
onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) }
|
onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen(screenModel)) }
|
||||||
) {
|
) {
|
||||||
@@ -52,7 +56,13 @@ class SearchScreen : Screen {
|
|||||||
CardsColumn(
|
CardsColumn(
|
||||||
modifier = Modifier.padding(it),
|
modifier = Modifier.padding(it),
|
||||||
lksStudents = list.students,
|
lksStudents = list.students,
|
||||||
onLongPress = { student -> bottomSheetNavigator.show(LongPressMenu(student)) }
|
onLongPress = { student -> bottomSheetNavigator.show(LongPressMenu(student)) },
|
||||||
|
onColumnOverflow = {
|
||||||
|
//Toast.makeText(context, "Hello!", Toast.LENGTH_SHORT).show()
|
||||||
|
screenModel.nextPage()
|
||||||
|
screenModel.update(screenModel.request.value)
|
||||||
|
//screenModel.nextPage()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package ru.megboyzz.lks.profile.ui.screens.sub
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
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.components.SearchContextMenu
|
||||||
import ru.megboyzz.lks.profile.ui.model.SearchScreenModel
|
import ru.megboyzz.lks.profile.ui.model.SearchScreenModel
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user