zov-tech/miniapp/assets/platform.js
wasrusgen ef51ebcb85 feat: platform.js — адаптер Telegram WebApp для миграции на VK Max
- platform.js: глобальный Platform (initData, initDataUnsafe, startParam,
  colorScheme, ready, expand, haptic, showAlert, onThemeChange, enableClosingConfirmation)
- tg остаётся глобальным для backward-совместимости модулей
- app.js: setupTelegram() и haptic() делегируют в Platform,
  все tg?.initData/initDataUnsafe → Platform.initData/initDataUnsafe
- index.html: platform.js грузится первым (перед icons.js)
- VK Max Phase 2: заменить platform.js, остальной код не трогать

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-18 18:06:03 +03:00

70 lines
3.8 KiB
JavaScript

/* ============================================================
platform.js — адаптер платформы
Telegram Phase 1 · VK Max Phase 2 (отдельно, не параллельно)
Загружается ПЕРВЫМ из всех app-скриптов (после telegram-web-app.js).
Определяет два глобальных:
tg — ссылка на WebApp (backward-совместимость модулей)
Platform — единый API без привязки к Telegram SDK
Миграция на VK Max: заменить этот файл, остальной код не трогать.
============================================================ */
/* global */ var tg = window.Telegram?.WebApp || null; // eslint-disable-line no-var
const Platform = (function () {
"use strict";
const _tg = tg;
return {
// ── Auth ────────────────────────────────────────────────
/** Подписанная строка initData — для HMAC-верификации на бэкенде */
get initData() { return _tg?.initData || ""; },
/** Небезопасный объект (fallback для Telegram Desktop) */
get initDataUnsafe() { return _tg?.initDataUnsafe || null; },
/** Параметр ?startapp= / start_param от бота */
get startParam() { return _tg?.initDataUnsafe?.start_param || null; },
// ── Тема ────────────────────────────────────────────────
/** "light" | "dark" — берём из платформы или matchMedia */
get colorScheme() {
return _tg?.colorScheme
|| (window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light");
},
// ── Lifecycle ───────────────────────────────────────────
/** Сигнал платформе: MiniApp готов к показу */
ready() { try { _tg?.ready?.(); } catch (e) { /* не в Telegram → ок */ } },
/** Развернуть на весь экран */
expand() { try { _tg?.expand?.(); } catch (e) {} },
/** Подтверждение при закрытии (предотвращает случайный свайп) */
enableClosingConfirmation() { try { _tg?.enableClosingConfirmation?.(); } catch (e) {} },
// ── События ─────────────────────────────────────────────
/** Подписка на смену темы платформой */
onThemeChange(cb) { try { _tg?.onEvent?.("themeChanged", cb); } catch (e) {} },
// ── UI ──────────────────────────────────────────────────
/** Нативный alert платформы (fallback → window.alert) */
showAlert(msg) {
if (_tg?.showAlert) { try { _tg.showAlert(msg); return; } catch (e) {} }
alert(msg);
},
// ── Haptic ──────────────────────────────────────────────
/**
* Тактильный отклик.
* @param {"impact"|"success"|"selection"} type
*/
haptic(type = "selection") {
try {
const hf = _tg?.HapticFeedback;
if (!hf) return;
if (type === "impact") hf.impactOccurred("light");
else if (type === "success") hf.notificationOccurred("success");
else hf.selectionChanged();
} catch (e) {}
},
};
})();