Mini Apps For Life
361 subscribers
28 photos
10 videos
1 file
35 links
Канал о разработке и тонкостях работы с мини-приложениями в Телеграме. О том, как их сделать удобнее и красивее для пользователей

Также новости, обзоры, мысли и другая интересная информация, попавшая в кругозор автора @maxsof
Download Telegram
🛃 Безопасные зоны

В недавнем обновлении АПИ отключили поддержку мета-свойства viewport-fit=contain и CSS-выражения env(safe-area-inset-*), но взамен дали нам две новых сущности:

1️⃣ Safe Area Inset

Предоставляет значения отступов для разных сторон экрана, чтобы контент приложения отображался без перекрытия системными элементами устройства, такими как вырезы, закругленные края, камеры или индикаторы навигации.


// Доступ через JS
Telegram.WebApp.safeAreaInset.top
Telegram.WebApp.safeAreaInset.bottom
Telegram.WebApp.safeAreaInset.left
Telegram.WebApp.safeAreaInset.right



/* Аналог на CSS */
var(--tg-safe-area-inset-top)
var(--tg-safe-area-inset-bottom)
var(--tg-safe-area-inset-left)
var(--tg-safe-area-inset-right)


2️⃣ Content Safe Area Inset

Так же предоставляет значения отступов для разных сторон экрана, но теперь уже избегая наложения с элементами интерфейса самого Телеграма.


// Доступ через JS
Telegram.WebApp.contentSafeAreaInset.top
Telegram.WebApp.contentSafeAreaInset.bottom
Telegram.WebApp.contentSafeAreaInset.left
Telegram.WebApp.contentSafeAreaInset.right



/* Аналог на CSS */
var(--tg-content-safe-area-inset-top)
var(--tg-content-safe-area-inset-bottom)
var(--tg-content-safe-area-inset-left)
var(--tg-content-safe-area-inset-right)


*️⃣ Events

В дополнении к этому добавили два события safeAreaChanged и contentSafeAreaChanged, которые пригодятся для отслеживания изменений отступов. Например, при повороте экрана или раскрытии на полный.

🆗 Что со всем этим делать

Манипулировать паддингами и марджинами в зависимости от интерфейса приложения. В самом простом случае достаточно добавить глобально стили на обертку сайта:


.wrapper {
padding-top: calc(var(--tg-safe-area-inset-top) + var(--tg-content-safe-area-inset-top));
padding-right: calc(var(--tg-safe-area-inset-right) + var(--tg-content-safe-area-inset-right));
padding-bottom: calc(var(--tg-safe-area-inset-bottom) + var(--tg-content-safe-area-inset-bottom));
padding-left: calc(var(--tg-safe-area-inset-left) + var(--tg-content-safe-area-inset-left));
}


ℹ️ Ньюансы и баги

— На клиенте для Мака, например, хочешь не хочешь, а пользователь в любом случае может включить фуллскрин из меню настроек, поэтому придется использовать var(--tg-content-safe-area-inset-top).

— На том же клиенте для Мака не обошлось без бага и в CSS-переменных значения для safe area inset попросту не приходят. Поэтому нужно прописать запасные значения, например, так var(--tg-safe-area-inset-top, 0px).

В веб-версии (А) var(--tg-safe-area-inset-bottom) равен высоте окна приложения, что выглядит как явный баг.

🔄 Обновлено 26.01.25: баг исправлен.

— В целом, значения content safe area inset для right, buttom и left как будто бы ни для чего не нужны, потому что Телеграм использует только в верхней части свои элементы.

🆒 Итог

Из всего вышесказанного, я для себя сделал такой итоговый CSS:


.wrapper {
padding-top: calc(var(--tg-safe-area-inset-top, 0px) + var(--tg-content-safe-area-inset-top));
padding-right: var(--tg-safe-area-inset-right, 0px);
padding-bottom: var(--tg-safe-area-inset-bottom, 0px);
padding-left: var(--tg-safe-area-inset-left, 0px);
}


🔄 Обновлено 26.01.25: добавил bottom.

Казалось бы, простая штука, а сколько много текста вышло. Пишите в комментах если есть чем дополнить?

@MiniAppsForLife
#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥105
This media is not supported in your browser
VIEW IN TELEGRAM
Делюсь красивостью 🎊

Думаю, всегда приятно получать обратную связь от интерфейса, а особенно — когда тратишь деньги.

Интересную анимацию можно найти на lottiefiles.com, поджать файл через lottiemizer.com и прикрутить к сайту с помощью lottie-web.

Всех с наступающим 🎄

⬇️@MiniAppsForLife
🔘#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥9👍21
This media is not supported in your browser
VIEW IN TELEGRAM
Просто прикольная фича 👾

Включается на Айфоне в дебаг-режиме (нажать 10 раз на кнопку настроек), пункт Ripple. Работает в любом чате.

⬇️@MiniAppsForLife
🔘#наблюдения
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍5🥴2🌚1
🕳 Локальная разработка через туннель

При разработке мини-приложения удобнее всего запускать его в реальной среде, то есть через сам Телеграм. Здесь адекватно работает АПИ, присутствует сам интерфейс и передаются все пользовательские данные. Для этого можно заморочиться с тестовой средой или запустить сайт через туннель, что гораздо проще.

Туннель — это технология, позволяющая связать локальный хост с публичным URL, доступным через интернет. Другими словами, вы запускаете свой проект у себя на компьютере через условный http://localhost:3000, а он виден глобально из интернета по какому-то определенному адресу (с https).

Сервисов туннелей есть множество. Я пробовал парочку:

🔜 Tuna
🔜 Ngrok

Но слышал и об этих:

➡️ localtunnel
➡️ Tunnelmole
➡️ Cloudflare Tunnel
➡️ VK Tunnel

В итоге остановился на Tune и даже купил подписку, так как устал от бесплатного лимита в 30 минут.

После несложной настройки завел отдельный /newapp в @BotFather, куда передал статичный домен (в платной версии это доступно). То есть, у меня есть основной бот, где работает прод, и есть отдельный апп, где запускается дев-версия, когда я над ней работаю.

Поделитесь опытом как и через что вы тестируете свои проекты?

⬇️@MiniAppsForLife
🔘#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍6🔥421
💻 Определение устройства

В АПИ мини-аппов есть параметр platform, который возвращает название платформы, на которой открыто приложение.

Так как официальных клиентов несколько, то вот что попадает в его значение:

ios (Айфон и Айпад);
macos (Мак);
tdesktop (Мак и Винда);
android (Андроид);
weba (Веб А);
web (Веб К);
unknown (если не определено).

Что можно с этим сделать? Ну, например, если у вас игра или тапалка, то можно открывать ее только на мобильных устройствах, а для десктопа показывать куаркод со сылкой.

Я использую этот параметр, чтобы показать, например, больше настроек на мобилках, типа фуллскрина и кнопки добавления на домашний экран.

А еще интерфейс приложений по мелочам разнится от клиента к клиенту и можно подтюнивать на каждом устройстве некоторые части, чтобы приложение выглядело роднее. Но это целая тема для отдельного поста.

Используете ли вы этот параметр? А для чего?)

⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍6
icon-telegram-stars.svg
508 B
Делюсь SVG-иконкой Телеграм Stars, а заодно и просто кодом, пригодится ⭐️


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="m11.47 18.6-4.5 2.73a1 1 0 0 1-1.37-.32.98.98 0 0 1-.12-.76l.7-2.73c.25-.98.93-1.8 1.85-2.24l4.91-2.34a.46.46 0 0 0 .22-.61.46.46 0 0 0-.5-.25l-5.46.94a3.85 3.85 0 0 1-3.12-.84l-1.72-1.43A.98.98 0 0 1 2.92 9l5.27-.41a1 1 0 0 0 .84-.61l2.04-4.88a1 1 0 0 1 1.83 0l2.04 4.88a1 1 0 0 0 .84.6l5.3.42a.99.99 0 0 1 .57 1.73l-4.04 3.43a.98.98 0 0 0-.33.98l1.25 5.13a.99.99 0 0 1-.74 1.2 1 1 0 0 1-.75-.13L12.5 18.6a1 1 0 0 0-1.03 0Z" />
</svg>


UPD: В комментах еще больше вариантов.

@MiniAppsForLife
#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍11🔥9
🔒 Блокировка ориентации экрана

Некоторые мини-приложения удобнее использовать в определенной ориентации экрана. Если пользователь случайно повернет устройство, это может сломать интерфейс или испортить опыт взаимодействия. Блокировка ориентации экрана поможет избежать таких проблем, сохраняя комфорт и предсказуемость.

Для управления ориентацией в АПИ доступны два метода: lockOrientation() и unlockOrientation().

Но сперва учтем некоторые моменты: экран можно поворачивать, поэтому нужно отслеживать ориентацию в реальном времени, чтобы в определенный момент заблокировать экран. Также пользователь может свернуть приложение, повернуть устройство и снова открыть его — это тоже нужно учитывать. Работать будем только с мобильными устройствами, так как на десктопах ориентация обычно горизонтальная, и ее поддержка только усложнит задачу.

Ниже я написал готовый код на чистом JS без привязки к фреймворку, чтобы можно было легко разобраться и затащить к себе. Пример блокирует устройство в портретном состоянии:


// Проверка поддержки ориентации в браузере
const isOrientationSupported = 'orientation' in screen;

// Блокировка и разблокировка ориентации
const lockOrientation = () => Telegram.WebApp.lockOrientation();
const unlockOrientation = () => Telegram.WebApp.unlockOrientation();

// Проверка текущей ориентации
const checkOrientation = () => {
// Работа только с мобильными устройствами
if (!['ios', 'android'].includes(Telegram.WebApp.platform)) {
return false;
}

// Блокировка при портретной (вертикальной) ориентации
if (screen.orientation.type.startsWith('portrait')) {
lockOrientation();
// Разблокировка при ландшафтной (горизонтальной) ориентации
} else if (screen.orientation.type.startsWith('landscape')) {
unlockOrientation();
}
};

// Установка слушателей событий
const setupOrientationListeners = () => {
if (!isOrientationSupported) {
return false;
}

// Прослушка изменения ориентации в реальном времени
window.addEventListener('orientationchange', checkOrientation);

// Прослушка событий сворачивания и разворачивания приложения
Telegram.WebApp.onEvent('activated', checkOrientation);
Telegram.WebApp.onEvent('deactivated', unlockOrientation);
}

// Очистка слушателей событий
const cleanupOrientationListeners = () => {
if (!isOrientationSupported) {
return false;
}

// Отписка от слушателей изменения ориентации
window.removeEventListener('orientationchange', checkOrientation);

// Отписка от слушателей сворачивания и разворачивания
Telegram.WebApp.offEvent('activated', checkOrientation);
Telegram.WebApp.offEvent('deactivated', unlockOrientation);
};

// Инициализация
checkOrientation();
setupOrientationListeners();

// Очистка (при необходимости)
// cleanupOrientationListeners();


Потестировать можно в 🍅 Помидорке. Там я пошел чуть дальше и в горизонтальном виде дополнительно добавил иконку с текстом о необходимости поворота.

⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍9🔥63
Оформил тут на досуге популярный канал и чат про мини-приложения, в котором состою, и который однажды, собственно, меня и подтолкнул на создание своего канала 💡

Спасибо автору @rvignatenko за отзывчивость и доверие

Присоединяйтесь к «зеленому» сообществу:
🚀 Telegram Mini Apps 🚀 с Романом Игнатенко
💬 Чат про Telegram Mini Apps

⬇️@MiniAppsForLife
🔘#личное
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥5👍3👏2
This media is not supported in your browser
VIEW IN TELEGRAM
Анимированные эффекты при отправке сообщения

В мае прошлого года вышло обновление в котором можно добавлять эффект при отправке сообщения в личной переписке.

От имени бота так же можно добавлять такой эффект в некоторых методах, используя уникальный идентификатор в параметре message_effect_id, но их всего шесть:

🔥5104841245755180586
👍5107584321108051014
❤️5159385139981059251
🎉5046509860389126442
👎5104858069142078462
💩5046589136895476101

Спасибо @kulikov_aleks за наводку 👍

⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥13🙏6
Часто замечаю в мини-аппах использование таббара. Проблема в том, что зачастую он прилипает к хоум-индикатору Айфона.

У Ильи Бирмана недавно вышел разбор про этот момент на Ютубе. Посмотрите на досуге, там всего две с половиной минуты.

Справедливости ради, стоит сказать, что автор этого приложения попытался это учесть, используя env(safe-area-inset-bottom), но в Телеграме такое не поддерживается и надо явно прописать var(--tg-safe-area-inset-bottom, 0px).

Напомню, что я как-то писал пост про безопасные зоны. Там были ньюансы, но Телеграм частично их поправил, где я пометил обновлениями.

⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥13👌63👍2
🌓 Светлая и темная темы

Современные устройства и приложения поддерживают два режима отображения интерфейса: светлый и темный. В зависимости от выбранного пользователем режима, элементы интерфейса — такие как фон, текст, кнопки, поля ввода, скроллбар и прочее — автоматически адаптируются к соответствующей теме.

Чтобы мини-приложение поддерживало такое поведение, необходимо добавить метатег и CSS-свойство:


<meta name="color-scheme" content="light dark">



:root {
color-scheme: light dark;
}


Работа метатега и CSS-свойства одинакова, однако метатег помогает немедленно загрузить необходимую тему, не дожидаясь загрузки CSS. Это позволяет избежать классической ситуации, когда при открытии приложения ночью экран сначала ослепляет белым светом, а затем переключается на темную тему 😵

В дополнение при запуске мини-приложения Телеграм предоставляет текущее значение цветовой схемы через CSS-переменную --tg-color-scheme. Она пригодится для разрешения конфликтов, когда, например, на уровне системы тема оформления светлая, а приложение Телеграма — темное.

В этом случае CSS можно переписать так:


:root {
color-scheme: var(--tg-color-scheme, light dark);
}


Далее было бы удобно манипулировать стилями через медиавыражение prefers-color-scheme, но на практике оно работает некорректно в некоторых случаях, поэтому выходом послужит добавление дата-атрибута с названием темы к корневому элементу html и последующего ориентирования на него в CSS.

Для этого Телеграм предоставляет свойство Telegram.WebApp.colorScheme, которое указывает текущую цветовую схему, а также событие themeChanged, чтобы отслеживать изменения темы динамически:


// Устанавливаем значение при запуске
document.documentElement.dataset.mode = Telegram.WebApp.colorScheme;

// Меняем его при переключении
Telegram.WebApp.onEvent('themeChanged', () => {
document.documentElement.dataset.mode = this.colorScheme;
});


Теперь можно легко управлять стилями:


body {
background-color: #fff;
color: #000;
}

[data-mode="dark"] body {
background-color: #000;
color: #fff;
}


Итоговый пример кода:


<html>
<head>
<!-- … -->
<meta name="color-scheme" content="light dark">
<style>
:root {
color-scheme: var(--tg-color-scheme, light dark);
}

body {
background-color: #fff;
color: #000;
}

[data-mode="dark"] body {
background-color: #000;
color: #fff;
}
</style>
<script>
document.documentElement.dataset.mode = Telegram.WebApp.colorScheme;

Telegram.WebApp.onEvent('themeChanged', () => {
document.documentElement.dataset.mode = this.colorScheme;
});
</script>
<!-- … -->
</head>

<body>
<!-- … -->
</body>
</html>


⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍12🔥8
🆕 Новое в версии АПИ 9.0 для мини-аппов

На днях подвезли два новых функционала для работы с хранилищами:

➡️ DeviceStorage. Позволяет использовать постоянное локальное хранилище на устройстве пользователя. Это аналог localStorage браузера, но интегрированый в клиент Телеграм.

➡️ SecureStorage. Позволяет использовать безопасное локальное хранилище на устройстве пользователя для конфиденциальных данных. Подходит для хранения токенов, секретов, состояния аутентификации и т. п.

Как итог, теперь мы имеем три сущности CloudStorage, DeviceStorage и SecureStorage.

Правда, есть ощущение, что при обновлении забыли изменить версию скрипта, отчего эти новые функции просто нет возможности проверить. То есть на всех клиентах Telegram.WebApp.version = 8.0 и пока обновлений в сторах не видно, а прошло уже 4 дня 🤷‍♂️

⬇️@MiniAppsForLife
🔘#новости
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥72👍1
📞 Павел на связи

Владислав Кибенко собрал с сообществом разработчиков необходимое количество звезд и написал сообщение Павлу Дурову. О том, как нам всем тяжело разрабатывать мини-приложения с багами, которые тянутся годами или появляются с каждым новым релизом.

Удивительно, но Павел дал ответ! По каким-то причинам тексты сообщений не разглашаются, но важен сам факт, что Павел готов прислушаться.

Описание багов собирают в этом чате. По итогу будет сформирован файл и отправлен начальнику 📨

⬇️@MiniAppsForLife
🔘#наблюдения
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥6
🆔 Идентификаторы профилей

По мере работы с АПИ иногда нужно быстро узнать ID пользователя, канала, группы или бота. Включить отображение идентификатора в профиле искомой сущности можно через:

➡️ Telegram Desktop: Настройки ▶️ Продвинутые настройки ▶️ Экспериментальные настройки ▶️ опция Show Peer IDs in Profile 

➡️ Telegram для MacOS: Настройки ▶️ Общие ▶️ опция «Показывать ID чатов в профиле»  

Стоит учесть, что в случае с группами и каналами к айдишнику в начале еще нужно приписать -100. То есть, если в профиле ID указан как 123456789, то итоговый ID будет -100123456789.

⬇️@MiniAppsForLife
🔘#инструкции
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍10🔥4
🥸 История про мошенника

Пару лет назад ко мне начали стучаться люди с вопросами о неком «разработчике». В своем резюме он опубликовал примеры из разных ботов и сервисов, которые якобы разрабатывал. Первой шла моя 👛 Копилка.

В своих работах я всегда указываю свое авторство — это, видимо, и помогло клиентам заподозрить неладное.

Некоторые писали после оплаты, когда мошенник уже исчезал. Я предупреждал их, даже пытался связаться с ним сам — но он использовал разные аккаунты, и ответов не было.

Один случай запомнился особенно. На вопрос клиента: «Почему вы не указаны как разработчик?» — он ответил, что я якобы был заказчиком, а он создал бота для меня.

Проблема большинства «его» проектов в том, что там отсутствовало авторство. Я даже хотел было написать пострадавшим и предупредить, но не смог этого сделать.

После этого я переписал текст в описании на «единственный автор и разработчик», что звучит глупо и так себе, но с тех пор год тишины — надеюсь, метод сработал.

А посыл сей истории в том, что если вы делаете ботов — указывайте свое имя в профиле, в самом боте или в коде. Это защитит вашу работу и убережет других от обмана.

Расскажите, были ли у вас похожие случаи и как вообще справляться с такими ситуациями?

⬇️@MiniAppsForLife
🔘#личное
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5