Skip to content

Commit 92d1c7a

Browse files
add sections and update version of library
1 parent 7ce784d commit 92d1c7a

2 files changed

Lines changed: 158 additions & 85 deletions

File tree

WebApp/src/jsMain/kotlin/main.kt

Lines changed: 157 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import androidx.compose.runtime.*
22
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
3-
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
4-
import dev.inmo.tgbotapi.types.CustomEmojiId
53
import dev.inmo.tgbotapi.types.userIdField
64
import dev.inmo.tgbotapi.types.webAppQueryIdField
75
import dev.inmo.tgbotapi.webapps.*
@@ -13,7 +11,6 @@ import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackStyle
1311
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType
1412
import dev.inmo.tgbotapi.webapps.orientation.DeviceOrientationStartParams
1513
import dev.inmo.tgbotapi.webapps.popup.*
16-
import dev.inmo.tgbotapi.webapps.storage.getWithResult
1714
import io.ktor.client.HttpClient
1815
import io.ktor.client.request.*
1916
import io.ktor.client.statement.bodyAsText
@@ -26,13 +23,11 @@ import kotlinx.dom.appendText
2623
import kotlinx.serialization.json.Json
2724
import org.jetbrains.compose.web.attributes.InputType
2825
import org.jetbrains.compose.web.attributes.placeholder
29-
import org.jetbrains.compose.web.css.DisplayStyle
3026
import org.jetbrains.compose.web.css.Style
3127
import org.jetbrains.compose.web.css.StyleSheet
3228
import org.jetbrains.compose.web.css.Color as ComposeColor
3329
import org.jetbrains.compose.web.css.backgroundColor
3430
import org.jetbrains.compose.web.css.color
35-
import org.jetbrains.compose.web.css.display
3631
import org.jetbrains.compose.web.dom.*
3732
import org.jetbrains.compose.web.dom.Text
3833
import org.jetbrains.compose.web.renderComposable
@@ -108,6 +103,7 @@ fun main() {
108103
P()
109104
Text("Chat from WebAppInitData: ${webApp.initDataUnsafe.chat}")
110105

106+
H3 { Text("Emoji status management") }
111107
val emojiStatusAccessState = remember { mutableStateOf(false) }
112108
webApp.onEmojiStatusAccessRequested {
113109
emojiStatusAccessState.value = it.isAllowed
@@ -148,7 +144,9 @@ fun main() {
148144
}
149145
}
150146
}
147+
P()
151148

149+
H3 { Text("Call server method with webAppQueryIdField") }
152150
Button({
153151
onClick {
154152
scope.launchLoggingDropExceptions {
@@ -166,10 +164,11 @@ fun main() {
166164
}
167165

168166
P()
167+
H3 { Text("User info") }
169168
Text("Allow to write in private messages: ${webApp.initDataUnsafe.user ?.allowsWriteToPM ?: "User unavailable"}")
170169

171170
P()
172-
Text("Alerts:")
171+
H3 { Text("Alerts") }
173172
Button({
174173
onClick {
175174
webApp.showPopup(
@@ -207,8 +206,22 @@ fun main() {
207206
}) {
208207
Text("Alert")
209208
}
209+
Button({
210+
onClick {
211+
webApp.showConfirm(
212+
"This is confirm message"
213+
) {
214+
logsState.add(
215+
"You have pressed \"${if (it) "Ok" else "Cancel"}\" in confirm"
216+
)
217+
}
218+
}
219+
}) {
220+
Text("Confirm")
221+
}
210222

211223
P()
224+
H3 { Text("Write access callbacks") }
212225
Button({
213226
onClick {
214227
webApp.requestWriteAccess()
@@ -227,6 +240,7 @@ fun main() {
227240
}
228241

229242
P()
243+
H3 { Text("Request contact") }
230244
Button({
231245
onClick {
232246
webApp.requestContact()
@@ -241,24 +255,9 @@ fun main() {
241255
}) {
242256
Text("Request contact with callback")
243257
}
244-
P()
245-
246-
Button({
247-
onClick {
248-
webApp.showConfirm(
249-
"This is confirm message"
250-
) {
251-
logsState.add(
252-
"You have pressed \"${if (it) "Ok" else "Cancel"}\" in confirm"
253-
)
254-
}
255-
}
256-
}) {
257-
Text("Confirm")
258-
}
259258

260259
P()
261-
260+
H3 { Text("Closing confirmation") }
262261
val isClosingConfirmationEnabledState = remember { mutableStateOf(webApp.isClosingConfirmationEnabled) }
263262
Button({
264263
onClick {
@@ -276,7 +275,7 @@ fun main() {
276275
}
277276

278277
P()
279-
278+
H3 { Text("Colors") }
280279
val headerColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
281280
fun updateHeaderColor() {
282281
val (r, g, b) = Random.nextUBytes(3)
@@ -301,7 +300,6 @@ fun main() {
301300
}
302301

303302
P()
304-
305303
val backgroundColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
306304
fun updateBackgroundColor() {
307305
val (r, g, b) = Random.nextUBytes(3)
@@ -326,7 +324,6 @@ fun main() {
326324
}
327325

328326
P()
329-
330327
val bottomBarColor = remember { mutableStateOf<Color.Hex>(Color.Hex("#000000")) }
331328
fun updateBottomBarColor() {
332329
val (r, g, b) = Random.nextUBytes(3)
@@ -350,60 +347,6 @@ fun main() {
350347
}
351348
}
352349

353-
P()
354-
355-
val storageTrigger = remember { mutableStateOf<List<Pair<CloudStorageKey, CloudStorageValue>>>(emptyList()) }
356-
fun updateCloudStorage() {
357-
webApp.cloudStorage.getAll {
358-
it.onSuccess {
359-
storageTrigger.value = it.toList().sortedBy { it.first.key }
360-
}
361-
}
362-
}
363-
key(storageTrigger.value) {
364-
storageTrigger.value.forEach { (key, value) ->
365-
val keyState = remember { mutableStateOf(key.key) }
366-
val valueState = remember { mutableStateOf(value.value) }
367-
Input(InputType.Text) {
368-
value(key.key)
369-
onInput { keyState.value = it.value }
370-
}
371-
Input(InputType.Text) {
372-
value(value.value)
373-
onInput { valueState.value = it.value }
374-
}
375-
Button({
376-
onClick {
377-
if (key.key != keyState.value) {
378-
webApp.cloudStorage.remove(key)
379-
}
380-
webApp.cloudStorage.set(keyState.value, valueState.value)
381-
updateCloudStorage()
382-
}
383-
}) {
384-
Text("Save")
385-
}
386-
}
387-
let { // new element adding
388-
val keyState = remember { mutableStateOf("") }
389-
val valueState = remember { mutableStateOf("") }
390-
Input(InputType.Text) {
391-
onInput { keyState.value = it.value }
392-
}
393-
Input(InputType.Text) {
394-
onInput { valueState.value = it.value }
395-
}
396-
Button({
397-
onClick {
398-
webApp.cloudStorage.set(keyState.value, valueState.value)
399-
updateCloudStorage()
400-
}
401-
}) {
402-
Text("Save")
403-
}
404-
}
405-
}
406-
407350
remember {
408351
webApp.apply {
409352

@@ -453,9 +396,10 @@ fun main() {
453396
}
454397
}
455398
}
456-
P()
457399

458-
let { // Accelerometer
400+
P()
401+
let {
402+
H3 { Text("Accelerometer") }
459403
val enabledState = remember { mutableStateOf(webApp.accelerometer.isStarted) }
460404
webApp.onAccelerometerStarted { enabledState.value = true }
461405
webApp.onAccelerometerStopped { enabledState.value = false }
@@ -496,7 +440,8 @@ fun main() {
496440
}
497441
P()
498442

499-
let { // Gyroscope
443+
let {
444+
H3 { Text("Gyroscope") }
500445
val enabledState = remember { mutableStateOf(webApp.gyroscope.isStarted) }
501446
webApp.onGyroscopeStarted { enabledState.value = true }
502447
webApp.onGyroscopeStopped { enabledState.value = false }
@@ -535,9 +480,10 @@ fun main() {
535480
Text("z: ${zState.value}")
536481
}
537482
}
538-
P()
539483

540-
let { // DeviceOrientation
484+
P()
485+
let {
486+
H3 { Text("Device Orientation") }
541487
val enabledState = remember { mutableStateOf(webApp.deviceOrientation.isStarted) }
542488
webApp.onDeviceOrientationStarted { enabledState.value = true }
543489
webApp.onDeviceOrientationStopped { enabledState.value = false }
@@ -576,9 +522,64 @@ fun main() {
576522
Text("gamma: ${gammaState.value}")
577523
}
578524
}
525+
579526
P()
527+
H3 { Text("Cloud storage") }
528+
val storageTrigger = remember { mutableStateOf<List<Pair<CloudStorageKey, CloudStorageValue>>>(emptyList()) }
529+
fun updateCloudStorage() {
530+
webApp.cloudStorage.getAll {
531+
it.onSuccess {
532+
storageTrigger.value = it.toList().sortedBy { it.first.key }
533+
}
534+
}
535+
}
536+
key(storageTrigger.value) {
537+
storageTrigger.value.forEach { (key, value) ->
538+
val keyState = remember { mutableStateOf(key.key) }
539+
val valueState = remember { mutableStateOf(value.value) }
540+
Input(InputType.Text) {
541+
value(key.key)
542+
onInput { keyState.value = it.value }
543+
}
544+
Input(InputType.Text) {
545+
value(value.value)
546+
onInput { valueState.value = it.value }
547+
}
548+
Button({
549+
onClick {
550+
if (key.key != keyState.value) {
551+
webApp.cloudStorage.remove(key)
552+
}
553+
webApp.cloudStorage.set(keyState.value, valueState.value)
554+
updateCloudStorage()
555+
}
556+
}) {
557+
Text("Save")
558+
}
559+
}
560+
let { // new element adding
561+
val keyState = remember { mutableStateOf("") }
562+
val valueState = remember { mutableStateOf("") }
563+
Input(InputType.Text) {
564+
onInput { keyState.value = it.value }
565+
}
566+
Input(InputType.Text) {
567+
onInput { valueState.value = it.value }
568+
}
569+
Button({
570+
onClick {
571+
webApp.cloudStorage.set(keyState.value, valueState.value)
572+
updateCloudStorage()
573+
}
574+
}) {
575+
Text("Save")
576+
}
577+
}
578+
}
580579

580+
P()
581581
let { // DeviceStorage
582+
H3 { Text("Device storage") }
582583
val fieldKey = remember { mutableStateOf("") }
583584
val fieldValue = remember { mutableStateOf("") }
584585
val message = remember { mutableStateOf("") }
@@ -624,6 +625,78 @@ fun main() {
624625
}
625626
P()
626627

628+
let { // DeviceStorage
629+
H3 { Text("Secure storage") }
630+
val fieldKey = remember { mutableStateOf("") }
631+
val fieldValue = remember { mutableStateOf("") }
632+
val message = remember { mutableStateOf("") }
633+
val restorableState = remember { mutableStateOf(false) }
634+
Div {
635+
Text("Start type title of key. If value will be found in device storage, it will be shown in value input")
636+
}
637+
638+
Input(InputType.Text) {
639+
placeholder("Key")
640+
value(fieldKey.value)
641+
onInput {
642+
fieldKey.value = it.value
643+
webApp.secureStorage.getItem(it.value) { e, v, restorable ->
644+
fieldValue.value = v ?: ""
645+
restorableState.value = restorable == true
646+
if (v == null) {
647+
if (restorable == true) {
648+
message.value = "Value for key \"${it.value}\" has not been found, but can be restored"
649+
} else {
650+
message.value = "Value for key \"${it.value}\" has not been found. Error: $e"
651+
}
652+
} else {
653+
message.value = "Value for key \"${it.value}\" has been found: \"$v\""
654+
}
655+
}
656+
}
657+
}
658+
if (restorableState.value) {
659+
Button({
660+
onClick {
661+
webApp.secureStorage.restoreItem(fieldKey.value) { e, v ->
662+
fieldValue.value = v ?: ""
663+
if (v == null) {
664+
message.value = "Value for key \"${fieldKey.value}\" has not been restored. Error: $e"
665+
} else {
666+
message.value = "Value for key \"${fieldKey.value}\" has been restored: \"$v\""
667+
}
668+
}
669+
}
670+
}) {
671+
Text("Restore")
672+
}
673+
}
674+
Div {
675+
Text("If you want to change value if typed key - just put it here")
676+
}
677+
Input(InputType.Text) {
678+
placeholder("Value")
679+
value(fieldValue.value)
680+
onInput {
681+
fieldValue.value = it.value
682+
webApp.secureStorage.setItem(fieldKey.value, it.value) { e, v ->
683+
if (v) {
684+
fieldValue.value = it.value
685+
message.value = "Value \"${it.value}\" has been saved"
686+
} else {
687+
message.value = "Value \"${it.value}\" has not been saved. Error: $e"
688+
}
689+
}
690+
}
691+
}
692+
693+
if (message.value.isNotEmpty()) {
694+
Div { Text(message.value) }
695+
}
696+
}
697+
P()
698+
699+
H3 { Text("Events") }
627700
EventType.values().forEach { eventType ->
628701
when (eventType) {
629702
EventType.AccelerometerChanged -> webApp.onAccelerometerChanged { /*logsState.add("AccelerometerChanged") /* see accelerometer block */ */ }

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ kotlin.daemon.jvmargs=-Xmx3g -Xms500m
66

77

88
kotlin_version=2.1.20
9-
telegram_bot_api_version=25.0.0-rc2
9+
telegram_bot_api_version=25.0.0-rc3
1010
micro_utils_version=0.25.3
1111
serialization_version=1.8.0
1212
ktor_version=3.1.1

0 commit comments

Comments
 (0)