feat(ui): mobile UI v2 — contrast, avatars, room-list density, compose FAB, gradient login (v1.8.0+12)
From a 7-agent design workflow (3 lenses judged + synthesised). Shipped the high-impact/low-risk tier: - message bubbles: self #1265ED (WCAG AA pass), incoming #1C2452 + hairline - deterministic per-user avatar colours (8-hue brand palette) - room tile: brighter unread preview, compact density, aligned timestamp - FAB -> New message (thumb zone), explore -> AppBar - login + welcome brand gradient, card outlines - input maxLines cap, bubble max-width viewport fraction, AppBar hairline All verified on production build in headless Chromium at mobile size. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
// Version: 1.0.0 | Created: 2026-04-02
|
||||
// Version: 1.1.0 | Created: 2026-04-02 | Updated: 2026-07-04
|
||||
// Shared avatar widget used throughout the app. Displays a cached network
|
||||
// image when an HTTP avatar URL is available, or falls back to a coloured
|
||||
// circle with the first letter of the display name.
|
||||
// image when an HTTP avatar URL is available, or falls back to a circle
|
||||
// coloured deterministically from the display name (so each person gets a
|
||||
// stable, distinct disc) with the first letter of the display name.
|
||||
//
|
||||
// The [avatarUrl] MUST be a resolved HTTP URL — never pass an mxc:// URI.
|
||||
|
||||
@@ -25,6 +26,21 @@ class MatrixAvatar extends StatelessWidget {
|
||||
/// Radius of the [CircleAvatar].
|
||||
final double radius;
|
||||
|
||||
/// Brand-compatible hues for initials avatars. All dark enough for white
|
||||
/// initials to remain legible.
|
||||
static const List<Color> _palette = [
|
||||
Color(0xFF1265ED), // brand blue
|
||||
Color(0xFF2E7DE0), // sky
|
||||
Color(0xFF1E88A8), // teal
|
||||
Color(0xFF3949AB), // indigo
|
||||
Color(0xFF6A4CC0), // violet
|
||||
Color(0xFF00897B), // green-teal
|
||||
Color(0xFF5C6BC0), // periwinkle
|
||||
Color(0xFFB1631F), // warm amber
|
||||
];
|
||||
|
||||
Color get _discColour => _palette[name.hashCode.abs() % _palette.length];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
@@ -40,13 +56,13 @@ class MatrixAvatar extends StatelessWidget {
|
||||
|
||||
return CircleAvatar(
|
||||
radius: radius,
|
||||
backgroundColor: theme.colorScheme.primary.withAlpha(51),
|
||||
backgroundColor: _discColour,
|
||||
child: Text(
|
||||
initials,
|
||||
style: TextStyle(
|
||||
fontSize: radius * 0.7,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: theme.colorScheme.primary,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user