11import androidx.compose.runtime.*
22import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
3- import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
4- import dev.inmo.tgbotapi.types.CustomEmojiId
53import dev.inmo.tgbotapi.types.userIdField
64import dev.inmo.tgbotapi.types.webAppQueryIdField
75import dev.inmo.tgbotapi.webapps.*
@@ -13,7 +11,6 @@ import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackStyle
1311import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType
1412import dev.inmo.tgbotapi.webapps.orientation.DeviceOrientationStartParams
1513import dev.inmo.tgbotapi.webapps.popup.*
16- import dev.inmo.tgbotapi.webapps.storage.getWithResult
1714import io.ktor.client.HttpClient
1815import io.ktor.client.request.*
1916import io.ktor.client.statement.bodyAsText
@@ -26,13 +23,11 @@ import kotlinx.dom.appendText
2623import kotlinx.serialization.json.Json
2724import org.jetbrains.compose.web.attributes.InputType
2825import org.jetbrains.compose.web.attributes.placeholder
29- import org.jetbrains.compose.web.css.DisplayStyle
3026import org.jetbrains.compose.web.css.Style
3127import org.jetbrains.compose.web.css.StyleSheet
3228import org.jetbrains.compose.web.css.Color as ComposeColor
3329import org.jetbrains.compose.web.css.backgroundColor
3430import org.jetbrains.compose.web.css.color
35- import org.jetbrains.compose.web.css.display
3631import org.jetbrains.compose.web.dom.*
3732import org.jetbrains.compose.web.dom.Text
3833import 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 */ */ }
0 commit comments