5.4 KiB
Ссылки в сообщениях
Android и Qt распознают http://, https:// и utun:// в обычном тексте
личных и групповых сообщений. HTTP/HTTPS нечувствительны к регистру схемы;
utun:// распознаётся только в нижнем регистре. Утилиты разбора не открывают ссылки.
Ссылки выделяются цветом и подчёркиванием; длинные веб-адреса переносятся по ширине.
Сокращённая строка структурированного PM-приглашения сохраняет полный utun:// адрес.
Пробелы, управляющие символы, кавычки и угловые скобки отделяют ссылку от текста.
Конечные . , ; : ! ? и лишние закрывающие скобки удаляются из распознанного адреса.
Сбалансированные скобки в адресе, параметры, fragment и Unicode сохраняются.
Адреса без схемы не распознаются. Некорректные веб-адреса остаются обычным текстом.
Исходное сообщение в БД и протоколе не меняется.
У utun:// распознаётся кандидат из обычного base64-алфавита с до двух конечных =.
На этом этапе не проверяются версия, поля и содержимое приглашения: utun://abc+/==
может получить подсветку, но быть отклонённым при открытии. Предпросмотр Qt и Android
использует общий src/chat/invite_link.c через Qt-обёртку/JNI; принимается версия 0x03.
Сам декодер не проверяет регистрацию/срок join_key и не даёт членства.
Разборщики возвращают непересекающиеся диапазоны исходного текста в порядке появления
и полные адреса в исходном написании: Qt — start/length, Android — start/end,
где end исключён. Единицы обоих API — UTF-16:
tools/chatgui/src/message_links.cpp, Android data/MessageLinks.kt.
Конец диапазона Android не включён в ссылку; Qt возвращает начало и длину.
Удаление внешней пунктуации занимает линейное время: баланс трёх видов скобок
считается один раз, хвост сокращается по индексу без повторного копирования адреса.
Порт веб-адреса пустой либо десятичный от 0 до 65535; знак перед числом недопустим.
Подсветка и нажатие используют эти диапазоны. Android подставляет emoji placeholders
только в обычный текст между ссылками: emoji внутри адреса остаётся частью полного URL.
Qt использует один QTextLayout для размеров, отрисовки, выделения и координат нажатия.
Перетаскивание выделяет текст без открытия ссылки.
HTTP/HTTPS открываются из GUI системным обработчиком: Android ACTION_VIEW,
Qt QDesktopServices::openUrl. На нажатии веб-адрес снова проверяется.
В Qt utun:// сначала декодируется: уже существующая группа, где узел является
участником, открывается без JOIN; иначе показывается JoinDialog с автоматической попыткой входа.
На Android адрес передаётся в существующий invite/JOIN flow.
Ошибки открытия показываются через перевод интерфейса и логируются.
Диагностика открытия содержит схему и host, без полного пути/query.
Общие случаи: tools/chatgui/tests/message_links_cases.tsv.
Qt test_invite_links проверяет разбор, перенесённые веб-ссылки, смесь схем,
нажатие, drag/copy и сокращённые приглашения; test_emoji_playback — жесты приглашений.
Android MessageLinksTest проверяет тот же TSV через Gradle, некорректные authority
и длинный хвост пунктуации. Аналогичный тест длинного хвоста есть в Qt.
Оба разбора не открывают ссылки; некорректный пользовательский текст не создаёт логов.
cd tools/chatgui-android
./gradlew :app:testDebugUnitTest --tests com.utun.chat.data.MessageLinksTest
tests/test_message_links.kt остаётся отдельным CLI-тестом того же TSV;
ему передаётся путь к файлу, а в classpath нужны собранные классы MessageLinks.