{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Блог Михаила Озорнина: заметки с тегом интерфейс",
    "_rss_description": "Главная · Блог · Работы",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/mikeozornin.ru\/blog\/tags\/interfeys\/",
    "feed_url": "https:\/\/mikeozornin.ru\/blog\/tags\/interfeys\/json\/",
    "icon": "https:\/\/mikeozornin.ru\/blog\/pictures\/userpic\/userpic@2x.jpg?1614204384",
    "authors": [
        {
            "name": "Михаил Озорнин",
            "url": "https:\/\/mikeozornin.ru\/blog\/",
            "avatar": "https:\/\/mikeozornin.ru\/blog\/pictures\/userpic\/userpic@2x.jpg?1614204384"
        }
    ],
    "items": [
        {
            "id": "229",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/agentic-ui-in-practice\/",
            "title": "Агентский поиск на примере Вкусвилла",
            "content_html": "<p class=\"lead\">Подоспел реальный пример для иллюстрации поста<\/p>\n<p><a href=\"https:\/\/mikeozornin.ru\/blog\/all\/agentic-ui\/\">В позапрошлом посте <\/a> я писал, что агентский поиск должен принимать пачку запросов за раз. Напомню идею: один тулкол, много запросов, один ответ. Иначе получается N+1: агент ищет, ищет, ищет.<\/p>\n<p>И вот поспел живой пример.<\/p>\n<p>У Вкусвилла появился <a href=\"https:\/\/mcp.vkusvill.ru\">официальный MCP<\/a>. <i>vkusvill_products_search<\/i> принимает один <i>q<\/i>. У меня <a href=\"https:\/\/recipe-scaler.ru\/about\">в приложении Recipe Scaler<\/a> список покупок для рецептов. Пара блюда — штук 20 ингредиентов. Чтобы собрать из них корзину Вкусвилла, мой агент делает примерно так:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">vkusvill_search_products({ q: &quot;яйца&quot; })\nvkusvill_search_products({ q: &quot;тесто фило&quot; })\nvkusvill_search_products({ q: &quot;апельсин&quot; })\nvkusvill_search_products({ q: &quot;греческий йогурт&quot; })\nvkusvill_search_products({ q: &quot;сахар&quot; })\nvkusvill_search_products({ q: &quot;разрыхлитель&quot; })\nvkusvill_search_products({ q: &quot;ваниль&quot; })\nvkusvill_search_products({ q: &quot;растительное масло&quot; })\nvkusvill_search_products({ q: &quot;апельсиновый сок&quot; })\nvkusvill_search_products({ q: &quot;корица&quot; })\nvkusvill_search_products({ q: &quot;вода&quot; })\nvkusvill_cart_link_create({ products: [...] })<\/code><\/pre><p>Каждый поиск — это полный цикл тулкола, кусок контекста, шанс упереться в рейт-лимит у меня или у мцп Вкусвилла. Да в целом я задумался, когда у меня сработала защита на число тулов в одном вопросе. Да и пользователю тоже неудобно: «ищем, ищем, ищем».<\/p>\n<p>Человеку так и надо: вбил «сметана», посмотрел выдачу. Агенту так не надо, он может посмотреть пять выдач параллельно.<\/p>\n<p>Могло бы быть так:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">{\n  &quot;queries&quot;: [\n    { &quot;q&quot;: &quot;сметана 20%&quot;, &quot;limit&quot;: 3 },\n    { &quot;q&quot;: &quot;мука пшеничная&quot;, &quot;limit&quot;: 3 },\n    { &quot;q&quot;: &quot;яйца С1&quot;, &quot;limit&quot;: 3 },\n    { &quot;q&quot;: &quot;черника свежая&quot;, &quot;limit&quot;: 3 }\n  ],\n  &quot;mode&quot;: &quot;short&quot;,\n  &quot;sort&quot;: &quot;rating&quot;,\n  &quot;vvonly&quot;: 1\n}<\/code><\/pre><p>И ответ:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">{\n  &quot;results&quot;: [\n    {\n      &quot;q&quot;: &quot;сметана 20%&quot;,\n      &quot;items&quot;: [\n        { &quot;id&quot;: 111, &quot;xml_id&quot;: 222, &quot;name&quot;: &quot;Сметана 20%&quot;, &quot;price&quot;: 89, &quot;rating&quot;: 4.8 }\n      ]\n    }\n  ]\n}<\/code><\/pre><p>Батчинг тоже надо делать не в тупую, например <i>limit<\/i> нужно на каждый запрос, не общий на всю выдачу. Для корзины из рецепта не нужны десять сметан. А общий лимит оставить только как защиту от дос-атаки.<\/p>\n",
            "summary": "В позапрошлом посте я писал, что агентский поиск должен принимать пачку запросов за раз. Напомню идею",
            "date_published": "2026-08-27T15:56:27+05:00",
            "date_modified": "2026-08-27T15:56:25+05:00",
            "tags": [
                "ИИ",
                "интерфейс"
            ],
            "_date_published_rfc2822": "Thu, 27 Aug 2026 15:56:27 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "229",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "227",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/agentic-ui\/",
            "title": "Что такое agentic UI \/ agent-friendly сервис",
            "content_html": "<p class=\"lead\">Нейросети сводят всех с ума, началась эпоха «агентского интерфейса».<\/p>\n<p>Только ленивый не говорит про агентский юикс, выходят посты, статьи как его делать. В целом этот агентский юикс немножко напоминает истерию с чат-ботами лет десять назад. Когда появились чат-боты (те, которые работали на скриптах, не поверх языковых моделей), тоже была истерика, что всё, Галя, отменяем все интерфейсы, всё переводим на чат-боты.<\/p>\n<p>Ну отлично, перевели на чат-ботов.<\/p>\n<p>А потом оказалось, что пропускная способность интерфейса чат-бот (количество бит информации, которое может пропустить чат-бот за одно взаимодействие), очень низкая. И людям неинтересно, смотреть по одному варианту чат-бота для билетов. Они хотят выдать хорошую, понятную, удобную выдачу с сортировкой и фильтрами. Они не хотят формулировать пару кликов мыши в виде сообщения «покажи сейчас варианты до 5 тыс, но если хорошие, то и до 7.5 тыс тоже можно».<\/p>\n<p>Чат-бот — это как ночной режим у меня в блоге (посмотрите, чтобы понять аналогию) — смотреть на маленькую область, а не видеть всю картину целиком.<\/p>\n<p><aside class=\"aside-margin-right\"><a href=\"https:\/\/habr.com\/en\/companies\/selectel\/articles\/1061986\/\">MCP как интерфейс продукта: почему я думаю, что GUI может стать не главным<\/a><span class=\"related-excerpt\"><\/br>Вот типичный пример — агентский интефрейс = MCP<\/span><\/aside><\/p>\n<p>Истерия истерией, но и когда начинают говорить про агентский интерфейс, к сожалению, очень многие говорят про него неправильно, делая фокус не на том. Мне кажется, когда говорят «агентский интерфейс», обычно имеют в виду MCP. Типа сделал себе MCP и хоба, получил agentic UI. Как бы да, но и нет.<\/p>\n<p>Рассказываю, что мне кажется более важным, чем MCP.<\/p>\n<h2>Что вообще значит «agent-friendly»<\/h2>\n<p>Еще одну минуту, я договориться об определениях.<\/p>\n<p>Agent-friendly — это продукт, в котором ллм-агент является first class citizen, наравне с человеком — продукт, в который может зайти и человек, и агент.<\/p>\n<p>Человек: открыть браузер, прочитать страницу, нажать кнопку.<br \/>\nАгент: дернуть API, прочитать контент, вызвать действие. В целом агент может и первым вариантом пойти, потыкать кнопочки, но это пока не очень нативный для него способ.<\/p>\n<p>Прямо сейчас продукты делаются для кожаных, а агентам с такими продуктами не очень удобно. Им тоже приходится тыкать кнопочки, скрывать куки-банеры и анализировать скриншоты — это все медленно и неудобно. MCP немного исправит ситуацию, но не полностью.<\/p>\n<h2>Что не так с MCP и прочим агентским юиксом сейчас<\/h2>\n<p>Мне кажется, что MCP, как протокол, как обертка вокруг имеющегося API, — это достаточно тупиковая ветка. Я не очень понимаю, зачем при наличии OpenAPI-спеки, нужно ещё какое-то описание. Почему клод, который настолько умный, что его опасно релизить, не может разобраться в OpenAPI-спеке и сделать всё по ней сразу? Зачем нужна какая-то специальная прослойка для этого? Вот тебе oauth, вот тебе описание методов, иди вызывай. Зачем MCP?<\/p>\n<p>Я бы ожидал, что скоро, либо в связи с улучшением агентов, либо с улучшением моделей, агентам не понадобится специальный протокол только для агентов. Они смогут взять, например, OpenAPI-спеку, разобраться в ней и сами сделать интеграцию на лету.<\/p>\n<p>Я благодарен антропику за то, что они придумали МСР и расширили наше сознание тем, что можно подключать к агентам. Я просто отношусь к этому как к временному явлению. Помните, раньше нужно было промпты писать в строго определенном порядке, структуре. А сейчас можно в целом очень сырой, очень противоречивый войс кодексу послать и как-то он разбирается. Он находит противоречия, он понимает, какая информация более свежая.<\/p>\n<p>Мне кажется, что такая же история будет с МСР, или превратится во что-то более сложное, или не будет нужен.<\/p>\n<p>Ну вот я сделал себе MCP в Recipe Scaler. Вышла, фактически, обёртка вокруг стандартного API. Я не понимаю, зачем я я вынужден её писать.<br \/>\nСам АПИ: ~3 100 строк кода<br \/>\nДополнительная MCP-слой: еще ~5 870<\/p>\n<p>Не кажется, ли что тут что-то не так? Мы делаем втрое больше кода, чтобы…?<\/p>\n<p>Расскажу что на самом деле важно, от базового — к надстройкам.<\/p>\n<h2>1. Доступность контента<\/h2>\n<p>Базовое условие: агент должен уметь прочитать контент продукта без браузера.<\/p>\n<p>Берем баш, пишем в нем:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">curl https:\/\/your-site\/important-page<\/code><\/pre><p>Если в ответ приходит осмысленный хтмл с контентом — всё в порядке. Если приходит СПА-шелл, в котором &lt;div id=’root’&gt;&lt;\/div&gt;и немного скрипт-тегов — все не очень хорошо. Агент не сможет прочитать страницу без playwright, puppeteer и прочих виртуальных браузеров. А поднимать его ради одной страницы — так себе история. Да и не все агенты умеют. Окей, кодекс разберется, клод сможет, а ваш доморощенный? А хватит на сервере памяти открыть 10 вкладок сразу? А 10 вкладок на каждого пользователя?<\/p>\n<p>Это касается всех страниц: главной, статей, поиска, карточки продукта, формы заказа. Angular и React без серверного рендера — это, так сказать, ред флаг.<\/p>\n<h2>2. Понятная структура контента<\/h2>\n<p>Дальше, после того как научились получать контент, можно говорить уже что такое контент. В идеале контент нужно не просто отдать, а отдать в простом, машиночитаемом, удобном для агента формате.<\/p>\n<p>Минимум:<\/p>\n<ul>\n<li>HTML с понятной семантикой (&lt;article&gt;, &lt;h1&gt;, &lt;time&gt;, &lt;nav&gt;), а не див на диве без каких-то поясненией.<\/li>\n<li>Все accessibility-штуки типа alt-описаний для картинок. Если нужно, агенты смогут скачать и прочитать картинку, но есть альт-текст, то как будто не всегда и нужно будет. Текст — проще, быстрее и дешевле.<\/li>\n<li>Субтитры для видео и аудио как отдельный слой данных. Если есть видео, дайти субтитры, чтобы агент понял что там. Вряд ли какой-то агент запарится, чтобы скачать видео, вырезать звук и распознать его.<\/li>\n<li>Микроформаты. Например, чтобы не разбирать неструктурированный текст рецепта, люди придумали специальную разметку. С ней агенту будет сильно проще (поисковику, кстати, тоже).<\/li>\n<\/ul>\n<p>Я бы еще предпочел, чтобы какой-то такой стандарт вошел в жизнь: content negotiation по «Accept». дин адрес, но:<\/p>\n<ul>\n<li>Accept: text\/html — человек видит страницу со всякими интерактивностями<\/li>\n<li>Accept: text\/markdown — агент получает маркдаун-описание, очищенное от навигации и прочих штук.<\/li>\n<\/ul>\n<h2>3. Поиск под агента<\/h2>\n<p>Поиск для людей обычно заточен под одно действие: ввёл запрос — увидел выдачу. Агентский поиск должен учитывать агентские сценарии: поискать 10 запросов сразу, собрать вместе, проанализировать. Намного удобнее будет поиск, который принимает сразу много запросов. Например, могло бы быть так:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">{\n  &quot;queries&quot;: [\n    { &quot;q&quot;: &quot;сброс пароля&quot;, &quot;limit&quot;: 5 },\n    { &quot;q&quot;: &quot;восстановить доступ&quot;, &quot;limit&quot;: 5 },\n    { &quot;q&quot;: &quot;reset password&quot;, &quot;limit&quot;: 3 }\n  ]\n}<\/code><\/pre><p>У меня в MCP сделано как раз так.<\/p>\n<p>Один тулкол, три синонима, один ответ — агент не делает три запроса по очереди, не ждет пинга по 200 мс, не упирается в рейт-лимиты, не тратит окно контекста на три тулкола.<\/p>\n<p>Что еще может пригодиться.<\/p>\n<ul>\n<li>Сниппеты. Нужно возвращать не только адрес результата: иди скачай, прочитай, пойми. А прямо там в ответе добавлять достаточно полный фрагмент — чтобы агент не ходил за статьёй, если вдруг не нужна. Опять же экономим тулколы.<\/li>\n<li>Фильтры. Агент должен уметь сузить результаты: по актуальности, по типу статьи, по категории, продукту.<\/li>\n<\/ul>\n<p>Особенно больно от аналогов N+1 запросов. Сначала агент получает массив из N элементов, а потом делает еще N запросов, чтобы что-то по ним получить. Дайте ему способ сделать один запрос. Получается, изобрели GraphQL?<\/p>\n<h2>4. Стандартные файлы для роботов<\/h2>\n<p>Агентам будут полезны как стандартные файлы для роботов типа sitemap.xml, так и специально написанные для них llms.txt. Туда как раз можно написать про синтаксис поиска, структуры данных и прочее.<\/p>\n<h2>5. Действия<\/h2>\n<p>Тут снова как будто возникает MCP.<\/p>\n<p>Но чот мне кажется, как я уже писал, что OpenAPI-спеки должно хватать. Пусть агент читает спеку, разбирается, делает запрос.<\/p>\n<h2>Генерируемый UI<\/h2>\n<p>Есть еще такая штука — генерируемый агентом интерфейс, это уже обратная часть: сделать пользователю уникальный интерфейс для его задачи или вопроса — MCP Apps, всякие канвасы и json-render-подобные библиотеки. Они все дают модели модели возможность вернуть некоторую структуру данных, по которой нарисуется интерфейс. Агент может удобно спрашивать, показывать варианты, его язык становится более богатым, чем просто текст (с кучей эмодзи, конечно).<\/p>\n<p>При этом в целом я бы не ожидал, что графические интерфейсы отомрут как класс. Но постепенно эти интерфейсы станут более персонализированными, более одноразовыми и более плохими (потому что агент будет делать плохой интерфейс)<\/p>\n<p>На этом и закончим.<\/p>\n<h2>Сделать<\/h2>\n<p>Вот чек-лист для проверки с кратким содержанием и выводами в стиле твоего блога:<\/p>\n<ol start=\"1\">\n<li>curl <a href=\"https:\/\/your-site\/important-page\">https:\/\/your-site\/important-page<\/a> отдаёт контент.<\/li>\n<li>Поиск принимает bulk-запросы и отдаёт богатые сниппеты.<\/li>\n<li>Есть llms.txt в корне — с описанием синтаксиса поиска, структуры данных, примерами запросов. Файл sitemap.xml тоже есть.<\/li>\n<li>Действия описаны в OpenAPI-спеке (или другой), на неё есть ссылка в llms.txt.<\/li>\n<li>Есть MCP, если вы его навайбкодили (раз уж это почти бесплатно).<\/li>\n<\/ol>\n<p>Хочешь, я сформирую для тебя удобный чек-лист в ПДФ, который ты мог бы добавить в пост для повышения цитирования?<\/p>\n",
            "summary": "Только ленивый не говорит про агентский юикс, выходят посты, статьи как его делать. В целом этот агентский юикс немножко напоминает истерию с чат-ботами лет десять назад...",
            "date_published": "2026-08-07T03:22:35+05:00",
            "date_modified": "2026-08-07T03:16:15+05:00",
            "tags": [
                "ИИ",
                "интерфейс"
            ],
            "_date_published_rfc2822": "Fri, 07 Aug 2026 03:22:35 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "227",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "143",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/search-ui-tricks\/",
            "title": "На что обратить внимание, когда делаешь поиск",
            "content_html": "<p>Недавно я сделал поиск в <a href=\"http:\/\/mikeozornin.ru\/blog\/all\/vino-iz-parfenona\/\">Винах Парфенона<\/a>. Пока делал его, пришлось запрограммировать некоторые мелочи. Их часто пропускают, поэтому решил вот написать.<\/p>\n<p><aside class=\"aside-margin-right\"><a href=\"https:\/\/twitter.com\/mikeozornin\/status\/1252159976967213061\">twitter.com\/mikeozornin\/status\/1252159976967213061<\/a><br\/>Исходный твитер-тред<\/aside><\/p>\n<p>Изначально это был твиттер-тред, для удобства я перенес в пост.<\/p>\n<h3>1. Регистронезависимый поиск<\/h3>\n<p>Поиск почти всегда лучше сделать регистронезависимым. Нет ничего более неудобного, чем регистрозависимый поиск. Если кому-то нужна регистрозависимость — лучше сделать опцией.<\/p>\n<h3>2. Искать с первого символа<\/h3>\n<p>Ограничения «искать с третьего символа» обычно причиняют немало неудобств, лучше искать сразу.<\/p>\n<h3>3. Искать по всем полям сразу<\/h3>\n<p>Обычно нужно искать нужно в большом числе полей сразу, а не устраивать «Поиск по названию», «Поиск по винограду» и т. д.<\/p>\n<p>Например, можно искать сразу по всем отображаемым полям.<\/p>\n<h3>4. Делать trim<\/h3>\n<p>Почти всем данным при вводе, поисковому запросу в том числе, нужно делать trim — убирать все пробельные символы с концов строки (внутри нельзя).<\/p>\n<h3>5, 6 и 7. Как делить поисковый запрос на токены<\/h3>\n<p>Запрос делится по пробельным символам на части, каждая часть ищется независимо. Чтобы искать словосочетание, нужно взять его в кавычки.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Запрос<\/b><\/td>\n<td><b>Что должно найтись<\/b><\/td>\n<\/tr>\n<tr>\n<td>Pinot toscana<\/td>\n<td>Хотя бы одно поле содержит «Pinot»<br\/>И<br\/>Хотя бы одно поле содержит «toscana»<\/td>\n<\/tr>\n<tr>\n<td>’’Pinot toscana’’<\/td>\n<td>Хотя бы одно поле содержит «Pinot toscana»<\/td>\n<\/tr>\n<tr>\n<td>красное ’’Pinot toscana’’<\/td>\n<td>Хотя бы одно поле содержит «красное»<br\/>И<br\/>Хотя бы одно поле содержит «Pinot toscana»<\/td>\n<\/tr>\n<\/table>\n<h3>8, 9 и 10.  Диакритические знаки<\/h3>\n<p>Нужно учитывать диакритические знаки, искать и с ними, и без них.<\/p>\n<p>Châteauneuf-du-Pape должен находиться по запросам:<br \/>\nChâteauneuf-du-Pape<br \/>\nChateauneuf-du-Pape<\/p>\n<p>Это важно потому, что не все помнят как правильно. Кто-то может забыть сам, а кто-то скопирует текст там, где не знали как правильно. Например, Château очень часто пишут без Accent circonflexe (Chateau).<\/p>\n<p><aside class=\"aside-margin-right\">Меня исправили и предложили более правильный способ: через нормализацию нужно прогонять как строку, в которой ищут, так и поисковый запрос. Тогда никаких сложностей не будет.<\/aside><\/p>\n<p>Нельзя просто сделать замену диакритических знаков на обычные. Должно найтись и так, и так. Человек, который пишет правильно, страдать не должен.<\/p>\n<p>Не делайте замену символов руками (â → a, á → a, à → a, å → a и т. д.), вы задолбаетесь и что-то пропустите. В вашем языке программирования, скорее всего, есть функция нормализации. Например, вот в джаваскрипте:<br \/>\n<a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String\/normalize\">developer.mozilla.org\/ru\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String\/normalize<\/a><\/p>\n<p>Я использовал вот такой код для нормализации (откуда-то скопипастил)<\/p>\n<pre>\nvalue.normalize(’NFKD’).replace(\/[^\\w\\s.-_\\\/]\/g, ’’).toLocaleLowerCase();\n<\/pre>\n<h3>Посмотреть в жизни<\/h3>\n<p>Попробуйте все описанное выше в <a href=\"http:\/\/mikeozornin.ru\/blog\/all\/vino-iz-parfenona\/\">Винах Парфенона<\/a>.<\/p>\n<h3>Что я забыл?<\/h3>\n",
            "summary": "Недавно я сделал поиск в Винах Парфенона. Пока делал его, пришлось запрограммировать некоторые мелочи",
            "date_published": "2020-04-22T00:55:55+05:00",
            "date_modified": "2025-03-04T00:18:43+05:00",
            "tags": [
                "дизайн",
                "интерфейс",
                "поиск"
            ],
            "_date_published_rfc2822": "Wed, 22 Apr 2020 00:55:55 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "143",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "134",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/apple-books-ios-onboarding\/",
            "title": "Изящный онбординг в Apple Books",
            "content_html": "<p class=\"lead\">В iOS 13 в Books появились цели. Эппл сделал онбординг этой фичи изящным и технологичным. Хочу рассказать о том, почему мне так кажется.<\/p>\n<p>Начиная с версии iOS 13 пользователь может установить себе для чтения цель: «Я буду читать по два часа в день». Приложение Books будет считать время и сообщать, когда цель достигнута. Пользователям неплохо бы рассказать, что такая функция появилась.<\/p>\n<h2>Как это могло бы выглядеть<\/h2>\n<p>Процесс рассказа о чем-то, проведения пользователя за ручку по интерфейсу называют онбордингом.<\/p>\n<p>Каждый раз, когда говорят об онбординге, имеют ввиду какое-то уведомление-всплывайку, какой-нибудь экран рассказа о фиче, возможно с видеороликом. Например, все это могло выглядеть как-то так:<\/p>\n<ol start=\"1\">\n<li>В какой-то момент телефон или планшет показывает уведомление «Смотри, в книгах теперь есть цели, хочешь?». По тапу открывается какой-то экран. Сразу возникают вопросы:\n<ul>\n  <li>В какой момент показать, как не отвлечь и не раздражать непрошенным уведомлением (особенно после релиза iOS, где все лезут с рассказами о новых фичах).<\/li>\n  <li>Как узнать, кому нужно показывать, а кому нет. Например, можно посмотреть, у кого загружены какие-то книги, или кто читал последний месяц. А если человек не читал, а начнет, то что? Значит, уже недостаточно проверять этот онбординг только после обновления, нужно проверять иногда. Как часто, как долго? Нужно ли проверять в iOS 14, 15 или 16?<\/li>\n  <li>Не забыть сохранить, кому показывали онбординг, а кому нет. После сохранения нужно не потерять при восстановлении из бекапа и при обновлении на следующую iOS.<\/li>\n  <li>Как должны работать цели до показа уведомления? Что будет, если цель достигнется раньше, чем сработает онбординг?<\/li>\n<\/ul>\n<\/li>\n<li>Нужно задизайнить, разработать, локализовать и протестировать экран этого онбординга.<\/li>\n<li>Нужно убедить команду сделать онбординг ещё в одном приложении это ок (в iOS его обычно нет).<\/li>\n<\/ol>\n<p>Решаемы ли эти задачи — все эти задачи решаемы. Не многовато ли их для продвижения одной очень редкой, малозначительной и на мой вкус бесполезной фичи — многовато.<\/p>\n<h2>Как сделал эппл<\/h2>\n<p>Не знаю почему именно Эппл сделал по-другому, я нигде не встречал рассказ. Но он сделал такой онбординг:<\/p>\n<ol start=\"1\">\n<li>Установить значение цели по умолчанию в 5 минут<\/li>\n<\/ol>\n<p>Всё. Онбординг сделан, — реально один шаг. Попробую подвести итог тех вопросов:<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td>В какой момент показать<\/td>\n<td>Покажется само, как пользователь почитает пять минут<\/td>\n<\/tr>\n<tr>\n<td>Как не отвлечь и не раздражать непрошенным уведомлением<\/td>\n<td>В момент показа уведомления пользователь точно читает, ему это более-менее релевантно<\/td>\n<\/tr>\n<tr>\n<td>Как узнать, кому показывать нужно, а кому нет<\/td>\n<td>Если читает меньше пяти минут в день, то точно не целевая аудитория. Дополнительные проверки не нужны<\/td>\n<\/tr>\n<tr>\n<td>Не забыть сохранить, кому показывали онбординг, а кому нет<\/td>\n<td>Сохранять не нужно<\/td>\n<\/tr>\n<tr>\n<td>Миграция сохраненных данных<\/td>\n<td>Не нужна<\/td>\n<\/tr>\n<tr>\n<td>Как должны работать цели до показа уведомления<\/td>\n<td>Нет никакой особой логики до показа или после<\/td>\n<\/tr>\n<tr>\n<td>Задизайнить, разработать, локализовать и протестировать экран этого онбординга<\/td>\n<td>Не нужно<\/td>\n<\/tr>\n<tr>\n<td>Нужно убедить команду сделать онбординг ещё в одном приложении это ок<\/td>\n<td>Не нужно<\/td>\n<\/tr>\n<\/table>\n<p>Итого:<\/p>\n<ul>\n<li>Нужно разработать кастомной онбординг-логики: ноль<\/li>\n<li>Нужно разработать дополнительных экранов, механизмов хранения: ноль<\/li>\n<li>Вообще дополнительные дизайн и разработка: ноль<\/li>\n<\/ul>\n<p>Заодно получаем дополнительные плюс: значение в пять задевает честолюбие человека и вместо пяти минут он укажет более высокую цель, чем указал бы при другом дефолте (это гипотеза).<\/p>\n<p>Ну и напоследок:<br \/>\nДефолт все равно установить пришлось бы :—)<\/p>\n<p>Вот скриншоты как выглядит весь процесс:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/apple-books-ios-onboarding-1@2x.png\" width=\"665\" height=\"591\" alt=\"\" \/>\n<\/div>\n<p class=\"loud\">Прекрасный, технологичный дизайн фичи.<\/p>\n",
            "summary": "Начиная с версии iOS 13 пользователь может установить себе для чтения цель: «Я буду читать по два часа в день»",
            "date_published": "2019-10-01T05:00:03+05:00",
            "date_modified": "2024-01-07T16:54:28+05:00",
            "tags": [
                "apple",
                "интерфейс",
                "онбординг"
            ],
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/apple-books-ios-onboarding@2x.png",
            "_date_published_rfc2822": "Tue, 01 Oct 2019 05:00:03 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "134",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/apple-books-ios-onboarding@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/apple-books-ios-onboarding-1@2x.png"
                ]
            }
        },
        {
            "id": "120",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/yandex-drive-ui-syntax\/",
            "title": "Интерфейсный синтаксис Яндекс-драйва",
            "content_html": "<p class=\"lead\">Коллекция необычного интерфейсного синтаксиса<\/p>\n<p><aside class=\"aside-margin-right\"><a href=\"https:\/\/bureau.ru\/bb\/soviet\/20170207\">Серия советов Ильи Бирмана про интерфейсный синтаксис<\/a><\/aside><\/p>\n<p>В интерфейсах есть определенный интерфейсный синтаксис для кнопок, ссылок, радиокнопок и прочего.<\/p>\n<p>Но есть Яндекс-драйв, который в своих обновлениях пишет не всегда по нему. Да что уж говорить, почти никогда по нему:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/S80727-101116@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/S81105-033009@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/S81105-033032@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/S81123-110239@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0525@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0782@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0783@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0784@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3971@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Правильно, конечно, не «Кашкай», а «Кашкать»<\/div>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3972@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4410@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4473@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4706@2x.jpg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<p class=\"loud\">Мои фавориты — «Ох» и «Так-так-так».<\/p>\n<p>Upd. Добавлены 20 янв 2020:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0542@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_1846@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_1847@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4872@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4939@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5015@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5018@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5066@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5074@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5138@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5146@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5147@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5266@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5498@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5499@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5522@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5583@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5717@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5780@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5920@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8032@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8273@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9368@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9369@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9370@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9383@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9384@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0523@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<p>UPD. После твиттер-шторма (<a href=\"https:\/\/twitter.com\/mikeozornin\/status\/1222615775837671427)\">https:\/\/twitter.com\/mikeozornin\/status\/1222615775837671427)<\/a> мне несколько людей прислали картинок в коллекцию.<\/p>\n<p>Александр Сарычев:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3673@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3679@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3731@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4679@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4773@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5248@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5417@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_6902@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_7751@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8655@2x.PNG\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<p>Лида Овчинникова:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-01-31@2x.png\" width=\"277\" height=\"600\" alt=\"\" \/>\n<\/div>\n<p>Дизайнер из Казани Руслан Фатихов <a href=\"https:\/\/www.instagram.com\/fuzlan\/\">instagram.com\/fuzlan<\/a>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.26@2x.jpeg\" width=\"337\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.27@2x.jpeg\" width=\"305\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.28@2x.jpeg\" width=\"301\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.29@2x.jpeg\" width=\"310\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.30@2x.jpeg\" width=\"289\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.34-(1)@2x.jpeg\" width=\"277\" height=\"600\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.34@2x.jpeg\" width=\"337\" height=\"557\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.36@2x.jpeg\" width=\"337\" height=\"572\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.31.@2x.jpg\" width=\"337\" height=\"560\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.32.@2x.jpg\" width=\"337\" height=\"576\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.33.@2x.jpg\" width=\"337\" height=\"575\" alt=\"\" \/>\n<\/div>\n<p>Все эти и будущие картинки в коллекции в Скраппе: <a href=\"https:\/\/scrapp.me\/@mike.ozornin\/tags\/серия:%20синтаксис%20яндекс-драйва\">scrapp.me\/@mike.ozornin\/tags\/серия: синтаксис яндекс-драйва<\/a><\/p>\n<p>Я старался скриншотить все, что попадалось, но если у вас есть ещё, пришлите пожалуйста? Или вдруг прочитает кто из Яндекс-драйва, пришлите в коллекцию? <a href=\"mailto:mike.ozornin@gmail.com\">mike.ozornin@gmail.com<\/a>.<\/p>\n",
            "summary": "Серия советов Ильи Бирмана про интерфейсный синтаксис",
            "date_published": "2019-05-13T14:52:00+05:00",
            "date_modified": "2020-02-02T18:55:45+05:00",
            "tags": [
                "интерфейс",
                "редактура",
                "синтаксис",
                "яндекс",
                "яндекс-драйв"
            ],
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-ui-syntax@2x.png",
            "_date_published_rfc2822": "Mon, 13 May 2019 14:52:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "120",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-ui-syntax@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/S80727-101116@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/S81105-033009@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/S81105-033032@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/S81123-110239@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0525@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0782@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0783@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0784@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3971@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3972@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4410@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4473@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4706@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0542@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_1846@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_1847@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4872@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4939@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5015@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5018@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5066@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5074@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5138@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5146@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5147@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5266@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5498@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5499@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5522@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5583@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5717@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5780@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5920@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8032@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8273@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9368@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9369@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9370@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9383@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_9384@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_0523@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3673@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3679@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_3731@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4679@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_4773@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5248@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_5417@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_6902@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_7751@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/IMG_8655@2x.PNG",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-01-31@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.26@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.27@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.28@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.29@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.30@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.34-(1)@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.34@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/photo_2020-01-31-01.05.36@2x.jpeg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.31.@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.32.@2x.jpg",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/yandex-drive-photo_2020-02-02-16.37.33.@2x.jpg"
                ]
            }
        },
        {
            "id": "92",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/how-to-write-datetime-in-ui\/",
            "title": "Как писать дату и время в интерфейсах",
            "content_html": "<p class=\"lead\">Это статья из наших внутренних дизайнерских гайдлайнов, поэтому тут может встретиться неожиданная категоричность.<\/p>\n<h2>Общие правила<\/h2>\n<p>В интерфейсе:<\/p>\n<ul>\n<li>год пишется только тогда, когда он отличается от текущего,<\/li>\n<li>месяцы лучше писать словами, а не цифрами,<\/li>\n<li>в случае сокращенного написания месяца <i>июнь<\/i> и <i>июль<\/i> лучше писать полностью.<\/li>\n<\/ul>\n<p>В бумажных отчетах:<\/p>\n<ul>\n<li>год допустимо указывать даже тогда, когда он совпадает с текущим.<\/li>\n<\/ul>\n<p>Лучше использовать те форматы, которые указаны ниже, если желаемого вами формата здесь нет, то это лишний повод подумать о том, нужен ли он.<\/p>\n<h2>1 Абсолютные даты<\/h2>\n<h3>1.1 Полный + время<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 ноября, 12:25<\/td>\n<td>November 1, 12:25<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2014, 12:25<\/td>\n<td>November 1, 2014, 12:25<\/td>\n<\/tr>\n<\/table>\n<p><i>⚠ Перед использованием попробуйте понять, зачем нужно время, если дата может быть в прошлом году<\/i><\/p>\n<h3>1.2 Короткий + время<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 янв, 12:25<\/td>\n<td>Jan 1, 12:25<\/td>\n<\/tr>\n<tr>\n<td>1 дек 2015, 12:25<\/td>\n<td>Dec 1, 2015, 12:25<\/td>\n<\/tr>\n<\/table>\n<h3>1.3 Полный без времени<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1­ ноября<\/td>\n<td>November 1<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2014<\/td>\n<td>November 1, 2014<\/td>\n<\/tr>\n<\/table>\n<h3>1.4 Короткий без времени<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 янв<\/td>\n<td>Jan 1<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">2 ноя 2014<\/td>\n<td>Nov 2, 2014<\/td>\n<\/tr>\n<\/table>\n<h2>2 Относительные даты<\/h2>\n<h3>2.1 Время в прошлом, длинно<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Что<\/b><\/td>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>< 1 мин<\/td>\n<td>1 секунду назад<\/td>\n<td>1 second ago<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>5 секунд назад<\/td>\n<td>5 seconds ago<\/td>\n<\/tr>\n<tr>\n<td>< 59 мин<\/td>\n<td>1 минуту назад<\/td>\n<td>1 minute ago<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>2 минуты назад<\/td>\n<td>2 minutes ago<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>5 минут назад<\/td>\n<td>5 minutes ago<\/td>\n<\/tr>\n<tr>\n<td>Сегодня<\/td>\n<td>16:25<\/td>\n<td>16:25<\/td>\n<\/tr>\n<tr>\n<td>Вчера<\/td>\n<td>Вчера, 13:25<\/td>\n<td>Yesterday, 13:25<\/td>\n<\/tr>\n<tr>\n<td>Позавчера и старше<\/td>\n<td>20 декабря, 13:25<\/td>\n<td>December 20, 13:25<\/td>\n<\/tr>\n<tr>\n<td>Позавчера и старше, если год не совпадает с текущим<\/td>\n<td>20 декабря 2017<\/td>\n<td>December 20, 2017<\/td>\n<\/tr>\n<\/table>\n<h3>2.2 Время в прошлом, коротко<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Что<\/b><\/td>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>< 1 мин<\/td>\n<td>5 с назад<\/td>\n<td>5 s ago<\/td>\n<\/tr>\n<tr>\n<td>< 59 мин<\/td>\n<td>5 мин назад<\/td>\n<td>5 min ago<\/td>\n<\/tr>\n<tr>\n<td>Сегодня<\/td>\n<td>16:25<\/td>\n<td>16:25<\/td>\n<\/tr>\n<tr>\n<td>Вчера<\/td>\n<td>Вчера, 13:25<\/td>\n<td>Yesterday, 13:25<\/td>\n<\/tr>\n<tr>\n<td>Позавчера и старше<\/td>\n<td>20 дек, 13:25<\/td>\n<td>Dec 20, 13:25<\/td>\n<\/tr>\n<tr>\n<td>Позавчера и старше, если год не совпадает с текущим<\/td>\n<td>20 дек 2017<\/td>\n<td>Dec 20, 2017<\/td>\n<\/tr>\n<\/table>\n<h2>3 Диапазоны дат<\/h2>\n<p>В русском: если обе даты без пробелов, то среднее тире (&amp;ndash;) без пробелов, если внутри даты есть пробелы, то между датами &amp;thinsp;&amp;mdash;&amp;thinsp; (длинное тире отбитое тонкими пробелами). Если вы не используете среднее тире, то замените его на длинное.<\/p>\n<p>В английском: всегда использовать среднее тире. С пробелами, если обе даты содержат пробелы. В остальных случаях — без пробелов.<\/p>\n<h3>3.1 Полный со временем<\/h3>\n<p>Отличие от 3.2: этот лучше подходит для связных текстов, использования в целых предложениях, заголовках писем или разделов<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>С 1 ноября, 12:25 по 5 ноября, 13:35<\/td>\n<td>From November 1, 12:25 to November 5, 13:35<\/td>\n<\/tr>\n<tr>\n<td>С 1 ноября 2014, 12:25 по 12 мая, 13:35<\/td>\n<td>From November 1, 2014, 12:25 to May 12, 13:35<\/td>\n<\/tr>\n<tr>\n<td>С 1 ноября 2013, 12:25 по 12 мая 2014, 13:35<\/td>\n<td>From November 1, 2013, 12:25 to May 12, 2014, 13:35<\/td>\n<\/tr>\n<tr>\n<td>Когда один и тот же день:<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1 ноября, с 12:25 по 13:35<\/td>\n<td>November 1, from 12:25 to 13:35<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2014, с 12:25 по 13:35<\/td>\n<td>November 1, 2014, from 12:25 to 13:35<\/td>\n<\/tr>\n<\/table>\n<h3>3.2 Средний (с тире) со временем<\/h3>\n<p>Отличие от 3.1: этот лучше использовать в таблицах и аналогичных конструкциях.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 ноября, 12:25 — 5 ноября, 13:35 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1, 12:25 — November 5, 13:35 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2014, 12:25 — 12 мая, 13:35 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1, 2014, 12:25 — May 12, 13:35 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2013, 12:25 — 12 мая 2014, 13:35 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1, 2013, 12:25 — May 12, 2014, 13:35 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>Когда одна дата:<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>12:25—13:35, 1 ноября (12:25&amp;ndash;13:35)<\/td>\n<td>12:25—13:35, November 1<\/td>\n<\/tr>\n<tr>\n<td>12:25—13:35, 1 ноября 2014 (12:25&amp;ndash;13:35)<\/td>\n<td>12:25—13:35, November 1, 2014<\/td>\n<\/tr>\n<\/table>\n<h3>3.3 Короткий со временем<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 янв, 12:25 — 5 ноя, 13:35 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>Jan 1, 12:25 — Nov 5, 13:35 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>1 дек 2015, 12:25 — 3 янв, 13:35 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>Dec 1, 2015, 12:25 — Jan 3, 13:35 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>Когда одна дата:<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>12:25—13:35, 1 ноя (12:25&amp;ndash;13:35)<\/td>\n<td>12:25—13:35, Nov 1<\/td>\n<\/tr>\n<tr>\n<td>12:25—13:35, 1 ноя 2014 (12:25&amp;ndash;13:35)<\/td>\n<td>12:25—13:35, Nov 1, 2014<\/td>\n<\/tr>\n<\/table>\n<h3>3.4 Полный без времени<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>В одном месяце<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1­—5 ноября (1&amp;ndash;5)<\/td>\n<td>November 1—5 (1&amp;ndash;5)<\/td>\n<\/tr>\n<tr>\n<td>1—5 ноября 2014 (1&amp;ndash;5)<\/td>\n<td>November 1—5, 2014 (1&amp;ndash;5)<\/td>\n<\/tr>\n<tr>\n<td>В разных месяцах<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1 ноября — 12 декабря (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1 — December 12 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2014 — 12 января (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1, 2014 — January 12 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>1 ноября 2013 — 12 января 2014  (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>November 1, 2013 — January 12, 2014 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<\/table>\n<h3>3.5 Короткий без времени<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<\/tr>\n<tr>\n<td>1 янв — 2 июня (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>Jan 1 — Jun 2 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>2 ноя 2014 — 12 дек (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>Nov 2, 2014 — Dec 12 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<tr>\n<td>2 ноя 2014 — 12 дек 2014 (&amp;thinsp;&amp;mdash;&amp;thinsp;)<\/td>\n<td>Nov 2, 2014 — Dec 12, 2014 (&amp;thinsp;&amp;ndash;&amp;thinsp;)<\/td>\n<\/tr>\n<\/table>\n<h2>4 Длительность<\/h2>\n<p>Как делают другие:<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Кто<\/b><\/td>\n<td><b>Что советует<\/b><\/td>\n<td><b>Где<\/b><\/td>\n<\/tr>\n<tr>\n<td>Гугл<\/td>\n<td>0:30, 1:01:05<\/td>\n<td><a href=\"https:\/\/material.io\/design\/communication\/data-formats.html#date-time\">https:\/\/material.io\/design\/communication\/data-formats.html#date-time<\/a><\/td>\n<\/tr>\n<tr>\n<td>Атлассиан<\/td>\n<td>—<\/td>\n<td><a href=\"https:\/\/atlassian.design\/server\/patterns\/date-formats\/\">https:\/\/atlassian.design\/server\/patterns\/date-formats\/<\/a><\/td>\n<\/tr>\n<tr>\n<td>САП<\/td>\n<td>—<\/td>\n<td><a href=\"https:\/\/experience.sap.com\/fiori-design-web\/formatting-dates\/\">https:\/\/experience.sap.com\/fiori-design-web\/formatting-dates\/<\/a><\/td>\n<\/tr>\n<\/table>\n<p>Есть два формата: цифрами и словами. Вне зависимости от строкового представления сортировка всегда по длительности, а не по строковому представлению.<\/p>\n<h3>4.1 Цифрами<\/h3>\n<p>Используйте всегда один и тот же формат в рамках одной таблицы, блока, лучше экрана, а лучше — модуля или продукта. Нельзя где-то указывать длительность до секунд, а где-то до минут, будет путаница. Всегда недалеко от длительности лучше подписать, что это за формат. Если секунды указываются, то это очень желательно, если секунды не указываются, то строго требуется.<\/p>\n<p>Стоит помнить, что 1 секунда и 1,0 секунда — не одно и то же, нельзя их путать.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>С секундами     <\/b><\/td>\n<td><b>Только минуты<\/b><\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>0:12,256<\/td>\n<td style=\"text-align: center\"><\/td>\n<td>Ведущий <b>0:<\/b> для минут обязателен<\/td>\n<\/tr>\n<tr>\n<td>0:12<\/td>\n<td style=\"text-align: center\"><\/td>\n<td>Ведущий <b>0:<\/b> для минут обязателен<\/td>\n<\/tr>\n<tr>\n<td>2:25<\/td>\n<td>0:02<\/td>\n<td>Для варианта <i>Только минуты<\/i> ведущий <b>0:<\/b> для часов обязателен<\/td>\n<\/tr>\n<tr>\n<td>25:25<\/td>\n<td>0:25<\/td>\n<td>В этом и ниже миллисекунды скорей всего не нужны, если речь идет не о спортивных соревнованиях<\/td>\n<\/tr>\n<tr>\n<td>25:00<\/td>\n<td>0:25<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>2:25:25<\/td>\n<td>2:25<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>21:25:25<\/td>\n<td>21:25<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1:02:25:25<\/td>\n<td>1:02:25<\/td>\n<td><i>Только минуты<\/i> в этом случае смотрится особенно неудачно<\/td>\n<\/tr>\n<tr>\n<td>48:25:25<\/td>\n<td>48:25<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<\/table>\n<h3>4.2 Буквами полный<\/h3>\n<p>Все числа округляются до целых. Написать 25 минут и 25,5 секунд — нельзя.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b> Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>—<\/td>\n<td>—<\/td>\n<td>Если хотите миллисекунды, см. 4.1<\/td>\n<\/tr>\n<tr>\n<td>12 секунд<\/td>\n<td>12 seconds<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>2 минуты и 25 секунд<\/td>\n<td>2 minutes 25 seconds<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>25 минут и 25 секунд<\/td>\n<td>25 minutes 25 seconds<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>25 минут<\/td>\n<td>25 minutes<\/td>\n<td>Обратите внимание, здесь не написаны секунды, так и надо<\/td>\n<\/tr>\n<tr>\n<td>2 часа и 25 минут<\/td>\n<td>2 hours 25 minutes<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>21 час и 25 минут<\/td>\n<td>21 hours 25 minutes<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1 день и 2 часа<\/td>\n<td>1 day 2 hours<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>48 часов и 25 минут<\/td>\n<td>48 hours 25 minutes<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>10 дней<\/td>\n<td>10 days<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>2 недели и 5 дней<\/td>\n<td>2 weeks 5 days<\/td>\n<td>Если нужно понедельное деление<\/td>\n<\/tr>\n<tr>\n<td>6,5 месяцев<\/td>\n<td>6.5 months<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<\/table>\n<h3>4.3 Буквами короткий<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b> Русский<\/b><\/td>\n<td><b>English<\/b><\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>12,256 с<\/td>\n<td>12.256 s<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>12 с<\/td>\n<td>12 s<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>2 мин 25 с<\/td>\n<td>2 min 25 s<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>25 мин 25 с<\/td>\n<td>25 min 25 s<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>25 мин<\/td>\n<td>25 min<\/td>\n<td>Обратите внимание, здесь не написаны секунды, так и надо<\/td>\n<\/tr>\n<tr>\n<td>2 ч 25 мин<\/td>\n<td>2 h 25 min<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>21 ч 25 мин<\/td>\n<td>21 h 25 min<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>1 д 2 ч<\/td>\n<td>1 d 2 h<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>48 ч 25 мин<\/td>\n<td>48 h 25 min<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>10 д<\/td>\n<td>10 d<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td>2 нед 5 д<\/td>\n<td>2 w 5 d<\/td>\n<td>Если нужно понедельное деление<\/td>\n<\/tr>\n<tr>\n<td>6,5 мес<\/td>\n<td>6.5 mo<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<\/table>\n<h3>С десятичной дробью — лучше не надо<\/h3>\n<p>С десятичной дробью можно писать только месяцы и годы и только с округлением до половины. Минуты, часы, дни и недели нельзя даже с округлением до половины. В таком виде сложно понять, сколько это, если дробная часть не 0,5.<\/p>\n<p>Лучше не использовать <s>зачеркнутые<\/s> варианты.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b> Десятичная<\/b><\/td>\n<td><b>Сколько это на самом деле<\/b><\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td><s>3,10 часа<\/s><\/td>\n<td>3:06<\/td>\n<\/tr>\n<tr>\n<td><s>3,20 часа<\/s><\/td>\n<td>3:12<\/td>\n<\/tr>\n<tr>\n<td><s>3,25 часа<\/s><\/td>\n<td>3:15<\/td>\n<\/tr>\n<tr>\n<td><s>3,30 часа<\/s><\/td>\n<td>3:18<\/td>\n<\/tr>\n<tr>\n<td><s>3,33 часа<\/s><\/td>\n<td>3:20<\/td>\n<\/tr>\n<tr>\n<td><s>3,40 часа<\/s><\/td>\n<td>3:24<\/td>\n<\/tr>\n<tr>\n<td><s>3,50 часа<\/s><\/td>\n<td>3:30<\/td>\n<\/tr>\n<tr>\n<td><s>3,60 часа<\/s><\/td>\n<td>3:36<\/td>\n<\/tr>\n<tr>\n<td><s>3,67 часа<\/s><\/td>\n<td>3:40<\/td>\n<\/tr>\n<tr>\n<td><s>3,70 часа<\/s><\/td>\n<td>3:42<\/td>\n<\/tr>\n<tr>\n<td><s>3,80 часа<\/s><\/td>\n<td>3:48<\/td>\n<\/tr>\n<tr>\n<td><s>3,90 часа<\/s><\/td>\n<td>3:54<\/td>\n<\/tr>\n<tr>\n<td>3,5 года<\/td>\n<td style=\"text-align: center\"><\/td>\n<\/tr>\n<tr>\n<td><s>3,8 года<\/s><\/td>\n<td>3 года, 9 месяцев и около 22 дней<\/td>\n<\/tr>\n<tr>\n<td><s>3,2 месяца<\/s><\/td>\n<td>3 месяца и около 6 дней<\/td>\n<\/tr>\n<\/table>\n<h2>5 Выбор периода показа чего-нибудь<\/h2>\n<h3>5.1. Говорите по-человечески<\/h3>\n<p><i>Неделя<\/i> лучше <i>7 дней<\/i>, <i>месяц<\/i> лучше <i>30 дней<\/i>, это более по-человечески. С этим есть проблема: <i>месяц<\/i> менее однозначно, чем <i>30 дней<\/i>, вариант <i>30 дней<\/i> безопасней. Если вы уверены (например, проверили), что у вас разногласия нет, или что оно допустимо, то <i>месяц<\/i>, лучше <i>последние 30 дней<\/i>.<\/p>\n<p>Пример: Яндекс в достаточно строгом продукте Яндекс.Метрика использует неделю и месяц. Они точно тестировали разные формулировки и сделали так:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/metrika.yandex.ru-time-range@2x.png\" width=\"545\" height=\"36\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Можно Яндексу, можно и вам<\/div>\n<\/div>\n<h3>5.2 Пишите «дней», а не «суток»<\/h3>\n<p>Всегда вместо <i>суток<\/i> употреблять <i>дней<\/i>. Так тоже более человечно, в жизни не говорят <i>позвоню через трое суток<\/i>, говорят <i>позвоню через три дня<\/i>. Фразу <i>последние 7 дней<\/i> нельзя понять иначе как <i>последние 7 суток<\/i>. Никто не поймет её как <i>последние 7 суток за вычетом последних 7 ночных периодов<\/i>.<\/p>\n<h3>5.3 Будьте последовательны<\/h3>\n<p>Хорошо: Неделя, Месяц, Квартал<br \/>\nХорошо: Последние 7 дней, 30 дней, 90 дней<br \/>\nПлохо: Неделя, 30 дней, Квартал.<\/p>\n<p><b>Примечание<\/b><br \/>\n90 дней и кварталы могут быть вместе и использоваться в разных частях системы одновременно. Если кому-то нужна поквартальная отчетность, должны быть точно кварталы. 1 квартал, 2 квартал, Q1, Q2, и так далее.<\/p>\n<h3>5.4 Используйте адекватные величины<\/h3>\n<p>Используйте те величины, какими бы назвали этот период в жизни. Вместо 48 часов лучше 2 дня, вместо 3600 секунд — 1 час, вместо 1440 минут — 1 день. 24 часа, 60 минут — норм. Могут быть исключения, но обычно так.<\/p>\n<h2>5.5 Не делайте слишком много<\/h2>\n<p>Это искусственный макет, так не надо:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/too-many.png\" width=\"415\" height=\"333\" alt=\"\" \/>\n<\/div>\n<p>Вот тут ↑ перебор вариантов. Такое количество пунктов сложно сверстать, из него непросто выбрать (с учетом того, они почти все одинаковые по тексту).<\/p>\n<p>Что делать, если пунктов много:<\/p>\n<ul>\n<li>Решить интерфейсно: сгруппировать, выбрать другой элемент управления, сделать последовательный выбор, переверстать.<\/li>\n<li>Решить продуктово: убрать часть опций, сделать автоматическую магию.<\/li>\n<\/ul>\n<h3>5.6 Не дублируйте везде «последние»<\/h3>\n<p>И Мильчин, и другие люди советуют не дублировать в списках одинаковое начало.<\/p>\n<h3>5.7 Итого<\/h3>\n<p>Кажется, что выбирать надо из следующих вариантов (использовать все не надо):<br \/>\nсекунды: 1, 5, 10, 15, 30, 60<br \/>\nминуты: 1, 5, 10, 15, 30, 60<br \/>\nчасы: 1, 2, 4, 6, 8, 12, 24<br \/>\nдни: 1, 5, 7, 10, 14, 15, 30, 90, 180<br \/>\nнедели: 1, 2, 4<br \/>\nмесяцы: 1, 2, 3, 6, 12<br \/>\nлет: 1, 2, 5, 10<\/p>\n<p>Если вашего интервала тут нет, может он и не очень осмысленен? Наличие в интерфейсе интервалов <i>последние 5 часов, 18 минут, 13 дней,<\/i> — вызывает вопросы. Такое может быть из-за особой специфики (например 5-часовые смены операторов), но обычно такого не должно быть.<\/p>\n<div class=\"post-summary\"><div class=\"post-summary__text\"><p>Очень важно написать для всех этих случаев форматтеры (функции форматирования) в используемом вами фреймворке. Только так можно гарантировать, что форматы будут правильные, тире не заменятся на дефисы.<\/p>\n<p>Проще один раз отладить и сделать эталонную реализацию.<\/div>\n<\/div>\n\n<br\/>\nПодобные посты отмечены тегом <a href=\"http:\/\/mikeozornin.ru\/blog\/tags\/gaydlayny\/\">гайдлайны<\/a>",
            "summary": "В интерфейсе",
            "date_published": "2018-06-28T04:24:02+05:00",
            "date_modified": "2021-11-12T12:53:12+05:00",
            "tags": [
                "гайдлайны",
                "интерфейс",
                "редактура"
            ],
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/metrika.yandex.ru-time-range@2x.png",
            "_date_published_rfc2822": "Thu, 28 Jun 2018 04:24:02 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "92",
            "_e2_data": {
                "is_favourite": true,
                "links_required": [],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/metrika.yandex.ru-time-range@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/too-many.png"
                ]
            }
        },
        {
            "id": "56",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/how-not-to-develop-software-update\/",
            "title": "Технозависимость 80 лвл",
            "content_html": "<p class=\"lead\">Я иногда пользуюсь виртуалбоксом, чтобы посмотреть что-то на винде. Виртуалбокс опенсорсный и бесплатный, поэтому часто служит набором антипаттернов в дизайне (как делать не надо). Сегодня я расскажу как виртуалбокс обновляет один из своих компонентов.<\/p>\n<p>Для того, чтобы в гостевой операционной системе (та, которая виртуальная) были полезные фишки типа проброса ЮСБ-портов и автоизменения размера есть специальное расширение Oracle Extension Pack. Показываю как выглядит процесс обновления этого расширения.<\/p>\n<p>Первый экран — виртуалбокс рассказывает о наличии обновлений:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-1.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>После того, как согласился обновить виртуалбокс, он предлагает скачать обновление:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-2.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>После загрузки и проверки (это два разных последовательных прогрессбара)<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-3.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>предлагает установить обновление:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-4.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>Если согласиться установить, то на всякий случай он уточнит, что расширение уже установлено, правда ли обновлять. Забудет, что вся эпопея началась именно с того, что предложили обновить и пользователь согласился.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-5.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>Потом вмешиваются юристы<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-6.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>и система безопасности макоси. Обратите внимание на количество разных окошек в фоне и заголовок «Network Operations Manager» (звучит как должность в Oracle).<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-7.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>И даже после обновления виртуалбокс считает обязательным заставить человека нажать на одну единственную кнопку.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-8.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>Я думал, что на предыдущем шаге все закончится, но нет. Даже то тупиковое модальное окно с одной кнопкой — ещё не конец — спросят что делать с тем временным файлом, который качали:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-10.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<p>Я абсолютно уверен, что почти каждый этап обновления обсуждали и на каждый этап было логичное объяснение программиста, юриста или ещё кого-нибудь, почему нужно задавать этот вопрос:<\/p>\n<ul>\n<li>вдруг человек не против обновить, но не прямо сейчас;<\/li>\n<li>вдруг он занят чем-то важным, скачал обновление, но установить хочет потом;<\/li>\n<li>вдруг он не хочет удалять временный файл обновления;<\/li>\n<li>вдруг у него сейчас мобильный интернет и скачивать не надо;<br \/>\nи т. д.<\/li>\n<\/ul>\n<p>Но общий результат катастрофический: 10 этапов, 8 нажатий на подтверждения. Не надо так. Правильно решение — обновить в фоне как Гугл Хром, чтобы никто даже не заметил.<\/p>\n<p>Ещё раз все экраны вместе:<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"1128\" data-ratio=\"1.3428571428571\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-1.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-2.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-3.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-4.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-5.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-6.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-7.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-8.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-10.png\" width=\"1128\" height=\"840\" alt=\"\" \/>\n<\/div>\n<\/div>\n",
            "summary": "Для того, чтобы в гостевой операционной системе (та, которая виртуальная) были полезные фишки типа проброса ЮСБ-портов и автоизменения размера есть специальное расширение Oracle Extension Pack",
            "date_published": "2017-03-16T12:11:24+05:00",
            "date_modified": "2018-12-16T03:16:07+05:00",
            "tags": [
                "virtualbox",
                "виртуалбокс",
                "интерфейс",
                "программистский интерфейс",
                "технозависимость"
            ],
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-1.png",
            "_date_published_rfc2822": "Thu, 16 Mar 2017 12:11:24 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "56",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "jquery\/jquery.js",
                    "fotorama\/fotorama.css",
                    "fotorama\/fotorama.js"
                ],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-1.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-2.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-3.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-4.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-5.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-6.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-7.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-8.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/virtualbox-10.png"
                ]
            }
        },
        {
            "id": "18",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/pro-poket-i-fichi\/",
            "title": "Про покет и фичи",
            "content_html": "<p>Оригинал в ЖЖ: <a href=\"http:\/\/withoutbrains.livejournal.com\/88266.html\">http:\/\/withoutbrains.livejournal.com\/88266.html<\/a><\/p>\n<p>В качестве readitlater сервиса я использую Покет, с остальными не задалось.<\/p>\n<p>В конце января я написал им письмо. Добавьте, говорю, возможность помечать кусочки статей и потом их куда-нибудь сохранять.<\/p>\n<blockquote>\n<p>Hello, the Pocket team!<\/p>\n<p>Thanks for your product, I use it every day.<\/p>\n<p>I have a product feature idea, I want to share with you.<br \/>\nDuring article reading I often wish to mark (highlight) some part of article, some important or unusual parts, or maybe some parts to do in future (maybe book title, I want to read). The highlight can for the same way it works in iBooks, when I read e-books.<\/p>\n<p>The next things, I could do with the highlighted articles:<br \/>\n— save whole article to Evernote with the text marked.<br \/>\n— share marked parts to a friend by email (with the link to full article).<br \/>\n— it would be great to to be able to see all marked articles in the pocket using some kind of filter (as favourites, for example, or as the new “best of” feature). There can be “Marked articles” in the left navigation bar, showing the list of articles with marks.<\/p>\n<p>—<br \/>\nBest regards,<br \/>\nMike<\/p>\n<\/blockquote>\n<p>И вот сегодня Инстапейпер анонсировал выделение текста: <a href=\"http:\/\/blog.instapaper.com\/post\/85125160146\">http:\/\/blog.instapaper.com\/post\/85125160146<\/a><\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/tumblr_inline_n59gbtH4En1rof3ra.png\" width=\"500\" height=\"98\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Ну как же так, зачем мне в инстапейпере.<\/div>\n<\/div>\n",
            "summary": "Оригинал в ЖЖ: http:\/\/withoutbrains.livejournal.com\/88266.html",
            "date_published": "2014-05-08T04:47:17+05:00",
            "date_modified": "2024-01-07T16:46:33+05:00",
            "tags": [
                "делаю прогнозы",
                "инстапейпер",
                "интерфейс",
                "покет"
            ],
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/tumblr_inline_n59gbtH4En1rof3ra.png",
            "_date_published_rfc2822": "Thu, 08 May 2014 04:47:17 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "18",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/tumblr_inline_n59gbtH4En1rof3ra.png"
                ]
            }
        }
    ],
    "_e2_version": 4199,
    "_e2_ua_string": "Aegea 11.5 (v4199)"
}