SMeetMini Apps

SMeet Mini Apps

Интерфейс

Страница заполняет окно под панелью SMeet. Панель, меню и все доверенные экраны рисует SMeet; всё остальное рисует страница, и если она хочет выглядеть своей, то в цветах и на языке SMeet.

Окно#

  • В web-версии на экране шириной от 768 пикселей окно стоит посередине, 420 на 760 пикселей (не больше 92% экрана), а Развернуть увеличивает его до 1100 на 900. На более узком экране оно занимает весь экран.
  • В SMeet для iOS окно занимает весь экран iPhone; на iPad и Mac это карточка посередине, которую Развернуть увеличивает.
  • Панель SMeet над страницей показывает Назад, пока у страницы есть обработчик «Назад», название, домен страницы, меню и Закрыть. Не рисуйте вторую кнопку закрытия или поддельную адресную строку.
  • Всё, что SMeet показывает сам (согласие, подтверждение результата, внешнюю ссылку, жалобу, меню, экраны ошибок), он рисует поверх страницы. Пока это открыто, по странице нельзя нажать и в неё нельзя перевести фокус.

Размер и клавиатура#

environment.viewport это видимая область приложения: под панелью SMeet и над экранной клавиатурой. environment.safeArea даёт вырезы устройства, которые её пересекают. Оба меняются через onViewportChanged: когда открывается и закрывается клавиатура, поворачивается устройство, меняется размер окна на Mac, окно разворачивается или сворачивается.

HTML
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
JavaScript
function applyViewport({ viewport, safeArea }) {
  const root = document.documentElement.style;
  root.setProperty("--app-height", `${viewport.height}px`);
  root.setProperty("--safe-bottom", `${safeArea.bottom}px`);
}
applyViewport(app.environment);
app.onViewportChanged(applyViewport);
  • Размечайте страницу по видимой области, а не по 100vh: на телефонах 100vh включает то, что закрывает клавиатура.
  • Держите поле с фокусом и его кнопку над клавиатурой; после onViewportChanged прокручивайте поле с фокусом в видимую часть.
  • Оставляйте свободным safeArea.bottom внизу полноэкранной разметки.

Тема#

environment.colorScheme равен light или dark, а environment.theme даёт цвета SMeet значениями CSS: bg, text, hint, link, button, buttonText, secondaryBg. Они меняются через onThemeChanged.

JavaScript
function applyTheme({ colorScheme, theme }) {
  const root = document.documentElement;
  root.style.colorScheme = colorScheme;
  for (const [name, value] of Object.entries(theme)) root.style.setProperty(`--smeet-${name}`, value);
}
applyTheme(app.environment);
app.onThemeChanged(applyTheme);

Берите цвета набором целиком и проверяйте контраст своих цветов с bg в обеих схемах.

Язык#

environment.language равен ru или en, это язык SMeet у человека. Показывайте страницу на нём. В web-версии смена языка приходит через onLanguageChanged; на iOS и macOS она закрывает окно, и следующий запуск идёт уже на новом языке. Ваш сервер получает то же значение как user.language_code.

«Назад» и закрытие#

  • app.setBackHandler(handler) заставляет Назад SMeet вызывать ваш обработчик, а не действовать самому; используйте это для шагов формы. app.setBackHandler(null) возвращает Назад SMeet, когда страница на первом шаге.
  • app.setClosingConfirmation(true), пока в форме есть несохранённые изменения: SMeet один раз переспросит перед закрытием окна, а второе нажатие закроет его. Выключайте это, когда изменения сохранены.
  • app.close() закрывает окно, например после отправки результата.

Черновик всё равно сохраняйте: окно может закрыться и без вопроса, когда человек выходит из SMeet или теряет доступ.

Без диалогов браузера#

alert(), confirm(), prompt() и print() в окне не работают. В web-версии фрейм не разрешает модальные диалоги; на iOS и macOS alert() сразу возвращается, confirm() даёт false, а prompt() даёт null. Диалог в окне мог бы выглядеть как диалог самого SMeet и спросить пароль, поэтому SMeet их никогда не показывает. Рисуйте свои подтверждения и сообщения на странице.

  • Страница не может открыть новое окно или вкладку (window.open, target="_blank") и не может перевести вкладку SMeet на другой адрес. Внешний адрес открывайте через app.openExternalLink(url): SMeet показывает адрес, и после Открыть его открывает браузер, вне SMeet и без входа человека в SMeet.
  • openExternalLink принимает абсолютный адрес https с хостом, без имени пользователя и пароля, до 2048 символов, не на собственном хосте SMeet. Всё остальное отказывает с INVALID_PARAMS без диалога. В web-версии после трёх нажатий Отмена подряд в одном запуске следующие вызовы отказывают с RATE_LIMITED без диалога, пока человек не откроет приложение заново.
  • Ссылки между страницами вашего origin работают как на любом сайте. Каждая страница подключает SDK и подключается заново (Подключение). Ссылка на другой origin уводит со своего домена: в web-версии SMeet закрывает окно слоем и пишет «Страница ушла с <домен> или не отвечает»; на iOS и macOS по ссылке переход не выполняется, и SMeet предлагает открыть её в браузере, как при openExternalLink.
  • Мини-приложение не ссылается на покупку цифровых товаров (Правила для авторов).

Чего фрейм не позволяет#

В web-версии у фрейма выключены камера, микрофон, геопозиция, запись экрана, полноэкранный режим, чтение буфера обмена, платежи, USB, Bluetooth и датчики движения; запись в буфер обмена работает. На iOS и macOS SMeet отказывает в доступе к камере, микрофону и датчикам движения. Человек может выбрать файл стандартным <input type="file">; системное окно выбора может предложить сделать снимок, и страница получает только готовый файл. Скачивание изнутри окна в web-версии не работает (Файлы).

Доступность#

Окно SMeet является диалогом со своим заголовком; при открытии фокус переходит в него, а клавиши, нажатые внутри страницы, принадлежат странице. Остальное за вами:

  • заголовки, подписи у каждого поля, кнопки элементом <button>, видимый фокус;
  • сообщения о состоянии страницы в области с role="status" или aria-live;
  • текст, который растёт вместе с размером шрифта человека, и никаких сведений, передаваемых только цветом;
  • работа с клавиатуры от первого поля до Отправить без мыши; Escape внутри страницы принадлежит странице.

Видимость#

На время звонка SMeet скрывает окно, не закрывая его, и присылает onVisibilityChanged с visible: false; после звонка приходит visible: true. Ставьте на паузу звук, видео и таймеры, которые удивили бы человека, пока окно скрыто. Форма и сессия остаются; сессию, закончившуюся за это время, продлевает новый вход.