Telegram Web Link
#инструмент дня

Да-да, я в курсе, что писать SQL-запросы, возможно, не самая частая компетенция у фронтендеров, но мы же все хотим расти, не правда ли?

А запросы ведь могут стать достаточно сложными. Конечно, есть EXPLAIN, но его вывод по сложности может сравниться с самим запросом. Если не сложнее.

К счастью, есть визуальные инструменты! И одним из таких является MySQL Visual Explain.

Уникальное название, согласен.

Ссылка: https://mysqlexplain.com/

Рекомендую посмотреть примеры и попробовать самим, если MySQL является частью вашего стека.

Кстати, у них даже API есть, одним из примеров использования является плагин для Laravel: https://github.com/tpetry/laravel-mysql-explain

То есть, вариант использования может быть таким:
1. Прогнали интеграционные тесты
2. Нашли медленные запросы с помощью telescope
3. Отправили их на визуальный анализ
4. ...
5. Пофиксили!

Да и для обучения — бесценно.

#mysql #explain #laravel
This media is not supported in your browser
VIEW IN TELEGRAM
#игра дня

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

В принципе, можно и табом с пробелом, но не то...

Итак, встречайте: первая игра на чистом CSS, в которой можно использовать стрелочки с клавиатуры! Автор — Темани Афиф, знакомый нам по CSS-фигурам.

Помоги Марио собрать все монетки!

Построена на использовании Scroll Timeline API и, соответственно, голова Марио — не что иное, как пересечение "лифтов" скроллбаров. И мышью (ну ок, тачпадом) игра проходится даже легче.

https://codepen.io/t_afif/full/OJYbVWP

Делитесь вашими скриншотами с лучшим временем :)

#css #scroll #game
#инструмент дня

Устал вручную типизировать ответы от API для TypeScript или любого другого типизированного языка?

Есть решение!

https://app.quicktype.io/

Фиганул туда JSON — получил нужную структуру или описание типа, даже с тайпгардами. Уютненько!

Есть расширение для VS Code: https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype

Ещё один мощный инструмент в тему дня: https://transform.tools. Одним типизированием JSON не ограничивается: можно CSS в Tailwind, а можно Flow в TypeScript.

Вот, например, если кто использует Zod — конвертор типов в схему Zod: https://transform.tools/typescript-to-zod

#json #typescript #type #бородач
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

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

Но у аккордеонов есть один очевидный минус: поиск по странице не подсветит найденное. Ну ещё бы, оно же скрыто.

Так вот, Chrome очень старается это исправить и именно поэтому начиная со 102 версии у атрибута hidden есть уникальное для Chrome значение until-found, говорящее само за себя.

Ссылка на блог разработчиков: https://developer.chrome.com/docs/css-ui/hidden-until-found

Сразу пример, если кому-то в лом на статью лезть: https://codepen.io/web-dot-dev/pen/JjMxmom

Попробуйте поискать слово, которое скрыто в каком-либо из аккордеонов.

Ну и для браузеров, которые не поддерживают этот атрибут, либо для иных UI-виджетов, они предлагают проверять поддержку события onbeforematch:

if (!(‘onbeforematch' in document.body)) {
// expand all hidden content
}

Довольно странное решение, если честно, но очевидно, что проблема существует и делать с ней что-то надо.

#chrome #hidden
#тред дня

А давно я не воровал твиты знакомил вас с крутыми тредами, которые вы могли пропустить. Если вообще, конечно, сидите в Твиттере X.

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

Поэтому, тема дня: как пройти алгоритмическое собеседование. Тред от Лены Анюшевой, бывшего сотрудника Google и нынешнего в Confluent.

Как всегда, ссылка на тред: https://x.com/lenka_colenka/status/1769699248780542208

И копия тут 🙂

Внимание, длиннопост! Кому-то проще будет на ThreadReader: https://threadreaderapp.com/thread/1769699248780542208.html?utm_campaign=topunroll

Но мне нужно для поиска по каналу, потому — поехали.

1. как человек, который проводил алгоритмические собесы в Google, а теперь собесит сеньоров, выкатываю тред про то, как готовиться к алгоритмическим собеседованиям!

2. да, вы слышали про leetcode, да, есть магические числа, типа прорешать 500 задач, и ты готова. Но собеседование — это сильно больше, чем написать код. Есть случаи, когда гросмейстреры на codeforces не проходили собесы, потому что они не смогли правильно коммуницировать.

3. у алгоритмического собеседования, как у сочинения на егэ, есть формат, которому я сильно рекомендую следовать. Вот хороший пример интервью по формату: https://www.youtube.com/watch?v=XKu_SEDAykw

4. Обычно интервью длится 45 или 60 минут, первые минут 5-10 интервьюер представляется, обычно говорит, как долго она работает в компании, в какой команде (запиши это!). Говорит формат интервью: мы порешаем задачку 30 или 45 минут, в конце оставим 10 минут на твои вопросы.

5. Тут есть 5 минут для тебя, чтобы кратко представиться: как зовут, где работаешь, кратко предыдущий опыт (буквально названия компаний и чем занималась). Если у тебя нет опыта прохождения собеседования на английском, порепетируй это!

6. Потом тебе формулируют задачку. Не бросайся сразу решать ее! нужно задать вопросы, даже если кажется, что тебе все понятно. Что-то типа "а что вернуть, если на вход дают пустой массив?", "а гарантируется, что массив отсортирован/не будет повторений"?

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

8. Сама приведи пример входных данных и напиши, какой результат ты ожидаешь! Типа если задача отсортировать массив, скажи, вот например на вход [10, -100, 22] результат будет [-100, 10, 22], а на вход [] результат будет []. Напечатай это, пусть будет у тебя перед глазами.

9. Теперь пришла пора... нет, не писать код!! Словами устно объяснить, что ты собираешься писать! Хорошая фраза в этом случае "first thing that comes to my mind is..." и говоришь очевидное brute-force решение. Например, для сортировки это будет bubble sort за квадрат.

10. Это дает тебе время подумать над более оптимальным решением. Это страховка на случай, если ты в итоге не придумаешь оптимальное решение (что-то ведь придумала!). Это дает интервьюеру понять, что ты понимаешь, что такое сложность алгоритмов.

11. Обычно интервьюер не просит писать код для этого решения, достаточно просто словами рассказать, как это работает. Потратишь на это от силы 5 минут, но за эти 5 минут произведешь хорошее впечатление, пока придумываешь более хорошее решение

12. У первого неоптимального решения обязательно скажи сложность работы! Типа "first thing that comes to my mind is bubble sort, but that will be quadratic. I think we can come up with a better solution". И переходим к более оптимальному решению!

13. Если ты сразу полностью придумала более оптимальное решение, это здорово! Если нет, нормально придумывать решение шаг за шагом, типа "I'd like to use priority queue here, then getting max will be cheap. But I need to think how to optimally insert data".
14. Интервьюер часто дает подсказки, не игнорируй их! Помни, что интервьюер на твоей стороне, она не хочет запутать тебя, она хочет помочь! Если ты понимаешь подсказки, это плюсик тебе в collaboration и technical communication.

15. Начинай писать код только после того, как интервьер подтвердила, что все поняла в твоем алгоритме и сама предложит написать код. Если интервьюер не предлагает, явно спроcи "should we start writing code?"

16. После того, как код написан, прогони его строчка за строчкой на каких-нибудь тестовых данных. Помнишь примеры, которые мы писали на шаге 8? Вот их и используй. Без опыта на английском языке это сложно сделать, поэтому проговаривай все это вслух пока готовишься

17. Теперь обязательно расскажи время работы алгоритма!! Это очень важно, ради этого мы и писали какое-то сложное решение. Метод за методом, в комментариях рядом напиши время работы в худшем и среднем случае.

18. Для этого нужно знать время работы операций структур данных в выбранном тобой языке. Заранее погугли время работы map, vector, array в твоем языке программирования. Например std::map и std::unordered_map отличаются во времени работы, так что это очень важно!

19. В конце в идеале должно остаться несколько минут для твоих вопросов. Помнишь мы записывали информацию про интервьюера в пункте 4? Пора подсмотреть в свои тетрадку и спросить, а чем именно занимается твоя команда? Чем тебе нравится компания? Что не нравится в компании?

20. Обычно в этот момент интервьюер говорит, что время закончилось и ей пора бежать. Поблагодарить и попрощаться. Вы великолепны!

21. Бонус темы для сеньоров: каков data access pattern? что мы оптимизируем, запись или чтение? является ли твое решение thread-safe? если нет, как можно его сделать thread-safe? если время осталось, можно подумать, как распараллелить на несколько машин

Длиннопост как он есть, да 🙂

#interview
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

Итак, сегодня в уютный канальчик™️ с ноги залетает уже всем известный Джей c кое-чем насколько потрясающим, настолько же и забытым.

И это API document.getAnimations(), позволяющий не только получить список всех CSS-анимаций, но и, внимание, выставить промис и дождаться их выполнения! 🤯

const animations = document.getAnimations()
.map(a => a.finished)
await Promise.all(animations)


Сразу кодпен: https://codepen.io/alinaki/pen/rNoEOwX

*с некоторых пор я начал форкать пены, потому что пропадают иной раз

Теперь о применимости.

Я нынче разработчик корпоративный, потому мне интересно это, например, с позиции совершения какой-нибудь операции по скрытию уведомления-тоста. Во время онбординга, например.

Ну а разработчикам промо-сайтов важность синхронизации действий и анимаций объяснять не надо.

Отличный пример забытых технологий 🙂

Не, ну серьёзно, оно с 75 Firefox доступно, как я мог его проглядеть?

А я знаю, как. Я же писал уже, что PR-служба Chrome работает прекрасно только в том случае, когда что-то появилось там первым...

#css #js #animations #promise #бородач
#день_рождения дня

Сегодня День рождения не только лишь у меня, но и у HTML тегов!

29 октября 1991 года Тим Бернерс-Ли выкатил документ с названием HTML Tags.

И состоял он из описания 18 первых тегов: <title>, <nextid>, <a>, <isindex>, <plaintext>, <listing>, <p>, <h1>…<h6>, <address>, <hp1>, <hp2>…, <dl>, <dt>, <dd>, <ul>, <li>,<menu> и <dir>.

Архивная версия: https://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html

С Днём рождения, HTML! Ну и я :)

#html
#заметка дня

Вы, наверняка, слышали выражение: «В экстремальной ситуации ты не поднимаешься до уровня своих ожиданий, а опускаешься до уровня своей подготовки».

Вот только соцсети настолько заездили его говорящими головами от самообороны, что мало кто воспринимает эту фразу в отрыве от «на тебя прут три гопника».

А ведь это — буквально закон Йеркса — Додсона, ссылка на Википедию.

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

Но если не повезёт в стрессе получить тяжёлую, сложную задачу... В какой-то момент кто-то даже начнёт кричать на монитор :)

Это я вообще к чему.

1. Слона нужно есть по-кусочкам.
2. Поведение в случае инцидента на работе должно быть строго задокументированое и разбито на понятные, простые действие.
3. Микроменеджмент, чайка-менеджмент — хороши для простых задач и абсолютное зло для больших.
4. Планирование — само по себе стресс, но в долгосрочной перспективе лучше с ним, чем без него.
5. Взгляните ещё раз на нижний график: важно знать, когда это самое планирование остановить и дать всем выдохнуть.

А ещё этот же принцип можно использовать для контроля команды и настроения команды в целом. Если человек постоянно занимается мелкими, пусть вроде и важными, задачами — самое время спросить, а всё ли в порядке, не нужен ли отпуск или выходной.

Немного сумбурно, пожалуй, но, надеюсь, я смог донести мысль.

Отдохните, котаны. И следите за собой и другими.

#stress #work
This media is not supported in your browser
VIEW IN TELEGRAM
#ссылка дня

Продолжаем серию постов о Tailwind+React UI компонентах от Паскаля Витьелло!

У нас уже были поля ввода и кнопки. Настало время, очевидно, чекбоксов, радиокнопок и всякого рода переключателей!

На сей раз уже не 50, а даже побольше :)

Ссылка: https://originui.com/checks-radios-switches

Как обычно, основано на shadcn и Tailwind. Вообще, вышло мило и даже разнообразно.

#tailwind #shadcn #react #ui
#фишка дня

Итак, все мы знаем, что при добавлении скроллбара (если этот скроллбар, конечно, виден) у нас происходит сдвиг по фазе полей справа.

Ну или слева, если вы араб.

Но это же можно исправить! Используя правило scrollbar-gutter: stable можно зарезервировать место под скроллбар, не прибегая к иным методам вроде overflow: scroll (который буквально этот самый скроллбар заранее покажет, даже если он не нужен).

Демо от Ахмада Шадида в его Defensive CSS: https://defensivecss.dev/tip/scrollbar-gutter/

Can I Use: https://caniuse.com/?search=scrollbar-gutter

Поддержка в Chrome и Firefox. В Safari пока только в TP, но на Apple-устройствах скроллбары, как правило, скрыты и отображаются поверх контента, не занимая места.

Выглядит это, правда, как дополнительный паддинг, но!

Есть интересное но в виде scrollbar-gutter: stable both-edges, которое зарезервирует место под скроллбар, и такое же — на другой стороне. Что, в целом, избавит нас от разных паддингов.

Раньше за похожее решение отвечало правило overflow: overlay, но его отменили в пользу gutter.

Лучше всего это работает, впрочем, для попапов. Мало кого волнует скроллбар на тексте, а вот прыгающий body при появлении модалки — это уже перебор.

#css #scrollbar #gutter
#фишка дня

Как-то так получилось, что на мобильных устройствах работать с файлами и буфером обмена ну... неудобно.

И ладно iOS, но на Android тоже интерфейсы такие себе. Даже на Windows Mobile и PalmOS было как-то... стандартнее чтоль.

С другой стороны, появилась идея шэринга, aka share. И она на самом деле отвечает запросам людей: перекинуть файл из одного приложения в другое, а что нам ещё нужно-то?

Итак, встречайте: Web Share API.

Пользоваться очень просто:

navigator.share({
title: "Будни разработчика",
text: "Фронтенд и не только",
url: "https://www.tg-me.com/htmlshit",
});


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

navigator.share({
files: [file],
title: 'hello.png'
});


На десктопе, к сожалению, не работает. Но там у нас иные средства имеются.

#web #share #api #бородач
#фишка дня

Мне очень понравился этот бред, так что в рамках субботы очень даже пойдёт.

Итак, как найти первое вхождение элемента на странице, даже если он — вложен где-то внутри другого? Можно же так?

Вы не поверите, можно!

Код:
.target {
&:nth-child(1 of &):not(:has(&) ~ * *):not(:has(&) ~ *):not(& ~ * *):not(& *) {
/* your CSS here */
}
}


Итак, что же тут происходит?

Это первый элемент среди своих сиблингов с таким же классом (&:nth-child(1 of &))
Это не потомок элемента с таким же классом (:not(& *))
Это не потомок элемента, перед которым находится элемент с таким же классом (:not(& ~ * *))
Перед ним нет элемента, который содержит элемент с таким же классом (:not(:has(&) ~ *))
Это не потомок элемента, перед которым находится элемент, содержащий элемент с таким же классом (:not(:has(&) ~ * *))

Как вам такое? :)

Демо: https://codepen.io/alinaki/pen/NWQzzv

Оригинал: https://css-tip.com/first-element-dom/

Естественно, есть похожее решение для последнего элемента: https://css-tip.com/last-element-dom/

#css #has #dom
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня

Сколько вы берёте за разработку лендинга?

$100? $300? $3000? $10000?

Ну ладно, у меня были сметы и по $20000, но это были проекты на целую веб-студию, а не мне одному 😭

И тут я натыкаюсь на это: https://x.com/alex_barashkov/status/1801219973236342910

$89,775

Девяносто кусков! За лендинг 🫠

Который, правда, чуток подтормаживает на MacBook Pro M2. Как быстро мой ноутбук устарел, а...

Ладно, на самом деле пост не об этом. Меня повеселило, что, по факту, ребята не только сделалил лендинг, но и по пути взлетели на полмиллиона просмотров твита, пропиарив продукт и заодно наняв нескольких инженеров.

Но название: Huly... Кремниевую долину пересмотрели?

Учитывая, что хайринг инженера стоит $5000-$10000, инвестиция уже отбилась!

Типичный диалог под обсуждением лендинга выглядел так:
— С точки зрения донесения информации полная ерунда.
— Слыш, а ты сам так умеешь?
...
— О, умеешь. Давай к нам.

Кроме шуток, у меня пруфы есть: https://x.com/platoff/status/1801240777026080980

Ладно, даже сейчас пост не об этом!

Утомил, да?

Короче, меня там заинтересовал текстовый редактор в виде плавающей панельки. Я полез в их гитхаб (а хули, хули — опенсорсный продукт) и нашёл это: https://tiptap.dev/docs/editor/introduction

TipTap это, как нынче считается хорошим тоном, не готовый текстовый редактор, а фреймворк для их построения (на базе ещё более низкоуровневого решения https://prosemirror.net/).

Хочешь — плавающая панель, хочешь — тулбар. Удобно. Крайне интересная вещь.

Вот так вот, интересно, когда есть в чём покопаться.

#web #editor #wysiwyg #бородач
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня

Что делать, если ну очень хочется выпендриться, но времена кейгенов и демосцены ты уже не застал, или вообще — начать с чего-то надо?

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

И решение на самом деле очевидно! Засирать консоль браузера!

Ну серьёзно, если человек туда попёрся — наверное, он что-то хотел увидеть? Так давайте предоставим такое удовольствие!

А секрет прост: консоль браузера поддерживает CSS. А значит, можно сделать всё, что угодно. Включая анимирование SVG. Или даже буквально анимированные SVG.

То есть представьте, что наше сообщение — это некий блок. В него можно вставить фоновый SVG, как анимированный, так и обычный. А уже в SVG можно писать свои стили в теге style.

Какой-то глитч на бесконечные стили. Вот бы с деньгами так.

Как-то так:

console.info(
'%c ',
`padding-left:750px;padding-top:200px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 750 200'%3E%3Cstyle%3E text %7B font-family: sans-serif; font-weight: 100; fill: %23d8eaff; %7D %23stop1 %7B animation: recolor 40s linear infinite alternate %7D %23stop2 %7B animation: recolor 40s -32s linear infinite alternate %7D @keyframes recolor %7B 0%25 %7B stop-color: %23388bee; %7D 20%25 %7B stop-color: %2324c6dc; %7D 40%25 %7B stop-color: %23af74fd; %7D 60%25 %7B stop-color: %23c020d9; %7D 80%25 %7B stop-color: %23514a9d; %7D 100%25 %7B stop-color: %23053ece; %7D %7D %3C/style%3E%3Cdefs%3E%3ClinearGradient id='grad'%3E%3Cstop id='stop1' offset='0%25' stop-color='%23388bee'%3E%3C/stop%3E%3Cstop id='stop2' offset='100%25' stop-color='%23514a9d'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='750' height='500' fill='url(%23grad)'%3E%3C/rect%3E%3Ctext text-anchor='end' font-size='50' x='725' y='125'%3E thanks for %3C/text%3E%3Ctext text-anchor='end' font-size='50' x='725' y='175'%3E stopping by %3C/text%3E%3C/svg%3E")`
);


Вы любите простыню кода в сообщениях, я знаю :)

Статья на тему: https://frontendmasters.com/blog/console-delight/

Демо, сконвертировал из обычного кодпена: https://codepen.io/alinaki/pen/BaXPmoV

Естественно, можно просто на файл сослаться, не обязательно столько кода упихивать :)

Если хотите делать своё, вам пригодится конвертер от Йоксель: https://yoksel.github.io/url-encoder/

#css #svg #devtools #console #fun
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня

Этого следовало ожидать и оно свершилось!

Дамы и господа, без лишних слов: библиотека и конструктор анимаций для Tailwind — Motion.

Сходу ссылка: https://rombo.co/tailwind/#animator

Казалось бы, бери да используй CSS-анимации, но... тут уж как есть. Думаю, работающим с тейлвиндом людям должно быть удобно, да и для конструкторов самое то.

Но, кроме шуток, инструмент и правда довольно оригинальный и подход к построению его интерфейса мне очень зашёл.

#css #tailwind #motion #animation #ui
This media is not supported in your browser
VIEW IN TELEGRAM
#codepen дня

Можно ли при помощи SVG-фильтров, не прибегая к помощи теней, экструдировать текст?

Экструзия — процесс выдавливания, как в 3D-принтере.

И да, можно! Как всегда, Ана Тюдор с прекрасным решением. На сей раз, кстати, у решения нет багов на HDR-экранах 😅 Всё отображается как надо.

Кодпен: https://codepen.io/thebabydino/pen/yLmxePV

Выглядит потрясно. Матрица экструзии там отдельная песня, конечно.

#svg #filter
Please open Telegram to view this post
VIEW IN TELEGRAM
#инструмент дня

Я, конечно, прошу прощения за неожиданную иллюстрацию к посту, но у меня примерно сейчас такие вот ощущения от либы, про которую хочу рассказать :)

И называется она, какая неожиданность, cigs.

Ну, буквально: 🚬 cigs

Сразу ссылка: https://github.com/cigs-tech/cigs

Итак, что же она делает.

А она позволяет задавать вопросы по заданной Zod-схеме обычным человеческим языком используя OpenAI-токены!

Короче, ещё более просто. Описываешь некую схему объекта, а потом спрашиваешь у системы: "А какой там любимый цвет у Джона?". И получишь ответ!

Пример:
function getUserCompliment(username: string) {
const colorMap = {
"Alice": "blue",
"Bob": "green",
"Charlie": "red",
};
return {
color: colorMap[input.username as keyof typeof colorMap] || "unknown",
};
}

const userInfoSchema = z.object({
username: z.string(),
});

// Define a cig to get a user's favorite color
const getFavoriteColor = cig("getFavoriteColor", userInfoSchema)
.handler(async (input) => {
// Simulated database lookup
return getUserCompliment(input.username);
});

// Usage example
(async () => {
try {
const result = await getFavoriteColor.run(
"What is the favorite color of Alice",
); // { color: 'blue' }
console.log(result);

const result2 = await getFavoriteColor.run(
"What is the favorite color of Susan",
); // { color: 'unknown' }
console.log(result2);

// You can also call that function with the specified input
const result3 = await getFavoriteColor.run({ username: "Alice" }); // { color: 'blue' }
console.log(result3);
// Expected output: { username: 'alice', favoriteColor: 'blue', compliment: 'You have great taste!' }
} catch (error) {
console.error("Error:", error);
}
})();


Вы вообще понимаете, что это значит для тех, кто пишет парсеры или генераторы фейковых данных? :)

Вытащить все спец предложения с "красной ценой" со страницы интернет-магазина? Да запросто! Даже если этот самый магазин обфуцирует код.

Или использует Styled Components.

Пройдите на страницу библиотеки и почитайте примеры. Это нечто потрясающее.

#ai #parser
Media is too big
VIEW IN TELEGRAM
#фишка дня

Когда я наткнулся на этот твит в обсуждении утилиты работы с цветами Андрея Ситника, я не сразу примерил его на себя. Но, как оказалось, стоило бы.

Итак, давайте поясню для тех, кто по ссылкам не ходит.

В азиатских иероглифических языках почти весь ввод с клавиатуры происходит в аккордном режиме или же в режиме т. н. композитинга, общее название — Input Method Editor.

TL;DR: На экране всплывает окошко с символами или их группами и пользователь может что-то выбрать.

На каких-то ОС оно вызывается долгим зажатием клавиши, где-то — по хоткею, а где-то — автоматически и сразу.

Так вот, одно дело азиатские языки (я очень рекомендую посмотреть сам твит), а другое — разные европейские. И речь о диакритических знаках: умляуты, акуты, ударения, птички и шапочки.

Так вот, я не имею финской раскладки, потому буквы ä, å и ö ввожу как раз в режиме композитинга, долгим зажатием «материнской» клавиши.

Собственно, так база для азиатских языков проникла и в мою жизнь.

Кстати, выбор Emoji из всплывающего окошка — туда же.

В JavaScript-событиях для этого режима имеется флаг isComposing. Поэтому если вы, как и я в примере на видео, решили реализовать ввод групп символов подобным образом — циклически перебирая поля ввода — стоит об этом подумать :)

Собственно, давайте и пример: https://codepen.io/alinaki/pen/MWMpdvO?editors=1010

И напишите в комментариях, как вы решаете проблему редкого ввода букв с диакритикой у себя в системе. Например, я не помню, как это происходит в Windows, а в Linux я использую клавишу Compose, она работает чуть иначе.

#javascript #composing #event #бородач
#инструмент дня

Вы, наверное, уже наслышаны от обладателей айфонов про AirDrop и дикпики.

Кроме шуток, передать файлы по локальной сети между двумя своими устройствами должно быть максимально просто же! Без ковыряний в Network Discovery, настроек Samba и так далее.

И такое решение есть, даже с открытым кодом: LocalSend.

Сайт: https://localsend.org/

Написано на Dart и Flutter, работает на всех разумно доступных платформах: Windows, Linux, MacOS, Android, iOS.

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

Никаких облаков, всё по локальной сети.

Поддержка нескольких получателей, поддержка буфера обмена.

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

Мне особенно импонирует Flutter. Я недавно вернулся к разработке своего пульта и это всё ещё очень приятный экспириенс.

#flutter #localsend #airdrop #network
2025/07/06 06:45:00
Back to Top
HTML Embed Code: