mirror of
https://github.com/block/buzz.git
synced 2026-10-29 13:31:44 +00:00
## Summary - render every agent/AI identity as a 30% squircle across desktop and mobile while keeping human avatars circular - propagate agent identity through message, thread, profile, reaction, member, DM, search, workflow, project, huddle, forum, pulse, and agent-management surfaces - preserve squircle geometry for fallbacks, focus/status treatments, add-agent controls, and overlapping avatar outlines (`calc(30% + 2px)` for the outer background) ### Related issue None found. This change was requested and visually reviewed in the originating Buzz thread. ### Testing - `just desktop-test` — 5,799 passed - `just mobile-test` — 2,008 passed - pre-push gates passed at `0d59d77b120dcb90aac2f918e422c11c9fa5353b`: desktop check, TypeScript typecheck, desktop full test suite, mobile format/analyze and full test suite, Rust tests, Tauri checks, and differential file-size gate - deterministic desktop visual sweep covered channel messages/thread summaries; thread, subthread, and sub-subthread depths; reactions and reactor popovers; hover/full profiles; added-to-channel activity; channel members/settings; agent library/team overlaps; agent creation; mention autocomplete; and DM header/sidebar/settings ### UI evidence The complete labeled visual matrix is available in the originating Buzz review thread. GitHub-hosted copies will be added in a follow-up PR comment using the repository screenshot script. --------- Signed-off-by: Fizz <dae5f6af70b8695a8b83c8deae555f63be41630ec2b8cd493e41a439c9527dd8@buzz.block.builderlab.xyz> Co-authored-by: Fizz <dae5f6af70b8695a8b83c8deae555f63be41630ec2b8cd493e41a439c9527dd8@buzz.block.builderlab.xyz>
51 lines
1.4 KiB
Dart
51 lines
1.4 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
@immutable
|
|
class UserProfile {
|
|
final String pubkey;
|
|
final String? displayName;
|
|
final String? avatarUrl;
|
|
final String? about;
|
|
final String? nip05Handle;
|
|
|
|
/// NIP-OA verified owner pubkey from the profile's `auth` tag; non-null
|
|
/// means this identity is an agent (mirrors desktop's `ownerPubkey`).
|
|
final String? ownerPubkey;
|
|
|
|
bool get isAgent => ownerPubkey != null;
|
|
|
|
const UserProfile({
|
|
required this.pubkey,
|
|
this.displayName,
|
|
this.avatarUrl,
|
|
this.about,
|
|
this.nip05Handle,
|
|
this.ownerPubkey,
|
|
});
|
|
|
|
factory UserProfile.fromJson(Map<String, dynamic> json) => UserProfile(
|
|
pubkey: json['pubkey'] as String,
|
|
displayName: json['display_name'] as String?,
|
|
avatarUrl: json['avatar_url'] as String?,
|
|
about: json['about'] as String?,
|
|
nip05Handle: json['nip05_handle'] as String?,
|
|
);
|
|
|
|
/// Short label: display name, or first 8 chars of pubkey.
|
|
String get label =>
|
|
displayName ??
|
|
'${pubkey.length >= 8 ? pubkey.substring(0, 8) : pubkey}...';
|
|
|
|
/// First letter for fallback avatar.
|
|
String get initial =>
|
|
(displayName?.isNotEmpty == true ? displayName! : pubkey)[0]
|
|
.toUpperCase();
|
|
}
|
|
|
|
/// Optional profile handle shown beside a message author's display name.
|
|
String? messageUsernameLabel(UserProfile? profile) {
|
|
final handle = profile?.nip05Handle?.trim();
|
|
if (handle != null && handle.isNotEmpty) return handle;
|
|
return null;
|
|
}
|