mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
The 33 descriptions (~16k chars, ~19k with paths) overran Codex's skill-list budget (2% of the context window, or 8,000 chars when unknown), and a review found most bodies stale: paths from before the commons/commonsUI moves, the deleted legacy desktop app, a callback signer API that no longer exists, and example APIs that were never in the tree. Kept, rewritten and checked against the code (every path, class and command): account-state (+feeds), amy-expert, android-expert, auth-signers, compose-expert (+API style, Navigation 3 back stacks), desktop-expert (+run/package), event-store-semantics (+NIP-50 search), find-missing- translations, kotlin-coroutines (+structured concurrency, flow modeling), kotlin-multiplatform (+Gradle, composable extraction), ngit-pr, nip85-trusted-assertions, nostr-expert (+NIP lookup, generated NIP catalog), relay-client. Dropped: textbook Compose/Kotlin technique skills, kotlin-expert, kotlin-types-value-class, gradle-expert, quartz-integration (external-facing; see the Quartz docs commit), find-non-lambda-logs (audit finished; the rule is now in AGENTS.md Kotlin Style), and the /nip, /desktop-run, /extract commands. The skill list is now ~4k chars. Also drops .claude/core-skills-plan.md (stale history) and repoints SearchableEvent's KDoc to event-store-semantics. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
2.2 KiB
Markdown
44 lines
2.2 KiB
Markdown
# Robohash avatars
|
|
|
|
Icons are fonts, not ImageVectors: see `AGENTS.md` "Icons" (Amethyst's `icons/*.kt` compile
|
|
into `amethyst_icons.ttf` and draw through `AmethystIconGlyph`; Material icons are
|
|
`MaterialSymbols` from a subset font). Robohash is the one generated vector asset.
|
|
|
|
## Files
|
|
|
|
Under `commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/robohash/`:
|
|
|
|
- `RobohashAssembler.kt`: `class RobohashAssembler` with `build(msg, isLightTheme): ImageVector`,
|
|
plus `inline fun roboBuilder(name, autoMirror, block)` (an `ImageVector.Builder` on the shared
|
|
viewport).
|
|
- `CachedRobohash.kt`: `object CachedRobohash`, an `LruCache` of 100 vectors.
|
|
`get(msg, isLightTheme)` builds or hits, `cached(...)` only hits, `trimToSize(maxItems)`.
|
|
The whole cache is evicted when the theme flips.
|
|
- `parts/`: 50 part files, 10 variants each of `Accessory*`, `Body*`, `Eyes*`, `Face*`, `Mouth*`
|
|
(for example `Face0C3po.kt`). Each adds layered paths to the builder with a seed-derived
|
|
foreground color and fixed black strokes / alpha shading.
|
|
|
|
## Behaviour worth knowing
|
|
|
|
- The seed is a hex pubkey. Hex of at least 22 chars is decoded directly (the assembler reads
|
|
bytes 0..10). Anything shorter or non-hex is SHA-256'd first, and a `Log.w` is emitted. A blank
|
|
seed falls back to an all-zero key.
|
|
- The color range depends on the theme: light theme uses bright channels (150+), dark uses
|
|
dim ones (50-100). Always pass `MaterialTheme.colorScheme.isLight`.
|
|
|
|
## Composables
|
|
|
|
In `commonsUI/.../commons/ui/components/`:
|
|
|
|
- `RobohashImage(robot, modifier, contentDescription, loadRobohash)` and an overload with
|
|
`alignment`, `contentScale`, `colorFilter`. When `loadRobohash` is false it draws the
|
|
`MaterialSymbols.Face` placeholder instead.
|
|
- `RobohashFallbackAsyncImage(robot, model, ...)` (`RobohashAsyncImage.kt`): loads the profile
|
|
picture `model` through Coil and falls back to the robohash. `RobohashAsyncImage` there is the
|
|
robohash-only variant. For a user's avatar prefer `UserAvatar(userHex, pictureUrl, size, ...)`
|
|
(`UserAvatar.kt`), which reads the display settings and draws through a platform
|
|
`expect fun AvatarImage`.
|
|
|
|
Benchmarks: `benchmark/src/androidTest/java/com/vitorpamplona/amethyst/benchmark/RobohashBenchmark.kt`
|
|
and `RobohashPartsBenchmark.kt`.
|