В правой панели фото появилась вкладка «Редактирование» с инструментом «Свет»: ползунки экспозиции, контраста, светов, теней, белых и чёрных и точечная кривая с выбором канала. Правки сохраняются автоматически, переключатель «Сброс» удаляет параметры правок и отредактированную версию фото. Редактирование неразрушающее: параметры хранятся в метаданных фото, а отредактированная версия рендерится в фоне отдельным объектом (edit, edit_thumb, edit_medium, edit_preview) рядом с исходными вариантами. Оригинал не меняется, скачивание отдаёт исходный файл. Сетка, просмотр и обложки альбомов показывают отредактированную версию, когда она отрендерена.
91 lines
4.9 KiB
Go
91 lines
4.9 KiB
Go
package photos
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"galo/internal/models"
|
|
)
|
|
|
|
// TrashIdentity is the minimal fact set needed to authorize a trashed photo
|
|
// during a bulk purge without loading the full photo.
|
|
type TrashIdentity struct {
|
|
ID string
|
|
AlbumID string
|
|
UploaderID string
|
|
}
|
|
|
|
// Repository is the persistence contract for the photos domain, including the
|
|
// object ledger, variant queue and garbage collection.
|
|
type Repository interface {
|
|
CreateWithOriginal(ctx context.Context, p *models.Photo, obj *Object) error
|
|
DeleteUpload(ctx context.Context, photoID, objectID string) error
|
|
GetByID(ctx context.Context, id, viewerID string) (*models.Photo, error)
|
|
List(ctx context.Context, in ListParams) ([]models.Photo, error)
|
|
SetDeleted(ctx context.Context, id string, deleted bool) error
|
|
UpdateAlbum(ctx context.Context, id, albumID string) error
|
|
Clone(ctx context.Context, src *models.Photo, albumID, uploaderID, id string) error
|
|
HardDelete(ctx context.Context, id string) error
|
|
ListTrash(ctx context.Context, userID string) ([]models.Photo, error)
|
|
// ListTrashIdentities returns every trashed photo accessible to the user
|
|
// (no display cap) so a bulk purge can authorize and remove each one.
|
|
ListTrashIdentities(ctx context.Context, userID string) ([]TrashIdentity, error)
|
|
TrashCount(ctx context.Context, userID string) (int, error)
|
|
RestoreToAlbum(ctx context.Context, id, albumID string) error
|
|
AlbumExists(ctx context.Context, albumID string) (bool, error)
|
|
ListTags(ctx context.Context, userID, q string) ([]models.Tag, error)
|
|
EnsureTag(ctx context.Context, userID, name string) (*models.Tag, error)
|
|
AttachTag(ctx context.Context, photoID, tagID string) error
|
|
DetachTag(ctx context.Context, photoID, tagID string) error
|
|
TagOwnedBy(ctx context.Context, tagID, userID string) (bool, error)
|
|
SetCoverIfEmpty(ctx context.Context, albumID, photoID string)
|
|
ClearCoverIfMatches(ctx context.Context, albumID, photoID string)
|
|
UpdateFilename(ctx context.Context, id, filename string) error
|
|
BackfillEXIF(ctx context.Context, fetch func(context.Context, string) ([]byte, error)) (int, error)
|
|
|
|
CreateObject(ctx context.Context, o *Object) error
|
|
SetObjectState(ctx context.Context, id, state string) error
|
|
ActivateObject(ctx context.Context, id string) error
|
|
MarkObjectDeleting(ctx context.Context, id string) error
|
|
DeleteObjectRow(ctx context.Context, id string) error
|
|
BindObject(ctx context.Context, photoID, objectID, role string) error
|
|
// BindUserAvatar, UserAvatarObject and ClearUserAvatar manage the object
|
|
// binding that backs a user's profile avatar.
|
|
BindUserAvatar(ctx context.Context, userID, objectID, role string) error
|
|
UserAvatarObject(ctx context.Context, userID, role string) (*Object, error)
|
|
ClearUserAvatar(ctx context.Context, userID string) error
|
|
PhotoObjectIDs(ctx context.Context, photoID string) ([]string, error)
|
|
ObjectRefCount(ctx context.Context, objectID string) (int, error)
|
|
OriginalObject(ctx context.Context, photoID string) (*Object, error)
|
|
PhotosByOriginalObject(ctx context.Context, originalObjectID string) ([]string, error)
|
|
ClaimGarbage(ctx context.Context, limit int) ([]Object, error)
|
|
ClaimStalePending(ctx context.Context, olderThan time.Duration, limit int) ([]Object, error)
|
|
// ClaimVariantJobs leases due jobs of the given kind ("" claims all kinds).
|
|
ClaimVariantJobs(ctx context.Context, kind string, limit int, lease time.Duration) ([]string, error)
|
|
CompleteVariantJob(ctx context.Context, photoID string) error
|
|
FailVariantJob(ctx context.Context, photoID, errMsg string, maxAttempts int) error
|
|
// SetMediaMeta records probed video facts: duration on the photo and frame
|
|
// dimensions on the original object.
|
|
SetMediaMeta(ctx context.Context, photoID, objectID string, durationMS int64, width, height int) error
|
|
|
|
// SetEditParams stores the non-destructive editing parameters of a photo.
|
|
SetEditParams(ctx context.Context, photoID string, params []byte) error
|
|
// ClearEditParams removes the editing parameters of a photo.
|
|
ClearEditParams(ctx context.Context, photoID string) error
|
|
// EnqueueEditJob schedules the render of the edited version of a photo.
|
|
EnqueueEditJob(ctx context.Context, photoID string) error
|
|
// DeleteEditJob drops the pending render of a photo.
|
|
DeleteEditJob(ctx context.Context, photoID string) error
|
|
// ClaimEditJobs leases due edit renders and returns their photo ids.
|
|
ClaimEditJobs(ctx context.Context, limit int, lease time.Duration) ([]string, error)
|
|
// CompleteEditJob removes a finished edit render.
|
|
CompleteEditJob(ctx context.Context, photoID string) error
|
|
// FailEditJob records a failure and schedules a retry.
|
|
FailEditJob(ctx context.Context, photoID, errMsg string, maxAttempts int) error
|
|
// DeleteObjectBindings removes the bindings of a photo for the given roles.
|
|
DeleteObjectBindings(ctx context.Context, photoID string, roles ...string) error
|
|
|
|
// AllStorageKeys returns every key registered in the object journal.
|
|
AllStorageKeys(ctx context.Context) ([]string, error)
|
|
}
|