И снова клон десктопного клиента Telegram

Казалось бы, сколько их уже есть, зачем еще один? Но случилось совпадение многих вещей — у меня было свободное время, желание что-то сделать, неудовлетворенность работой официального клиента и нежелание изучать существующие альтернативные версии и перечень их отличий. В результате я реализовал свой Луна-парк, с нужными мне фичами. Подробнее под катом.

aeffb75020fe59b01ae873a5a626e709.png

Минутка философии

Я прекрасно понимаю, что нельзя угодить всем. И, разрабатывая массовый программный продукт, можно все время добавлять и усложнять настройки, определяющие его работу. Но это экстенсивный путь, по большому счету. Кому-то подавай темную тему, кому-то выбор звуков оповещений, кому-то кастомные эмодзи и анимации… И я подозреваю, что подобные решения принимаются не просто так от настроения менеджера как он встал с утра, а набирается фокус-группа репрезентативных пользователей продукта, выясняются их приоритеты, потом анализируются временнЫе и финансовые затраты на реализацию и т.п. И в результате продукт обрастает новыми фичами и настройками, постепенно превращаясь в неповоротливиго трудноподдерживаемого монстра.

Мне никогда не было нужно 90% свистелок и фичей Телеграм. Более того, наличие и невозможность отключить некоторые из них мне откровенно не нравится. Но меня никто не спрашивал, я не член фокус группы. С другой стороны, меня не устраивает работа приложения в определенных моментах, но опять же, никто не спешит реализовывать мои хотелки. И тут самое время вспомнить слова великого селекционера Ивана Мичурина: «Если гора не идет к Магомету…» нет, вроде у него было по-другому, но суть та же: «Мы не можем ждать милостей от природы. Взять их у нее — наша задача.» И такое решение принимают многие пользователи, насколько я могу судить по обилию кастомных клиентов этого апи. Вот и я решил пополнить их ряды.

Ближе к делу

Одна из моих претензий к Телеграм в том, что мы по-разному понимаем термин «заблокированный пользователь». Мне хочется, чтобы если я заблокировал пользователя, то мне не приходили уведомления о его действиях (я знаю, что есть отдельная галочка «Отключить уведомления»), чтобы не появлялись картинки с новыми упоминаниями и реакциями от него, чтобы не появлялись новые истории (!) от него (я знаю, что можно удалить из списка контактов или скрыть истории персонально), чтобы были не видны сообщения от него во всех чатах и группах (с возможностью просмотра при желании), чтобы… Короче, чтобы эмулировалось его полное и абсолютное отсутствие в природе.

Телеграм даже идет мне навстречу в части моих пожеланий — например, если заблокированный пользователь упомянет меня в группе или чате, то клиент не покажет, что появилось новое упоминание. Подозреваю, потому что сервер (!) не пошлет флаг MentionMe в наборе флагов этого сообщения. Думаете, у заблокированного пользователя теперь нет возможности упомянуть меня? Оказывается, есть — если он будет цитировать или отвечать на мои сообщения, упоминания прекрасно будут показываться клиентом. Я думаю, что это баг на стороне сервера, но кто я такой, чтобы давать такие оценки :) Участников фокус-группы, видимо, такая логика работы приложения устраивает, или они считают это не настолько важным, как анимация реакций, к примеру. Тут уже вспоминаются слова великого поэта Владимира Маяковского (в переложении Де Моргана): «Если на небе не зажигаются звезды, значит это никому не нужно!»

Технические детали и возникшие трудности

В общем, решил я допилить существующий клиент под мои хотелки. Начал с десктопного, мобильный в планах. Благо продукт опенсорсный, лицензия позволяет, апи открытое и документация доступна. И столкнулся с некоторыми сложностями — существующее апи не предусматривает мои пожелания. Это было предсказуемо, но не пугало — я решил, что сделаю максимум из того, что смогу в рамках этих непреодолимых ограничений. Например, при старте приложения (а также при других событиях, но это не важно) идет запрос к апи за некоторым саммари по группам и каналам пользователя, для демонстрации наличия/отсутствия упоминаний в канале, новых реакций, количества новых сообщений и т.п. Разумеется, сервер не хочет думать, какие упоминания были от заблокированных пользователей, а какие нет. То же касается и сообщений с реакциями. В результате, я вынужден в фоне запрашивать детализацию по всем непрочитанным упоминаниям и реакциям, анализировать из авторов, и все только ради того, чтобы принять бинарное решение — показать или нет пиктограммку с наличием упоминаний в группе. С реакциями ситуация еще сложнее — помимо списка собственно сообщений с непрочитанными реакциями, я запрашиваю еще детализацию всех непрочитанных реакций каждого сообщения в разрезе реакторов (кто реагировал) с целью принятия решения — есть ли непрочитанные реакции к данному сообщению от незаблокированных пользователей или нет. Благо, соответствующие методы присутствуют в апи, и это радует. Но если бы сервер был последователен, и не считал упоминаниями от заблокированных пользователей не только написание моего ника в тексте, а еще и ответы и цитаты моих сообщений, жить было бы немного проще)

В онлайн режиме возникают подобные описанным выше проблемы — например, при событии от сервера «появились новые реакции» точно так же нужно детально запрашивать и проверять их авторов. И в определенных случаях отправлять на сервер уведомления о том, что контент сообщения прочитан, иначе сервер будет наивно полагать, что нам надо все время напоминать о том, что у нас есть важные непрочитанные сообщения, и заботливо это делать при каждом удобном случае.

Также были и чисто клиентские моменты: например, группировка «пузырей» отдельных сообщений от одного пользователя в пачки, где аватар и вытянутый к нему носик пузыря показываются только у самого нижнего сообщения в пачке, а большие радиусы закруглений у самого верхнего, создавая иллюзию одного общего мульти-пузыря всей пачки. Или, например, жесткая ориентация на строго определенную высоту превью сообщений в списке результатов поиска — вплоть до того, что метод Repaint определяет область своей перерисовки исключительно по номеру сообщения в списке, рассчитывая смещение как номер (количество элементов выше него) умноженный на жестко заданную высоту каждого виджета, что не облегчает задачу пропуска и скрытия из результатов поиска сообщений от заблокированных пользователей. Но тут хоть проблема не в апи, а значит в принципе решаемая.

Но я считаю, что в большой мере мне удалось реализовать мои идеи и пожелания, даже в рамках подобных ограничений. В некоторых моментах пришлось пойти на компромиссы, но работа не закончена, может еще реализую получше.

Отдельный вопрос был со сборкой релизного бинарника. Я на Убунте, и как ни странно, это добавило проблем и неочевидных моментов при сборке. Продакшен билды официальных релизов разумеется никто собирать у себя на коленке не разрешит, а скрипты и сценарии катомных билдов в проекте обновляются и актуализируются далеко не каждый раз, ибо разработчиками самого Телеграма очевидно не используются. В довершение этого, инструкция по сборке даже кастомного релизного бинарника просто отсутствует в документации официального клиента, есть только версия для дебага. В результате пришлось спрашивать некоторые моменты у гуру, которые, к их чести, помогли.

Счастливый (надеюсь, не) конец

В итоге, я в данный момент имею рабочую альфа версию пре-релиза моего кастомного клиента, который я назвал Kilogram. Примеров кода в статье не было, но они в изобилии представлениы в репозитории проекта на гитхабе: https://github.com/Ivana-/kilogram-desktop

Там кратко перечислены изменения в интерфейсе и фичи, реализованные на текущий момент.

Кому просто покритиковать код, репозитория достаточно.
Кому сбилдить свою версию — в ридми написано как.
Кому скачать и попробовать — там же на закладке Релизы готовый бинарник под Убунту. Вирусов и троянов не добавлял, никакие либы в проект не тащил, стучать майору и колонелу будет не больше чем официальный Телеграм клиент. Но если у вас взорвется компьютер или за вами придут, то я ни при чем)

Habrahabr.ru прочитано 1479 раз