Repository navigation
fix(avatar): raft-ui sticker frame, crisp pixel faces, presence light per avatar step - #3207
Merged
stamp-build[bot] merged 6 commits intoOct 20, 2026
Conversation
stamp-build
Bot
force-pushed
the
agent/sindresorhus/visual-radius
branch
from
October 20, 2026 05:39
df42794 to
f6179f0
Compare
stamp-build
Bot
force-pushed
the
agent/sindresorhus/avatar-polish
branch
from
October 20, 2026 05:57
621d158 to
24f8650
Compare
stamp-build Bot
added a commit
that referenced
this pull request
Oct 20, 2026
… error dialogs (#3227) The first-character emulator lane failed at random on PRs (#3207, #3211, #3219) for two infra reasons: - the image's GMS crashed and ActivityManager killed our app because it depends on a provider in the dying process ("Process crashed."), which the classifier treated as a real failure; - a system "isn't responding" dialog stole window focus, timing out every focus-dependent test after it. run-instrumentation-with-retry.sh now reads the attempt's logcat (since the attempt started; logcat is never cleared) and treats "Process crashed" as an infra abort only when ActivityManager logged killing a build.raft.app process for depending on a provider in a dying process. A real app crash still fails fast. The suite also sets hide_error_dialogs during prep. Co-authored-by: sindresorhus <raft+sindresorhus@agents.stamp.build> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
stamp-build
Bot
force-pushed
the
agent/sindresorhus/visual-radius
branch
from
October 20, 2026 08:07
f6179f0 to
263220a
Compare
RaftAppAvatar now draws raft-ui 0.8.0 Avatar exactly: - root: 4dp rounded-sticker, 1.5dp sticker-ink edge at every size (was a 1dp line-strong edge on most call sites), plus the 1.5dp sticker-edge ring outside it (transparent in light, the die-cut edge in dark). - face: inset inside the ink edge with 2dp corners (`rounded-[2px]`), so photos and pixel faces are no longer painted under the border. - pixel avatars: one renderer on every platform; every 8x8 cell edge is snapped to whole device pixels (nearest-neighbour, no anti-aliased seams or smeared cells). Drops the Android-only fractional-cell path and the now unused isRaftNativePixelAvatarViewSupported expect/actuals. - fallback: a person without a photo shows 1-2 initials (Space Grotesk bold, leading-none, -0.01em, sticker-ink) sized per raft-ui step (40/22/15/13/11/8; one initial at sm and below); the placeholder icon only when there is no name, at the step's icon size. - RaftAvatarStep maps any avatar Dp onto the nearest raft-ui step. - Call sites drop their hand-picked 1dp/1.5dp borderWidth; activity "SY" and external-author fallbacks and the muted overlay take the sticker corners. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rBadge RaftAvatarWithStatus derives the light from the raft-ui step nearest its avatarSize instead of every caller hardcoding statusSize: - size: xl 20 / lg 14 / md 11 / sm 9 / xs+2xs 7 / 3xs 6dp; - ink edge: 1.5dp (2dp on xl, 1dp on xs/2xs/3xs); - cut-out: 2dp layer-canvas outline (1dp on xs/2xs/3xs) that follows the light's corners (outer radius = 2dp + outline), drawn behind the light with no layout of its own; `cutoutColor` names the surface; - overhang: raft-ui's -8/-5/-4/-3/-2px offsets are measured from the avatar's padding edge, so the light passes the outer edge by the offset minus the 1.5dp ink border (6.5 / 3.5 / 2.5 / 1.5 / 0.5dp). The status pixel itself takes raft-ui's `rounded-[2px]` (1px on the 6px Status xs). `statusSize` stays as an override; all callers (thread, members, search, create-channel, modal member rows, sidebar) drop theirs, and the raft-ui library avatar fixture renders through the shared avatar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raft-ui places AvatarBadge with right/bottom offsets that CSS measures from the avatar's padding edge, inside its 1.5px ink border; the light therefore overhangs the outer edge by the offset minus 1.5 (xl 6.5, lg 3.5, md 2.5, sm 1.5, xs/2xs/3xs 0.5dp), not by the full offset. Goldens re-recorded (avatar, avatar_list_row_states). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…able RaftAvatarStep repeated every value of designsystem RaftAvatarSize (edge, presence light size/border/cut-out/overhang, initials and icon size). The step now wraps its RaftAvatarSize and reads those values from it (they are public on RaftAvatarSize now); it only folds raft xs/2xs into one step. `nearest` states its tie-break explicitly (halfway sizes take the larger step) instead of an epsilon bias. raftAvatarInitials / raftFirstGrapheme move to RaftAvatarInitials.kt, so model and data code can derive initials without initialising the Avatar file's drawing resources (android.graphics.Path in JVM unit tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rutal unchanged
Initials (raftAppAvatarInitials):
- always the raftAvatarInitials rule (first character of the first one or
two words); the "short word is already initials" uppercase shortcut is
gone. raft-ui itself takes initials as children, so this is the
design-system port of avatar.md's 1-2 initials rule.
- what cannot stand as an initial (emoji, punctuation such as @ ? #, lone
surrogates) is skipped at the start of each word; a label with no letter
or digit yields "" and the placeholder icon shows. Characters are whole
graphemes (surrogate pairs, combining marks); CJK keeps its first char.
Labels, fixed at the source:
- every model/parser `avatarLabel = name.take(1).uppercase()` (HomeParser,
CanonicalMessageV2ThreadProjection, SharedThreadStore, MembersPage,
ThreadPage, ThreadTimelineSlice, MemberAgentParser, ...) now uses
toRaftAvatarLabel(): one whole initial, never half a surrogate pair.
- avatars that know the person's name get the full name (DM rows, the user
header, thread authors, inline replies, members, channel settings,
composer suggestions/mention actions, forward targets, the DM header,
the foreground banner), so md+ avatars show two initials.
- no junk: the pinned-member "?" fallback, the member/author id fallbacks
(ThreadPage member/author profiles, ThreadTimelineSlice, inline replies,
modal member rows), the mention action "?"/target-type initial, the
composer fixture's index labels and the "Custom avatar" picker label all
give way to "" -> the icon.
Fill: agents without a photo sit on RaftColor.Inactive (web bg-inactive)
via raftAvatarFallbackFill(kind) at agent-aware call sites (members, agent
DM rows, thread authors with authorKind agent, followers, modal member
rows, activity senders, forward targets, mention actions); people stay
lavender.
Frame:
- the initials Text is hidden from semantics (clearAndSetSemantics {}).
- RaftAppAvatarFrame is internal; the external-author (Slack bridge)
fallback and the activity "SY" app avatar draw through it with their own
fill, so they get the dark-mode sticker-edge ring.
- its RoundedCornerShapes are top-level vals.
- brutal (!raftActive()) keeps its old avatar: 1dp black line drawn over
the face, square corners, no ring, lavender fill and the 56% person icon
instead of initials; only raft gets the sticker frame and initials.
- RaftUiAvatar reserves badgeOverhang + badgeCutout for the light instead
of a flat 4dp.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Parameterized commonTest cases for RaftAvatarStep.nearest (edges and the 31/43/75dp ties, 44dp), raftAppAvatarInitials (emoji, lone surrogate, CJK, whitespace, "@x", "?", one and two words, combining accent), toRaftAvatarLabel, and pixelAvatarGridEdge at 10-16px (whole-pixel edges, monotonic, every cell 1-2px wide). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stamp-build
Bot
force-pushed
the
agent/sindresorhus/avatar-polish
branch
from
October 20, 2026 08:19
24f8650 to
75c1447
Compare
stamp-build
Bot
merged commit Oct 20, 2026
352157b
into
agent/sindresorhus/visual-radius
14 checks passed
stamp-build Bot
added a commit
that referenced
this pull request
Oct 20, 2026
… per avatar step Re-applies #3207 (352157b), dropped when this branch was rebased onto main. - RaftAppAvatar draws through RaftAppAvatarFrame: 4dp sticker, 1.5dp sticker-ink edge, dark-mode sticker-edge ring, face inset with 2dp corners. - Pixel faces: one Canvas renderer with whole-pixel cell edges; the isRaftNativePixelAvatarViewSupported expect/actuals are gone. - No photo: 1-2 initials sized per RaftAvatarStep (icon when there is no usable name) on fallbackFill (agents on inactive, people lavender). - RaftAvatarWithStatus sizes the presence light, ink edge, cut-out and overhang from the nearest avatar step; replaces the simpler cut-out (cutoutWidth / avatarBorderWidth / AvatarSize) and callers drop statusSize. - Models derive avatarLabel via toRaftAvatarLabel(); initials helpers move to designsystem RaftAvatarInitials.kt. Ported onto main's structure: raft-ui is the only path (no brutal branches); DirectMessageAvatar and MembersStickerAvatar keep main's layout and pass the full name and fallback fill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stamp-build Bot
added a commit
that referenced
this pull request
Oct 20, 2026
…hugging Activity filter (#3205) * fix(ui): round Activity cards and inline replies, cut out avatar presence lights - Activity rows: container radius (10dp) on the card, its border and the selected sticker shadow. - Inline "N replies" surface: raft-ui MessageReplies rounded-container. - RaftAvatarWithStatus: canvas-coloured cut-out around the presence light (2dp; 1dp with a 1dp ink edge for the 7dp light on xs/2xs avatars), as raft-ui 0.8.0 AvatarBadge. Sidebar channel/DM avatar light 8dp -> 7dp. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(avatar): raft-ui sticker frame, crisp pixel faces, presence light per avatar step Re-applies #3207 (352157b), dropped when this branch was rebased onto main. - RaftAppAvatar draws through RaftAppAvatarFrame: 4dp sticker, 1.5dp sticker-ink edge, dark-mode sticker-edge ring, face inset with 2dp corners. - Pixel faces: one Canvas renderer with whole-pixel cell edges; the isRaftNativePixelAvatarViewSupported expect/actuals are gone. - No photo: 1-2 initials sized per RaftAvatarStep (icon when there is no usable name) on fallbackFill (agents on inactive, people lavender). - RaftAvatarWithStatus sizes the presence light, ink edge, cut-out and overhang from the nearest avatar step; replaces the simpler cut-out (cutoutWidth / avatarBorderWidth / AvatarSize) and callers drop statusSize. - Models derive avatarLabel via toRaftAvatarLabel(); initials helpers move to designsystem RaftAvatarInitials.kt. Ported onto main's structure: raft-ui is the only path (no brutal branches); DirectMessageAvatar and MembersStickerAvatar keep main's layout and pass the full name and fallback fill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: sindresorhus <raft+sindresorhus@agents.stamp.build> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: stamp-build[bot] <328845999+stamp-build[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Avatar rendering aligned with the web raft-ui
Avatar/AvatarBadge(artin, item 7). Stacked on #3205.--sticker-edgeouter ring (drawn outside, no layout change); image/pixel face inset inside the edge with 2dp corners.RaftAvatarWithStatusderives size / ink edge / canvas cut-out / overhang fromavatarSize(xl 20, lg 14, md 11, sm 9, xs 7, 3xs 6dp); call sites no longer hardcodestatusSize. Same overhang fix in designsystemRaftAvatar(goldens re-recorded).Known remaining diffs: presence lights still pulse where callers ask; cut-out is canvas colour, not the actual surface; uploaded photos always on lavender.
Checks: Android shared/designsystem/app compile + avatar unit tests + designsystem desktop screenshot tests pass locally; iOS via CI (
full-ci). Visual Testing before/after posted in the PR thread.🤖 Generated with Claude Code