В этой статье рассмотрим старт проекта как обычное веб-приложение с минимальным функционалом. Остальные функции будут завязаны на Telegram API и веб-приложение сможет запускаться из Telegram.
Навигация по циклу статей
Часть 1. Пишем веб-приложение кликер на Kotlin – текущая статья
Раскрытые темы в цикле
-
Web приложение на Kotlin – часть 1
-
Интеграция приложения с Telegram Mini Apps – часть 2
-
Работа с элементами интерфейса TMA приложения. Тема,
MainButton
,BackButton
– часть 2 -
Поделиться ссылкой на приложение через Telegram. Передача данных через ссылку – часть 2
-
Аутентификации через TMA приложение – часть 2 и 2.5
-
Telegram Payments API– часть 3
Техническое задание. Кратко
Разработать Telegram Mini Apps приложение-кликер с основными механиками:
-
Тапать на коин и увеличивать счётчик
-
Сохранять количество тапов для каждого пользователя
-
Приглашать друзей через ссылку из приложения
-
Просматривать список друзей.
-
Оплата премиум статуса через Telegram
-
В будущем перенести на Android/IOS
Зачем нужен Kotlin в Web. Ещё один .js фреймворк?
Kotlin Multiplaform анонсирован ещё в 2017 с поддержкой JVM, Native и JS таргетов. И именно JS тартет наиболее недооценён как самой JetBrains, так и компаниями, применяющими в разработке язык Kotlin.
Только в середине 2023 года JetBrains заявила о смене аббревиатуры с KMM (Kotlin Multiplatform Mobile) на KMP (Kotlin Multiplatform), что говорит о перспективах развития всех тартетов.
Зачем бизнесу нужен Kotlin Multiplatform, тем более в веб-разработке? В мобильные приложения уже давно интегрируют общий код между платформами, однако JS таргет, хоть и представлен давно, не все разработчики видят в его использовании смысл. Однако причина писать веб-приложения на Kotlin такая же как и для мобильных платформ – это шаринг кода между платформами. Уже имея приложение на KMP под две платформы – Android и iOS – можно третьей добавить браузер и разработать веб приложение, не переписывая бизнес логику, хотя конечно же доступа к системе у веб-приложений меньше, из-за чего придётся уменьшить количество поддерживаемых фичей.
Kotlin/JS тартет способен компилироваться в JavaScript код, вызывать методы из JS модулей или самим быть вызываем, что значительно расширяет возможности приложений на Kotlin/JS и даёт возможность писать на Kotlin с кодовой базовой уже существующих JS приложений.
Главная трудность – это написание UI. Сейчас есть выбор между четырьмя реализациями
-
Написать UI на HTML и CSS. И работать с DOM деревом как в старые добрые – получать элемент по id и изменять его
-
Использовать React in Kotlin ( kotlin-wrappers/kotlin-rea… @GitHub) из модуля kotlin-wrappers. Однако такой подход выглядит неестественным для языка Kotlin. Повсеместное использование external для props, неоднородные стили с CSS in Kotlin
-
Использовать Compose for Web (пока статус Alpha) из Compose Multiplatform. Можно компилировать под WASM (который использует wasm gc, поддержки которого пока нет в Safari/WebKit) и JS, где уже встречаются баги взаимодействия со скроллом и нестабильной работой.
-
Наиболее перспективный вариант Compose HTML library.
Выбор на чем писать UI
Подробнее о Compose HTML library. Код компилируется в JS и использует compose runtime и html теги с css in kotlin стилями, по идеологии схож с JSX.
Доступен базовый функционал compose runtime: Composable аннотация, Side-effects, states и д.р. из пакета compose-runtime.
Не доступны другие пакеты, как compose-ui, compose-material, из-за чего нельзя использовать привычные Column
, Row
, Box
, Scaffold
, Button
(composable ui функции), MaterialTheme
и д.р.
Для написания UI используются функции Div
, Button
, Span
, TextArea
и д.р. браузерные теги, только вызываемые как функции с заглавной буквы. Стили применяются через СSS in Kotlin через отдельный StyleSheet
или блок style
в attrs
любого тега.
Старт проекта
Для упрощения старта можно использовать шаблон, однако ещё разберём особенности настройки.
Файловая структура – типичная для проекта для kotlin multiplatform.
В build.gradle.kts
composeApp модуля подключим плагины (также нужно объявить в корневом модуле build.gradle.kts
)
plugins { id("org.jetbrains.kotlin.multiplatform") id("org.jetbrains.kotlin.plugin.compose") // компилятор, необходимый для сборки модуля с compose на Kotlin 2.X id("org.jetbrains.compose") // работа с compose multiplatform }
Зададим JS таргет и зависимости в блоке kotlin{}
модуля composeApp
kotlin { js(IR) { browser() binaries.executable() } sourceSets { jsMain.dependencies { implementation(compose.runtime) implementation(compose.html.core) } } }
Создаём директории для наших исходников commonMain
и jsMain
В resources jsMain
нужно создать index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>EllowBurgerBot</title> <script src="https://telegram.org/js/telegram-web-app.js"></script> </head> <body id="app" class="app"> <script src="app.js"> </script> </body> </html>
Далее определим точку входа в приложение. Создаём main.kt
с функцией main
, которая и будет точкой входа в наше приложение
fun main() { renderComposable(rootElementId = "app") { /* Весь интерфейс здесь */ } }
Напишем простой экран, который будет сообщать, что это веб-приложение, написанное на Kotlin
Важно: UI находится в
jsMain
, поскольку это нативный для браузера способа отображения
@Composable fun App() { Div { H2 { Text("This is my Kotlin web application") } } }
Вызовем функцию с нашим приложением в блоке renderComposable
renderComposable(rootElementId = "app") { App() }
Первоначальная настройка закончена, теперь можно запустить приложение и проверить, что всё работает как надо
./gradlew composeApp:jsRun
Но страница выглядит просто как текст, Compose HTML library может инжектить в браузер свои стили, которые пишутся на Kotlin. Добавим таблицу стилей в наше приложение
object AppStyles: StyleSheet() { val MainContainer by style { display(DisplayStyle.Flex) width(100.vw) height(100.vh) textAlign("center") alignItems(AlignItems.Center) justifyContent(JustifyContent.Center) } }
Важно, что каждый StyleSheet
должен быть явно определён, именно в этот момент он инжектится в браузерную страницу. Применяем таблицу стилей.
renderComposable(rootElementId = "app") { Style(AppStyles) App() }
Далее через поля из AppStyles
применим стиль к нашему Div
.
@Composable fun App() { Div( attrs = { classes(AppStyles.MainContainer) } ) { H2 { Text("This is my Kotlin web application") } } }
Запускаем ещё раз и наблюдаем, как наши стили применились и приложение выглядит, как нам нужно.
Добавляем ресурсы
Теперь переходим к созданию полноценного веб-приложения. Каждый этап описан не будет, однако основные моменты будут описаны. Некоторые из доступных, хоть и ограниченных, возможностей Compose runtime и Compose HTML library, при работе с KMP
Для этого используем библиотеку moko-resources
. Подключается вместе с gradle плагином в build.gradle.kts
модуля composeApp
plugins { // ... id("dev.icerock.mobile.multiplatform-resources") } kotlin { //... sourceSets { commonMain.dependencies { implementation("dev.icerock.moko:resources:0.24.1") } //... } } multiplatformResources { resourcesPackage.set("your.package.name") resourcesClassName.set("Res") }
Добавим нашу картинку, по которой будем тапать в commonMain
модуль.
И получим url
до картинки через сгенерированный класс Res
и поле Res.images.click_item
.
@Composable fun App() { Div( attrs = { classes(AppStyles.MainContainer) } ) { Img( src = Res.images.click_item.fileUrl, attrs = { classes(AppStyles.MainImage) // стиль с указанием размера картинки } ) } }
Создаём UI нашего кликера
Поскольку это кликер, обязательно нужно добавить счётчик нажатий на наш «подставить на кого будем кликать».
Создадим состояние, значение которого будем увеличивать по клику на картинку.
@Composable fun App() { var score by remember { mutableStateOf(0) } Div( attrs = { classes(AppStyles.MainContainer) } ) { H2 { Text("Score: \$score") } Img( src = Res.images.click_item.fileUrl, attrs = { classes(AppStyles.ClickImage) onClick { score++ } } ) } }
Итоги
В данной статье мы научились разрабатывать веб-приложения на довольно нестандартном стеке.
Список используемых библиотек на данный момент:
-
Compose Runtime
-
Moko-resources
Дальше – больше, в следующих статьях это просто веб-приложение с одной кнопкой станет полноценным Telegram-кликером со своей реферальной системой.
ссылка на оригинал статьи https://habr.com/ru/articles/830120/
Добавить комментарий