Реализована функция копирования в буфер обмена
@@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
@@ -5,12 +5,6 @@
|
|||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
</SelectionState>
|
</SelectionState>
|
||||||
<SelectionState runConfigName="SearchTextFieldPrev">
|
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
|
||||||
</SelectionState>
|
|
||||||
<SelectionState runConfigName="SearchContextMenuPrev">
|
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
|
||||||
</SelectionState>
|
|
||||||
</selectionStates>
|
</selectionStates>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -2,7 +2,7 @@ plugins {
|
|||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.android)
|
alias(libs.plugins.kotlin.android)
|
||||||
alias(libs.plugins.kotlin.compose)
|
alias(libs.plugins.kotlin.compose)
|
||||||
kotlin("kapt")
|
id("com.google.devtools.ksp")
|
||||||
id("com.google.dagger.hilt.android")
|
id("com.google.dagger.hilt.android")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ dependencies {
|
|||||||
debugImplementation(libs.androidx.ui.test.manifest)
|
debugImplementation(libs.androidx.ui.test.manifest)
|
||||||
|
|
||||||
implementation(libs.hilt.android)
|
implementation(libs.hilt.android)
|
||||||
kapt(libs.hilt.android.compiler)
|
ksp(libs.hilt.android.compiler)
|
||||||
|
|
||||||
|
|
||||||
implementation(libs.voyager.navigator)
|
implementation(libs.voyager.navigator)
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"ИДО": "Институт дополнительного образования",
|
||||||
|
"ИМО": "Институт международного образования",
|
||||||
|
"ИДП": "Институт довузовской подготовки",
|
||||||
|
"ИТХТ": "Институт тонких химических технологий имени М.В. Ломоносова",
|
||||||
|
"ИИИ": "Институт искусственного интеллекта",
|
||||||
|
"БК250": "Базовая кафедра № 250 - математического обеспечения информационных систем",
|
||||||
|
"ИПТ": "Институт перспективных технологий и индустриального программирования",
|
||||||
|
"БК235": "Базовая кафедра № 235 - цифровых устройств и систем защиты информации",
|
||||||
|
"КСТУ": "Кафедра современных технологий управления",
|
||||||
|
"БК536": "Базовая кафедра № 536 - программного обеспечения систем РЭА",
|
||||||
|
"ИКДТ": "Институт кибербезопасности и цифровых технологий",
|
||||||
|
"УПО": "Управление платных образовательных услуг",
|
||||||
|
"КВМ3": "Кафедра высшей математики-3",
|
||||||
|
"КФТМ": "Кафедра физики и технической механики",
|
||||||
|
"УОРТ": "Учебный отдел Института радиотехнических и телекоммуникационных систем",
|
||||||
|
"БК333": "Базовая кафедра № 333 имени профессора Лобанова Б.С. - систем радиоэлектронной борьбы",
|
||||||
|
"БК334": "Базовая кафедра № 334 - дальней радиосвязи",
|
||||||
|
"БК338": "Базовая кафедра № 338 - космической радиоэлектроники",
|
||||||
|
"КИЭТ": "Кафедра инженерной экологии техносферы",
|
||||||
|
"КИЯ1": "Кафедра иностранных языков 1",
|
||||||
|
"КРЭСК": "Кафедра радиоэлектронных систем и комплексов",
|
||||||
|
"КБПФ": "Кафедра биотехнологии и промышленной фармации",
|
||||||
|
"КДГП": "Кафедра документоведения, истории государства и права",
|
||||||
|
"БК340": "Базовая кафедра № 340 - информационных космических систем",
|
||||||
|
"БК343": "Базовая кафедра № 343 - моделирования радиофизических процессов",
|
||||||
|
"ЦДО": "Центр дистанционного обучения",
|
||||||
|
"КФТМ2024": "Кафедра физики и технической механики (от 19.06.2024 № 26-ст)",
|
||||||
|
"КИТГУ": "Кафедра информационных технологий в государственном управлении",
|
||||||
|
"КМОСИТ": "Кафедра математического обеспечения и стандартизации информационных технологий",
|
||||||
|
"КПК": "Колледж программирования и кибербезопасности",
|
||||||
|
"КВТ": "Кафедра вычислительной техники",
|
||||||
|
"ИИТ": "Институт информационных технологий",
|
||||||
|
"КИГ": "Кафедра инженерной графики",
|
||||||
|
"КЭТ": "Кафедра экономической теории",
|
||||||
|
"КОИ": "Кафедра общей информатики",
|
||||||
|
"ККПРЭС": "Кафедра конструирования и производства радиоэлектронных средств",
|
||||||
|
"КСИ": "Кафедра системной инженерии",
|
||||||
|
"Аспирантура": "Аспирантура",
|
||||||
|
"ПОДГ": "Подготовительное отделение для иностранных граждан",
|
||||||
|
"Ректорат": "Ректорат",
|
||||||
|
"ИРИ": "Институт радиоэлектроники и информатики",
|
||||||
|
"ЮО": "Юридический отдел",
|
||||||
|
"УМУ": "Учебно-методическое управление",
|
||||||
|
"УК": "Управление кадров",
|
||||||
|
"ФФГБОУВОС": "Филиал федерального государственного бюджетного образовательного учреждения высшего образования «МИРЭА - Российский технологический университет» в г. Ставрополе",
|
||||||
|
"УГОЧС": "Управление гражданской обороны и чрезвычайных ситуаций",
|
||||||
|
"КН": "Кафедра наноэлектроники",
|
||||||
|
"Бухгалтерия": "Бухгалтерия",
|
||||||
|
"УОИМО": "Учебный отдел института международного образования",
|
||||||
|
"СПВ86": "Сектор «Проспект Вернадского, 86»",
|
||||||
|
"СИАО": "Студенческий информационно-архивный отдел",
|
||||||
|
"УЭФ": "Управление экономики и финансов",
|
||||||
|
"УМС": "Управление международных связей",
|
||||||
|
"УВСР": "Управление по воспитательной и социальной работе",
|
||||||
|
"ПР": "Первый отдел",
|
||||||
|
"СГИ": "Служба главного инженера",
|
||||||
|
"НТБ": "Научно-техническая библиотека",
|
||||||
|
"УИ": "Управление информатизации",
|
||||||
|
"КМС": "Кафедра метрологии и стандартизации",
|
||||||
|
"ССт20": "Сектор «Стромынка, 20»",
|
||||||
|
"ИАО": "Информационно-аналитический отдел",
|
||||||
|
"ОСПР": "Отдел судебно-претензионной работы",
|
||||||
|
"БК140": "Базовая кафедра № 140 - фотоники",
|
||||||
|
"УД": "Управление делами",
|
||||||
|
"УМП": "Управление мобилизационной подготовки",
|
||||||
|
"БК130": "Базовая кафедра № 130 - твердотельной электроники",
|
||||||
|
"НОЦТЦ": "Научно-образовательный центр «Технологический центр»",
|
||||||
|
"БК131": "Базовая кафедра № 131 - оптико-физических измерений",
|
||||||
|
"БК132": "Базовая кафедра № 132 - лазерной техники",
|
||||||
|
"БК136": "Базовая кафедра № 136 - СВЧ приборов и устройств",
|
||||||
|
"ФМШ": "Физико-математическая школа",
|
||||||
|
"КПВВ": "Курсы по подготовке к поступлению в вуз",
|
||||||
|
"ОМКО": "Отдел менеджмента качества образования",
|
||||||
|
"ОТСО": "Отдел технических средств обучения",
|
||||||
|
"ОЗЗИ": "Отдел обеспечения защиты информации",
|
||||||
|
"ОТК": "Отдел технического контроля",
|
||||||
|
"Автобаза": "Автобаза",
|
||||||
|
"Академия ТВ": "Академия ТВ",
|
||||||
|
"ГИВЦ": "Главный информационно-вычислительный центр",
|
||||||
|
"УНИР": "Управление научно-исследовательских разработок",
|
||||||
|
"КДЦ": "Культурно-досуговый центр",
|
||||||
|
"МНТЦИС": "Межотраслевой научно-технический центр интеллектуальных технологий обработки информации и управления «Интеллектуальные системы»",
|
||||||
|
"НТЦН": "Научно-технологический центр «Наука»",
|
||||||
|
"НИЦРСВТ": "Научно-исследовательский центр разработки специальной вычислительной техники",
|
||||||
|
"НИЦИПМ": "Научно-исследовательский центр «Инновационные полимерные материалы и изделия»",
|
||||||
|
"ОИТОСБ": "Отдел инженерно-технического обеспечения средств безопасности",
|
||||||
|
"ЦПИС": "Центр проектирования интегральных схем, устройств наноэлектроники и микросистем",
|
||||||
|
"ЦЯП": "Центр языковой подготовки",
|
||||||
|
"ИМПМО": "Институт молодежной политики и международных отношений",
|
||||||
|
"НИИМФП": "Научно-исследовательский институт медицинской и фармацевтической промышленности",
|
||||||
|
"ИПЦСНК": "Инженерно-научный производственный центр «Средства неразрушающего контроля» МИРЭА",
|
||||||
|
"УЦВ": "Учебный центр подготовки водителей",
|
||||||
|
"ИТП": "Институт технологического предпринимательства",
|
||||||
|
"СУЛСДФ": "Специализированная учебно-научная лаборатория сверхбыстрой динамики ферроиков",
|
||||||
|
"УНИИСУ": "Учебно-научный институт информатики и систем управления",
|
||||||
|
"УМЦИТ": "Учебно-методический центр интерактивных технологий",
|
||||||
|
"ОКБМИРЭА": "Особое конструкторское бюро МИРЭА",
|
||||||
|
"ИУС": "Институт учета и статистики",
|
||||||
|
"НИЦПНТП": "Научно-инжиниринговый центр «Перспективные научно-технические проекты»",
|
||||||
|
"Наноцентр МИРЭА": "Наноцентр МИРЭА",
|
||||||
|
"НТЦИРФ": "Научно-технологический центр «Интегральная радиофотоника»",
|
||||||
|
"РИО": "Редакционно-издательский отдел",
|
||||||
|
"ПЛМА": "Проблемная лаборатория молекулярной активации"
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
|||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package ru.megboyzz.lks.profile.ui
|
package ru.megboyzz.lks.profile.ui
|
||||||
|
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
@@ -24,5 +28,27 @@ fun Modifier.clickableWithNormalRipple(
|
|||||||
onLongClick = onLongClick
|
onLongClick = onLongClick
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun Modifier.clickableWithNoEffect(
|
||||||
|
onClick: () -> Unit = {},
|
||||||
|
onLongClick: () -> Unit = {},
|
||||||
|
) = this.combinedClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick
|
||||||
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Int.asPainter() = painterResource(this)
|
fun Int.asPainter() = painterResource(this)
|
||||||
|
|
||||||
|
fun Context.copyToClipboard(content: String) {
|
||||||
|
val clipboardManager = this.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
|
||||||
|
val clip = ClipData.newPlainText("label", content)
|
||||||
|
|
||||||
|
clipboardManager.setPrimaryClip(clip)
|
||||||
|
|
||||||
|
Toast.makeText(this, "Текст скопирован в буфер обмена", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
@@ -9,14 +9,17 @@ import cafe.adriel.voyager.navigator.Navigator
|
|||||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||||
import cafe.adriel.voyager.transitions.SlideTransition
|
import cafe.adriel.voyager.transitions.SlideTransition
|
||||||
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
import ru.megboyzz.lks.profile.ui.screens.SearchScreen
|
||||||
|
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainNavigator(screen: Screen) {
|
fun MainNavigator(screen: Screen) {
|
||||||
BottomSheetNavigator(
|
BottomSheetNavigator(
|
||||||
sheetShape = RoundedCornerShape(12.dp)
|
sheetShape = RoundedCornerShape(12.dp)
|
||||||
) {
|
) {
|
||||||
Navigator(screen) {
|
MainTheme {
|
||||||
SlideTransition(it)
|
Navigator(screen) {
|
||||||
|
SlideTransition(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.components
|
package ru.megboyzz.lks.profile.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
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
|
||||||
@@ -18,19 +17,18 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowRight
|
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||||
|
import androidx.compose.material.icons.outlined.AccountCircle
|
||||||
|
import androidx.compose.material.icons.outlined.Person
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedButton
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.OutlinedTextFieldDefaults
|
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
@@ -42,7 +40,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
@@ -62,7 +60,7 @@ fun ContextMenuContainer(
|
|||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(4.dp)
|
.padding(horizontal = 4.dp, vertical = 8.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.navigationBarsPadding(),
|
.navigationBarsPadding(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
@@ -264,7 +262,7 @@ fun ContextMenuButton(
|
|||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(0.dp)
|
||||||
.clickableWithNormalRipple(onClick = onClick)
|
.clickableWithNormalRipple(onClick = onClick)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
@@ -275,19 +273,20 @@ fun ContextMenuButton(
|
|||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = icon,
|
painter = icon,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color.Unspecified
|
tint = Color.Unspecified,
|
||||||
|
modifier = Modifier.size(36.dp)
|
||||||
)
|
)
|
||||||
Text(text = label)
|
Text(text = label)
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
|
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
|
||||||
contentDescription = null
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -311,10 +310,12 @@ fun ContextMenuButtonPrev() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun LongPressCardContextMenu(
|
fun LongPressCardContextMenu(
|
||||||
lksStudent: LksStudent,
|
lksStudent: LksStudent,
|
||||||
onClick: () -> Unit
|
onGoToVk: () -> Unit,
|
||||||
|
onCopyName: (String) -> Unit,
|
||||||
|
onCopyGroup: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
ContextMenuContainer {
|
ContextMenuContainer {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
"${lksStudent.studentFullName} ${lksStudent.group}"
|
"${lksStudent.studentFullName} ${lksStudent.group}"
|
||||||
@@ -323,7 +324,17 @@ fun LongPressCardContextMenu(
|
|||||||
ContextMenuButton(
|
ContextMenuButton(
|
||||||
icon = R.drawable.vk_ic.asPainter(),
|
icon = R.drawable.vk_ic.asPainter(),
|
||||||
label = "Переидти в VK",
|
label = "Переидти в VK",
|
||||||
onClick = onClick
|
onClick = onGoToVk
|
||||||
|
)
|
||||||
|
ContextMenuButton(
|
||||||
|
icon = rememberVectorPainter(Icons.Outlined.AccountCircle),
|
||||||
|
label = "Скопировать имя пользователя",
|
||||||
|
onClick = { onCopyName.invoke(lksStudent.studentFullName ?: "") }
|
||||||
|
)
|
||||||
|
ContextMenuButton(
|
||||||
|
icon = rememberVectorPainter(Icons.Outlined.Person),
|
||||||
|
label = "Скопировать группу",
|
||||||
|
onClick = { onCopyGroup.invoke(lksStudent.group ?: "") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,7 +351,9 @@ private fun LongPressCardContextMenuPrev() {
|
|||||||
|
|
||||||
LongPressCardContextMenu(
|
LongPressCardContextMenu(
|
||||||
lksStudent = lksStudent,
|
lksStudent = lksStudent,
|
||||||
onClick = {}
|
onGoToVk = {},
|
||||||
|
onCopyName = {},
|
||||||
|
onCopyGroup = {}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ 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
|
||||||
|
import ru.megboyzz.lks.profile.ui.clickableWithNoEffect
|
||||||
import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple
|
import ru.megboyzz.lks.profile.ui.clickableWithNormalRipple
|
||||||
import ru.megboyzz.lks.profile.ui.screens.sub.LongPressMenu
|
import ru.megboyzz.lks.profile.ui.screens.sub.LongPressMenu
|
||||||
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
import ru.megboyzz.lks.profile.ui.theme.MainTheme
|
||||||
@@ -120,12 +121,16 @@ fun ProfileCard(
|
|||||||
@Composable
|
@Composable
|
||||||
fun MainScaffold(
|
fun MainScaffold(
|
||||||
onFloatingButtonClick: () -> Unit,
|
onFloatingButtonClick: () -> Unit,
|
||||||
|
onTopClick: () -> Unit = {},
|
||||||
content: @Composable (PaddingValues) -> Unit
|
content: @Composable (PaddingValues) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
Surface(shadowElevation = 8.dp) {
|
Surface(
|
||||||
|
shadowElevation = 8.dp,
|
||||||
|
modifier = Modifier.clickableWithNoEffect(onTopClick)
|
||||||
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("LKS Search") }
|
title = { Text("LKS Search") }
|
||||||
)
|
)
|
||||||
@@ -217,7 +222,10 @@ fun CardsColumn(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(modifier) {
|
Column(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
contentPadding = PaddingValues(12.dp),
|
contentPadding = PaddingValues(12.dp),
|
||||||
|
|||||||
@@ -39,28 +39,27 @@ class SearchScreenModel @Inject constructor(
|
|||||||
|
|
||||||
val state = MutableStateFlow<UiState>(UiState.Idle)
|
val state = MutableStateFlow<UiState>(UiState.Idle)
|
||||||
|
|
||||||
init {
|
suspend fun nextPage() {
|
||||||
_curPageNumber.onEach {
|
if(_responseList.value.availablePages > _curPageNumber.value) {
|
||||||
|
_curPageNumber.emit(_curPageNumber.value + 1)
|
||||||
update(_request.value)
|
update(_request.value)
|
||||||
}.launchIn(CoroutineScope(Dispatchers.IO))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nextPage() = screenModelScope.launch { _curPageNumber.emit(_curPageNumber.value++) }
|
suspend fun resetStudents() {
|
||||||
|
_curPageNumber.value = 1
|
||||||
fun resetStudents() = screenModelScope.launch {
|
|
||||||
_responseList.emit(LksResponse())
|
_responseList.emit(LksResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newSearch(request: LksRequest) {
|
fun newSearch(request: LksRequest) {
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
screenModelScope.launch(Dispatchers.IO) {
|
||||||
|
state.emit(UiState.Loading)
|
||||||
resetStudents()
|
resetStudents()
|
||||||
update(request)
|
state.emit(update(request))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun update(request: LksRequest) {
|
suspend fun update(request: LksRequest): UiState {
|
||||||
|
|
||||||
state.emit(UiState.Loading)
|
|
||||||
|
|
||||||
_request.emit(request)
|
_request.emit(request)
|
||||||
|
|
||||||
@@ -68,21 +67,19 @@ class SearchScreenModel @Inject constructor(
|
|||||||
|
|
||||||
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("Ошибка :-("))
|
return UiState.Error("Ошибка :-(")
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val list = result.getOrElse { LksResponse() }
|
val list = result.getOrElse { LksResponse() }
|
||||||
|
|
||||||
val updatedStudents = _responseList.value.copy(
|
val updatedStudents = LksResponse(
|
||||||
students = _responseList.value.students + list.students,
|
students = _responseList.value.students + list.students,
|
||||||
availablePages = _responseList.value.availablePages + list.availablePages
|
availablePages = list.availablePages
|
||||||
)
|
)
|
||||||
|
|
||||||
_responseList.emit(updatedStudents)
|
_responseList.emit(updatedStudents)
|
||||||
|
|
||||||
state.emit(UiState.Idle)
|
return UiState.Idle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,9 @@ 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)) },
|
||||||
|
onTopClick = { }
|
||||||
) {
|
) {
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
@@ -60,7 +59,7 @@ class SearchScreen : Screen {
|
|||||||
onColumnOverflow = {
|
onColumnOverflow = {
|
||||||
//Toast.makeText(context, "Hello!", Toast.LENGTH_SHORT).show()
|
//Toast.makeText(context, "Hello!", Toast.LENGTH_SHORT).show()
|
||||||
screenModel.nextPage()
|
screenModel.nextPage()
|
||||||
screenModel.update(screenModel.request.value)
|
//screenModel.update(screenModel.request.value)
|
||||||
//screenModel.nextPage()
|
//screenModel.nextPage()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ru.megboyzz.lks.profile.ui.screens
|
package ru.megboyzz.lks.profile.ui.screens
|
||||||
|
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
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
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
import ru.megboyzz.lks.profile.domain.entities.LksStudent
|
||||||
import ru.megboyzz.lks.profile.ui.components.LongPressCardContextMenu
|
import ru.megboyzz.lks.profile.ui.components.LongPressCardContextMenu
|
||||||
|
import ru.megboyzz.lks.profile.ui.copyToClipboard
|
||||||
|
|
||||||
|
|
||||||
class LongPressMenu(private val lksStudent: LksStudent) : Screen {
|
class LongPressMenu(private val lksStudent: LksStudent) : Screen {
|
||||||
@@ -18,13 +19,20 @@ class LongPressMenu(private val lksStudent: LksStudent) : Screen {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
LongPressCardContextMenu(
|
LongPressCardContextMenu(
|
||||||
lksStudent = lksStudent
|
lksStudent = lksStudent,
|
||||||
) {
|
onCopyName = {
|
||||||
Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show()
|
context.copyToClipboard(lksStudent.studentFullName.toString())
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://vk.com/search?q=${lksStudent.studentFullName?.split(" ")?.dropLast(1)?.joinToString(" ")}"))
|
},
|
||||||
browserIntent.`package` = "com.vkontakte.android"
|
onCopyGroup = {
|
||||||
context.startActivity(browserIntent)
|
context.copyToClipboard(lksStudent.studentFullName.toString())
|
||||||
}
|
},
|
||||||
|
onGoToVk = {
|
||||||
|
Toast.makeText(context, "Переход на VK", Toast.LENGTH_SHORT).show()
|
||||||
|
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://vk.com/search?q=${lksStudent.studentFullName?.split(" ")?.dropLast(1)?.joinToString(" ")}"))
|
||||||
|
browserIntent.`package` = "com.vkontakte.android"
|
||||||
|
context.startActivity(browserIntent)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,43 +12,40 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
||||||
private val DarkColorScheme = darkColorScheme(
|
private val DarkColorScheme = darkColorScheme(
|
||||||
primary = Purple80,
|
primary = Color(0xFFB0BEC5), // Серый с голубым оттенком
|
||||||
secondary = PurpleGrey80,
|
secondary = Color(0xFF90A4AE), // Более мягкий серо-голубой
|
||||||
tertiary = Pink80
|
tertiary = Color(0xFFB39DDB), // Нежный фиолетовый
|
||||||
|
|
||||||
|
background = Color(0xFF121212), // Темный фон для контраста
|
||||||
|
surface = Color(0xFF1E1E1E), // Темная поверхность
|
||||||
|
onPrimary = Color.Black,
|
||||||
|
onSecondary = Color.Black,
|
||||||
|
onTertiary = Color.Black,
|
||||||
|
onBackground = Color(0xFFECEFF1), // Светлый текст на темном фоне
|
||||||
|
onSurface = Color(0xFFECEFF1) // Светлый текст на поверхностях
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LightColorScheme = lightColorScheme(
|
private val LightColorScheme = lightColorScheme(
|
||||||
primary = Purple40,
|
primary = Color(0xFF90CAF9), // Голубой с пастельным оттенком
|
||||||
secondary = PurpleGrey40,
|
secondary = Color(0xFFB3E5FC), // Мягкий голубой
|
||||||
tertiary = Pink40,
|
tertiary = Color(0xFFC5CAE9), // Светлый фиолетовый
|
||||||
|
|
||||||
// Other default colors to override
|
background = Color(0xFFF5F5F5), // Очень светлый фон
|
||||||
background = Color(0xFFFFFBFE),
|
surface = Color(0xFFFFFFFF), // Чисто белая поверхность
|
||||||
surface = Color(0xFFFFFBFE),
|
|
||||||
onPrimary = Color.White,
|
onPrimary = Color.White,
|
||||||
onSecondary = Color.White,
|
onSecondary = Color.Black,
|
||||||
onTertiary = Color.White,
|
onTertiary = Color.Black,
|
||||||
onBackground = Color(0xFF1C1B1F),
|
onBackground = Color(0xFF212121), // Темный текст на светлом фоне
|
||||||
onSurface = Color(0xFF1C1B1F),
|
onSurface = Color(0xFF212121) // Темный текст на поверхностях
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainTheme(
|
fun MainTheme(
|
||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
// Dynamic color is available on Android 12+
|
dynamicColor: Boolean = false, // Отключаем динамические цвета для четкости палитры
|
||||||
dynamicColor: Boolean = true,
|
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colorScheme = when {
|
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
|
||||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
|
||||||
val context = LocalContext.current
|
|
||||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
darkTheme -> DarkColorScheme
|
|
||||||
else -> LightColorScheme
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 982 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
@@ -5,5 +5,6 @@ plugins {
|
|||||||
alias(libs.plugins.kotlin.compose) apply false
|
alias(libs.plugins.kotlin.compose) apply false
|
||||||
alias(libs.plugins.jetbrains.kotlin.jvm) apply false
|
alias(libs.plugins.jetbrains.kotlin.jvm) apply false
|
||||||
alias(libs.plugins.android.library) apply false
|
alias(libs.plugins.android.library) apply false
|
||||||
|
id("com.google.devtools.ksp") version "2.0.0-1.0.24" apply false
|
||||||
id("com.google.dagger.hilt.android") version "2.51.1" apply false
|
id("com.google.dagger.hilt.android") version "2.51.1" apply false
|
||||||
}
|
}
|
||||||