Telegram Web
Меня всё никак не покидает идея сделать свой настоящий блог (может даже переводить какие-то посты на английский?), но руки не доходят уже наверное год как.

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

Из плюсов: запускается в две строчки и из коробки весьма хорошо смотрится и работает. Для простенького блога набросать за 15 минут — самое то. И RSS из коробки есть.

Теперь к недостаткам:
- Нет SSG, то есть блог не билдится в статику, а требует рантайма. Более того, нет даже этапа сборки. Это значит, что .md файлы компилируются в html на лету (может быть кешируются, не знаю). С одной стороны ожидаемо от команды Deno, которым выгодно продвигать свой serverless сервис Deno Deploy, но совсем не то, что я бы хотел в своем блоге.
- Из фич есть только сааамые базовые. Нет поддержки мультиязычности, нет подсветки синтаксиса в коде. Наверняка ещё кучи всего нет, я копал не так глубоко.

В общем, поигрался полчасика и понял, что это не моё. Ждите ещё постов.
Полтора года назад я попробовал Arc и влюбился в вертикальные вкладки, спейсы и Mini Arc.

Пару месяцев назад я попробовал Firefox+Sidebery и понял, что древовидные вкладки ещё удобнее, чем просто вертикальные. Но одних только древовидных вкладок оказалось недостаточно, чтобы перебраться с Arc на Firefox.

Последние несколько дней я усиленно копался во внутренностях лисы, чтобы слепить себе идеальный браузер. Я перебрал все настройки Sidebery, попробовал несколько userChrome кастомов и даже научился кастомить интерфейс самостоятельно.

Свои находки я документирую в этой статье, прошу любить и жаловать. Дисклеймер: изложение там довольно хаотичное. Контент будет дополняться в процессе моих дальнейших приключений. Жду ваших комментариев!
Делать одно и то же дважды

Замечаю за собой, что часто вместо того, чтобы фокусироваться на каком-то одном решении проблемы, поддерживаю параллельно два варианта. Например:
- У меня на маке сейчас настроен и zsh, и fish. Оба шелла настроены примерно одинаково, но я никак не могу выбрать один вместо другого. Сейчас пользуюсь fish, но за пару месяцев несколько раз переключался туда-обратно.
- Хоть в основном я пользуюсь Arc, сейчас пытаюсь настроить Firefox (см. предыдущий пост). У каждого браузера есть свои уникальные фичи, и я никак не могу выбрать один из них.
- То же самое с iPhone и Android. У меня на руках iPhone 14 Pro и Nothing Phone (2). Я устраивал тестовую неделю «если бы я перешел на андроид», но в итоге вернулся обратно на айфон. За последние три года я три раза метался между андроидом и яблоком.

И тут я задумался: а стоит ли оно того? С одной стороны, я трачу вдвое больше сил вместо того, чтобы отдаться одной стороне и получать удовольствие. А с другой стороны, у этого есть свои преимущества.
Во-первых, мне нравится этим заниматься. Если бы мне не нравилось, я бы не занимался 🤷‍♂️.
Во-вторых, это понижает степень моей вендорлокнутости. Благодаря тому, что оба решения примерно равны по удобству, я точно знаю, что, если моё текущее решение загнётся, я легко смогу перейти на другое.
Ну и в-третьих, что если это ошибка выжившего? Если в этих случаях у меня не получилось занять одну из сторон, не стоит переставать инвестировать в альтернативы. Может быть, в другой раз победитель нарисуется сам по себе, и мой экспириенс только выиграет.

Что думаете? Встречались с таким?
👨‍🎓 Университетские хроники: Web Basics

Одним из предметов в последней четверти этого года были Web Basics. Как можно понять из названия, там нас учили основам веб-разработки, а именно фронтенду (чистый html+js+css) и бэкенду (nodejs+express+sqlite)

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

Как и у многих других предметов, у Web Basics не было никаких промежуточных элементов контроля, только один главный дедлайн, к которому надо написать своё фулстек-приложение (в одиночку, не группой).

Проект состоял из трёх основных частей: бэкенд, фронтенд и документация.
Бэкенд должен быть написан на nodejs, использовать express и sqlite в качестве БД, иметь минимум 3 сущности с отношениями между ними, REST-compliant апи для взаимодействия с CRUD операциями. ESM обязателен, CJS харам. Typescript нельзя 😨
Фронтенд должен быть написан на html+js+css без js-фреймворков и библиотек, без этапа сборки, с использованием флексов/гридов и медиа выражений (oddly specific but ok). Server-side рендеринг нельзя, для подгрузки данных только fetch.
В документации надо было сделать спецификацию апи (с помощью swagger или в goofy ahh docx template который нам предоставили), пару sequence diagram, wireframes (это как макеты, только ещё более на минималках) и обоснования для нестандартных решений (я там похвастался что затащил kysely для работы с БД, valibot для валидации и prettier для форматирования)

Предметную область можно было взять любую, я выбрал максимально дефолтную: таск-трекер с тегами и комментариями (не спрашивайте). Проект, на который нам давалось 7 недель, я начал за 2.5 дня до дедлайна. Темп был весьма ударный, как на тех видосах с потным спидраннером. Но, в принципе, успел сделать всё что требовалось. Конечно, некоторые углы пришлось срезать (например, нигде не было написано что все CRUD-операции должны быть доступны с фронта, поэтому редактирование тегов и комментариев я не реализовал). Сложнее всего было писать код без тайпскрипта и реактивного фреймворка. К хорошему быстро привыкаешь, и поэтому написание небезопасного и императивного кода казалось просто пыткой.

За проект я получил 9/10. Часть баллов сняли не потому что что-то не успел, а потому что прикопались к коду (например, им не очень понравилось как я разделил бэкенд на слои). Хотя я бы и поспорил с некоторыми фидбеками, в общем и целом я доволен оценкой.

Сложность: 1/10
Приятность: 7/10
Польза: 2/10. С нуля скорее всего полезнее, но лично я не узнал чего-то нового.

Интересный факт: в начале следующего года у нас будет предмет Web Advanced, где на фронте можно будет использовать реактивщину. Получается, что страдания первогодок с document.createElement оказались напрасны.

В комментах выложу мини демку и кусочки документации (выкладывать весь код на github мне стыдно)
Please open Telegram to view this post
VIEW IN TELEGRAM
Loskir's
Полтора года назад я попробовал Arc и влюбился в вертикальные вкладки, спейсы и Mini Arc. Пару месяцев назад я попробовал Firefox+Sidebery и понял, что древовидные вкладки ещё удобнее, чем просто вертикальные. Но одних только древовидных вкладок оказалось…
Выложил на гитхаб свою тему для Sidebery, вдохновлённую дизайном Arc

Потвикал паддинги, добавил побольше скруглений, пофиксил неконсистентности в стилях, добавил отступы по бокам, поменял дизайн цветных вкладок и ещё пара мелочей. Конечно, осталось ещё много нестилизованных мест, но мне кажется уже выглядит гораздо лучше чем из коробки.

Кроме того, добавил и quality of life твики вроде мультистрочных названий вкладок. Хоть смотрится не очень чисто, но для меня очень полезная фича. За это мне и нравится кастомизация — можно найти свой баланс дизайна и пользы, и никакие дизайнеры со своим видением прекрасного не могут мне помешать 😈

Использовать очень просто — копируете style.css и вставляете в специальное поле в настройках Sidebery. На самом деле я даже не ожидаю что эти стили подойдут вам из коробки, скорее что их можно использовать как образец или просто скопировать какие-то решения себе.

https://github.com/Loskir/sidebery-theme-arc
🌇 Immich — селфхост хранилище фотографий здорового человека

Прошлый раз я углублялся в эту тему больше трёх лет назад, за это время появилось много новых решений. Посмотрев на табличку-сравнение, я решил попробовать Immich.

Я был удивлён тем, насколько он хорошо работает. Сервер разворачивается через docker compose в пару команд, подключиться к нему можно через веб-интерфейс или мобильное приложение. Клиенты довольно удобные, иногда даже забываешь, что это FOSS.

В приложениях можно настроить автоматическую загрузку новых фото на сервер (хотя я пока не тестировал, насколько хорошо это работает на iOS).

Есть поддержка геопозиций, нескольких пользователей, live photos, альбомов, распознавания лиц и даже публичного шаринга. И всё это полностью на своём сервере!

Так что всем селфхост энтузиастам советую обратить внимание на этот проект. А сам я, наверное, так и буду разрываться между GPhotos, iCloud и Immich.
Loskir's
🎩 Самая неприятная мелочь в новых макбуках — в меню-бар не помещаются все иконки! Мало того, что чёлка занимает место, так еще и иконки не перепрыгивают на левую сторону. В итоге некоторые иконки просто недоступны, а общее количество доступного места уменьшилось…
Опенсорсная замена Bartender

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

Почему это важно? На новых макбуках с чёлкой места для иконок очень ограниченное количество, ведь если они не влезают в правую половину экрана, они не показываются вовсе. Поэтому классический подход, где скрытые иконки рисуются там же в меню-баре, тут бесполезен.

Плюс недавно слышал новость, что Bartender продался компании со спорной историей, от которой непонятно что можно ожидать в будущем. Поэтому вдвойне приятно выбросить Bartender и перейти на опенсорсное решение. Скачать можно тут.
🏴‍☠️ Поднимаем свой VPN в Docker

У меня уже пару лет как поднят свой сервер Wireguard в docker-compose. Всё это время он отлично выполнял свою задачу, но недавно в России начали блокировать протокол Wireguard, и VPN отвалился на большинстве операторов связи.

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

1. Marzban
Это all-in-one решение для селф-хостинга VPN. Работает на базе xray, обещает быть устойчивым к блокировкам. Для подключения к нему нужно использовать специальные клиенты, сравнение можно посмотреть на сайте VPN от вастрик.клуба. Я советую Streisand для iOS и v2rayNG для Android. На мак пока не настраивал.
Поднимается легко, нужно только прокинуть несколько портов. Сервер выдаёт общую ссылку-подписку, которую можно добавить в клиент, и туда автоматически подтянутся все актуальные способы подключения к серверам. Поднял в том числе и ноду у себя дома в России, чтобы из-за границы можно было иметь российский IP.
Можно делиться VPN с друзьями, создав каждому по собственной учётке. При желании можно даже ограничить количество трафика или время действия.

2. AmneziaWG Easy
Это сборка, аналогичная wg-easy (который у был поднят у меня), но с AmneziaWG под капотом. AmneziaWG — это форк протокола WireGuard, созданный русскими умельцами специально для обхода блокировок. Здесь тоже есть веб-админка, позволяющая создавать отдельные данные для входа каждому пользователю VPN. Правда, для подключения придётся использовать другие приложения: Amnezia или AmneziaWG. С мобильных устройств пользоваться нормально, а вот на мак, кажется, адекватных приложений нет (только мобильная версия, пересобранная под десктоп).
Media is too big
VIEW IN TELEGRAM
Смотрите, какую багофичу нашёл на Яндекс картах

Строящийся небоскрёб в Сити имеет полупрозрачную текстуру, но 3д здания за ним превращаются в 2д.

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

Посмотреть можно тут: https://yandex.ru/maps/213/moscow/?ll=37.543459,55.754281&tilt=0.8726646259971648&z=17.52
🤭 Babe wake up, new browser just dropped

Zen Browser — очередной необраузер, на этот раз на базе Firefox. Разрабатывается не VC-backed стартапом, а чуть ли не в одиночку. А код, кстати, открыт.

Среди фич — нативные вертикальные вкладки, split view, кастомизация, магазин тем. Пока что браузер находится в альфа-стадии, поэтому иногда встречаются кривоватые моменты и недоработки. По удобству, конечно, не дотягивает до моего закастомленного Firefox-а (хотя в Zen в теории можно реализовать штуки, которые нельзя закастомить в самой лисе), но из коробки очень даже приятен.

Кстати, доступен не только под макось, но и под винду с линуксом. Скачать-потыкать можно тут
🍕 Додо-аналитика 2024 edition

Больше двух лет назад я анализировал додокоины и комбо в Додо Пицце. Время прошло, цены изменились, пора актуализировать таблички.

• Бруслетики больше не самый выгодный товар за додокоины! Теперь на первом месте с большим отрывом средняя пицца Цыпленок барбекю
• С комбо ситуация почти не изменилась. 2×30 всё так же стабильно выгоднее, чем 3×30. Также добавил в табличку комбо 3×25
• Цены слегка отличаются по регионам, но общая картинка сохраняется. Зато цены в додокоинах от региона не зависят. Это значит, что в дорогих регионах тратить додокоины выгоднее!

Кому интересно, вот ссылки на таблички: додокоины и комбо
Galaxy Tab S9

Купил планшет. Основной юзкейс для него у меня — просмотр контента с периодическим серфингом веба, ничего особенного. Заметки стилусом я на планшетах не веду, хоть и пробовал на несколько лет назад. Поэтому основной фокус был на экран и чуть-чуть динамики. Очень хотелось амолед экран, потому что на айпадах в темноте серые рамки вокруг видоса раздражали. И от 120 герц тоже отказываться не хотелось, потому что на планшетах герцовка особенно заметна, а вообще 2024 год на дворе, камон.

Откинув бюджетные модели по одному из параметров выше, я пришёл к трём вариантам: айпады, Huawei MatePad Pro 11 и Samsung Galaxy Tab S9. Айпады быстро отвалились, потому что за адекватную цену там либо IPS экран, либо 60 герц, либо и то и то, а новые прошки стоят раза в два дороже. Между хуавеем и самсунгом я таки выбрал самсунг, потому что стоили они примерно одинаково, характеристики у них сопоставимые, но у самсунга новее проц (плюс у меня было больше доверия самсунговской оболочке).

Купил я его в одном из серых магазов, обошёлся он в 51к₽ и ещё за 6к₽ купил оригинальный чехол-обложку. Стилус был в комплекте.

Планшетом я крайне доволен. По железу всё как и ожидалось: ярко, плавно, быстро. А вот софт меня приятно удивил: в One UI пофиксили почти все недочёты, которые бесили меня в AOSP / гугловской оболочке. Остановка записи экрана без залезания в шторку, приятный календарь, продвинутая многозадачность. До режима Slide Over на айпаде по удобству не дотягивает, но как будто это самое близкое к iPadOS, что можно получить на андроиде. One UI мне настолько понравился, что подумываю следующим андроид-телефоном взять именно самсунг

Чехольчик сомнительный, но окэй. Бока не совсем защищает, впрочем как и Smart Folio для айпада. На задней части есть смешно раскладывающаяся подставка (можно ставить как горизонтально, так и вертикально) и откидная крышка для стилуса. Зарядка для стилуса на задней панели выглядит странно, но я уже привык; разве что корпус становится чуть толще. Передняя панелька совсем дурацкая, я её вообще снял. Она выполнена в виде сплошного плоского листа (в отличие от айпадной, которая складывается в двух местах). Более того, на задней панели она никуда не примагничивается, и просто болтается туда-сюда.

Про стилус мне особо нечего сказать. Есть ховер эффект (когда планшет замечает стилус в паре сантиметров от экрана, а не только при касании) и кнопка (в разных приложениях можно выполнять разные действия по нажатиям или жестам в стороны). За счёт прорезиненного наконечника возникает больше трения об экран по сравнению с айпадом, что на мой субъективный взгляд ощущается даже приятнее. Но опять же, я стилусом почти не пользуюсь.
Купил Quest 3 (но есть нюанс)

У моего второго квеста сломался usb-порт. Я не смог его починить, и поэтому решил, что пришла пора купить новый

Первые впечатления:
- Мощности стало ощутимо больше, в standalone режиме не тормозит запись в 60fps (на втором было неиграбельно)
- Он стал реально тоньше, если снять накладку на лицо, то в толщину будет максимум сантиметра два
- Новые контроллеры непривычные. Так и хочется схватиться за колечко или поставить вертикально на стол
- Цветной passthrough прикольный, но никак не полное погружение. Он всё так же как и старые модели (емнип, в т.ч. квест1) строит 3д сцену в низком разрешении и натягивает на нее текстуры. Из-за этого искажения геометрии заметны. Интересно было бы сравнить с apple vision pro
- Ремешок на голову такой же дурацкий, как и дефолтный у к2. После bobovr заметный даунгрейд. Надо будет докупить
- В комплекте к второму квесту шел силиконовый чехол на накладку для лица. Благодаря этому она вообще не намокала после потной игры. Здесь такой можно докупить отдельно
- Обновили механизм открытия крышки у контроллеров. В первой версии были магнитные крепления (которые иногда открывались во время игры), во второй — обычные сдвижные защёлки, а тут сделали защёлку с кнопкой
- Обновили пружинки удерживающие батарейку (в первой версии при резких взмахах она могла отсоединяться)
- Сделали first-party аккумуляторы, с которыми контроллеры можно заряжать на специальной док-станции (насколько понимаю, три контакта внутри это для них)

А нюанс в том, что буквально через день после того, как я получил посылку, мета выпустила новую ревизию 3S и снизила цену на к3 на €70. Поэтому свой квест я решил вернуть в магазин (я покупал прямо на сайте меты). Скорее всего куплю такую же тройку, но по низкой цене. 3S хоть и стоит €330 вместо €480, но имеет такую же оптическую систему, как и в к2 (а мне кажется, за более продвинутую стоит переплатить, хоть и не то чтобы обязательно)
Please open Telegram to view this post
VIEW IN TELEGRAM
🪪 В некоторых нидерландских банках используется необычный и даже немного дикий механизм двухфакторной аутентификации.

При открытии счёта вместе с банковской картой тебе присылают по почте ещё и вот такой интересный девайс, который генерирует коды для подтверждения транзакций.

Помимо всего прочего, он оснащён ещё и маленькой камерой на задней части! Для подтверждения платежа нужно вставить в девайс свою карточку, просканировать QR-код на сайте оплаты, и только после этого он выдаст некий TOTP-код, который надо ввести на сайте.
Loskir's
👨‍🎓 Университетские хроники: Web Basics Одним из предметов в последней четверти этого года были Web Basics. Как можно понять из названия, там нас учили основам веб-разработки, а именно фронтенду (чистый html+js+css) и бэкенду (nodejs+express+sqlite) На пары…
👨‍🎓 Если в конце прошлого года у нас был курс web basics, где нас учили чистому html+js+css+node, то сейчас у нас идёт web advanced. Главное отличие — svelte на фронте, настоящий реактивный фреймворк!

Хоть я и недолюбливаю svelte за его рандомный нелогичный синтаксис и single-file components, мне кажется, что он вполне неплохо подходит для обучения благодаря обширности встроенных quality of life штук. Я считаю, что если научить человека мыслить в реактивной-компонентной парадигме, то дальше можно легко пересесть с одного фреймворка на другой (разумеется, если не лезть достаточно глубоко во внутреннее устройство)

Хотя typescript не преподавался вообще (с чем я так-то согласен, в начале обучения студенты абсолютно точно будут отстреливать себе ноги чаще, чем ловить несоответствия типов), я в начале курса спросил у препода, можно ли использовать typescript. Он ответил что-то типа «well in my experience svelte doesnt go well with typescript but sure, go on», что меня полностью устроило.
Сегодня я узнал, что в JavaScript свойство length у функций отвечает за то, сколько параметров эта функция ожидает

Например, для function f(a, b, c) {} оно будет равно 3
И на это теоретически можно завязать некоторую логику (например, express таким образом отличает обычные мидлвари от хендлеров ошибок).

И что самое противное, это никак нельзя описать в терминах тайпскрипта. То есть даже если описать тип

type FunctionWithTwoParameters = (a: number, b: number) => void

то

const functionWithOneParameter: FunctionWithTwoParameters = (a) => {}

будет валидным кодом, но при этом зафейлит логику в том месте, где ожидается length === 2
2025/01/29 02:38:00
Back to Top
HTML Embed Code: