Zellij — обновленный tmux на расте

Нарисовано специально для runhub.today

20241014_084526_e96ffe.webp

Настройка WordPress + GraphQL + Next.js

Когда-то давно, примерно лет 12 назад, я много работал с WordPress. Хотя он всегда позиционировал себя CMS для блогов, многие делали на нем не только блоги, потому что WordPress предоставлял удобную админку. Темы и плагины писать тоже было удобно. Но с развитием фронтенда со всеми сборщиками, реактами и полной сепарацией от бэкенда, возникла проблема: темы WP всегда были неотделимы от него, а фронтенд становился сложнее. В результате верстать и писать логику на js стало неудобно.

Спустя много лет, я решил посмотреть как же развивается WordPress и с удивлением обнаружил, что он теперь у него есть api. Более того, теперь можно запрашивать данные не только через REST API, но из GraphQL.

Изменилось все, даже способ установки. Так, к примеру, для установки WordPress на локальной машине можно использовать Docker образ для WordPress. Появились решения вроде LocalWP, Kinsta позволяющие запускать WordPress на локальной машине в один клик.

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

По url https://yourdomain/wp-json/ доступен список всех роутов.

20241014_084614_8395c6.webp

С помощью плагина WPGraphQL можно добавить поддержку GraphQL.

20241014_084634_6ccae6.webp

Ниже опишу пример создания блога на WordPress + Nextjs.

Установим wordpress. Я использовал LocalWP.

20241014_084653_019a22.webp

Выбираем Create a new site и прокликиваем опции, оставляя все настройки по умолчанию. В результате, работающий на локальной машине WordPress должен выглядеть вот так. Нам нужен адрес сайта: notes.local.

20241014_084711_89d968.webp

Если хотите использовать сразу production сервер, могу посоветовать railway.app. Для простого пет-проекта подойдет бесплатный тариф.

После развертывания проекта, нам потребуется url, по которому будет доступен WordPress. В моем случае это dailynotes.up.railway.app.

20241014_084734_dc26f7.webp

Этот адрес сайта потребуется нам для запросов. Его следует вынести в .env файл, а сам файл добавить в .gitignore, чтобы этот файл не попал на github. Одна из причин по которой так следует делать: чтобы разные настройки не перемешивались. Например, на локальной машине у вас может быть один адрес сайта, а на продакшене другой. Другая причина — в .env файлах можно хранить ключи доступа, которые не должны быть доступны публично.

Следующим шагом устанавливаем nextjs: npx create-next-app@latest.

В корневой директории проекта я сделал файл .env.local и добавил туда url сайта:

NEXT_PUBLIC_WORDPRESS_API_URL=https://dailynotes.up.railway.app

В этом примере я использую сразу путь к сайту на railway. Потому что кроме установки плагина я не планирую никаких изменений в WordPress и хочу сразу получать настоящие данные со своего блога.

Для получения данных мы создадим в корневой файл ./helpers/api.js:

const API_URL = `${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/graphql
async function fetchAPI(query = '', { variables } = {}) {
const headers = { 'Content-Type': 'application/json' }
const res = await fetch(API_URL, {
headers,
method: 'POST',
body: JSON.stringify({
query,
variables,
}),
})
const json = await res.json()
if (json.errors) {
console.error(json.errors)
throw new Error('Failed to fetch API')
}
return json.data
}
export async function fetchNotes() {
const data = await fetchAPI(`
query FetchNotes {
posts(where: {status: PUBLISH}) {
nodes {
id
title
content
date
}
}
}
`)
return data?.posts
}

fetchAPI предназначена для выполнения асинхронных запросов к API с использованием метода POST. Она принимает два аргумента: query (по умолчанию пустая строка) и объект параметров с именем variables (по умолчанию пустой объект).

Для получения постов мы будем использовать fetchNotes(), которая в свою очередь будет использовать функцию fetchApi(). На странице ./page.js можно будет вызвать fetchNotes(), чтобы запросить данные:

import { fetchNotes } from '@/app/helpers/api'
export default async function Home() {
const notes = await fetchNotes()
return (
<section>
{notes.nodes.map((note) => {
return (
<article className="note" key={note.id}>
<h2>{note.title}</h2>
<div className="note-content" dangerouslySetInnerHTML={{ __html: note.content }}></div>
</article>
)
})}
</section>
)
}

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

От умных часов к глупым. Apple Watch, старая советская Seconda и Casio G-Shock

Upd: пост был написан 09 января 2022.

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

Около двух лет я носил Apple Watch Series 3. Носил их и днём и ночью, делая перерывы лишь на подзарядку. Но спустя какое-то время мне надоело заряжать каждый день, получать на них уведомления (даже если отключить звук и вибрацию, остается видна красная точка-индикатор), ставить на них обновления их и думать, что вот вышли новые часы и вот мои S3 уже не так хороши.

20241014_084815_9ef304.webp
Apple Watch 3

В какой-то момент я просто снял Apple Watch и больше не надевал. Поначалу без часов было немного странно. Мне очень нравилось что:

— ничего не надо заряжать
— если оставить телефон в другой комнате, то ничто не может меня побеспокоить. И тут важен именно психологический момент: нужно осознано взять и оставить телефон далеко. Не перевести его в беззвучный, а именно где-то оставить, чтобы иногда не заглядывать в него «а вдруг что-то важное».

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

20241014_084837_041184.webp
Часы Seconda

Однажды на Авито наткнулся на продажу старых советских часов Seconda. Это механические часы на калибре 2609. Очень милые и простые часы. Я носил их несколько месяцев, пока случайно не открутил с вала заводную головку. Заводить часы всё так же не составляло проблем. Проблема возникла при корректировке времени — ее невозможно было сделать (удобным способом). Особенность в том, что их суточная погрешность -20/+40 секунд. То есть раз в два-три дня приходилось изворачиваться, чтобы скорректировать время.

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

В какой-то момент я даже начал собирать коллекцию часов, которые мне нравятся, на Pinterest. В этой коллекции есть как доступные по цене модели, так и те, которые никак не вписываются в разумные траты. Все часы из этой коллекции выглядят красиво (для меня конечно же, коллекция-то моя 😀 ), но не все они функциональны. Это те самые часы, в которых можно пойти на встречу, в кафе или в гости. Они хорошо дополняют вечерний взрослый наряд. Но хотелось чего-то повседневного. Того, что можно носить не снимаю. Купаться, работать во дворе и не бояться сломать. К тому же они должны стоить не слишком дорого, чтобы в случае их поломки, не нужно было копить пару лет, а просто пойти и купить другие без ощутимого ущерба для бюджета.

20241014_084859_51a697.webp
Casio G-Shock GA-2110SU-3A

Размышляя о приоритете функциональности над эстетикой я пришел к Casio G-Shock. Моя модель GA-2110SU-3A, она показалась мне одной из самых простых и имеет небольшую толщину по сравнению с остальными версиями джишоков.

Сравнивая их с Apple Watch, хочу сказать, что несмотря на практически одинаковый вес (AW – 52.8гр, G-Shock – 51гр), они ощущаются легче. Возможно из-за вида ощущения пластика, но ощущаются легче. К каучуковому ремешку Джишоков после силиконового или текстильного ремешков AW пришлось привыкать. Он жестковат и хотелось бы его немного разносить, смягчить. Но спустя месяц носки, мне кажется, что это отличный ремешок. Часы на руке сидят немного свободно и мне это удобно.

Джишоки — это просто часы, которые показывают время. Батарейки должно хватить на сколько-то там лет. На сайте Casio заявлено три года работы от батарейки, но там посмотрим.

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

Вот пример того, как светятся стрелки, если зайти в темноту из хорошо освещенной комнаты.

20241014_084933_aafa6a.webp
Casio G-Shock GA-2110SU-3A

20241014_084956_15aa04.webp
Casio G-Shock GA-2110SU-3A

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

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

Радует, что эти часы абсолютно не зависят от телефона. Они самодостаточны. Это просто часы.

Краткий пересказ книги «Ловушки мышления» (Чип Хиз и Дэн Хиз)

Нормальный процесс принятия решений выглядит следующим образом:

— вы сталкиваетесь с необходимостью выбирать;
— вы анализируете варианты;
— вы делаете выбор;
— а затем вы с этим живете.

В книге четыре стадии процесса принятия решений обозначаются аббревиатурой WRAP (Widen, Reality-test, Attain distance, Prepare). В русском варианте это могло бы звучать так:

— Расширьте границы выбора;
— Проверьте в реальных условиях;
— Дистанцируйтесь;
— Приготовьтесь.

Вы сталкиваетесь с необходимостью выбирать

Узкие рамки

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

Пример: Хочу в кино и на вечеринку. Но надо выбрать что-то одно. Стоит ли мне идти на вечеринку или нет?

А почему бы не заглянуть на вечеринку совсем на чуть-чуть, а потом поехать в кино? Вариант «и то, и другое» мы почему-то отсеяли, сведя выбор к «или».

Фиктивные варианты

Вторая крайность — слишком много вариантов. Среди них могут быть «фиктивные», склоняющие вас к выбору, который выгоден не вам.

Заимствуйте опыт

Может пока вы ищите альтернативы, кто-то уже решил вашу проблему. Поищите того, у кого перенять передовой опыт.

Вы анализируете варианты

При анализе вариантов происходит сбор данных. Почему вариант А лучше Б?

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

Пример: в институте канонизации существовала должность укрепителя веры (адвоката дьявола). Его функция заключалась в том, чтобы собрать аргументы, которые могли бы помешать канонизации или беатификации праведника.

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

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

Вы делаете выбор

Выбирать нужно умом, а не сердцем. Эмоции провоцируют нас на неверный выбор.

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

А еще: «спешите купить, эта модель последняя». Мы не любим терять. Ощущение потери для нас болезненно и не компенсируется ощущением удовольствия от равнозначной выгоды.

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

Дистанцируйтесь

Попробуйте посмотреть на ситуацию из вне. Допустим, выбор нужно сделать не вам, а другу. Чтобы вы ему посоветовали в этом случае?

Можно дистанцироваться с помощью правила 10/10/10: станет ли для меня это важно через 10 минут/ 10 месяцев/ 10 лет?

Однако успокоение эмоций может не облегчить решение. Если разум говорит одно, а сердце другое, это означает конфликт приоритетов. Подумайте что вы хотите. Составьте список «прекратить делать», в котором опишите что отбросить, чтобы сосредоточиться на приоритетах. Заведите будильник, который будет периодически звонить, побуждая вас задать вопрос «а тем ли я занят?» Это поможет перестать двигаться на автопилоте и осознать выбор.

Изменения происходят постепенно и мы можем не замечать их. Чтобы не двигаться на автопилоте лучше определять сроки.

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

А затем вы с этим живете

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

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

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

Пример: вы хотите повышения зарплаты. Вы решаете обсудить это с шефом. Что может произойти в результате вашего общения?

— вам повысят зарплату
— вы получите отказ
— повысят зарплату, но не настолько, насколько вы хотели

Когда вы готовитесь к разговору, прокрутите в голове альтернативные исходы разговора. Что делать в каждом из возможных исходов?

Вывод: принятие решения — процесс, который можно разложить на этапы: поиск вариантов, сбор данных, выбор… А потом вы с этим живете.

Настройка MacOS

Этот список переходит из блога в блог и играет роль хранилища ссылок. Программы устаревают, обновляются и все повторяется по кругу.

Самая полезная ссылка — Mac OS X Setup Guide.

В первую очередь

— Atom => VS Code, neovim
iTerm, Warp
— Wunderlist => Singularity

Мессенджеры

— Skype
— Slack
— Telegram

Браузеры

Firefox

Графические программы

— Adobe Photoshop => Pixelmator

Утилиты

Macs Fan Control
The Unarchiver
Transmission
Spotify
VLC Player
Xcode: xcode-select --install

Настройка системы

Mac OS X Setup Guide

Homebrew
ohmyz.sh + .zshrc config
— Git: brew install git
NodeJS

JavaScript. Функции, типы данных и методы работы с ними

Примечание: Это статья — конспект моей лекции. В ней описываются ключевые понятия.

Типы данных

Примитивные типы данных в JavaScript:

number: числовое значение, например, 5 или 3.14.
string: строковое значение, например, "Привет" или 'Мир'.
boolean: логическое значение, true или false.
null: специальное значение, представляющее отсутствие значения.
undefined: значение, которое не было присвоено.
symbol (в ECMAScript 6): уникальное и неизменное значение.

Объекты

Объекты в JavaScript представляют собой коллекции пар ключ-значение, где ключи – это строки (или символы), а значения могут быть любого типа данных, включая другие объекты, массивы и функции.

const person = {
name: "John",
age: 30,
isAdmin: false,
greet: function() {
console.log(`Привет, меня зовут ${this.name}!`);
}
};
console.log(person.name); // Вывод: John
console.log(person.age); // Вывод: 30
person.greet(); // Вывод: Привет, меня зовут John!

Объекты могут быть созданы с использованием фигурных скобок {} и заполнены парами ключ-значение.

Доступ к свойствам объекта можно получить с помощью оператора . или квадратных скобок [].

console.log(person.name); // Вывод: John
console.log(person["age"]); // Вывод: 30

Свойства объекта могут быть добавлены или изменены после его создания.

person.country = "USA"; // Добавление нового свойства
person.age = 31; // Изменение значения существующего свойства

Свойства объекта могут быть удалены с помощью оператора delete.

delete person.isAdmin; // Удаление свойства

Свойства объекта могут быть перебраны с использованием циклов или методов перебора.

// Цикл for..in
for (let key in person) {
console.log(key + ": " + person[key]);
}
// Метод Object.keys()
const keys = Object.keys(person);
console.log(keys); // Вывод: ["name", "age", "country"]

Существование свойств в объекте можно проверить с помощью оператора in или метода hasOwnProperty.

console.log("name" in person); // Вывод: true
console.log(person.hasOwnProperty("age")); // Вывод: true

Копирование объектов может быть выполнено с использованием различных методов, таких как Object.assign(), оператор распространения (...) или конструктор Object.

// Object.assign()
const copiedPerson1 = Object.assign({}, person);
// Оператор распространения (spread operator)
const copiedPerson2 = { person };
// Конструктор Object
const copiedPerson3 = new Object(person);

Массивы

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

Массивы могут быть созданы с использованием литерала массива [] или с помощью конструктора new Array().

const numbers = [1, 2, 3, 4, 5]; // Массив чисел
const names = ['John', 'Alice', 'Bob']; // Массив строк
const mixedArray = [1, 'two', true]; // Массив смешанных типов данных
const emptyArray = []; // Пустой массив
// Создание массива с помощью конструктора
const fruits = new Array('apple', 'banana', 'orange');

Элементы массива можно получить, используя индекс элемента. Индексы массивов начинаются с 0.

console.log(numbers[0]); // Вывод: 1console.log(names[1]); // Вывод: Alice

Элементы могут быть добавлены в конец массива с помощью метода push() и удалены с помощью метода pop(). Также элементы могут быть добавлены и удалены из начала массива с помощью методов unshift() и shift().

const colors = ['red', 'green', 'blue'];
colors.push('yellow'); // Добавление элемента в конец массива
console.log(colors); // Вывод: ['red', 'green', 'blue', 'yellow']
colors.pop(); // Удаление последнего элемента массива
console.log(colors); // Вывод: ['red', 'green', 'blue']

Массивы могут быть перебраны с использованием различных методов, таких как цикл for, метод forEach(), цикл for...of и др.

// Использование цикла forfor (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
// Использование метода forEach()
numbers.forEach((number) => {
console.log(number);
});
// Использование цикла for…of
for (let number of numbers) {
console.log(number);
}

JavaScript предоставляет множество встроенных методов для работы с массивами, таких как concat(), slice(), indexOf(), filter(), map() и многие другие. Эти методы предоставляют функциональность для добавления, удаления, изменения и фильтрации элементов массива.

const numbers1 = [1, 2, 3];
const numbers2 = [4, 5, 6];
const combinedNumbers = numbers1.concat(numbers2); // Объединение массивов
console.log(combinedNumbers); // Вывод: [1, 2, 3, 4, 5, 6]
const slicedNumbers = combinedNumbers.slice(2, 4); // Вырезка подмассива
console.log(slicedNumbers); // Вывод: [3, 4]
const index = combinedNumbers.indexOf(5); // Поиск индекса элемента
console.log(index); // Вывод: 4

Прототипы

Это механизм, который позволяет объектам наследовать свойства и методы других объектов. Каждый объект в JavaScript имеет ссылку на свой прототип, которая используется для поиска свойств и методов, которые не определены непосредственно в самом объекте.

Как работают прототипы:

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

Если свойство или метод не найдены в прототипе объекта, JavaScript продолжает поиск в прототипе этого прототипа, и так далее, пока не будет найдено нужное свойство или метод, либо цепочка прототипов не достигнет конечного объекта null. Эта цепочка прототипов называется “цепочкой прототипов” (prototype chain).

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

// Создание объекта с помощью литерала объекта
const animal = {
type: 'Animal',
sound: function() {
console.log('Издает звук');
}
};
// Создание нового объекта с использованием animal в качестве прототипа
const dog = Object.create(animal);
dog.type = 'Dog'; // Переопределение свойства type для объекта dog
// Вызов метода из прототипа animal
dog.sound(); // Вывод: Издает звук
// Проверка, является ли animal прототипом для dog
console.log(Object.getPrototypeOf(dog) === animal); // Вывод: true

Функции

Позволяют переиспользовать код, упрощают поддержку и читаемость.

Могу быть объявлены несколькими способами.

Function declaration

// Используем ключевое слово function
function greet(name) {
return Hi ${name}
}

Function expression

// Используем стрелочную функци
const greet = (name) => {
return Hi ${name}
}

Функции могут принимать параметры и возвращать значения. Возвращаемое значение — это результат выполнения функции. Этот результат может быть передан обратно в вызывающий код.

const summ = (x, y) => {
return x + y
}
const log = () => {
console.log(summ(1, 2))
}
log() // Результат вывода: 3

Callback functions

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

const button = document.querySelector('#myButton')
function handleClick() {
console.log('Кнопка нажата')
}
button.addEventListener('click', handleClick)

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

В чем проблема? Вложенные callback-функции могут привести к нечитаемому и трудно поддерживаемому коду, известному как “callback hell”. Этого можно избежать, используя методы, такие как Promises или async/await, которые предлагают более линейный и читаемый подход к обработке асинхронного кода.

Пример “callback hell”:

function fetchData(url, callback) {
setTimeout(() => {
const data1 = 'Данные 1';
callback(data1, (data1, callback) => {
setTimeout(() => {
const data2 = 'Данные 2';
callback(data2, (data2, callback) => {
setTimeout(() => {
const data3 = 'Данные 3';
callback(data3);
}, 1000);
});
}, 1000);
});
}, 1000);
}
fetchData('https://example.com/api', (data1, callback) => {
console.log(data1);
callback(data1, (data2, callback) => {
console.log(data2);
callback(data2, (data3) => {
console.log(data3);
});
});
});

Пример использования промисов для асинхронных запросов:

function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Данные';
resolve(data);
}, 1000);
});
}
fetchData('https://example.com/api')
.then((data1) => {
console.log(data1);
return fetchData('https://example.com/api');
})
.then((data2) => {
console.log(data2);
return fetchData('https://example.com/api');
})
.then((data3) => {
console.log(data3);
})
.catch((error) => {
console.error('Произошла ошибка:', error);
});

Этот код использует промисы для выполнения асинхронных операций и избегает “callback hell”, предоставляя более линейный и читаемый подход к обработке асинхронных запросов. Каждый .then() блок представляет собой следующую операцию после успешного выполнения предыдущей. Если происходит ошибка, она обрабатывается в блоке .catch().

Прототипы и функции

В JavaScript функции также являются объектами, и у них также есть прототипы. Функции имеют свойство prototype, которое используется при создании объектов с помощью оператора new. Когда объект создается с использованием конструктора функции, прототип этой функции становится прототипом создаваемого объекта.

// Определение конструктора функции
function Person(name) {
this.name = name;
}
// Добавление метода в прототип функции Person
Person.prototype.greet = function() {
console.log(`Привет, меня зовут ${this.name}!`);
};
// Создание объекта с использованием конструктора Person
const person1 = new Person('John');
const person2 = new Person('Alice');
// Вызов метода из прототипа функции Person
person1.greet(); // Вывод: Привет, меня зовут John!
person2.greet(); // Вывод: Привет, меня зовут Alice!

Картина Три тигра

20241014_085054_2e8220.webp

Привет, мир!

Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!

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

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

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