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