fix(mobile/upload): activities now appear in browser after upload; reconcile synced_at on fresh server

Three bugs fixed:
- /api/upload/bas and /api/upload/raw never updated user_dir/index.json, so
  merge_all couldn't include uploaded activities in year shards — they existed
  on disk but were invisible to the browser feed. Fixed by _upsert_index_summary()
  called before merge_all().
- Silent catch {} in uploadLocalActivities swallowed all per-activity errors;
  replaced with console.warn so failures are visible in Expo logs.
- After a server wipe, synced_at flags on the device caused "Nothing to upload"
  forever. uploadFeed() now reconciles against GET /api/feed at the start of each
  upload: local activities not found on the server get synced_at cleared.

Also: live upload progress ("Uploading N / M…"), failed count in result message,
onProgress callback on uploadFeed(), countPendingUploads() helper.
This commit is contained in:
Davide Scaini
2026-04-27 11:03:00 +02:00
parent b1cf18a2f0
commit 220efb0d05
4 changed files with 143 additions and 26 deletions
+8 -3
View File
@@ -53,14 +53,19 @@ export default function FeedScreen() {
const doUpload = useCallback(async () => {
setUploading(true);
setStatusMsg(null);
const result = await uploadFeed(db);
const result = await uploadFeed(db, (n, total) => {
setStatusMsg({ ok: true, text: `Uploading ${n} / ${total}` });
});
setUploading(false);
if (result.error) {
showMsg(false, result.error);
} else if (!result.uploaded) {
} else if (!result.uploaded && !result.failed) {
showMsg(true, 'Nothing to upload');
} else {
showMsg(true, `Uploaded ${result.uploaded} activit${result.uploaded === 1 ? 'y' : 'ies'}`);
const parts: string[] = [];
if (result.uploaded) parts.push(`${result.uploaded} uploaded`);
if (result.failed) parts.push(`${result.failed} failed`);
showMsg(result.failed ? false : true, parts.join(', '));
}
}, [db]);