Четыре способа вернуть потерянное: отмена, версии, корзина и защита от перезаписи

Productivity

Есть программные ошибки, в которых пользователи винят себя. Нажали не ту клавишу, заметка пропала, и первая мысль не «приложение должно было это предусмотреть», а «надо было быть внимательнее».

Быть внимательнее вы не обязаны. Приложение для заметок нужно ровно для того, чтобы перестать держать всё в голове. Если оно иногда теряет заметку, оно нарушает своё единственное обещание.

В Notez четыре отдельных механизма восстановления. Они не дублируют друг друга: каждый закрывает сбой, который не закрывают остальные, и работает на своём отрезке времени.

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

⌘Z — уровень, которым пользуются не задумываясь. Он отменяет пять конкретных действий:

  • Удаление — вы переместили заметку в корзину

  • Перемещение карточки — вы перетащили карточку в другую колонку доски

  • Изменение свойства — вы задали или очистили значение пользовательского свойства

  • Быстрое сохранение — вы что-то сохранили и сразу пожалели

  • Перенос напоминания — вы перетащили напоминание на другой день в календаре

Стек хранит двадцать действий. Каждая запись содержит ровно то, что нужно для отмены: для перемещения карточки — колонку и позицию, откуда она пришла, в том числе если карточка лежала в «Без колонки».

Три детали в поведении отмены сделаны намеренно.

Удаление и сохранение показывают всплывающее уведомление, перемещение карточек — нет. Если показывать уведомление на каждое перетаскивание, с доской станет невозможно работать. Перемещение по-прежнему отменяется, просто молча.

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

В уведомлении о сохранении две кнопки: «Отменить» и «Открыть». Чаще всего после сохранения хочется не отменить его, а посмотреть, что сохранилось.

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

Второй уровень: история версий за последние 30 дней

У каждой заметки своя история версий, она хранится 30 дней.

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

Снимок хранит не только текст заметки, но и её теги. Это важно при восстановлении: вернув версию прошлого вторника, вы получите и теги прошлого вторника, а не старый текст в заметке, теги которой с тех пор незаметно поменялись.

История версий нужна для того, до чего отмена не дотягивается: не «секунду назад что-то пошло не так», а «за последние две недели заметка стала хуже, и непонятно, когда именно». Вы просматриваете версии и восстанавливаете нужную.

Третий уровень: корзина, где удалённое лежит 30 дней

Удаление заметки её не удаляет. Заметка помечается удалённой, получает отметку времени и 30 дней остаётся в корзине: её можно открыть и восстановить.

Интереснее, что происходит с вложенными заметками.

Удаление заметки удаляет всё её поддерево. Удалите заметку проекта, и вместе с ней уйдут все вложенные в неё заметки. Другое поведение не имеет смысла: дочерняя заметка, оставшаяся без родителя, — это утечка, а не спасение.

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

Посмотрим, что сделала бы наивная версия. Допустим, в марте вы удалили одну устаревшую заметку о встрече. В августе удаляете весь проект, потом передумываете и восстанавливаете его. Наивное восстановление вернёт всё поддерево, включая мартовскую заметку, которую вы сознательно выбросили пять месяцев назад. Вам пришлось бы найти её и удалить снова — если бы вы вообще это заметили.

Раз восстановление сверяет время удаления, оно отменяет ровно одно удаление и не трогает ни одного прежнего решения.

Четвёртый уровень: отклонённое сохранение

Первые три уровня исправляют ваши ошибки. Четвёртый нужен потому, что в рабочем пространстве может быть несколько человек, а там сбой выглядит иначе: никто не ошибается, а работа всё равно пропадает.

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

Notez такую запись отклоняет.

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

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

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

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

Как уровни делят работу

Отрезок времени

Механизм

Переживает перезагрузку?

Секунды

Стек отмены ⌘Z, последние 20 действий

Нет

От минут до 30 дней

История версий, снимки раз в 5 минут

Да

До 30 дней

Корзина с восстановлением по каскаду

Да

Сразу

Защита от конфликта сохранений

Да

Чего здесь нет, чтобы вы знали границы:

  • Отмена работает в пределах сессии. Закрыли вкладку — стека больше нет.

  • История версий и корзина хранят данные 30 дней. Ни то ни другое не резервная копия.

  • Отмена не касается правок текста заметки: для них есть история версий.

  • Офлайн-редактирования нет, поэтому нет и офлайн-конфликтов, которые пришлось бы разрешать.

Зачем это нужно

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

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

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

Читайте также