add sections and update version of library

This commit is contained in:
2025-05-25 13:49:02 +06:00
parent 7ce784d0a2
commit 92d1c7a402
2 changed files with 159 additions and 86 deletions

View File

@@ -1,7 +1,5 @@
import androidx.compose.runtime.* import androidx.compose.runtime.*
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.types.CustomEmojiId
import dev.inmo.tgbotapi.types.userIdField import dev.inmo.tgbotapi.types.userIdField
import dev.inmo.tgbotapi.types.webAppQueryIdField import dev.inmo.tgbotapi.types.webAppQueryIdField
import dev.inmo.tgbotapi.webapps.* import dev.inmo.tgbotapi.webapps.*
@@ -13,7 +11,6 @@ import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackStyle
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType
import dev.inmo.tgbotapi.webapps.orientation.DeviceOrientationStartParams import dev.inmo.tgbotapi.webapps.orientation.DeviceOrientationStartParams
import dev.inmo.tgbotapi.webapps.popup.* import dev.inmo.tgbotapi.webapps.popup.*
import dev.inmo.tgbotapi.webapps.storage.getWithResult
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
@@ -26,13 +23,11 @@ import kotlinx.dom.appendText
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.jetbrains.compose.web.attributes.InputType import org.jetbrains.compose.web.attributes.InputType
import org.jetbrains.compose.web.attributes.placeholder import org.jetbrains.compose.web.attributes.placeholder
import org.jetbrains.compose.web.css.DisplayStyle
import org.jetbrains.compose.web.css.Style import org.jetbrains.compose.web.css.Style
import org.jetbrains.compose.web.css.StyleSheet import org.jetbrains.compose.web.css.StyleSheet
import org.jetbrains.compose.web.css.Color as ComposeColor import org.jetbrains.compose.web.css.Color as ComposeColor
import org.jetbrains.compose.web.css.backgroundColor import org.jetbrains.compose.web.css.backgroundColor
import org.jetbrains.compose.web.css.color import org.jetbrains.compose.web.css.color
import org.jetbrains.compose.web.css.display
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text import org.jetbrains.compose.web.dom.Text
import org.jetbrains.compose.web.renderComposable import org.jetbrains.compose.web.renderComposable
@@ -108,6 +103,7 @@ fun main() {
P() P()
Text("Chat from WebAppInitData: ${webApp.initDataUnsafe.chat}") Text("Chat from WebAppInitData: ${webApp.initDataUnsafe.chat}")
H3 { Text("Emoji status management") }
val emojiStatusAccessState = remember { mutableStateOf(false) } val emojiStatusAccessState = remember { mutableStateOf(false) }
webApp.onEmojiStatusAccessRequested { webApp.onEmojiStatusAccessRequested {
emojiStatusAccessState.value = it.isAllowed emojiStatusAccessState.value = it.isAllowed
@@ -148,7 +144,9 @@ fun main() {
} }
} }
} }
P()
H3 { Text("Call server method with webAppQueryIdField") }
Button({ Button({
onClick { onClick {
scope.launchLoggingDropExceptions { scope.launchLoggingDropExceptions {
@@ -166,10 +164,11 @@ fun main() {
} }
P() P()
H3 { Text("User info") }
Text("Allow to write in private messages: ${webApp.initDataUnsafe.user ?.allowsWriteToPM ?: "User unavailable"}") Text("Allow to write in private messages: ${webApp.initDataUnsafe.user ?.allowsWriteToPM ?: "User unavailable"}")
P() P()
Text("Alerts:") H3 { Text("Alerts") }
Button({ Button({
onClick { onClick {
webApp.showPopup( webApp.showPopup(
@@ -207,8 +206,22 @@ fun main() {
}) { }) {
Text("Alert") Text("Alert")
} }
Button({
onClick {
webApp.showConfirm(
"This is confirm message"
) {
logsState.add(
"You have pressed \"${if (it) "Ok" else "Cancel"}\" in confirm"
)
}
}
}) {
Text("Confirm")
}
P() P()
H3 { Text("Write access callbacks") }
Button({ Button({
onClick { onClick {
webApp.requestWriteAccess() webApp.requestWriteAccess()
@@ -227,6 +240,7 @@ fun main() {
} }
P() P()
H3 { Text("Request contact") }
Button({ Button({
onClick { onClick {
webApp.requestContact() webApp.requestContact()
@@ -241,24 +255,9 @@ fun main() {
}) { }) {
Text("Request contact with callback") Text("Request contact with callback")
} }
P()
Button({
onClick {
webApp.showConfirm(
"This is confirm message"
) {
logsState.add(
"You have pressed \"${if (it) "Ok" else "Cancel"}\" in confirm"
)
}
}
}) {
Text("Confirm")
}
P() P()
H3 { Text("Closing confirmation") }
val isClosingConfirmationEnabledState = remember { mutableStateOf(webApp.isClosingConfirmationEnabled) } val isClosingConfirmationEnabledState = remember { mutableStateOf(webApp.isClosingConfirmationEnabled) }
Button({ Button({
onClick { onClick {
@@ -276,7 +275,7 @@ fun main() {
} }
P() P()
H3 { Text("Colors") }
val headerColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) } val headerColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
fun updateHeaderColor() { fun updateHeaderColor() {
val (r, g, b) = Random.nextUBytes(3) val (r, g, b) = Random.nextUBytes(3)
@@ -301,7 +300,6 @@ fun main() {
} }
P() P()
val backgroundColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) } val backgroundColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
fun updateBackgroundColor() { fun updateBackgroundColor() {
val (r, g, b) = Random.nextUBytes(3) val (r, g, b) = Random.nextUBytes(3)
@@ -326,7 +324,6 @@ fun main() {
} }
P() P()
val bottomBarColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) } val bottomBarColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
fun updateBottomBarColor() { fun updateBottomBarColor() {
val (r, g, b) = Random.nextUBytes(3) val (r, g, b) = Random.nextUBytes(3)
@@ -350,60 +347,6 @@ fun main() {
} }
} }
P()
val storageTrigger = remember { mutableStateOf<List<Pair<CloudStorageKey, CloudStorageValue>>>(emptyList()) }
fun updateCloudStorage() {
webApp.cloudStorage.getAll {
it.onSuccess {
storageTrigger.value = it.toList().sortedBy { it.first.key }
}
}
}
key(storageTrigger.value) {
storageTrigger.value.forEach { (key, value) ->
val keyState = remember { mutableStateOf(key.key) }
val valueState = remember { mutableStateOf(value.value) }
Input(InputType.Text) {
value(key.key)
onInput { keyState.value = it.value }
}
Input(InputType.Text) {
value(value.value)
onInput { valueState.value = it.value }
}
Button({
onClick {
if (key.key != keyState.value) {
webApp.cloudStorage.remove(key)
}
webApp.cloudStorage.set(keyState.value, valueState.value)
updateCloudStorage()
}
}) {
Text("Save")
}
}
let { // new element adding
val keyState = remember { mutableStateOf("") }
val valueState = remember { mutableStateOf("") }
Input(InputType.Text) {
onInput { keyState.value = it.value }
}
Input(InputType.Text) {
onInput { valueState.value = it.value }
}
Button({
onClick {
webApp.cloudStorage.set(keyState.value, valueState.value)
updateCloudStorage()
}
}) {
Text("Save")
}
}
}
remember { remember {
webApp.apply { webApp.apply {
@@ -453,9 +396,10 @@ fun main() {
} }
} }
} }
P()
let { // Accelerometer P()
let {
H3 { Text("Accelerometer") }
val enabledState = remember { mutableStateOf(webApp.accelerometer.isStarted) } val enabledState = remember { mutableStateOf(webApp.accelerometer.isStarted) }
webApp.onAccelerometerStarted { enabledState.value = true } webApp.onAccelerometerStarted { enabledState.value = true }
webApp.onAccelerometerStopped { enabledState.value = false } webApp.onAccelerometerStopped { enabledState.value = false }
@@ -496,7 +440,8 @@ fun main() {
} }
P() P()
let { // Gyroscope let {
H3 { Text("Gyroscope") }
val enabledState = remember { mutableStateOf(webApp.gyroscope.isStarted) } val enabledState = remember { mutableStateOf(webApp.gyroscope.isStarted) }
webApp.onGyroscopeStarted { enabledState.value = true } webApp.onGyroscopeStarted { enabledState.value = true }
webApp.onGyroscopeStopped { enabledState.value = false } webApp.onGyroscopeStopped { enabledState.value = false }
@@ -535,9 +480,10 @@ fun main() {
Text("z: ${zState.value}") Text("z: ${zState.value}")
} }
} }
P()
let { // DeviceOrientation P()
let {
H3 { Text("Device Orientation") }
val enabledState = remember { mutableStateOf(webApp.deviceOrientation.isStarted) } val enabledState = remember { mutableStateOf(webApp.deviceOrientation.isStarted) }
webApp.onDeviceOrientationStarted { enabledState.value = true } webApp.onDeviceOrientationStarted { enabledState.value = true }
webApp.onDeviceOrientationStopped { enabledState.value = false } webApp.onDeviceOrientationStopped { enabledState.value = false }
@@ -576,9 +522,64 @@ fun main() {
Text("gamma: ${gammaState.value}") Text("gamma: ${gammaState.value}")
} }
} }
P()
P()
H3 { Text("Cloud storage") }
val storageTrigger = remember { mutableStateOf<List<Pair<CloudStorageKey, CloudStorageValue>>>(emptyList()) }
fun updateCloudStorage() {
webApp.cloudStorage.getAll {
it.onSuccess {
storageTrigger.value = it.toList().sortedBy { it.first.key }
}
}
}
key(storageTrigger.value) {
storageTrigger.value.forEach { (key, value) ->
val keyState = remember { mutableStateOf(key.key) }
val valueState = remember { mutableStateOf(value.value) }
Input(InputType.Text) {
value(key.key)
onInput { keyState.value = it.value }
}
Input(InputType.Text) {
value(value.value)
onInput { valueState.value = it.value }
}
Button({
onClick {
if (key.key != keyState.value) {
webApp.cloudStorage.remove(key)
}
webApp.cloudStorage.set(keyState.value, valueState.value)
updateCloudStorage()
}
}) {
Text("Save")
}
}
let { // new element adding
val keyState = remember { mutableStateOf("") }
val valueState = remember { mutableStateOf("") }
Input(InputType.Text) {
onInput { keyState.value = it.value }
}
Input(InputType.Text) {
onInput { valueState.value = it.value }
}
Button({
onClick {
webApp.cloudStorage.set(keyState.value, valueState.value)
updateCloudStorage()
}
}) {
Text("Save")
}
}
}
P()
let { // DeviceStorage let { // DeviceStorage
H3 { Text("Device storage") }
val fieldKey = remember { mutableStateOf("") } val fieldKey = remember { mutableStateOf("") }
val fieldValue = remember { mutableStateOf("") } val fieldValue = remember { mutableStateOf("") }
val message = remember { mutableStateOf("") } val message = remember { mutableStateOf("") }
@@ -624,6 +625,78 @@ fun main() {
} }
P() P()
let { // DeviceStorage
H3 { Text("Secure storage") }
val fieldKey = remember { mutableStateOf("") }
val fieldValue = remember { mutableStateOf("") }
val message = remember { mutableStateOf("") }
val restorableState = remember { mutableStateOf(false) }
Div {
Text("Start type title of key. If value will be found in device storage, it will be shown in value input")
}
Input(InputType.Text) {
placeholder("Key")
value(fieldKey.value)
onInput {
fieldKey.value = it.value
webApp.secureStorage.getItem(it.value) { e, v, restorable ->
fieldValue.value = v ?: ""
restorableState.value = restorable == true
if (v == null) {
if (restorable == true) {
message.value = "Value for key \"${it.value}\" has not been found, but can be restored"
} else {
message.value = "Value for key \"${it.value}\" has not been found. Error: $e"
}
} else {
message.value = "Value for key \"${it.value}\" has been found: \"$v\""
}
}
}
}
if (restorableState.value) {
Button({
onClick {
webApp.secureStorage.restoreItem(fieldKey.value) { e, v ->
fieldValue.value = v ?: ""
if (v == null) {
message.value = "Value for key \"${fieldKey.value}\" has not been restored. Error: $e"
} else {
message.value = "Value for key \"${fieldKey.value}\" has been restored: \"$v\""
}
}
}
}) {
Text("Restore")
}
}
Div {
Text("If you want to change value if typed key - just put it here")
}
Input(InputType.Text) {
placeholder("Value")
value(fieldValue.value)
onInput {
fieldValue.value = it.value
webApp.secureStorage.setItem(fieldKey.value, it.value) { e, v ->
if (v) {
fieldValue.value = it.value
message.value = "Value \"${it.value}\" has been saved"
} else {
message.value = "Value \"${it.value}\" has not been saved. Error: $e"
}
}
}
}
if (message.value.isNotEmpty()) {
Div { Text(message.value) }
}
}
P()
H3 { Text("Events") }
EventType.values().forEach { eventType -> EventType.values().forEach { eventType ->
when (eventType) { when (eventType) {
EventType.AccelerometerChanged -> webApp.onAccelerometerChanged { /*logsState.add("AccelerometerChanged") /* see accelerometer block */ */ } EventType.AccelerometerChanged -> webApp.onAccelerometerChanged { /*logsState.add("AccelerometerChanged") /* see accelerometer block */ */ }

View File

@@ -6,7 +6,7 @@ kotlin.daemon.jvmargs=-Xmx3g -Xms500m
kotlin_version=2.1.20 kotlin_version=2.1.20
telegram_bot_api_version=25.0.0-rc2 telegram_bot_api_version=25.0.0-rc3
micro_utils_version=0.25.3 micro_utils_version=0.25.3
serialization_version=1.8.0 serialization_version=1.8.0
ktor_version=3.1.1 ktor_version=3.1.1