fix: prevent Automerge sync from overwriting local image state

onChange handler was resetting _tweetImages on every sync event,
undoing local deletions before they could round-trip. Now only
updates state in readonly mode; edit mode preserves local changes.

Also add cache-busting timestamps to uploaded/generated image URLs
to prevent browser from showing stale cached images.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-05 21:43:16 -08:00
parent b7111f01ee
commit 5b2862afd7
1 changed files with 13 additions and 6 deletions

View File

@ -121,10 +121,15 @@ export class FolkThreadBuilder extends HTMLElement {
this._offlineUnsub = runtime.onChange(docId, (updated: SocialsDoc) => {
if (this._threadId && updated?.threads?.[this._threadId]) {
// Deep-clone to avoid Automerge proxy — direct property writes
// on proxies are silently ignored outside change() calls
this._thread = JSON.parse(JSON.stringify(updated.threads[this._threadId]));
this._tweetImages = this._thread?.tweetImages || {};
const synced = JSON.parse(JSON.stringify(updated.threads[this._threadId])) as ThreadData;
// In readonly mode, always take the synced version
if (this._mode === 'readonly') {
this._thread = synced;
this._tweetImages = synced.tweetImages || {};
this.render();
}
// In edit mode, only update thread metadata (not images)
// to avoid overwriting in-flight local changes
}
});
} catch (e: any) {
@ -652,7 +657,8 @@ export class FolkThreadBuilder extends HTMLElement {
const res = await fetch(this.basePath + 'api/threads/' + this._threadId + '/tweet/' + index + '/upload-image', { method: 'POST', body: form });
const data = await res.json();
if (data.imageUrl) {
this._tweetImages[index] = data.imageUrl;
// Bust browser cache with timestamp
this._tweetImages[index] = data.imageUrl + '?t=' + Date.now();
if (this._thread) {
this._thread.tweetImages = { ...this._tweetImages };
await this.saveToAutomerge(this._thread);
@ -676,7 +682,8 @@ export class FolkThreadBuilder extends HTMLElement {
const res = await fetch(this.basePath + 'api/threads/' + this._threadId + '/tweet/' + index + '/image', { method: 'POST' });
const data = await res.json();
if (data.imageUrl) {
this._tweetImages[index] = data.imageUrl;
// Bust browser cache with timestamp
this._tweetImages[index] = data.imageUrl + '?t=' + Date.now();
if (this._thread) {
this._thread.tweetImages = { ...this._tweetImages };
await this.saveToAutomerge(this._thread);