feat(icons): preserve user-uploaded icons from bulk fetch/clear
Auto-fetched favicons and user uploads shared one icon_b64 column, so
"Clear cache" wiped custom uploads and "Re-fetch all" overwrote them — data
loss the user can't undo (a custom icon exists precisely because DDG can't
fetch that site).
New icon_custom flag (0=fetched cache, 1=user upload). Invariant: an
automatic action never touches a custom icon; only the user changes/removes
it per entry.
- Schema: icon_custom INTEGER on vault_entries.
- POST /entries/{id}/icon takes {custom}; GET /entries echoes icon_custom;
DELETE /entries/icons/all filters COALESCE(icon_custom,0)=0.
- saveEntryIcon(id, uri, isCustom): upload→true, fetch/remove→false.
- backfillFavicons skips icon_custom even on force (Re-fetch all).
- clearAllFavicons clears only non-custom locally + refreshes the open editor
(the icon preview didn't update on clear before).
- duplicate re-stamps a copied custom icon; import-overwrite carries the flag.
Not propagated across bulk-import / sync (the bulk INSERT doesn't read it) —
a restored icon counts as fetched. Documented; custom icons are typically
self-hosted sites DDG won't re-fetch anyway.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -262,8 +262,20 @@ La SEULE feature qui sort sur le réseau côté Delphi (HIBP est côté JS).
|
||||
`Bridge.onFaviconResult(reqId, host, dataUri)`
|
||||
- Stockage : colonne `vault_entries.icon_b64 TEXT` (nullable). Endpoint
|
||||
dédié `POST /entries/{id}/icon` pour ne pas forcer un PUT complet
|
||||
(qui re-PUT le password chiffré)
|
||||
- Bulk : `DELETE /entries/icons/all` purge tout (bouton "Clear cache")
|
||||
(qui re-PUT le password chiffré). Body `{icon_b64, custom:bool}`.
|
||||
- **Provenance `icon_custom INTEGER`** (0 = favicon auto-fetchée = cache
|
||||
jetable, 1 = upload utilisateur). **Invariant : une icône custom n'est
|
||||
JAMAIS touchée par une action automatique.** `saveEntryIcon(id, uri,
|
||||
isCustom)` pose le flag (upload→1, fetch/remove→0). `backfillFavicons`
|
||||
skippe `icon_custom` (même sur "Re-fetch all"), `DELETE /entries/icons/all`
|
||||
filtre `COALESCE(icon_custom,0)=0`. Seul l'utilisateur change/retire une
|
||||
custom, par entrée (boutons Upload/Remove du slideover). `GET /entries`
|
||||
echoe `icon_custom`. **Non propagé** par import bulk / sync / export
|
||||
(l'INSERT bulk ne lit pas le flag) → une icône restaurée sur un device
|
||||
neuf compte comme fetchée ; assumé (les customs sont surtout des sites
|
||||
self-hosted, que DDG ne re-fetch pas de toute façon).
|
||||
- Bulk : `DELETE /entries/icons/all` purge le cache auto (bouton "Clear
|
||||
cache") — préserve les uploads custom
|
||||
- Render : `entry-avatar` contient `<img class="entry-avatar-img">` si
|
||||
`icon_b64`, sinon fallback aux initials. `onerror` repasse aux
|
||||
initials si la data URI est corrompue
|
||||
|
||||
Reference in New Issue
Block a user