1 changed files with 57 additions and 0 deletions
@ -0,0 +1,57 @@ |
|||||||
|
# Приглашение в группу через PM |
||||||
|
|
||||||
|
В desktop chatgui и Android кнопка «+» доступна в строке другого участника |
||||||
|
и в шапке личной беседы. Она открывает один диалог с фиксированным получателем |
||||||
|
и выбором группы, в которой отправитель состоит. Группа не выбирается автоматически. |
||||||
|
|
||||||
|
После нажатия «Пригласить» клиент создаёт свежую ссылку через `invite_build`, |
||||||
|
ожидает подтверждения регистрации ключа и отправляет ссылку обычным текстовым PM. |
||||||
|
Успех означает сохранение сообщения и исходящей задачи в одной транзакции. |
||||||
|
Доставку, повтор и шифрование обеспечивает существующий механизм DM. |
||||||
|
После успешной отправки открывается личная беседа с получателем. |
||||||
|
|
||||||
|
Срок действия ключа — **10 минут с момента создания**, а не получения PM. |
||||||
|
Он указан в диалогах отправки и подключения. Поздняя offline-доставка |
||||||
|
может принести уже просроченную ссылку; в этом случае нужно новое приглашение. |
||||||
|
Ссылка не содержит время истечения, поэтому клиент показывает длительность, |
||||||
|
без обратного отсчёта и вычисления оставшегося времени. |
||||||
|
|
||||||
|
Нажатие на `utun://` в сообщении запускает существующий JOIN и показывает его результат. |
||||||
|
Если клиент уже состоит в группе, открывается эта группа. Перенос длинной ссылки |
||||||
|
не меняет её содержимое; на desktop перетаскивание выделяет текст без запуска JOIN. |
||||||
|
|
||||||
|
## Контракт операции |
||||||
|
|
||||||
|
`dm_invite_trampoline` выполняется в uasync-потоке. Запрос содержит `request_id`, |
||||||
|
ID получателя, выбранную группу и исходную общую группу для создания PM. |
||||||
|
Из шапки существующей PM исходная группа может быть пустой. |
||||||
|
|
||||||
|
На instance допускается одно ожидание регистрации приглашения в PM. |
||||||
|
Повтор во время ожидания возвращает BUSY. Закрытие диалога отменяет только |
||||||
|
соответствующий `request_id`; уже отправленное сообщение не отзывается. |
||||||
|
Отмена и остановка DM завершают принятый запрос ровно один раз. |
||||||
|
|
||||||
|
`CHAT_EVT_DM_INVITE_RESULT` содержит 28 байт: |
||||||
|
`[request_id:u64][result:i32][peer:u64][conv_id:u64]` в порядке байтов ядра. |
||||||
|
Desktop и Android сопоставляют результат с запросом и получателем. |
||||||
|
Ошибки регистрации или сохранения сообщения оставляют диалог открытым для повторной попытки. |
||||||
|
|
||||||
|
JOIN во вторую группу может использовать уже открытый транспорт общей группы. |
||||||
|
Поэтому обработчики JOIN_REQUEST и JOIN_READY явно планируют member_sync, |
||||||
|
а JOIN_READY обновляет кеш каналов до запуска синхронизации. |
||||||
|
|
||||||
|
## Проверка и диагностика |
||||||
|
|
||||||
|
- `tests/test_dm_invite`: настоящая UDP-доставка ссылки в другую группу, JOIN, |
||||||
|
репликация участника и отправка группового сообщения после вступления; |
||||||
|
отмена, BUSY, неверная группа, rollback при ошибке commit и остановка DM. |
||||||
|
- `tests/test_chat_join`, `tests/test_chat_join_e2e`, `tests/test_dm_e2e`: |
||||||
|
существующие сценарии регистрации ключей, JOIN и PM-доставки. |
||||||
|
- Qt `test_invite_links`: переносы двух ссылок, их полное содержимое при нажатии, |
||||||
|
выделение текста и выбор получателя кнопкой в строке участника. |
||||||
|
- Qt `test_emoji_playback`: перетаскивание ссылки не активирует подключение. |
||||||
|
|
||||||
|
Для сетевого теста подробности включаются через `UTUN_TEST_DEBUG=1`. |
||||||
|
В приложении полезны категории `dm=debug`, `chat_sync=debug`, `member_sync=debug`. |
||||||
|
Операция пишет request, peer, group, результат и TTL; сообщения диагностики |
||||||
|
новой операции не выводят саму invite-ссылку. |
||||||
Loading…
Reference in new issue