Files
iu fa210e6c7f feat(android): album/photo attribute-actions and device gallery sync fixes
Album panel and photo sheet with attributes/actions for every album (server and
device), local album rename/cover/delete, EXIF attribute settings, and a unified
device-gallery sync check:

- add repository "Атрибуты и действия" panel (swipe left) on server and device
  albums: cover, info, navigation, rename/delete; album settings screen; photo
  sheet (swipe up) with info, tags and actions; EXIF attribute settings backed by
  profile preferences
- local albums use local metadata and actions: app-only display name and cover
  (new device_album_meta table), delete removes photos from the phone via the
  system delete consent
- unified mode x state policy (GallerySyncPolicy/SyncCheck) runs on start and on
  album open: upload/offload in move, restore originals in copy/off
- fix move->copy restore, offload of any linked-but-local original, provenance
  recovery that no longer overwrites the album mode, serialized reconcile and
  duplicate-upload suppression; prompt for "all files" access on start
- album card caption: name (with linked server name when different) and storage
  icons (memory card / cloud) with item count

Sync delta specs into android-client and archive the change
add-mobile-album-photo-actions.

Verified: unit/Robolectric suite green, :app:assembleDebug, :app:lint, and the
DeviceSyncE2ETest instrumented suite on the emulator (7/7).
2026-10-13 21:49:12 +03:00

21 KiB

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 лист показывает локальные атрибуты и локальные действия элемента