Лента — место, где пост Korat виден лучше всего, и почти всё, что делает Korat, — группы, страницы заведений, истории, ссылки, которыми делятся, — построено на одной строке поста, а не на четырёх параллельных системах. Пост в группе — обычный пост с идентификатором группы. Пост страницы — обычный пост с идентификатором бизнеса. Из этого решения следует, что реакции, комментарии, упоминания и уведомления везде ведут себя одинаково, а исправление в одном месте чинит сразу всё. Так что страница на самом деле описывает материал, из которого сделано остальное приложение.
Четыре способа написать пост
Пост бывает простым текстом; текстом на цветном фоне — для короткой строки, которая потерялась бы серым абзацем; или набором до четырёх изображений в сетке, подстраивающейся под их количество. Опубликовать можно от себя или от страницы заведения, которым вы управляете, а вместо основной ленты — в группу.
У каждого поста своя видимость — публично или для друзей, — и её можно изменить после публикации, а не только в момент отправки. Люди постоянно ошибаются с аудиторией: написанное для друзей оказывается достойным всех, или наоборот — становится очевидно через час. Единственное исключение — пост от страницы заведения: он всегда публичный, потому что пост магазина, видимый лишь части покупателей, — это будущее обращение в поддержку.
На любой пост, комментарий и историю можно пожаловаться, выбрав причину из готового списка. Жалоба проходит через функцию, работающую с *вашими* правами, а не с правами сервера, поэтому пост, который вам не виден, и пост, которого не существует, отвечают одинаково: кнопка жалобы никогда не становится способом выяснить, существует ли материал, который вам видеть не положено. Ограничение по частоте действует в базе данных, а не в приложении. Свой пост можно отредактировать и удалить. Комментарии поддерживают упоминания, которые ведут к настоящим людям, — упоминание это ссылка на человека, а не строка, начинающаяся с собачки, и упомянутому приходит уведомление.
Шесть реакций, по одной на человека
Реакций шесть — 👍 ❤️ 😄 😮 😢 😡 — и на один пост человек ставит ровно одну. Нажать ту же ещё раз — снять; нажать другую — перенести. Накрутить счётчик повторными нажатиями нельзя, и нет отдельной бухгалтерии «лайки плюс реакции», которую пришлось бы сводить.
Шесть, а не одна — потому что один лайк двусмыслен под плохой новостью. Шесть, а не тридцать — потому что длинный хвост редких реакций делает счётчики нечитаемыми. Шести хватает, чтобы отличить согласие от сочувствия и от злости, а это и есть различие, которое людям нужно.
Лента ранжируется, и ранжирование записано
Основная лента не строго по времени. Порядок задаёт функция ранжирования, живущая в одном файле исходников — data/Ranking.kt, — и каждый её вес описан в документе по базовому алгоритму проекта рядом с весами для рекомендаций друзей, знакомств и поиска. Меняется вес — меняется документ.
Мы об этом говорим, потому что «алгоритм» — обычно та часть социального продукта, которую никто описывать не станет. Ранжирование — это набор чисел, которые кто-то выбрал; записанные в одном месте, они превращаются из чёрного ящика в то, с чем можно спорить. Посты групп исключаются из основной ленты ровно в одной точке этого конвейера: они принадлежат своей группе и там и остаются.
Альбомы и куда попадают ваши фотографии
Фотографии складываются в альбомы со своей видимостью — публичной, для друзей или приватной, — независимой от постов, в которых они использованы. У альбома есть обложка, его можно переименовать и удалить, а три альбома существуют с самого начала: фото профиля, обложки и изображения постов. Так что загрузка фотографии в пост не создаёт молча вторую копию вашей библиотеки где-то, куда вы не смотрите.
Приватный альбом приватен в том смысле, что интерфейс Korat не покажет его никому другому. Он не приватен в криптографическом смысле — и здесь начинается честная часть.
Загруженные файлы читаются по прямой ссылке кем угодно. Korat не использует подписанные URL и закрытые хранилища. Любой, у кого есть прямой адрес файла, откроет изображение независимо от видимости поста или альбома: видимость управляет тем, кто видит файл *в приложении*, а не тем, кто может его скачать.
Ничего в Korat не шифруется сквозным шифрованием, шифрования на уровне приложения при хранении тоже нет. Считайте загруженную фотографию тем, до чего дотянется любой, кто получит её адрес, и не загружайте того, для чего такой исход был бы серьёзным. Страница безопасности перечисляет это ограничение вместе со всеми остальными.
Как поделиться — и ссылка, которая ничего не рассказывает
Всё, чем можно поделиться, уходит карточкой в чат, в вашу ленту, в историю или наружу в любое приложение через обычное системное меню Android. А ещё из этого получается ссылка на koratland.com вида koratland.com/s/<token>, где токен — 14 случайных символов. Так можно поделиться постом, профилем, заведением и историей.
Токен непрозрачен намеренно. Когда его открывают, сервер раскрывает его функцией, которая возвращает ровно две вещи: тип объекта и какой именно объект. Она никогда не отдаёт ни автора ссылки, ни число переходов. Подсчёт кликов устроен наоборот: отдельная функция записывает переход, а права на вставку в саму таблицу нет ни у кого — посетитель увеличивает счётчик, не имея возможности записать туда что-либо ещё. Поэтому ссылка, вставленная в чужой чат, не говорит получателям ничего о том, чем вы делились раньше.
Истории исчезают, список зрителей — нет
История — это фотография или текст на цвете, со встроенным шрифтом на выбор, свободным размещением текста по холсту и выбранным цветом надписи. Видимость — публично или для друзей, те же два варианта, что у поста, и она истекает сама. Свою историю можно удалить раньше.
Автор истории получает список зрителей — конкретных людей, а не число. Счётчик говорит, что историю смотрели; список говорит кто, а это и есть то, что вы хотели знать, и заодно всем очевидно, что просмотр не анонимен. Тренировку из модуля спорта и здоровья тоже можно отправить в историю с подписью на выбранном фоне — это тот же объект истории с другим содержимым.