Заряд
Ваш собственный ресурс, а не батарея телефона. Четыре состояния, время между переключениями и картинка на рабочий стол.

Зачем этот экран
Приоритеты отвечают на вопрос «куда ушло время». Этот экран отвечает на другой: в каком состоянии оно уходило. Четыре часа работы на полном заряде и четыре часа на нуле — это разные четыре часа, и без второй величины первая обманывает.
Единица здесь не клик, а переключение. Вы отмечаете состояние, когда оно действительно изменилось; приложение считает время между отметками. Один тап утром описывает всё утро.
Что на экране
- Герой — большая батарея текущего состояния, его название и строка «Сегодня в этом состоянии — …». Сразу после первой отметки вместо времени стоит «Отсчёт пошёл».
- «Как вы сейчас» — четыре состояния подряд: «Полный заряд», «Средний», «На нуле», «Заряжаюсь». У каждого — расшифровка и время, набранное сегодня.
- «Сегодня» — полоса, разбитая по долям состояний за сутки. Появляется, когда за сегодня есть что делить.
- «Отметки за день» — лента из четырнадцати дней и список переключений выбранного дня: время, состояние и сколько оно продержалось.
- «Поставь заставку на рабочий стол» — генератор обоев.

Что означают четыре состояния
| Состояние | Смысл |
|---|---|
| Полный заряд | Есть силы на сложное. Беритесь за то, что требует головы. |
| Средний | Рабочее состояние. Тянете рутину, но не подвиги. |
| На нуле | Ресурс кончился. Всё, что делается, делается через силу. |
| Заряжаюсь | Восстанавливаетесь: сон, тишина, прогулка, ничегонеделание. |
«Заряжаюсь» — не четвёртый уровень шкалы, а другое измерение: это занятие, а не величина. Поэтому в средний заряд дня оно не входит вовсе (подробнее — в статистике).
Как этим пользоваться
Отметить состояние
Нажмите на нужную строку. Повторное нажатие на уже выбранное состояние ничего не делает — это не событие.
То же можно сделать с любой вкладки, нажав батарею в шапке: она стоит и на главном экране, и в статистике, и в навыках, и в настройках. Шторка там та же, и вопрос про расход из неё задаётся тоже.
Ответить, что посадило батарею
При переходе на «на нуле» появляется вопрос.

Одно касание — и ответ уходит в отдельную статистику («Что сажает батарею»). Ответ «Не знаю» — тоже ответ, он считается наравне с остальными.
Если энергию съело то, чего в приоритетах нет — дорога, чужая просьба, недосып, — напишите это в поле под списком и нажмите стрелку (или Enter). Ответ станет отдельной строкой в статистике, а одинаковые тексты сложатся в одну: «недосып», названный трижды, покажет «3 раза». Длина ограничена 40 знаками — это подпись строки, а не дневник.
Кнопка «Пропустить» три секунды заблокирована и показывает отсчёт: она появляется ровно там, где палец уже стоит после выбора «на нуле», и без паузы нажималась бы рефлекторно. Ответить можно сразу — задержка касается только пропуска.

Пока отсчёт идёт, шторку нельзя закрыть ни фоном, ни системной «назад» — иначе задержка на кнопке ничего не значила бы.
Дописать или исправить отметку
Классический случай: легли спать и забыли переключить на «Заряжаюсь» — вся ночь засчиталась как то состояние, в котором вы были вечером.
Выберите день в ленте «Отметки за день» и нажмите «Добавить отметку»: время и состояние. Всё, что было после неё, пересчитается само — отмечается момент переключения, а не отрезок, поэтому одна отметка в 23:00 чинит всю ночь.
Нажатие на существующую отметку открывает её же: можно передвинуть время, поменять состояние или удалить.
Над списком стоит строка «С начала суток — …»: она показывает состояние, перенесённое с прошлого дня. Без неё день, в котором ничего не переключали, выглядел бы пустым, хотя всё это время человек в каком-то состоянии был.
Причина «на нуле» переезжает вместе с отметкой, но исчезает, если поменять состояние: у полного заряда причины разряда быть не может.
Сделать обои

Нажмите «Сделать обои с зарядом», выберите состояние и размер экрана. Подробности, включая три способа сохранения, — на странице «Обои с зарядом».
Пустое состояние

Пока не сделано ни одной отметки, батарея приглушена, а вместо времени стоит объяснение: отсчёт начнётся с первого выбора.
Пределы и предупреждения
- Отмечайте изменение, а не факт. Если вы отметили «полный заряд» утром и больше не трогали приложение, все сутки засчитаются как полный заряд — включая ночь.
- Состояние переходит через полночь: отметка в пятницу вечером без последующих изменений засчитывается и на субботу, и на воскресенье.
- Сегодняшний день считается только до текущего момента, вечер не начисляется авансом.
- Вопрос «что съело энергию» появляется, только если в списке есть хотя бы один приоритет: иначе это пустая модалка.
Чего здесь нельзя
- Отметить заряд глубже четырнадцати дней назад. Столько же, сколько у блоков: дальше уже не вспомнить.
- Отметить будущее. Лента предлагает только прошедшие дни и сегодня.
- Задать длительность напрямую. Отмечается момент переключения; длительность всегда считается между соседними отметками.
- Добавить своё состояние. Их ровно четыре, и они зашиты.
- Посмотреть неделю или месяц. Здесь только сегодня; разборы — в статистике.
Рядом
Статистика · Обои с зарядом · Приоритеты
Как это работает внутри
- Экран —
src/screens/ChargeScreen.tsx. Уровни —BATTERY_LEVELS = [3, 2, 1, 4]вsrc/domain/types.ts; порядок именно такой, потому что это порядок показа, а числа — то, как состояние лежит в хранилище. - Хранится не состояние, а список переключений:
BatteryShift— это[минута_дня, уровень]либо[минута_дня, уровень, чем_посажен]. Третий элемент необязателен по типу, поэтому записи, сделанные до появления вопроса, читаются без миграции. - Правка списка смен — чистые
setShiftиremoveShiftвsrc/domain/battery.ts, покрытыеsrc/domain/battery.test.ts. Редьюсер (battery-set,battery-removeвsrc/store/useStore.tsx) только зовёт их и выкидывает опустевший день из журнала, чтобы он не считался днём «с отметками». - Повтор того же уровня отбрасывается в
setBattery, а не в редьюсере: это правило живого нажатия. Задним числом такая отметка бывает осмысленной — например, когда вечернее состояние надо явно продлить после ночной паузы. - Время между отметками считает
computeBatteryStats(src/domain/stats.ts). Она же переносит состояние через полночь (levelEnteringDay) и обрезает сегодняшний день поminuteOfDay(now). Строку «с начала суток» на экране даёт экспортированнаяlevelBeforeиз того же файла. - Лента дней — общий
src/components/DayPicker.tsx. Он принимает предикатhasEntries, а не журнал: лента одна и та же для кликов и для заряда, а «непустой день» у них значит разное. - Ответ «что посадило» прикрепляется к последней отметке дня; если сегодня отметок ещё нет, действие уходит на ближайший предыдущий день с отметками (случай
drainтам же) — это случай «спросили в 23:59, ответили в 00:01». - «Не знаю» хранится как
DRAIN_UNKNOWN = '?', а не пустая строка: пустая была неотличима от «ответа нет» при сериализации и пропадала при перезагрузке. - Ответ своими словами хранится там же, с префиксом
DRAIN_TEXT_PREFIX = '!'(drainCustom/drainTextOfвsrc/domain/types.ts). Префикс, а не отдельное поле: id приоритетов состоят из букв и цифр, поэтому по первому знаку всегда видно, ссылка это или чужая причина. Предел —DRAIN_TEXT_MAX = 40, и разбор месяца режет длину повторно, потому что файл копии мог приехать чужим. - Смена заряда живого времени идёт через один
usePickBattery(src/components/BatteryPrompt.tsx), и вопрос задаётся там же. До этого он жил внутри экрана «Заряд», и та же смена на «на нуле» из батарейки в шапке проходила молча — статистика причин зависела от того, каким путём отметили состояние. - Задержка пропуска —
SKIP_DELAY_SECONDS = 3вsrc/components/DrainSheet.tsx.