# Spec Delta ## ADDED Requirements ### Requirement: Проверка доступа «Все файлы» при запуске Приложение SHALL при запуске, когда оно уже настроено и авторизовано, проверять наличие доступа «Все файлы» и при его отсутствии SHALL предлагать его включить, открывая системный экран настроек. #### Scenario: Доступ не выдан - **WHEN** приложение запущено и доступ «Все файлы» не выдан - **THEN** показывается диалог с предложением включить доступ #### Scenario: Включение доступа - **WHEN** пользователь подтверждает - **THEN** открывается системный экран выдачи доступа «Все файлы» #### Scenario: Доступ уже выдан - **WHEN** доступ уже выдан - **THEN** диалог не показывается ### Requirement: Возврат оригиналов при выходе из переноса При переключении альбома из режима переноса в «копии» или «выключено» приложение SHALL возвращать оригиналы с сервера (когда пользователь выбирает возврат), а незавершённый возврат SHALL довосстанавливаться при следующей проверке (при запуске и при открытии альбома). #### Scenario: Перенос → копии - **WHEN** пользователь переключает альбом из переноса в копии и подтверждает возврат оригиналов - **THEN** оригиналы скачиваются с сервера и заменяют превью на устройстве #### Scenario: Довосстановление - **WHEN** альбом не в режиме переноса, но содержит превью с серверным фото - **THEN** при запуске или открытии альбома оригиналы довосстанавливаются #### Scenario: Перенос → выключено - **WHEN** пользователь переключает перенос в выключено - **THEN** предлагается вернуть оригиналы или оставить превью ### Requirement: Единая проверка соответствия режиму При запуске и при открытии альбома приложение SHALL приводить локальное содержимое в соответствие режиму для всех сочетаний состояния ассета: в «переносе» разгружать уже загруженные оригиналы, а в «копиях»/«выключено» восстанавливать превью; отсутствующий локальный индекс SHALL восстанавливаться по метке происхождения. #### Scenario: Копии с разгруженными файлами - **WHEN** альбом в режиме копий, а часть файлов разгружена (превью) - **THEN** проверка восстанавливает оригиналы #### Scenario: Перенос с неразгруженными файлами - **WHEN** альбом в режиме переноса, файл есть на сервере, но оригинал ещё на телефоне - **THEN** проверка разгружает оригинал #### Scenario: Потерянный индекс - **WHEN** у разгруженного медиа нет записи в локальном индексе - **THEN** связь и происхождение восстанавливаются по метке в файле #### Scenario: Выключенный режим - **WHEN** альбом без синхронизации содержит превью - **THEN** оригиналы восстанавливаются, а сервер не затрагивается ### Requirement: Отсутствие дублей и гонок при синхронизации Проверка синхронизации SHALL выполняться последовательно (без одновременных проходов по одной галерее) и SHALL NOT ставить повторную загрузку, пока по тому же элементу уже есть задание в очереди. Метка происхождения в разгруженном файле SHALL хранить режим синхронизации, а не состояние элемента, чтобы восстановление не меняло режим галереи. #### Scenario: Повторная проверка во время загрузки - **WHEN** проверка запускается снова, пока загрузка элемента ещё стоит в очереди - **THEN** повторная загрузка не ставится #### Scenario: Метка происхождения хранит режим - **WHEN** разгруженный файл восстанавливается после переустановки - **THEN** режим галереи берётся из метки как режим (перенос/копии), а не как состояние элемента ### Requirement: Подпись карточки альбома Карточка альбома SHALL показывать в первой строке имя альбома, а для связанной пары — со стрелкой имя связанного серверного альбома, и только когда имена различаются. Вторая строка SHALL показывать значками расположение содержимого и число элементов: значок карты памяти для локального без синхронизации, значки карты памяти и облака для режима копий, значок облака для режима переноса; для серверного альбома — значок облака. #### Scenario: Локальный без синхронизации - **WHEN** показан локальный альбом без синхронизации - **THEN** вторая строка показывает значок карты памяти и число элементов #### Scenario: Режим копий - **WHEN** локальный альбом синхронизируется в режиме копий - **THEN** вторая строка показывает значки карты памяти и облака и число элементов #### Scenario: Режим переноса - **WHEN** локальный альбом синхронизируется в режиме переноса - **THEN** вторая строка показывает значок облака и число элементов #### Scenario: Разные имена связанной пары - **WHEN** имя локального альбома не совпадает с именем связанного серверного - **THEN** первая строка показывает «имя → имя серверного» #### Scenario: Одинаковые имена - **WHEN** имена совпадают - **THEN** стрелка и имя серверного не показываются ### Requirement: Панель атрибутов и действий альбома Приложение SHALL открывать панель «Атрибуты и действия» по свайпу справа налево на экране любого альбома — серверного и локального. Панель SHALL повторять структуру web: разделы «Обложка», «Информация», «Навигация» и раздел «Действия». #### Scenario: Открытие свайпом - **WHEN** пользователь свайпает справа налево в открытом альбоме - **THEN** открывается панель «Атрибуты и действия» #### Scenario: Структура панели - **WHEN** панель открыта - **THEN** показаны разделы «Обложка», «Информация», «Навигация» и «Действия» #### Scenario: Закрытие панели - **WHEN** пользователь закрывает панель (свайп в обратную сторону или касание вне панели) - **THEN** панель скрывается, сетка медиа снова доступна ### Requirement: Источник атрибутов локального альбома Для локального альбома приложение SHALL показывать ту же панель «Атрибуты и действия», что и для серверного, а метаданные SHALL брать локально (имя, число элементов, локальная обложка, режим синхронизации, связанный серверный альбом). Действия локального альбома SHALL применяться локально. #### Scenario: Локальные метаданные - **WHEN** пользователь открывает панель локального альбома - **THEN** раздел «Информация» показывает локальные имя, число элементов и обложку #### Scenario: Неактивная навигация без связи - **WHEN** локальный альбом не связан с серверным - **THEN** строки «Участники» и «Ссылки для просмотра» показаны, но неактивны #### Scenario: Активная навигация при связи - **WHEN** локальный альбом связан с серверным - **THEN** строки «Участники» и «Ссылки для просмотра» активны и относятся к связанному серверному альбому ### Requirement: Переименование и обложка локального альбома Для локального альбома действие «Переименовать» SHALL менять отображаемое имя в приложении, не изменяя медиа или bucket на устройстве, а «Выбрать обложку»/«Сбросить» SHALL назначать или снимать обложку из медиа этого альбома. Имя и обложка SHALL храниться локально. #### Scenario: Переименование - **WHEN** пользователь вводит новое имя локального альбома - **THEN** панель, заголовок и карточка в списке альбомов показывают новое имя #### Scenario: Назначение и сброс обложки - **WHEN** пользователь выбирает медиа обложкой или сбрасывает её - **THEN** панель и карточка альбома отражают выбор ### Requirement: Удаление локального альбома с телефона Действие «Удалить» локального альбома SHALL после подтверждения удалять все фото и видео этого альбома с устройства, запрашивая при необходимости системное согласие. #### Scenario: Подтверждение - **WHEN** пользователь выбирает «Удалить» локального альбома - **THEN** открывается диалог с предупреждением, что медиа будут удалены с телефона #### Scenario: Удаление - **WHEN** пользователь подтверждает удаление - **THEN** медиа удаляются с устройства, а альбом исчезает из приложения ### Requirement: Атрибуты альбома Панель SHALL показывать обложку с выбором и сбросом, информацию (название, описание, число фото и участников) и переходы к участникам, настройкам и ссылкам для просмотра. Управление обложкой и раздел «Навигация» SHALL быть доступны только владельцу и администратору. #### Scenario: Управление обложкой - **WHEN** владелец или администратор выбирает или сбрасывает обложку - **THEN** изменение сохраняется на сервере и отражается в списке и панели #### Scenario: Наблюдатель - **WHEN** наблюдатель открывает панель - **THEN** управление обложкой не показывается, а строки «Настройки» и «Ссылки для просмотра» неактивны #### Scenario: Переход к настройкам - **WHEN** владелец или администратор открывает настройки из раздела «Навигация» - **THEN** доступны правка названия и описания и управление ссылками для просмотра ### Requirement: Действия с альбомом Панель SHALL содержать действия «Переименовать» и «Удалить». Удаление SHALL подтверждаться диалогом, а удалённый альбом SHALL помещать свои фото в корзину. #### Scenario: Переименование - **WHEN** владелец или администратор выбирает «Переименовать» и вводит новое название - **THEN** название сохраняется на сервере и отражается в списке и заголовке #### Scenario: Удаление с подтверждением - **WHEN** владелец выбирает «Удалить» и подтверждает в диалоге - **THEN** альбом удаляется, а его фото попадают в корзину ### Requirement: Лист атрибутов и действий фото Полноэкранный просмотр SHALL открывать лист «Атрибуты и действия» по свайпу вверх как в серверном, так и в device-просмотре. Лист SHALL повторять структуру web: разделы «Информация», «Метки» и «Действия». При зуме изображения, панораме или активном управлении видео свайп вверх SHALL NOT открывать лист. #### Scenario: Открытие листа - **WHEN** пользователь свайпает вверх во вписанном изображении - **THEN** открывается лист «Атрибуты и действия» для текущего элемента #### Scenario: Зум или панорама - **WHEN** изображение увеличено или открыта панорама, и пользователь свайпает вверх - **THEN** лист не открывается, жест обрабатывается изображением #### Scenario: Видео - **WHEN** открыт видеоэлемент, и пользователь взаимодействует с плеером - **THEN** свайп вверх не мешает управлению воспроизведением ### Requirement: Атрибуты фото в листе Раздел «Информация» SHALL показывать автора, размер файла, тип, разрешение, EXIF-атрибуты, дату съёмки, координаты и дату загрузки. Раздел «Метки» SHALL позволять добавлять и снимать метки с поиском по меткам пользователя и созданием новых. #### Scenario: Информация - **WHEN** лист открыт - **THEN** раздел «Информация» показывает метаданные и EXIF текущего фото #### Scenario: Метки - **WHEN** пользователь добавляет или снимает метку в разделе «Метки» - **THEN** изменение сразу отражается в просмотре без перезагрузки ### Requirement: Настройки списка атрибутов Раздел «Информация» SHALL давать доступ к настройкам со списком EXIF-атрибутов, где пользователь отмечает отображаемые атрибуты и задаёт их подписи, с действиями «отметить все» и «снять все». Настройки SHALL применяться ко всем фото и сохраняться в профиле пользователя. #### Scenario: Открытие настроек - **WHEN** пользователь открывает настройки атрибутов - **THEN** показан список EXIF-атрибутов с галочками видимости и полями подписей #### Scenario: Сохранение настроек - **WHEN** пользователь отмечает атрибуты, задаёт подписи и сохраняет - **THEN** настройки сохраняются в профиле и применяются в разделе «Информация» #### Scenario: Сброс настроек - **WHEN** пользователь сбрасывает настройки - **THEN** применяется базовый набор атрибутов с исходными подписями ### Requirement: Действия с фото в листе Раздел «Действия» SHALL содержать «Скачать», «Переместить», «Копировать», «Установить как обложку альбома» (по правам) и «Удалить»; из сетки также «Открыть (просмотр)». Удаление SHALL подтверждаться диалогом. Переименование SHALL выполняться по тапу на имя файла. #### Scenario: Состав действий - **WHEN** лист открыт - **THEN** показаны действия «Скачать», «Переместить», «Копировать», «Установить как обложку» и «Удалить» по правам #### Scenario: Удаление фото - **WHEN** пользователь выбирает «Удалить» и подтверждает - **THEN** фото уходит в корзину, а просмотр переходит к соседнему элементу #### Scenario: Переименование фото - **WHEN** автор, владелец или администратор меняет имя файла на непустое - **THEN** новое имя сохраняется и отражается в просмотре и сетке ### Requirement: Источник атрибутов device-медиа Для device-медиа приложение SHALL показывать атрибуты и действия сопоставленного серверного фото, когда сопоставление есть, и локальные атрибуты и действия (имя, размер, тип, разрешение, дата, путь) при его отсутствии. #### Scenario: Сопоставлено серверному фото - **WHEN** device-медиа сопоставлено серверному фото - **THEN** лист показывает серверные атрибуты и серверные действия этого фото #### Scenario: Не сопоставлено - **WHEN** сопоставления с серверным фото нет - **THEN** лист показывает локальные атрибуты и локальные действия элемента