From 7d3d3517c5a67b2f6f45500936f7a0b77e27c8f0 Mon Sep 17 00:00:00 2001 From: megboyzz Date: Sun, 22 Sep 2024 22:44:41 +0300 Subject: [PATCH] Search funcs --- .idea/deploymentTargetSelector.xml | 6 + .../ru/megboyzz/lks/profile/MainActivity.kt | 11 +- .../lks/profile/data/di/DataModule.kt | 4 +- .../ru/megboyzz/lks/profile/ui/HiltModule.kt | 12 + .../java/ru/megboyzz/lks/profile/ui/Util.kt | 20 + .../profile/ui/components/MainNavigator.kt | 20 + .../ui/components/SearchBottomComponents.kt | 346 ++++++++++++++++++ .../profile/ui/components/SearchComponents.kt | 154 +++++++- .../lks/profile/ui/model/SearchScreenModel.kt | 40 +- .../lks/profile/ui/screens/SearchScreen.kt | 58 +-- .../profile/ui/screens/sub/LongPressMenu.kt | 25 ++ .../ui/screens/sub/SearchBottomScreen.kt | 19 + .../ru/megboyzz/lks/profile/ui/theme/Theme.kt | 7 +- .../ru/megboyzz/lks/profile/ui/theme/Type.kt | 7 +- app/src/main/res/drawable/vk_ic.xml | 12 + 15 files changed, 700 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt create mode 100644 app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt create mode 100644 app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt create mode 100644 app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt create mode 100644 app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt create mode 100644 app/src/main/res/drawable/vk_ic.xml diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef3..600b76c 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -5,6 +5,12 @@ + + + + \ No newline at end of file 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 25a849e..9113a1f 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/MainActivity.kt @@ -6,13 +6,21 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator +import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator import dagger.hilt.android.AndroidEntryPoint +import ru.megboyzz.lks.profile.ui.components.MainNavigator +import ru.megboyzz.lks.profile.ui.screens.SearchScreen import ru.megboyzz.lks.profile.ui.screens.SignInScreen import ru.megboyzz.lks.profile.ui.theme.MainTheme @@ -21,8 +29,9 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() + setContent { - Navigator(SignInScreen()) + MainNavigator(SearchScreen()) } } } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/data/di/DataModule.kt b/app/src/main/java/ru/megboyzz/lks/profile/data/di/DataModule.kt index 47aef50..72fc539 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/data/di/DataModule.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/data/di/DataModule.kt @@ -31,8 +31,8 @@ class DataModule { fun providesDefaultCookies() = mapOf( "PHPSESSID" to "deleted", "BITRIX_SM_SOUND_LOGIN_PLAYED" to "Y", - "BITRIX_SM_UIDH" to "00000000000000000000000000000000", - "BITRIX_SM_UIDL" to "ivachev.a.a%40edu.mirea.ru" + "BITRIX_SM_UIDH" to "22f459c5c83cff9cd62c99693b00c361", + "BITRIX_SM_UIDL" to "kits.m.a%40edu.mirea.ru" ) } \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/HiltModule.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/HiltModule.kt index dadf8e7..5d08af2 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/HiltModule.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/HiltModule.kt @@ -9,7 +9,9 @@ import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityComponent import dagger.multibindings.IntoMap +import ru.megboyzz.lks.profile.ui.model.SearchScreenModel import ru.megboyzz.lks.profile.ui.model.SignInScreenModel +import javax.inject.Qualifier @Module @InstallIn(ActivityComponent::class) @@ -22,6 +24,9 @@ interface HiltModule { signInScreenModel: SignInScreenModel ) : ScreenModel*/ + @Qualifier + annotation class MyFactory + @Binds @IntoMap @ScreenModelFactoryKey(SignInScreenModel.Factory::class) @@ -29,4 +34,11 @@ interface HiltModule { factory: SignInScreenModel.Factory ): ScreenModelFactory + @Binds + @IntoMap + @ScreenModelKey(SearchScreenModel::class) + fun bindSearchScreenModelFactory( + factory: SearchScreenModel + ): ScreenModel + } \ 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 new file mode 100644 index 0000000..fe065c3 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/Util.kt @@ -0,0 +1,20 @@ +package ru.megboyzz.lks.profile.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import kotlin.concurrent.thread + +@Composable +fun Modifier.clickableWithNormalRipple(onClick: () -> Unit) = this.clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = true), + onClick = onClick +) + +@Composable +fun Int.asPainter() = painterResource(this) \ No newline at end of file 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 new file mode 100644 index 0000000..983bf38 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/MainNavigator.kt @@ -0,0 +1,20 @@ +package ru.megboyzz.lks.profile.ui.components + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +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 ru.megboyzz.lks.profile.ui.screens.SearchScreen + +@Composable +fun MainNavigator(screen: Screen) { + BottomSheetNavigator( + sheetShape = RoundedCornerShape(12.dp) + ) { + + Navigator(screen) + } +} \ 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 new file mode 100644 index 0000000..abead6b --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/components/SearchBottomComponents.kt @@ -0,0 +1,346 @@ +package ru.megboyzz.lks.profile.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.KeyboardArrowRight +import androidx.compose.material.icons.filled.KeyboardArrowUp +import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +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.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator +import ru.megboyzz.lks.profile.R +import ru.megboyzz.lks.profile.domain.entities.LksRequest +import ru.megboyzz.lks.profile.domain.entities.LksStudent +import ru.megboyzz.lks.profile.domain.entities.Student +import ru.megboyzz.lks.profile.ui.asPainter +import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple + +@Composable +fun ContextMenuContainer( + content: @Composable ColumnScope.() -> Unit +) { + + Column( + modifier = Modifier + .padding(4.dp) + .fillMaxWidth() + .navigationBarsPadding(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + + Box( + modifier = Modifier + .size(32.dp, 4.dp) + .clip(RoundedCornerShape(80)) + .background(MaterialTheme.colorScheme.onBackground) + ) + Spacer(Modifier.height(16.dp)) + Column ( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 12.dp) + .padding(bottom = 12.dp), + content = content + ) + + + } + +} + +@Preview +@Composable +private fun ContextMenuContainerPrev() { + + ContextMenuContainer { + + Text("Hello!") + Text("Hello!") + + } + +} + +@Composable +fun SearchTextField( + value: String, + onValueChange: (String) -> Unit, + suggestions: List? = null, + label: String? = null +) { + + var expanded by remember { mutableStateOf(false) } + + var dropDownWidth by remember { mutableIntStateOf(0) } + + val icon = if (expanded) + Icons.Filled.KeyboardArrowUp + else + Icons.Filled.KeyboardArrowDown + + + Column() { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + modifier = Modifier + .fillMaxWidth() + .onSizeChanged { dropDownWidth = it.width }, + label = { Text(label ?: "Label") }, + trailingIcon = { + if(suggestions != null) + Icon( + icon, + "contentDescription", + Modifier.clickableWithNormalRipple{ expanded = !expanded } + ) + } + ) + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + modifier = Modifier + .width(with(LocalDensity.current){dropDownWidth.toDp()}) + ) { + suggestions?.forEach { label -> + DropdownMenuItem( + onClick = { onValueChange(label) }, + text = { Text(text = label) } + ) + } + } + } + +} + +@Preview +@Composable +fun SearchTextFieldPrev() { + + val suggestions = listOf("Item1","Item2","Item3") + var value by remember { mutableStateOf("") } + + SearchTextField( + value = value, + onValueChange = { value = it }, + suggestions = suggestions + ) + +} + +@Composable +fun SearchContextMenu( + onSearch: (LksRequest) -> Unit +) { + + val bottomSheetNavigator = LocalBottomSheetNavigator.current + + var name by remember { mutableStateOf("") } + var surname by remember { mutableStateOf("") } + var family by remember { mutableStateOf("") } + + var group by remember { mutableStateOf("") } + var departamnet by remember { mutableStateOf("") } + + ContextMenuContainer { + + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + + SearchTextField( + value = family, + onValueChange = {family = it}, + label = "Фамилия" + ) + + SearchTextField( + value = name, + onValueChange = {name = it}, + label = "Имя" + ) + + SearchTextField( + value = surname, + onValueChange = {surname = it}, + label = "Отчество" + ) + + Spacer(Modifier.height(1.dp)) + HorizontalDivider(color = MaterialTheme.colorScheme.onBackground) + + SearchTextField( + value = group, + onValueChange = {group = it}, + label = "Учебная группа" + ) + + SearchTextField( + value = departamnet, + onValueChange = { departamnet = it }, + label = "Подразделение" + ) + + Button( + shape = OutlinedTextFieldDefaults.shape, + modifier = Modifier.fillMaxWidth(), + onClick = { + val lksRequest = LksRequest( + student = Student( + name = name, + surname = family, + patronymic = surname + ), + group = group, + department = departamnet + ) + onSearch(lksRequest) + bottomSheetNavigator?.hide() + } + ) { + Text("Поиск") + } + + } + + } + +} + +@Preview +@Composable +private fun SearchContextMenuPrev() { + + SearchContextMenu { + + } + +} + +@Composable +fun ContextMenuButton( + icon: Painter, + label: String, + onClick: () -> Unit +) { + + Box( + modifier = Modifier + .padding(8.dp) + .clickableWithNormalRipple(onClick) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { + Icon( + painter = icon, + contentDescription = null + ) + Text(text = label) + } + + Icon( + imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight, + contentDescription = null + ) + + } + + } + +} + +@Preview +@Composable +fun ContextMenuButtonPrev() { + + ContextMenuButton( + icon = R.drawable.vk_ic.asPainter(), + label = "Переидти в VK", + onClick = {} + ) + +} + +@Composable +fun LongPressCardContextMenu( + lksStudent: LksStudent, + onClick: () -> Unit +) { + ContextMenuContainer { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + + Text( + "${lksStudent.studentFullName} ${lksStudent.group}" + ) + HorizontalDivider(color = MaterialTheme.colorScheme.onBackground) + ContextMenuButton( + icon = R.drawable.vk_ic.asPainter(), + label = "Переидти в VK", + onClick = onClick + ) + } + } +} + +@Preview +@Composable +private fun LongPressCardContextMenuPrev() { + + val lksStudent = LksStudent( + studentFullName = "Киц Михаил Андреевич", + group = "ИКБО-03-20" + ) + + LongPressCardContextMenu( + lksStudent = lksStudent, + onClick = {} + ) + + +} + 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 a058271..bf9a6ba 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 @@ -1,14 +1,166 @@ package ru.megboyzz.lks.profile.ui.components import android.provider.ContactsContract.Profile +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +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.WindowInsets +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Search +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +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.theme.MainTheme @Composable -fun ProfileCard(lksStudent: LksStudent) { +fun ProfileCard( + lksStudent: LksStudent, + onLongPress: () -> Unit +) { + + var toggled by remember { mutableStateOf(false) } + + Box( + modifier = Modifier + .border( + border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary), + shape = RoundedCornerShape(16.dp) + ) + .defaultMinSize(minWidth = 240.dp) + .clickableWithNormalRipple { toggled =! toggled }, + contentAlignment = Alignment.Center + ) { + Column( + modifier = Modifier.fillMaxWidth().padding(12.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + text = lksStudent.studentFullName ?: "<Нет имени>" + ) + Text( + text = lksStudent.group ?: "<Нет группы>" + ) + AnimatedVisibility(toggled) { + + Column( + modifier = Modifier.padding(top = 4.dp).fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + HorizontalDivider( + modifier = Modifier.fillMaxWidth(), + color = MaterialTheme.colorScheme.primary + ) + Text( + text = lksStudent.department ?: "<Нет подразделения>" + ) + } + } + } + } + +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainScaffold( + onFloatingButtonClick: () -> Unit, + content: @Composable (PaddingValues) -> Unit +) { + + Scaffold( + topBar = { + Surface(shadowElevation = 8.dp) { + TopAppBar( + title = { Text("LKS Search") } + ) + } + }, + floatingActionButton = { + FloatingActionButton(onFloatingButtonClick) { + Icon( + imageVector = Icons.Default.Search, + contentDescription = null + ) + } + }, + content = content + ) + +} + +@Preview +@Composable +private fun ProfileCardPrev() { + + val student = LksStudent( + studentFullName = "Киц Михаил Андреевич", + department = "ИИТ", + group = "ИКБО-03-20" + ) + + ProfileCard( + lksStudent = student + ) { } + +} + +@Preview +@Composable +private fun Main() { + + val student = LksStudent( + studentFullName = "Киц Михаил Андреевич", + department = "ИИТ", + group = "ИКБО-03-20" + ) + + MainTheme { + MainScaffold( + onFloatingButtonClick = {} + ) { + Column(modifier = Modifier.padding(it)) { + ProfileCard( + lksStudent = student + ) { } + } + } + } } \ No newline at end of file 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 63a46a6..e0b6a6e 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 @@ -2,14 +2,19 @@ package ru.megboyzz.lks.profile.ui.model import cafe.adriel.voyager.core.model.ScreenModel 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.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import ru.megboyzz.lks.profile.domain.DefaultCookies import ru.megboyzz.lks.profile.domain.entities.LksRequest import ru.megboyzz.lks.profile.domain.entities.LksResponse import ru.megboyzz.lks.profile.domain.repositories.LksRepository +import ru.megboyzz.lks.profile.ui.HiltModule.MyFactory import javax.inject.Inject class SearchScreenModel @Inject constructor( @@ -27,30 +32,49 @@ class SearchScreenModel @Inject constructor( private val _responseList = MutableStateFlow(LksResponse()) val responseList = _responseList.asStateFlow() + sealed class UiState(val status: String? = null) { + data object Loading: UiState() + //data object Success: SignInState("Успешный вход") + data class Error(val _status: String) : UiState(_status) + data object Idle: UiState() + } + + val state = MutableStateFlow(UiState.Idle) + init { - _curPageNumber.onEach { + /* _curPageNumber.onEach { update() - } + }*/ + + _request.onEach { + update() + }.launchIn(screenModelScope) + } fun nextPage() = screenModelScope.launch { _curPageNumber.emit(_curPageNumber.value++) } private fun update() = screenModelScope.launch { + state.emit(UiState.Loading) + val result = lksRepository.getPage(_request.value, cookies, curPageNumber.value) + if(result.isFailure) { + state.emit(UiState.Error("Ошибка :-(")) + return@launch + } + val list = result.getOrElse { LksResponse() } _responseList.emit(list) + + state.emit(UiState.Idle) } - fun newSearch() = screenModelScope.launch { - - _curPageNumber.emit(1) - update() - + 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 6037b43..d809b1a 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,44 +1,58 @@ 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.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.OutlinedTextField +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue 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.LocalNavigator +import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator +import ru.megboyzz.lks.profile.ui.components.MainScaffold +import ru.megboyzz.lks.profile.ui.components.ProfileCard import ru.megboyzz.lks.profile.ui.model.SearchScreenModel +import ru.megboyzz.lks.profile.ui.screens.sub.LongPressMenu +import ru.megboyzz.lks.profile.ui.screens.sub.SearchBottomScreen class SearchScreen : Screen { @Composable override fun Content() { + val bottomSheetNavigator = LocalBottomSheetNavigator.current + val screenModel = getScreenModel() - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.TopCenter + val state by screenModel.state.collectAsState() + + val list by screenModel.responseList.collectAsState() + + MainScaffold( + onFloatingButtonClick = { bottomSheetNavigator.show(SearchBottomScreen()) } ) { - Column( - verticalArrangement = Arrangement.spacedBy(16.dp) + + LazyColumn( + contentPadding = PaddingValues(8.dp) ) { - Spacer(Modifier.height(20.dp)) - val navigator = LocalNavigator.current!! - - - - + item { + when(state) { + is SearchScreenModel.UiState.Loading -> CircularProgressIndicator() + is SearchScreenModel.UiState.Error -> Text(state.status ?: "Ошибка") + SearchScreenModel.UiState.Idle -> {} + } + } + 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 new file mode 100644 index 0000000..a461ca0 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/LongPressMenu.kt @@ -0,0 +1,25 @@ +package ru.megboyzz.lks.profile.ui.screens.sub + +import android.widget.Toast +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +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 + override fun Content() { + + val context = LocalContext.current + + LongPressCardContextMenu( + lksStudent = lksStudent + ) { + Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show() + } + + + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..2bb3d47 --- /dev/null +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/screens/sub/SearchBottomScreen.kt @@ -0,0 +1,19 @@ +package ru.megboyzz.lks.profile.ui.screens.sub + +import androidx.compose.runtime.Composable +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 { + + @Composable + override fun Content() { + + val screenModel = getScreenModel() + + SearchContextMenu { lksRequest -> screenModel.newSearch(lksRequest) } + + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Theme.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Theme.kt index fa181e4..33aa5e3 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Theme.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Theme.kt @@ -8,6 +8,7 @@ import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext private val DarkColorScheme = darkColorScheme( @@ -19,9 +20,9 @@ private val DarkColorScheme = darkColorScheme( private val LightColorScheme = lightColorScheme( primary = Purple40, secondary = PurpleGrey40, - tertiary = Pink40 + tertiary = Pink40, - /* Other default colors to override + // Other default colors to override background = Color(0xFFFFFBFE), surface = Color(0xFFFFFBFE), onPrimary = Color.White, @@ -29,7 +30,7 @@ private val LightColorScheme = lightColorScheme( onTertiary = Color.White, onBackground = Color(0xFF1C1B1F), onSurface = Color(0xFF1C1B1F), - */ + ) @Composable diff --git a/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Type.kt b/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Type.kt index aa54b05..4a79773 100644 --- a/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Type.kt +++ b/app/src/main/java/ru/megboyzz/lks/profile/ui/theme/Type.kt @@ -14,11 +14,11 @@ val Typography = Typography( fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.5.sp - ) - /* Other default text styles to override + ), + // Other default text styles to override titleLarge = TextStyle( fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, + fontWeight = FontWeight.Medium, fontSize = 22.sp, lineHeight = 28.sp, letterSpacing = 0.sp @@ -30,5 +30,4 @@ val Typography = Typography( lineHeight = 16.sp, letterSpacing = 0.5.sp ) - */ ) \ No newline at end of file diff --git a/app/src/main/res/drawable/vk_ic.xml b/app/src/main/res/drawable/vk_ic.xml new file mode 100644 index 0000000..483c2b3 --- /dev/null +++ b/app/src/main/res/drawable/vk_ic.xml @@ -0,0 +1,12 @@ + + + +