Внедрены новые функции

Этот коммит содержится в:
Глеб Иваницкий 2024-12-20 00:14:43 +03:00
родитель ac3dfa49b8
Коммит 04b05587bf
12 изменённых файлов: 230 добавлений и 147 удалений

Просмотреть файл

@ -57,6 +57,7 @@ kotlin {
implementation(compose.components.uiToolingPreview) implementation(compose.components.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.navigation.compose)
} }
desktopMain.dependencies { desktopMain.dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)

Двоичные данные
composeApp/src/commonMain/composeResources/drawable/citto_48.png Обычный файл

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.4 KiB

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Просмотреть файл

@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -16,57 +15,55 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationRail import androidx.compose.material3.NavigationRail
import androidx.compose.material3.NavigationRailItem import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import corp_tularegion_extension.composeapp.generated.resources.Res import corp_tularegion_extension.composeapp.generated.resources.Res
import corp_tularegion_extension.composeapp.generated.resources.logo_48 import corp_tularegion_extension.composeapp.generated.resources.tularegion_48
import corp_tularegion_extension.composeapp.generated.resources.round_info_24 import corp_tularegion_extension.composeapp.generated.resources.round_info_24
import corp_tularegion_extension.composeapp.generated.resources.round_open_in_new_24 import corp_tularegion_extension.composeapp.generated.resources.round_open_in_new_24
import corp_tularegion_extension.composeapp.generated.resources.round_settings_24 import corp_tularegion_extension.composeapp.generated.resources.round_settings_24
import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import ru.tularegion.corp.backend.JsCallbacks import ru.tularegion.corp.backend.openCorpPortal
import ru.tularegion.corp.backend.setAutoAuthLogin import ru.tularegion.corp.screens.AboutScreen
import ru.tularegion.corp.backend.setAutoAuthMode import ru.tularegion.corp.screens.SettingsScreen
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
import ru.tularegion.corp.ui.theme.darkScheme import ru.tularegion.corp.ui.theme.darkScheme
enum class Screen( enum class Screen(
val title: String, val route: String,
val label: String,
val icon: DrawableResource, val icon: DrawableResource,
) { ) {
Settings( Settings(
title = "Настройки", route = "settings",
label = "Открыть вкладку «Настройки»",
icon = Res.drawable.round_settings_24, icon = Res.drawable.round_settings_24,
), ),
About( About(
title = "О расширении", route = "about",
label = "Открыть вкладку «О расширении»",
icon = Res.drawable.round_info_24, icon = Res.drawable.round_info_24,
), ),
} }
@Composable @Composable
fun App() { fun App() {
val navController = rememberNavController()
val navBackStackEntry = navController.currentBackStackEntryAsState()
MaterialTheme( MaterialTheme(
colorScheme = darkScheme, colorScheme = darkScheme,
) { ) {
Surface { Surface {
Row { Row {
val navigationState = remember {
mutableStateOf(Screen.Settings)
}
NavigationRail( NavigationRail(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow, containerColor = MaterialTheme.colorScheme.surfaceContainerLow,
) { ) {
@ -87,21 +84,25 @@ fun App() {
.height(8.dp), .height(8.dp),
) )
Image( Image(
painter = painterResource(Res.drawable.logo_48), painter = painterResource(Res.drawable.tularegion_48),
contentDescription = null, contentDescription = "Герб Тульской области",
) )
Spacer( Spacer(
modifier = Modifier modifier = Modifier
.height(24.dp), .height(24.dp),
) )
Screen.entries.forEach { Screen.entries.forEach { screen ->
NavigationRailItem( NavigationRailItem(
selected = it == navigationState.value, selected = navBackStackEntry.value?.destination?.hierarchy?.any {
onClick = {}, it.route == screen.route
} == true,
onClick = {
navController.navigate(screen.route)
},
icon = { icon = {
Icon( Icon(
painter = painterResource(it.icon), painter = painterResource(screen.icon),
contentDescription = null, contentDescription = screen.label,
) )
}, },
) )
@ -109,18 +110,22 @@ fun App() {
} }
NavigationRailItem( NavigationRailItem(
selected = false, selected = false,
onClick = {}, onClick = {
openCorpPortal()
},
icon = { icon = {
Icon( Icon(
painter = painterResource(Res.drawable.round_open_in_new_24), painter = painterResource(Res.drawable.round_open_in_new_24),
contentDescription = null, contentDescription = "Открыть Корпоративный портал",
) )
}, },
) )
} }
} }
Column( NavHost(
navController = navController,
startDestination = Screen.Settings.route,
modifier = Modifier modifier = Modifier
.verticalScroll( .verticalScroll(
state = rememberScrollState(), state = rememberScrollState(),
@ -130,112 +135,11 @@ fun App() {
) )
.fillMaxSize(), .fillMaxSize(),
) { ) {
Column( composable(Screen.Settings.route) {
modifier = Modifier SettingsScreen()
.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)
},
)
}
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()
} }
} }
} }

Просмотреть файл

@ -86,3 +86,6 @@ fun autoAuthPasswordCallback(
external fun setAutoAuthPassword( external fun setAutoAuthPassword(
value: String, value: String,
) )
@JsName("openCorpPortal")
external fun openCorpPortal()

Просмотреть файл

@ -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),
)
}
}

Просмотреть файл

@ -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,
)
}
}
}
}

Просмотреть файл

@ -36,8 +36,8 @@ enum class CopyMode(
override val title: String, override val title: String,
) : DropdownSelect { ) : DropdownSelect {
NO_REPLACE(0, "Отключить"), NO_REPLACE(0, "Отключить"),
LOCAL_TO_RU(1, "Заменять LOCAL на RU"), // RU_TO_LOCAL(1, "Заменять RU на LOCAL"),
RU_TO_LOCAL(2, "Заменять RU на LOCAL"), // LOCAL_TO_RU(2, "Заменять LOCAL на RU"),
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)

Просмотреть файл

@ -8,11 +8,8 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardColors import androidx.compose.material3.CardColors
@ -23,8 +20,6 @@ import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color

Просмотреть файл

@ -25,3 +25,17 @@ function setAutoAuthLogin(value) {
function setAutoAuthPassword(value) { function setAutoAuthPassword(value) {
chrome.storage.local.set({ autoAuthPassword: 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
}
})
}

Просмотреть файл

@ -2,13 +2,14 @@
<html lang="ru-RU"> <html lang="ru-RU">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="color-scheme" content="dark light" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Расширение Корпоративного портала</title> <title>Расширение Корпоративного портала</title>
<link type="text/css" rel="stylesheet" href="./index.css" /> <link rel="stylesheet" href="./index.css" type="text/css" />
<script type="text/javascript" src="./api.js"></script> <script src="./api.js" type="text/javascript"></script>
<script type="application/javascript" src="./composeApp.js"></script> <script src="./composeApp.js" type="application/javascript"></script>
</head> </head>
<body> <body>
<script type="text/javascript" src="./index.js"></script> <script src="./index.js" type="text/javascript"></script>
</body> </body>
</html> </html>

Просмотреть файл

@ -15,6 +15,7 @@ compose-multiplatform = "1.7.0"
junit = "4.13.2" junit = "4.13.2"
kotlin = "2.1.0" kotlin = "2.1.0"
kotlinx-coroutines = "1.9.0" kotlinx-coroutines = "1.9.0"
navigationComposeVersion = "2.7.0-alpha07"
[libraries] [libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 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-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" } 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" } 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] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }