Эмодзи/мобильный чат: убрать загрузку с GitHub, клавиатура, тихий Script error

- Пикер: анимированные webp грузились с raw.githubusercontent.com (в репо их
  нет) — у пользователей с VPN/операторскими блокировками тап по эмодзи давал
  сетевую ошибку и «моргание»/подмену картинки. Теперь всегда локальные
  статичные превью, без внешних запросов и pointer capture; мёртвая константа
  GitHub-URL удалена. Возврат анимаций — только локальным паком.
- Чат (тач): открытие эмодзи-пикера прячет клавиатуру (blur), вставка эмодзи
  не фокусирует textarea на сенсорных устройствах — поле больше не
  перекрывается клавиатурой (на десктопе фокус как раньше).
- Глобальный обработчик ошибок: кросс-ориджин «Script error.» без файла/стека
  больше не показывается алертом (лог и captureClientError остаются) —
  устраняет пугающую плашку на Xiaomi/Safari.
- VERSION: client 1.2.327.

Проверено в превью: тап по эмодзи — 0 запросов к githubusercontent, 😈
вставляется ровно как 😈, картинка кнопки стабильна; фильтр алерта: Script
error. — тихо, реальная ошибка — алерт показывается.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pixel
2026-07-16 19:48:22 +03:00
co-authored by Claude Opus 4.8
parent d6bc883520
commit ea2ee1711c
5 changed files with 39 additions and 10 deletions
+14 -5
View File
@@ -914,6 +914,10 @@ export function render({ navigate, route }) {
emojiToggle?.setAttribute('aria-expanded', 'false');
};
// На сенсорных устройствах фокус в textarea поднимает клавиатуру поверх пикера —
// поэтому при вставке эмодзи фокусируем поле только там, где есть «точный» указатель.
const isFinePointer = window.matchMedia?.('(hover: hover) and (pointer: fine)')?.matches ?? true;
const insertEmoji = (emoji) => {
if (!input) return;
const value = String(input.value || '');
@@ -922,11 +926,13 @@ export function render({ navigate, route }) {
input.value = `${value.slice(0, start)}${emoji}${value.slice(end)}`;
const nextPosition = start + emoji.length;
emojiSelection = { start: nextPosition, end: nextPosition };
input.focus();
try {
input.setSelectionRange(nextPosition, nextPosition);
} catch {
// Ignore browsers that do not expose textarea selection during focus changes.
if (isFinePointer) {
input.focus();
try {
input.setSelectionRange(nextPosition, nextPosition);
} catch {
// Ignore browsers that do not expose textarea selection during focus changes.
}
}
autoResizeComposer(input);
};
@@ -1247,6 +1253,9 @@ export function render({ navigate, route }) {
emojiPickerOpen = !emojiPickerOpen;
emojiSlot.hidden = !emojiPickerOpen;
emojiToggle.setAttribute('aria-expanded', String(emojiPickerOpen));
// Как в Telegram: либо клавиатура, либо пикер. На тач-устройствах при
// открытии пикера прячем клавиатуру, чтобы поле ввода оставалось видно.
if (emojiPickerOpen && !isFinePointer) input?.blur();
});
screen.addEventListener('pointerdown', (event) => {
if (!emojiPickerOpen || form.contains(event.target)) return;