From 04b05587bfefb7b35bd57ae84e3c4228c307ee80 Mon Sep 17 00:00:00 2001 From: csasq Date: Fri, 20 Dec 2024 00:14:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composeApp/build.gradle.kts | 1 + .../composeResources/drawable/citto_48.png | Bin 0 -> 2828 bytes .../{logo_48.png => tularegion_48.png} | Bin .../kotlin/ru/tularegion/corp/App.kt | 176 ++++-------------- .../kotlin/ru/tularegion/corp/backend/api.kt | 3 + .../ru/tularegion/corp/screens/AboutScreen.kt | 23 +++ .../tularegion/corp/screens/SettingsScreen.kt | 140 ++++++++++++++ .../corp/ui/components/DropdownSelect.kt | 4 +- .../corp/ui/components/SwitchSpoiler.kt | 5 - composeApp/src/wasmJsMain/resources/api.js | 14 ++ .../src/wasmJsMain/resources/index.html | 9 +- gradle/libs.versions.toml | 2 + 12 files changed, 230 insertions(+), 147 deletions(-) create mode 100644 composeApp/src/commonMain/composeResources/drawable/citto_48.png rename composeApp/src/commonMain/composeResources/drawable/{logo_48.png => tularegion_48.png} (100%) create mode 100644 composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/AboutScreen.kt create mode 100644 composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/SettingsScreen.kt diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 8d19633..4964a9f 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -57,6 +57,7 @@ kotlin { implementation(compose.components.uiToolingPreview) implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.navigation.compose) } desktopMain.dependencies { implementation(compose.desktop.currentOs) diff --git a/composeApp/src/commonMain/composeResources/drawable/citto_48.png b/composeApp/src/commonMain/composeResources/drawable/citto_48.png new file mode 100644 index 0000000000000000000000000000000000000000..feed9d0ad5e0cc60f1bf831504d1395922cb03bf GIT binary patch literal 2828 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 eZ-*XVIQ|bfsY^t{OUGOQ0000 NavigationRailItem( - selected = it == navigationState.value, - onClick = {}, + selected = navBackStackEntry.value?.destination?.hierarchy?.any { + it.route == screen.route + } == true, + onClick = { + navController.navigate(screen.route) + }, icon = { Icon( - painter = painterResource(it.icon), - contentDescription = null, + painter = painterResource(screen.icon), + contentDescription = screen.label, ) }, ) @@ -109,18 +110,22 @@ fun App() { } NavigationRailItem( selected = false, - onClick = {}, + onClick = { + openCorpPortal() + }, icon = { Icon( painter = painterResource(Res.drawable.round_open_in_new_24), - contentDescription = null, + contentDescription = "Открыть Корпоративный портал", ) }, ) } } - Column( + NavHost( + navController = navController, + startDestination = Screen.Settings.route, modifier = Modifier .verticalScroll( state = rememberScrollState(), @@ -130,112 +135,11 @@ fun App() { ) .fillMaxSize(), ) { - Column( - modifier = Modifier - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - val redirectModeState = remember { - mutableStateOf(RedirectMode.NO_REDIRECT) - } - JsCallbacks.redirectMode = { value -> - redirectModeState.value = RedirectMode.entries.find { - it.id == value - } ?: RedirectMode.NO_REDIRECT - } - DropdownSelect( - title = "Перенаправление между RU и LOCAL", - caption = "Перенаправлять все страницы на RU, либо на LOCAL", - items = RedirectMode.entries, - valueState = redirectModeState, - onValueChange = { - setRedirectMode(it) - }, - ) - - val copyModeState = remember { - mutableStateOf(CopyMode.NO_REPLACE) - } - JsCallbacks.copyMode = { value -> - copyModeState.value = CopyMode.entries.find { - it.id == value - } ?: CopyMode.NO_REPLACE - } - DropdownSelect( - title = "Замена ссылок при копировании", - caption = "Заменять все ссылки при копировании на RU, либо на LOCAL", - items = CopyMode.entries, - valueState = copyModeState, - onValueChange = { - setCopyMode(it) - }, - ) + composable(Screen.Settings.route) { + SettingsScreen() } - - val autoAuthModeState = remember { - mutableStateOf(false) - } - JsCallbacks.autoAuthMode = { - autoAuthModeState.value = it - } - SwitchSpoiler( - title = "Автоматический вход", - caption = "Выполнять вход на портал автоматически", - enabledState = autoAuthModeState, - onValueChange = { - setAutoAuthMode(it) - }, - ) { - Column( - modifier = Modifier - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - val loginState = remember { - mutableStateOf("") - } - JsCallbacks.autoAuthLogin = { - loginState.value = it - } - OutlinedTextField( - value = loginState.value, - onValueChange = { - setAutoAuthLogin(it) - loginState.value = it - }, - modifier = Modifier - .fillMaxWidth(), - label = { - Text( - text = "Логин", - ) - }, - singleLine = true, - ) - - val passwordState = remember { - mutableStateOf("") - } - JsCallbacks.autoAuthPassword = { - passwordState.value = it - } - OutlinedTextField( - value = passwordState.value, - onValueChange = { - setAutoAuthPassword(it) - passwordState.value = it - }, - modifier = Modifier - .fillMaxWidth(), - label = { - Text( - text = "Пароль", - ) - }, - visualTransformation = PasswordVisualTransformation(), - singleLine = true, - ) - } + composable(Screen.About.route) { + AboutScreen() } } } diff --git a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/backend/api.kt b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/backend/api.kt index 221fd37..36f503f 100644 --- a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/backend/api.kt +++ b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/backend/api.kt @@ -86,3 +86,6 @@ fun autoAuthPasswordCallback( external fun setAutoAuthPassword( value: String, ) + +@JsName("openCorpPortal") +external fun openCorpPortal() diff --git a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/AboutScreen.kt b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/AboutScreen.kt new file mode 100644 index 0000000..1dafaa3 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/AboutScreen.kt @@ -0,0 +1,23 @@ +package ru.tularegion.corp.screens + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import corp_tularegion_extension.composeapp.generated.resources.Res +import corp_tularegion_extension.composeapp.generated.resources.citto_48 +import org.jetbrains.compose.resources.painterResource + +@Composable +fun AboutScreen() { + Column { + Image( + painter = painterResource(Res.drawable.citto_48), + contentDescription = "Логотип ГАУ ТО «ЦИТ»", + modifier = Modifier + .padding(16.dp), + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/SettingsScreen.kt new file mode 100644 index 0000000..9b1dff1 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/screens/SettingsScreen.kt @@ -0,0 +1,140 @@ +package ru.tularegion.corp.screens + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.unit.dp +import ru.tularegion.corp.backend.JsCallbacks +import ru.tularegion.corp.backend.setAutoAuthLogin +import ru.tularegion.corp.backend.setAutoAuthMode +import ru.tularegion.corp.backend.setAutoAuthPassword +import ru.tularegion.corp.backend.setCopyMode +import ru.tularegion.corp.backend.setRedirectMode +import ru.tularegion.corp.ui.components.CopyMode +import ru.tularegion.corp.ui.components.DropdownSelect +import ru.tularegion.corp.ui.components.RedirectMode +import ru.tularegion.corp.ui.components.SwitchSpoiler + +@Composable +fun SettingsScreen() { + val redirectModeState = remember { + mutableStateOf(RedirectMode.NO_REDIRECT) + } + JsCallbacks.redirectMode = { value -> + redirectModeState.value = RedirectMode.entries.find { + it.id == value + } ?: RedirectMode.NO_REDIRECT + } + + val copyModeState = remember { + mutableStateOf(CopyMode.NO_REPLACE) + } + JsCallbacks.copyMode = { value -> + copyModeState.value = CopyMode.entries.find { + it.id == value + } ?: CopyMode.NO_REPLACE + } + + val autoAuthModeState = remember { + mutableStateOf(false) + } + JsCallbacks.autoAuthMode = { + autoAuthModeState.value = it + } + + val loginState = remember { + mutableStateOf("") + } + JsCallbacks.autoAuthLogin = { + loginState.value = it + } + + val passwordState = remember { + mutableStateOf("") + } + JsCallbacks.autoAuthPassword = { + passwordState.value = it + } + + Column { + Column( + modifier = Modifier + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + DropdownSelect( + title = "Перенаправление между RU и LOCAL", + caption = "Перенаправлять все страницы на RU, либо на LOCAL", + items = RedirectMode.entries, + valueState = redirectModeState, + onValueChange = { + setRedirectMode(it) + }, + ) + DropdownSelect( + title = "Замена ссылок при копировании", + caption = "Заменять все ссылки при копировании на RU, либо на LOCAL", + items = CopyMode.entries, + valueState = copyModeState, + onValueChange = { + setCopyMode(it) + }, + ) + } + + SwitchSpoiler( + title = "Автоматический вход", + caption = "Выполнять вход на портал автоматически", + enabledState = autoAuthModeState, + onValueChange = { + setAutoAuthMode(it) + }, + ) { + Column( + modifier = Modifier + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + OutlinedTextField( + value = loginState.value, + onValueChange = { + setAutoAuthLogin(it) + loginState.value = it + }, + modifier = Modifier + .fillMaxWidth(), + label = { + Text( + text = "Логин", + ) + }, + singleLine = true, + ) + OutlinedTextField( + value = passwordState.value, + onValueChange = { + setAutoAuthPassword(it) + passwordState.value = it + }, + modifier = Modifier + .fillMaxWidth(), + label = { + Text( + text = "Пароль", + ) + }, + visualTransformation = PasswordVisualTransformation(), + singleLine = true, + ) + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/DropdownSelect.kt b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/DropdownSelect.kt index 359d0ec..45b1eea 100644 --- a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/DropdownSelect.kt +++ b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/DropdownSelect.kt @@ -36,8 +36,8 @@ enum class CopyMode( override val title: String, ) : DropdownSelect { NO_REPLACE(0, "Отключить"), - LOCAL_TO_RU(1, "Заменять LOCAL на RU"), - RU_TO_LOCAL(2, "Заменять RU на LOCAL"), +// RU_TO_LOCAL(1, "Заменять RU на LOCAL"), +// LOCAL_TO_RU(2, "Заменять LOCAL на RU"), } @OptIn(ExperimentalMaterial3Api::class) diff --git a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/SwitchSpoiler.kt b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/SwitchSpoiler.kt index e808efb..335f11e 100644 --- a/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/SwitchSpoiler.kt +++ b/composeApp/src/commonMain/kotlin/ru/tularegion/corp/ui/components/SwitchSpoiler.kt @@ -8,11 +8,8 @@ import androidx.compose.foundation.layout.Arrangement 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.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.material3.CardColors @@ -23,8 +20,6 @@ import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color diff --git a/composeApp/src/wasmJsMain/resources/api.js b/composeApp/src/wasmJsMain/resources/api.js index 8239816..d2c8f15 100644 --- a/composeApp/src/wasmJsMain/resources/api.js +++ b/composeApp/src/wasmJsMain/resources/api.js @@ -25,3 +25,17 @@ function setAutoAuthLogin(value) { function setAutoAuthPassword(value) { chrome.storage.local.set({ autoAuthPassword: value }) } + +function openCorpPortal() { + chrome.storage.local.get(['redirectMode']).then((data) => { + switch (data.redirectMode) { + case 1: + window.open('https://corp.tularegion.local/') + break + + default: + window.open('https://corp.tularegion.ru/') + break + } + }) +} diff --git a/composeApp/src/wasmJsMain/resources/index.html b/composeApp/src/wasmJsMain/resources/index.html index 367adb3..a00f2d3 100644 --- a/composeApp/src/wasmJsMain/resources/index.html +++ b/composeApp/src/wasmJsMain/resources/index.html @@ -2,13 +2,14 @@ + Расширение Корпоративного портала - - - + + + - + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cdc71f1..5e3bea2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ compose-multiplatform = "1.7.0" junit = "4.13.2" kotlin = "2.1.0" kotlinx-coroutines = "1.9.0" +navigationComposeVersion = "2.7.0-alpha07" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -30,6 +31,7 @@ androidx-activity-compose = { module = "androidx.activity:activity-compose", ver androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" } androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } +navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigationComposeVersion" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }