На чат опирается всё остальное. Друг зовёт вас за свой стол — приглашение приходит карточкой. Кто-то делится постом — карточка открывает пост. Совпадение в знакомствах становится настоящим разговором в ту же секунду, когда симпатия оказалась взаимной. Сообщения приходят в одно место, значит, и смотреть надо в одно место. А мессенджеру остаётся сделать хорошо одну вещь: переписку двух людей, где вложений хватает, чтобы не уходить в другое приложение.
Два человека, одна переписка
Личная переписка в Korat — только между двумя людьми: в ветке ровно двое, и третьего туда не добавить. Разговор нескольких людей живёт в двух других местах, и ни одно из них не этот мессенджер. Группы несут его постами: пост получает идентификатор группы и вместе с ним комментарии, упоминания и уведомления от обычного механизма ленты — с ветками, доступный поиску и никуда не пропадающий. А у группы и у спортивного клуба могут быть комнаты: текстовые каналы в духе Discord, перечисленные внутри группы, на своих таблицах и со своими правами — и умеющие заметно меньше, чем личная переписка. Ограничения полностью выписаны ниже, потому что комната, которая выглядит как чат и им не является, хуже, чем отсутствие комнаты.
Взамен переписка двух людей получает глубину. Можно ответить на конкретное сообщение цитатой, отредактировать отправленное, отменить отправку, закрепить главное наверху и поставить реакцию — быстрым набором из шести эмодзи или панелью из тридцати. Индикатор набора текста и статус прочтения работают так, как вы ожидаете.
Что можно вложить в сообщение
Кроме текста: изображения, произвольные файлы и голосовые, записанные штатным MediaRecorder в AAC внутри контейнера M4A, с проигрыванием прямо в пузырьке. Можно отправить геопозицию. И есть системные карточки, которые выпускает остальное приложение: пост, которым поделились, приглашение за стол, запись о состоявшемся звонке.
Новое сообщение отправляет push-уведомление на устройство собеседника — и в переписке один на один, и во входящих заведения. Оно доходит только до устройств, которые не отозваны, а открытие переписки гасит её уведомление. Чат, который производит сообщения, о которых никому не сообщают, не тихий — он сломан. Ограничение, которое надо назвать рядом: в веб-версии push нет. Если вы пишете из браузера, сообщение видно при открытии вкладки, а не в момент, когда оно приходит.
Карточка звонка важнее, чем кажется. Пропущенный звонок иначе невидим: вы открываете приложение позже, и ничто не говорит, что что-то было. Записанный в переписку звонок делает историю отношений одним прокручиваемым списком, а не разговором в одном месте и журналом вызовов в другом.
Ещё два объекта приходят в эту переписку из других частей Korat: цифровая визитка передаётся ссылкой, которую получатель откроет в любом браузере, а у каждого спортивного клуба есть своя текстовая комната — отдельная от описанных здесь переписок один на один и с ограничениями из врезки ниже, а не с тем, что умеет личная ветка.
Звонки, которые оба человека разрешили
Голос и видео работают на настоящем WebRTC: отключение микрофона и камеры, переключение камеры, полноэкранный входящий звонок и уведомление, когда приложение свёрнуто. Необычен замок перед ними: согласие на звонки двустороннее и своё в каждой переписке. Кнопки звонка не появляются, пока оба человека не откроют замок со своей стороны. До этого позвонить не может ни один из вас.
Это осознанный ответ на то, что звонящий телефон — самое навязчивое, что может сделать приложение. Незнакомец из знакомств или со страницы заведения может написать сообщение, которое вы проигнорируете; заставить ваш телефон звонить в два часа ночи он не может, пока вы прямо этого не разрешили. Согласие живёт в конкретной переписке, поэтому согласие с одним человеком ничего не говорит про остальных, и это замок, который вы открываете, а не настройка, зарытая в параметрах.
Два честных ограничения. Личная переписка — только между двумя людьми: ветку нельзя превратить в групповую, и многопользовательской версии описанного здесь мессенджера не существует. Что существует — комнаты, которые получают группа и клуб, и это более тонкая система на других таблицах: чистый текст, который можно отправить и удалить, без редактирования, без ответа на конкретное сообщение, без реакций, без фотографий, файлов и голосовых сообщений и без звонков. Ничто на этой странице не описывает комнату.
Звонки не имеют сквозного шифрования, и TURN-сервера нет. Медиапоток идёт напрямую между устройствами там, где сети позволяют дотянуться друг до друга, но без ретранслятора некоторые сочетания мобильного оператора и строгого NAT просто не соединяются. Если звонок не устанавливается, обычно причина в этом — и это часть инфраструктуры, которую мы не подняли, а не ошибка в приложении.
Присутствие — это heartbeat, а не сокет
Зелёная точка в Korat означает ровно одно: клиент этого человека записал отметку last_seen в последние девяносто секунд. Это опрос по таймеру, а не постоянное соединение, — дёшево для батареи и грубо по точности. Тот, кто закрыл приложение сорок секунд назад, всё ещё выглядит онлайн. Тот, кто въехал в туннель, гаснет, никуда не уходя.
Мы называем это heartbeat, а не «онлайн», потому что присутствие — та функция, которую чаще всего читают как доказательство: что сообщение увидели, что вас игнорируют. Девяностосекундное окно опроса такого веса не выдерживает.
Как найти нужную переписку
Основную работу по поддержанию длинного списка чатов делают две вещи. Первая — своё название чата: переименуйте переписку так, как вы на самом деле зовёте этого человека, и новое имя видите только вы. Оно никогда не попадает в ленту, в группы, в комментарии и на профиль. Человек, записанный у вас как «хозяин квартиры», везде показывается своим именем, ровно так, как он его написал. Имена в Korat подставляются из профиля в момент показа — именно чтобы переименование в одном месте не разошлось с другим.
Вторая — метки: цветные ярлыки, которые вы создаёте сами и наполняете сами; метку можно завести, переименовать и удалить. Они же работают фильтрами списка чатов рядом со встроенными: непрочитанные, официальные аккаунты и переписки из знакомств. Поиск идёт по названию чата и по последнему сообщению, так что полузабытой фразы достаточно. Чат можно закрепить, отметить прочитанным или удалить.
Что видит сервер и что можно сделать с человеком
Сообщения хранятся на сервере открытым текстом, а доступ к ним ограничен политиками защиты на уровне строк: строки переписки видны только двум её участникам. Сквозного шифрования чатов, звонков и файлов в Korat нет нигде, и шифрования на уровне приложения поверх того, что даёт управляемая база, тоже нет. Если для вашего разговора это обязательное требование — возьмите инструмент, построенный ради него: точное описание нашей модели угроз полезнее успокаивающего слова.
По человеческой части: заблокировать можно прямо из переписки или из профиля — это скрывает чаты и посты и одновременно убирает человека из вашей колоды знакомств; пожаловаться можно и на человека, и на отдельный материал — запись, комментарий, историю или сообщение. Блокировка — одно действие с последствиями во всём приложении, а не то, что нужно повторять на каждом экране.