Documentation
¶
Overview ¶
Package contacts pkg/skychat/contacts/store.go c4-app-chat the address book: what THIS visor's operator calls each public key.
Why this is not localStorage any more ¶
A nickname used to live in the chat page's localStorage, which made it invisible to everything that is not that page. The two surfaces that most need a name are both outside it: a notification, whose title is composed in Go before any UI is involved, and a phone's native call screen, which is Kotlin and cannot read a WebView's storage. Both showed 66 hex characters for a person the user had already named — and a nickname also died with a cache clear, and never reached the same visor's other UI.
So the name moves to where every consumer can reach it: one small file beside the profile, read through the app's HTTP surface.
What a nickname is, and why it wins ¶
It is the operator's private label for a key, chosen by them and stored only here. It is NOT the profile a peer publishes about itself (pkg/skychat/profile) — that is the peer's claim, fetched over the network, and a label the user chose must never be replaceable by the person it labels. The UI resolves in that order (nickname, then published name, then the shortened key) and writes a fetched name in here only when there is no nickname yet, which is what lets one map serve both.
Local by design: nothing here is published, gossiped or sent to a peer.
Index ¶
Constants ¶
const MaxEntries = 5000
MaxEntries bounds the address book. Generous for a human's contact list, and the reason it exists is that this file is written whole on every change: an unbounded map turns one rename into an ever-growing rewrite.
Variables ¶
var ErrFull = errors.New("skychat contacts: address book is full")
ErrFull is returned when a new name would exceed MaxEntries. Renaming an existing contact always succeeds.
Functions ¶
This section is empty.
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the on-disk address book: public key → the name this operator gave it. Safe for concurrent use — the HTTP surface reads it on every render while a rename may be landing.
func OpenStore ¶
OpenStore opens (or prepares) the address book at path.
A missing file is not an error — an operator who has named nobody has an empty book. A file that exists but cannot be parsed IS one: starting blank would look exactly like every nickname having been silently discarded.
func (*Store) Merge ¶
Merge adds every name that is not already set, and reports how many landed.
Never overwrites: this is the path a UI's own older store is imported through (localStorage, historically), and an import must not be able to revert a rename the operator made since. Malformed entries are skipped rather than failing the batch — one bad key in a migration should not cost the operator the other 200.