feat(android): sync device albums with a server album
Add phone album sync to the Android client: MediaStore source (device albums), a Room index with upload provenance, on-device previews, and a mixed server + device album list where a linked pair collapses into a single device card with a link indicator and mode label. Three modes over one pipeline: A (off), B (upload copies, originals stay local), C (upload originals and offload them locally to previews). The sync engine tracks device changes (add/remove/rename/move/content), matches assets to server photos by sha256 content hash, deletes only this client's uploads, and reflects server changes without touching local originals. Offload is automatic; the zoomed viewer pulls the server original. Backend: expose the original content checksum in photo data (Postgres and SQLite), additive with no migration. Also anchor the `.gitignore` `data/` rule to `/data/` so the Android `com.galo.android.data` package is tracked, and add the halo launcher icon.
This commit is contained in:
@@ -25,7 +25,7 @@ const sqlitePhotoColumns = `p.id, COALESCE(p.album_id, ''), p.uploader_id,
|
||||
COALESCE(o_m.storage_key, ''),
|
||||
COALESCE(o_p.storage_key, ''),
|
||||
COALESCE(o_pb.storage_key, ''),
|
||||
p.original_filename, COALESCE(o_o.size, 0), COALESCE(o_o.width, 0), COALESCE(o_o.height, 0), COALESCE(o_o.mime_type, ''),
|
||||
p.original_filename, COALESCE(o_o.size, 0), COALESCE(o_o.width, 0), COALESCE(o_o.height, 0), COALESCE(o_o.mime_type, ''), COALESCE(o_o.checksum, ''),
|
||||
p.kind, COALESCE(p.duration_ms, 0),
|
||||
p.taken_at, p.latitude, p.longitude, COALESCE(p.caption, ''), p.created_at,
|
||||
u.id, u.name, COALESCE(u.avatar_url, ''),
|
||||
@@ -58,7 +58,7 @@ func scanSQLitePhoto(scan func(...any) error) (*models.Photo, error) {
|
||||
var liked int
|
||||
if err := scan(&p.ID, &p.AlbumID, &p.UploaderID, &p.StorageKey,
|
||||
&p.ThumbKey, &p.MediumKey, &p.PreviewKey, &p.PlaybackKey,
|
||||
&p.OriginalFilename, &p.Size, &p.Width, &p.Height, &p.MimeType,
|
||||
&p.OriginalFilename, &p.Size, &p.Width, &p.Height, &p.MimeType, &p.OriginalChecksum,
|
||||
&p.Kind, &p.DurationMS,
|
||||
&takenAt, &lat, &long, &p.Caption, &createdAt,
|
||||
&p.Uploader.ID, &p.Uploader.Name, &p.Uploader.AvatarURL,
|
||||
@@ -283,7 +283,7 @@ func (s *SQLiteStore) ListTrash(ctx context.Context, userID string) ([]models.Ph
|
||||
var liked int
|
||||
if err := rows.Scan(&p.ID, &p.AlbumID, &p.UploaderID, &p.StorageKey,
|
||||
&p.ThumbKey, &p.MediumKey, &p.PreviewKey, &p.PlaybackKey,
|
||||
&p.OriginalFilename, &p.Size, &p.Width, &p.Height, &p.MimeType,
|
||||
&p.OriginalFilename, &p.Size, &p.Width, &p.Height, &p.MimeType, &p.OriginalChecksum,
|
||||
&p.Kind, &p.DurationMS,
|
||||
&takenAt, &lat, &long, &p.Caption, &createdAt,
|
||||
&p.Uploader.ID, &p.Uploader.Name, &p.Uploader.AvatarURL,
|
||||
|
||||
Reference in New Issue
Block a user