T5 products in the client's inventory
CI / build (push) Successful in 25s

The inventory's product list (test.showInventory) gets the community products the person has: local packs, and
hub products in their library. Hiding one is answered by the proxy (and removes a hub product from the library).
When the library changes, the client is told to load its inventory again, with the server event IMVU sends
after a purchase. A product whose revision or info changes gets a new local ID, since the client keeps product
info for good; names lose characters the client's pages could take as HTML.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-29 18:59:52 -07:00
1 parent c281fb572c
commit ca7a86ce89
8 files changed
+225 -5

No files matched your search

+22
View File
@@ -42,8 +42,11 @@ type Fetcher struct {
// OnReady, if set, is called when a product was written (or updated) in the cache.
OnReady func(id string)
// OnLibrary, if set, is called after the library was read and its products fetched.
OnLibrary func()
mu sync.Mutex
library map[string]bool // the person's library, as last read
inflight map[string]bool
failed map[string]time.Time // products that failed lately (not retried for a while)
access string
@@ -69,6 +72,18 @@ func (f *Fetcher) SyncLibrary(ctx context.Context) {
f.logf("fetch: reading the library: %v", err)
return
}
ids := map[string]bool{}
for _, e := range lib {
ids[e.Product.ID] = true
}
f.mu.Lock()
f.library = ids
f.mu.Unlock()
defer func() {
if f.OnLibrary != nil {
f.OnLibrary()
}
}()
for _, e := range lib {
if err := f.Ensure(ctx, e.Product.ID); err != nil {
f.logf("fetch: %s (%s): %v", e.Product.ID, e.Product.Name, err)
@@ -291,3 +306,10 @@ func copyFile(src, dst string) error {
}
return out.Close()
}
// Owned reports whether a product is in the person's library (as last read).
func (f *Fetcher) Owned(id string) bool {
f.mu.Lock()
defer f.mu.Unlock()
return f.library[id]
}