понедельник, 14 мая 2018 г.

Команды Emacs

При работе в консоли мы используем команды Emacs, но редко когда что-то сложнее [CTRL-R] для поиска по истории. Хотя зачастую возникает непонимание, почему поиск по истории оказывается "пустым" и не находит ничего. Это все потому, что он начал

И помимо этой - есть еще несколько других малоизвестных, но очень полезных команд Emacs:

[ESC-B]      Move one word backward
[ESC-F]      Move one word forward
[ESC-DEL]    Kill one word backward
[ESC-CTRL-H] Kill one word backward
[ESC-D]      Kill one word forward
[CTRL-Y]     Retrieve ("yank") last item killed


Команды для работы с несколькими строками:

[CTRL-A] Move to beginning of line
[CTRL-E] Move to end of line
[CTRL-K] Kill forward to end of line
[CTRL-P] Move to previous line
[CTRL-N] Move to next line
[CTRL-R] Search backward
[ESC-<]  Move to first line of history list
[ESC->]  Move to last line of history list


среда, 7 февраля 2018 г.

Лучше из 2017

2017 год скудный на новые посты, но насыщенный на путешествия и новые проекты.

Online курсы
"Практика. Рисование персонажей на основе простейших фигур" Максим Костенко
Конференция
Amsterdam React, Berlin Day React
Технология
React Native, Twilio Chat
Книга
"Тошнота" Жан Поль Сартра и "Над пропастью во ржи" Сэлинджера
Игра
Zelda "Breath of the Wild"
Блюдо
Селедка с лучком; суп из цветной капусты в кокосовом молоке
Activity
Сноуборд, баскетбол
Мультфильм
"Твоё имя"
Город
Алматы, Осака, Амстердам, Баку, Берлин, Прага
Страна
Казахстан, Япония, Нидерланды, Азербайджан, Германия
Достижение
Inktober
Год, который подарил самые необычные впечатления. Это и впечатления от Японии, и от Амстердама. И от совершенно нового подхода к построению приложений на React Native.

воскресенье, 24 декабря 2017 г.

Погружение в React Native: навигация, работа оффлайн, пуш нотификации

Навигация


Правильный выбор навигации - залог хорошего проектирования приложений на React Native. От этого зависит не только структура проекта, но и его производительность. На данный момент существует два вида навигации:

1. Нативная

Она реализованная с помощью нативных элементов в iOS и Android и представлена двумя библиотеками:
Их преимущество - быстродействие и отображение специфичных для каждой платформы эелементов навигации.

2. javascript-реализация

Здесь можно потеряться в выборе и даже написать свою версию с помощью redux'а. Но самой популярной и часто используемой всё же является:
Она достаточно проста в использовании, предоставляет основной набор навигации: Stack, Tabs и Drawer, а также возможность создавать вложенные навигаторы. Из недостатков - все анимации просчитываются с помощью javascript'а, и возможны утечки памяти при неправильном проектировании приложения. Так, например, если используется сложная навигации, то переход по навигатору из одной ветки через родителя в другую ветку осуществляется порождением новой компоненты для скрина, а не перерисовыванием старой. Нужно избегать подобных переходов и всегда следить за состоянием структуры роута.

Работа приложения оффлайн


Так же хорошо, как принцип "Mobile first" работает для web'а, в мобильном приложении главенствует принцип "Offline first".

Достигается это следующими способами:

1. Заданием начального состояния приложения

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

2. Использованием локального хранилища

В React Native это будет AsyncStorage. Здесь можно хранить те данные, которые должны быть доступны оффлайн, например, токен авторизованного пользователя, что позволит при следующем открытии приложения избежать повторногого логина.
Доступ к хранилищу можно либо огранизовать самому, либо воспользоваться библиотекой Redux Persist.

3. Следить за состоянием сети в помощью NetInfo

В этом случае важно определиться как реагировать приложению на отсутствие сети:
  • самый простой способ уведомить пользователя - показать ему сообщение:
    react-native-dropdownalert - плагин, реализующий алерт для вывода различного рода уведомлений: не только о потере соединения, но и о новых сообщениях в чате, сообщениях о любых успешно или неуспешно завершенных операциях.
  • react-native-offline - универсальная утилита для работы приложения в режиме онлайн/оффлайн. Основные ее особености: проверка наличия доступа в сеть пингом указанного сайта с заданной частотой (в отличие от NetInfo, которая показыват только наличие сети, не заботясь о том, что доступ в интернет все еще не доступен), использование этой проверки в рендере для выбора компоненты, добавление состояния сети в стейт,  блокировка запросов при отсутствии сети в редаксе или сагах, построение и управление очередью запросов при отсутствии соединения. В целом ну оочень богатая на функционал библиотека.
Важно понять, нужно ли обрабатывать обращения пользователя к серверу и ставить их в очередь, которая будет потом отравлена на сервер при появлении доступа, или же игнорировать все действия и блокировать все запросы. Второй случай проще, при первом же нужно подумать как организовать эту очередь событий, что делать при наличи двух похожих запросов, а так же как обрабатывать эти запросы на сервере в случае конфликтов с текущим состоянием.

Push notification


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



Так как фомирование нотификации происходит на сервере, то всегда можно решить какие данные нам нужны для того или иного рода нотификации. Так, в зависимости от типа пришедшего уведомления можно по-разному его обрабатывать: разделить на системные и пользовательские нотификации.


четверг, 7 декабря 2017 г.

React Native: путь новичка

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

Краткое содержание статьи:

1. Источники информации
2. React модули
3. React Native модули
4. JavaScript библиотеки
5. "Баги"
6. Выводы

React Native - самая, пожалуй, интересная и быстроразвивающаяся платформа. Сегодня ты создаешь новый проект на базе её последней версии, и уже через несколько месяцев она успевает устареть на несколько релизов. И если ещё год назад React Native был еще достаточно сырым продуктом, то уже сейчас к нем написано множество как плагинов для работы с нативными компонентами, так и обычных react-компонент.

Итак, с чего начать?


Могу порекомендовать книгу "Learning React Native: Building Native Mobile Apps with JavaScript" Bonnie Eisenman. Несмотря на то, что примеры из книги написаны с использованием устаревшего синтаксиса, её прекрасно можно использовать как пособие по изучению базовых принципов построения приложений на react-native. Книга рассматривает весь процесс создания приложения, вплоть до деплоя в стор c разбором отдельных компонент: как и зачем их использовать. Примеры же отлично укрепят полученные знания, так как копипастить тут не получится и нужно будет, переосмысливая, переписывать их на новый лад.

Далее по важности: документация. Здесь прекрасно то, что она актуальна. Все новинки релизов описаны. Все устаревшие методы указаны.
Выбираем вкладку "Building Projects with Native Code" и понеслась!..

Ну и далеко не последняя пристань react-native разработчика: http://stackoverflow.com/

Далее определимся с набором инструментов для react.


Хотелось бы отметить наиболее значимые и используемые модули:
  1. redux
    • react-redux
    • redux-logger - незаменимый инструмент при отладке
    • redux-saga - лучшее решение для организации сайд-эффектов

  2. селекторы
    • reselect - выбор данных из состояния приложения и компоновка их в нужную структуру. Удобно вынести эту логику из редьюсеров и вьюх в специальное место.
  3. jest - тестирование, идет из коробки. Главное - не пренебрегать и писать тесты =)
  4. eslint - инструмент для унификации стиля написания кода, а также выявления глупых и/или синстаксических ошибок.

Полезности RN


Ещё не могу не упомянуть об уже существующих библиотеках для react-native, которые несомненно упростят жизнь разработчику дабы не изобретать велосипед:

По работе с камерой и библиотекой фото и видео, загрузкой и шаринге есть неплохая статья на medium. А так же следующие библиотеки:


Последние три требуют дополнительных разрешений на телефоне, таких как: доступ к библиотеке, камере, локальному хранилище данных. Нужно отметить, что эти разрешения автоматически будут запрашиваться у пользователя при установке приложения. Исключение составляют новые (выше 6-ой) версии Андроида. Поэтому их нужно запрашивать во время обращения к нужным службам приложения (и вот почему). В документации есть пример, который можно оформить в виде небольшой библиотеки:

import { PermissionsAndroid, Platform } from 'react-native'

export const requestExternalStoragePermission = async (onSuccess, onError) => {
  // only for Android 6 and greater
  if ((Platform.OS === 'android') && (Platform.Version > 22)) {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
        {
          title: 'App read external storage Permission',
          message: `App needs access to your external storage
                    so you can take keep your data.`
        }
      )
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        onSuccess()
      } else {
        onError()
      }
    } catch (err) {
      console.warn(err)
    }
  } else {
    onSuccess()
  }
}

Здесь можно хранить запросы и на доступ к микрофону и камере.

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

Андроид (пример приложения фейсбука):

iPhone (пример приложения фейсбука):


Дело в том, что при вычислении высоты экрана берется фактическая высота устройства, но реальная область, доступная для приложения для Андроида, будет меньше на высоту этой самой шапки в 20px (смотри на картинке на самую верхнуюю полосу). Тогда как в iOS "шапка" накладывается поверх приложения и не занимает дополнительного места.

Кстати, особенность верстки в React Native - это возможность легко брать высоту и ширину экрана с помощью модуля Dimensions:

const height = Dimensions.get('window').height
const width = Dimensions.get('window').width


Ну а к верстке флексами привыкаешь быстро. Важно помнить, что если у блока не заданы ширина, высота или флекс > 0, то все внутренние элементы не будут показаны (!).

Не могу не упомянуть еще одну вещь, которую вы непременно будете использовать в своем приложении, - это генерация иконок приложения для Android и iOS. Их нужно иметь тысячу и одну, чтобы приложение красиво выглядело на любом устройстве. К счастью, имея всего node 6 и ImageMagick, а также исходное изображение не менее 200х200 пикселей, через командную строку можно получить все мыслимые и немыслимые иконки. В двух словах трех командах:

npm install -g yo generator-rn-toolbox
brew install imagemagick
yo rn-toolbox:assets --icon <path to your icon>


Дополнительные javascript библиотеки:

  • ramda - из полезного: работа с различными структурами данных, линзы.
  • moment - работа с датами.

Так как код выполняется с помощью javascript, то здесь может быть любой набор библиотек на усмотрение разработчика.

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

  Подводные грабли:


Возможные ошибки в iOS:

- при создании билда в XCode сборка попадает в Other Items, из-за чего нельзя залить в AppStore.
Ошибка возникает из-за дополнительных библиотек, которые вы используете в проекте; при сборке они собираются не как используемые библиотеки, а самостоятельные проекты. Решение: во все проектах, которые находятся в Library нужно выставить
"Build Setting": Skip install = yes

- отсутствие обновления проекта при его изменении, "зависания" и прочие непредсказуемости
Одна из возможных причин кроется в том, что "clean project" в XCode не полностью удаляет создаваемые им временные файлы. Решение: удалить временные файлы вручную. Находятся они в директории:
cd /Users/[local machine]/Library/Developer/Xcode/DerivedData/

- при создании Архива для AppStore XCode ругается на дублирование файлов
Такое может произойти если вы используете pod и в нем реакт со своими компонентами, а так же часть из них напрямую из node_modules. Решение: исключить файлы при сборке проекта, добавив в ios/Podfile:

post_install do |installer|

  installer.pods_project.targets.each do |target|
    if target.name == "React"
      target.remove_from_project
    end
  end
end


Для Андроида желательно привести все используемые библиотеки к одной версии.

Заключение


Дорогу осилит идущий.

Разработка приложений на React Native - это удивительный процесс открытия новых вершин и радости от того, как по-другому могут строится вещи для других платформ. Это новый, еще только зарождающийся мир, в котором ты - первооткрыватель, пусть даже порой - первооткрыватель документации.

И осилив азы, можно приступать к проектированию своего первого приложения, задавая себе все новые и новые вопросы:

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

    воскресенье, 1 января 2017 г.

    Лучшее из 2016

    Очень насыщенный и, возможно, в чем-то продуктивный был год. Из запланированных хотелок осуществились следующие:
    1. прошла достойный курс на coursera
    2. прошла хороший курс по рисованию персонажей и работе с цветом
    3. вышли на большой конкурс по бальным танцам. Пусть и не заняли мест, но был опыт.
    4. прочитала еще несколько хороших книг, если Дозоры считать неплохим чтивом =)
    Ну и конечно лучшее в 2016 году:
    Online курсы
    4 курса из специализации "Create Imaginative Games" (CalArts)
    Курсы
    Харьковский летний интенсив: Academic Painting, Photoshop, Character Design, ZBrush Tools
    Книга
    "Дозоры" Лукьяненко
    Игра
    WoW
    Блюдо
    Макаруны
    Activity
    Сноуборд, катание на яхте
    Мультфильм
    Зоотрополис
    Конференция
    ОдессаJS, ХарьковJS
    Город
    Стамбул, Минск, Санкт-Петербург, Гродно
    Страна
    Республика Белорусь, Греция (Крит), Италия
    Курорт
    Буковель, Драгобрат, Валь ди Фасса
    Достижение
    Участие в кубке мэра г. Днепропетровска
    Очень насыщенные рисованием и творчеством выдались весна и лето. Теперь главное, не растерять это и не забросить =)

    В целом год получился невероятно богат на впечатления и путешествия. Из более серьезных планов на этот год:
    - начать изучать какую-нибудь новую технологию. ReactNative, why not?
    - завершить домашний проект на реакте, двигаться дальше
    - прочитать еще несколько достойных книг
    - и попробовать что-нибудь еще в первый раз =)

    четверг, 10 марта 2016 г.

    CSS Bliss: основные особенности методологии

    Среди множества методологий организации стилей (BEM, SMACSS, OOCSS, SUITECSS) хочется отдельно выделить одну: CSS Bliss. Это квинтэссенция удобства использования и читабельности.

    Для начала определимся в основных понятиях: модуль, элемент и модификатор. Эти определения наиболее близки БЭМу, за исключением того, что Модулем в CSS Bliss именуется Блок. Далее будет понятно, почему Модуль - более подходящее значение. В целом сама методология очень близка к БЭМу, но имеет свои особенности, о которых стоит поговорить отдельно, потому что именно они позволяют стать CSS Bliss на ступеньку выше остальных.



    Основные отличия CSS Bliss:

    1. Именование модуля, элементов и модификаторов:

    Если в БЭМе основными разделительными частицами выступают "-" и "_":

    .my-module__my-element_modifier

    то CSS Bliss улучшает читабельность путем использования заглавных букв:

    .MyModule-myElement--modifier

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

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

    <li class="custom-user-menu__list-item_size-normal"></li>

    <li class="CustomUserMenu-listItem--sizeNormal"></li>

    Первый БЭМовский вариант длиннее и сложнее в прочтении. Особенно сливается модификатор с названием элемента. Второй (CSS Bliss) более компактен и визуально разделен на понятные компоненты: модуль, элемент и модификатор. При чем отличие в первой букве моментально дает понимание что перед нами: модуль или элемент (модуль начинается с заглавной, а элемент - со строчной).

    Если я вас еще не убедила, вот еще один пример из документации БЭМа для модификаторов "ключ - значение":

    .block-name__elem-name_mod-name_mod-val

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

    2. Позиционирование компонентов.

    Модуль независим и самодостаточен сам по себе. Он должен выглядеть одинаково в любом месте и при любом разрешении, именно поэтому он имеет одно важное ограничение: модуль не должен содержать в себе свойства, которые бы жестко задавали его позиционирование, а именно: размеры (width), внешние отступы (margin) и позиционирование по отношение к другим элементам (position). Эти свойства должны задаваться либо в модификаторе модуля либо этот модуль так же является элементом внешнего блока, который (элемент) и определяет его положение.

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

    3. Организация структуры

    Несмотря на удобство организации файловой структуры в БЭМе, он предполагает излишне дробное деление: каждый модификатор и элемент выносится в отдельный файл. Пример:

    blocks
    ├─── popup
    |    ├──── _target
    |    |    ├──── popup_target.css
    |    |    ├──── popup_target_anchor.css
    |    |    └──── popup_target_position.css
    |    └──── _visible
    |         ├──── popup_visible.css
    |         ├──── popup.css
    |         └──── popup.js


    Тогда как в CSS Bliss предполагает создавать файлы только для модулей, а его внутренние элементы и модификаторы описывать внутри этого же файла, так как вне его они не имеют смысла:

    css
    ├─── modules
    |    ├──── _PopupDialog.scss
    |    ├──── _Btn.scss
    |    └──── _ElmInfo.scss
    ├─── _base.scss
    ├─── _colors.scss
    ├─── _mixins.scss
    ├─── _zindex.scss
    └─── application.scss


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

    4. Состояние элемента: state

    Очень часто нам нужно определять состояние элемента или модуля: активный, скрытый, доступный, использованный и проч. Использование для этого модификатора не только загромождает читаемость html, но и загрязняет javascript.

    Пример на БЭМе:

    <div class="my-module__my-mlement my-module__my-mlement_my-modifier-with-state"></div>

    Пример на Bliss CSS:

    <div class="MyModule-myElement isState"></div>

    В последнем примере мы используем для изменения состояния в js не длиное название модификатора: "my-module__my-mlement_my-modifier-with-state", а привычное и универсальное "isState". Из-за того, что состояние определяется только для конкретного модуля или элемента, оно обладает локальным воздействием на него. А универсальное наименование состояния позволяет при необходимости переиспользовать js-код для различных элементов страницы.

    5. Использование @extend

    Лично я - противник использования такой возможности sass как расширение классов с помощью @extend. Главные требования к CSS должны быть:
    • простота
    • читабельность
    • легкоизменяемость

    С помощью @extend вы расширяете исходные классы дополнительным кодом, при чем из любого другого места. Несмотря на кажущуюся простоту концепции, @extend в корне противоречит отновному принципу каскадности стилей; им сложно управлять и читать. Неудивительно, что Bliss CSS запрещает использование @extend для классов и элементов.

    6. Документация

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

    Это лучшая прикладная документация, которую я встречала.

    Выводы

    Несмотря на большую популярность БЭМа в последнее время, CSS Bliss по всем вышеуказанным причинам гораздо практичнее. И как и прочие методологии она вырабатывает привычку думать не в разрезе страницы, а в терминах компонентов: модули, элементы, модификаторы; что делает процесс написания css'a более осознанным, так как от привильного разбиения на компоненты зависит не только красота кода, но и жизнеспособность стилей в будущем.

    четверг, 18 февраля 2016 г.

    Прогноз погоды в консоли

    Замечательный погодный сервис в твоей консоли:
    
    curl http://wttr.in
    



    Можно прописать алиас:
    
    alias weather='function _weather(){ curl http://wttr.in/$1 };_weather'
    

    и после этого набирать в консоли (для текущей локации, города или помощи):
    
    weather
    weather London
    weather :help
    

    Команды Emacs

    При работе в консоли мы используем команды Emacs, но редко когда что-то сложнее [CTRL-R] для поиска по истории. Хотя зачастую возникает неп...