Разработана двусторонняя интеграция Kotlin и JavaScript

Этот коммит содержится в:
Глеб Иваницкий 2024-12-19 12:51:14 +03:00
родитель 4512c9bc75
Коммит dad92a5a45
8 изменённых файлов: 118 добавлений и 76 удалений

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

@ -30,7 +30,9 @@ import corp_tularegion_extension.composeapp.generated.resources.round_open_in_ne
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.getRedirectMode import ru.tularegion.corp.backend.JsCallbacks
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.CopyMode
import ru.tularegion.corp.ui.components.DropdownSelect import ru.tularegion.corp.ui.components.DropdownSelect
import ru.tularegion.corp.ui.components.RedirectMode import ru.tularegion.corp.ui.components.RedirectMode
@ -76,13 +78,17 @@ fun App() {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Spacer(
modifier = Modifier
.height(8.dp),
)
Image( Image(
painter = painterResource(Res.drawable.logo_48), painter = painterResource(Res.drawable.logo_48),
contentDescription = null, contentDescription = null,
) )
Spacer( Spacer(
modifier = Modifier modifier = Modifier
.height(12.dp), .height(24.dp),
) )
Screen.entries.forEach { Screen.entries.forEach {
NavigationRailItem( NavigationRailItem(
@ -128,11 +134,19 @@ fun App() {
val redirectModeState = remember { val redirectModeState = remember {
mutableStateOf(RedirectMode.NO_REDIRECT) mutableStateOf(RedirectMode.NO_REDIRECT)
} }
JsCallbacks.redirectMode = { value ->
redirectModeState.value = RedirectMode.entries.find {
it.id == value
} ?: RedirectMode.NO_REDIRECT
}
DropdownSelect( DropdownSelect(
title = "Перенаправление между RU и LOCAL", title = "Перенаправление между RU и LOCAL",
caption = "Перенаправлять все страницы на RU, либо на LOCAL", caption = "Перенаправлять все страницы на RU, либо на LOCAL",
items = RedirectMode.entries, items = RedirectMode.entries,
valueState = redirectModeState, valueState = redirectModeState,
onValueChange = {
setRedirectMode(it)
},
) )
val copyModeState = remember { val copyModeState = remember {
@ -143,6 +157,9 @@ fun App() {
caption = "Заменять все ссылки при копировании на RU, либо на LOCAL", caption = "Заменять все ссылки при копировании на RU, либо на LOCAL",
items = CopyMode.entries, items = CopyMode.entries,
valueState = copyModeState, valueState = copyModeState,
onValueChange = {
setCopyMode(it)
},
) )
} }

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

@ -1,42 +1,86 @@
package ru.tularegion.corp.backend package ru.tularegion.corp.backend
import kotlin.js.ExperimentalJsExport
import kotlin.js.JsExport
import kotlin.js.JsName import kotlin.js.JsName
@JsName("getRedirectMode") object JsCallbacks {
external fun getRedirectMode(): Int var redirectMode: ((Int) -> Unit)? = null
var copyMode: ((Int) -> Unit)? = null
var autoAuthMode: ((Boolean) -> Unit)? = null
var autoAuthLogin: ((String) -> Unit)? = null
var autoAuthLPassword: ((String) -> Unit)? = null
}
@OptIn(ExperimentalJsExport::class)
@JsExport
fun redirectModeCallback(
value: Int,
) {
JsCallbacks.redirectMode?.let {
it(value)
}
}
@JsName("setRedirectMode") @JsName("setRedirectMode")
external fun setRedirectMode( external fun setRedirectMode(
value: Int, value: Int,
) )
@JsName("getCopyMode") @OptIn(ExperimentalJsExport::class)
external fun getCopyMode(): Int @JsExport
fun copyModeCallback(
value: Int,
) {
JsCallbacks.copyMode?.let {
it(value)
}
}
@JsName("setCopyMode") @JsName("setCopyMode")
external fun setCopyMode( external fun setCopyMode(
value: Int, value: Int,
) )
@JsName("getAutoAuthMode") @OptIn(ExperimentalJsExport::class)
external fun getAutoAuthMode(): Int @JsExport
fun autoAuthModeCallback(
value: Boolean,
) {
JsCallbacks.autoAuthMode?.let {
it(value)
}
}
@JsName("setAutoAuthMode") @JsName("setAutoAuthMode")
external fun setAutoAuthMode( external fun setAutoAuthMode(
value: Int, value: Int,
) )
@JsName("getAutoAuthLogin") @OptIn(ExperimentalJsExport::class)
external fun getAutoAuthLogin(): Int @JsExport
fun autoAuthLoginCallback(
value: String,
) {
JsCallbacks.autoAuthLogin?.let {
it(value)
}
}
@JsName("setAutoAuthLogin") @JsName("setAutoAuthLogin")
external fun setAutoAuthLogin( external fun setAutoAuthLogin(
value: String, value: String,
) )
@JsName("getAutoAuthLPassword") @OptIn(ExperimentalJsExport::class)
external fun getAutoAuthLPassword(): Int @JsExport
fun autoAuthLPasswordCallback(
value: String,
) {
JsCallbacks.autoAuthLPassword?.let {
it(value)
}
}
@JsName("setAutoAuthLPassword") @JsName("setAutoAuthLPassword")
external fun setAutoAuthLPassword( external fun setAutoAuthLPassword(

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

@ -27,8 +27,8 @@ enum class RedirectMode(
override val title: String, override val title: String,
) : DropdownSelect { ) : DropdownSelect {
NO_REDIRECT(0, "Отключить"), NO_REDIRECT(0, "Отключить"),
RU_TO_LOCAL(1, "Перенаправлять LOCAL на RU"), RU_TO_LOCAL(1, "Перенаправлять RU на LOCAL"),
LOCAL_TO_RU(2, "Перенаправлять RU на LOCAL"), LOCAL_TO_RU(2, "Перенаправлять LOCAL на RU"),
} }
enum class CopyMode( enum class CopyMode(
@ -36,8 +36,8 @@ enum class CopyMode(
override val title: String, override val title: String,
) : DropdownSelect { ) : DropdownSelect {
NO_REPLACE(0, "Отключить"), NO_REPLACE(0, "Отключить"),
RU_TO_LOCAL(1, "Заменять LOCAL на RU"), LOCAL_TO_RU(1, "Заменять LOCAL на RU"),
LOCAL_TO_RU(2, "Заменять RU на LOCAL"), RU_TO_LOCAL(2, "Заменять RU на LOCAL"),
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@ -47,6 +47,7 @@ fun <T>DropdownSelect(
caption: String, caption: String,
items: EnumEntries<T>, items: EnumEntries<T>,
valueState: MutableState<T>, valueState: MutableState<T>,
onValueChange: (Int) -> Unit,
) where T : Enum<T>, T : DropdownSelect { ) where T : Enum<T>, T : DropdownSelect {
val dropdownMenuState = remember { val dropdownMenuState = remember {
mutableStateOf(false) mutableStateOf(false)
@ -98,6 +99,7 @@ fun <T>DropdownSelect(
) )
}, },
onClick = { onClick = {
onValueChange(it.id)
valueState.value = it valueState.value = it
dropdownMenuState.value = false dropdownMenuState.value = false
}, },

27
composeApp/src/wasmJsMain/resources/api.js Обычный файл
Просмотреть файл

@ -0,0 +1,27 @@
function getValueByKey(key) {
return new Promise(resolve => {
chrome.storage.local.get([key]).then((data) => {
resolve(data[key])
})
})
}
function setRedirectMode(value) {
chrome.storage.local.set({ redirectMode: value })
}
function setCopyMode(value) {
chrome.storage.local.set({ copyMode: value })
}
function setAutoAuthMode(value) {
chrome.storage.local.set({ autoAuthMode: value })
}
function setAutoAuthLogin(value) {
chrome.storage.local.set({ autoAuthLogin: value })
}
function setAutoAuthLPassword(value) {
chrome.storage.local.set({ autoAuthLPassword: value })
}

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

@ -6,10 +6,8 @@ html, body {
html { html {
position: relative; position: relative;
width: 100%; width: 48rem;
height: 100%; height: 32rem;
max-width: 48rem;
max-height: 32rem;
} }
body { body {

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

@ -4,10 +4,11 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<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="./styles.css" /> <link type="text/css" rel="stylesheet" href="./index.css" />
<script type="text/javascript" src="./scripts.js"></script> <script type="text/javascript" src="./api.js"></script>
<script type="application/javascript" src="./composeApp.js"></script> <script type="application/javascript" src="./composeApp.js"></script>
</head> </head>
<body> <body>
<script type="text/javascript" src="./index.js"></script>
</body> </body>
</html> </html>

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

@ -0,0 +1,7 @@
composeApp.then(module => {
getValueByKey('redirectMode').then(value => module.redirectModeCallback(value))
getValueByKey('copyMode').then(value => module.copyModeCallback(value))
getValueByKey('autoAuthMode').then(value => module.autoAuthModeCallback(value))
getValueByKey('autoAuthLogin').then(value => module.autoAuthLoginCallback(value))
getValueByKey('autoAuthLPassword').then(value => module.autoAuthLPasswordCallback(value))
})

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

@ -1,54 +0,0 @@
function _getValueByKey(key) {
let complete = false
let value;
new Promise(resolve => {
chrome.storage.local.get([key]).then((data) => {
value = data[key]
complete = true
resolve()
})
})
while (true) {
if (value) return value
}
}
function getRedirectMode() {
return _getValueByKey('redirectMode')
}
function setRedirectMode(value) {
chrome.storage.local.set({ redirectMode: value })
}
function getCopyMode() {
return _getValueByKey('copyMode')
}
function setCopyMode(value) {
chrome.storage.local.set({ copyMode: value })
}
function getAutoAuthMode() {
return _getValueByKey('autoAuthMode')
}
function setAutoAuthMode(value) {
chrome.storage.local.set({ autoAuthMode: value })
}
function getAutoAuthLogin() {
return _getValueByKey('autoAuthLogin')
}
function setAutoAuthLogin(value) {
chrome.storage.local.set({ autoAuthLogin: value })
}
function getAutoAuthLPassword() {
return _getValueByKey('autoAuthLPassword')
}
function setAutoAuthLPassword(value) {
chrome.storage.local.set({ autoAuthLPassword: value })
}