Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mobile/lib/features/channels/channel_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:lucide_icons_flutter/lucide_icons.dart';

import '../../shared/relay/relay.dart';
import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../../shared/widgets/frosted_app_bar.dart';
import '../../shared/widgets/frosted_scaffold.dart';
import '../profile/presence_cache_provider.dart';
Expand Down
22 changes: 9 additions & 13 deletions mobile/lib/features/channels/channel_detail_page/app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,17 @@ class _DmAppBarTitle extends ConsumerWidget {
child: Stack(
clipBehavior: Clip.none,
children: [
CircleAvatar(
AvatarImage(
imageUrl: avatarUrl,
radius: 14,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null
? NetworkImage(avatarUrl)
: null,
child: avatarUrl == null
? Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
)
: null,
fallback: Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
),
),
Positioned(
right: -1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,17 @@ class _UserAvatar extends StatelessWidget {
profile?.initial ?? (pubkey.isNotEmpty ? pubkey[0].toUpperCase() : '?');
final avatarUrl = profile?.avatarUrl;

return CircleAvatar(
return AvatarImage(
imageUrl: avatarUrl,
radius: 14,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,
child: avatarUrl == null
? Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
)
: null,
fallback: Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
),
);
}
}
Expand Down
1 change: 1 addition & 0 deletions mobile/lib/features/channels/channels_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../shared/auth/auth.dart';
import '../../shared/relay/relay.dart';
import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../../shared/widgets/frosted_app_bar.dart';
import '../../shared/widgets/frosted_scaffold.dart';
import '../profile/profile_avatar.dart';
Expand Down
22 changes: 10 additions & 12 deletions mobile/lib/features/channels/channels_page/channel_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -390,20 +390,18 @@ class _DmAvatar extends ConsumerWidget {
child: Stack(
clipBehavior: Clip.none,
children: [
CircleAvatar(
AvatarImage(
imageUrl: avatarUrl,
radius: 10,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,
child: avatarUrl == null
? Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
fontSize: 9,
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
)
: null,
fallback: Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
fontSize: 9,
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
),
),
Positioned(
right: -1,
Expand Down
13 changes: 6 additions & 7 deletions mobile/lib/features/channels/channels_page/sheets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,12 @@ class _NewDirectMessageSheet extends HookConsumerWidget {
children: [
for (final user in availableResults)
ListTile(
leading: CircleAvatar(
backgroundImage: user.avatarUrl != null
? NetworkImage(user.avatarUrl!)
: null,
child: user.avatarUrl == null
? Text(user.label.substring(0, 1).toUpperCase())
: null,
leading: AvatarImage(
imageUrl: user.avatarUrl,
radius: 20,
fallback: Text(
user.label.substring(0, 1).toUpperCase(),
),
),
title: Text(user.label),
subtitle: Text(user.secondaryLabel),
Expand Down
1 change: 1 addition & 0 deletions mobile/lib/features/channels/compose_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:nostr/nostr.dart' as nostr;

import '../../shared/relay/relay.dart';
import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../profile/user_cache_provider.dart';
import '../profile/user_profile.dart';
import '../custom_emoji/custom_emoji.dart';
Expand Down
20 changes: 8 additions & 12 deletions mobile/lib/features/channels/compose_bar/suggestions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,16 @@ class _MentionSuggestions extends StatelessWidget {
return ListTile(
dense: true,
visualDensity: VisualDensity.compact,
leading: CircleAvatar(
leading: AvatarImage(
imageUrl: avatarUrl,
radius: 14,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null
? NetworkImage(avatarUrl)
: null,
child: avatarUrl == null
? Text(
name[0].toUpperCase(),
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
),
)
: null,
fallback: Text(
name[0].toUpperCase(),
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
),
),
),
title: Text(name, style: context.textTheme.bodyMedium),
subtitle: _MentionSuggestionInfo.build(
Expand Down
22 changes: 6 additions & 16 deletions mobile/lib/features/channels/members_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../profile/user_cache_provider.dart';
import '../profile/user_profile.dart';
import '../profile/user_status.dart';
Expand Down Expand Up @@ -449,29 +450,18 @@ class _RoleSelector extends StatelessWidget {
}
}

class _MemberAvatar extends HookWidget {
class _MemberAvatar extends StatelessWidget {
final String? avatarUrl;
final String initial;

const _MemberAvatar({required this.avatarUrl, required this.initial});

@override
Widget build(BuildContext context) {
final failed = useState(false);

useEffect(() {
failed.value = false;
return null;
}, [avatarUrl]);

final url = avatarUrl;
if (url == null || failed.value) {
return CircleAvatar(child: Text(initial));
}
return CircleAvatar(
backgroundImage: NetworkImage(url),
onBackgroundImageError: (_, _) => failed.value = true,
child: null,
return AvatarImage(
imageUrl: avatarUrl,
radius: 20,
fallback: Text(initial),
);
}
}
22 changes: 6 additions & 16 deletions mobile/lib/features/channels/reaction_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../custom_emoji/custom_emoji_render.dart';
import '../profile/user_cache_provider.dart';
import '../profile/user_profile.dart';
Expand Down Expand Up @@ -279,29 +280,18 @@ class _ReactorTile extends StatelessWidget {
}
}

class _ReactorAvatar extends HookWidget {
class _ReactorAvatar extends StatelessWidget {
final String? avatarUrl;
final String initial;

const _ReactorAvatar({required this.avatarUrl, required this.initial});

@override
Widget build(BuildContext context) {
final failed = useState(false);

useEffect(() {
failed.value = false;
return null;
}, [avatarUrl]);

final url = avatarUrl;
if (url == null || failed.value) {
return CircleAvatar(child: Text(initial));
}
return CircleAvatar(
backgroundImage: NetworkImage(url),
onBackgroundImageError: (_, _) => failed.value = true,
child: null,
return AvatarImage(
imageUrl: avatarUrl,
radius: 20,
fallback: Text(initial),
);
}
}
Expand Down
23 changes: 11 additions & 12 deletions mobile/lib/features/channels/small_avatar.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';

import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../profile/user_profile.dart';

/// 20px circle avatar used in thread summary rows and other compact lists.
Expand All @@ -24,20 +25,18 @@ class SmallAvatar extends StatelessWidget {
shape: BoxShape.circle,
border: Border.all(color: context.colors.surface, width: 1.5),
),
child: CircleAvatar(
child: AvatarImage(
imageUrl: avatarUrl,
radius: 9,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,
child: avatarUrl == null
? Text(
initial,
style: TextStyle(
fontSize: 8,
fontWeight: FontWeight.w600,
color: context.colors.onPrimaryContainer,
),
)
: null,
fallback: Text(
initial,
style: TextStyle(
fontSize: 8,
fontWeight: FontWeight.w600,
color: context.colors.onPrimaryContainer,
),
),
),
);
}
Expand Down
21 changes: 10 additions & 11 deletions mobile/lib/features/channels/thread_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../../shared/widgets/frosted_app_bar.dart';
import '../../shared/widgets/frosted_scaffold.dart';
import '../profile/user_cache_provider.dart';
Expand Down Expand Up @@ -569,19 +570,17 @@ class _Avatar extends StatelessWidget {
profile?.initial ?? (pubkey.isNotEmpty ? pubkey[0].toUpperCase() : '?');
final avatarUrl = profile?.avatarUrl;

return CircleAvatar(
return AvatarImage(
imageUrl: avatarUrl,
radius: 14,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,
child: avatarUrl == null
? Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
)
: null,
fallback: Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
),
);
}
}
21 changes: 10 additions & 11 deletions mobile/lib/features/forum/forum_post_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

import '../../shared/theme/theme.dart';
import '../../shared/widgets/avatar_image.dart';
import '../channels/message_content.dart';
import '../profile/user_cache_provider.dart';
import '../profile/user_profile_sheet.dart';
Expand Down Expand Up @@ -260,19 +261,17 @@ class _PostAvatar extends StatelessWidget {
profile?.initial ?? (pubkey.isNotEmpty ? pubkey[0].toUpperCase() : '?');
final avatarUrl = profile?.avatarUrl;

return CircleAvatar(
return AvatarImage(
imageUrl: avatarUrl,
radius: 14,
backgroundColor: context.colors.primaryContainer,
backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,
child: avatarUrl == null
? Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
)
: null,
fallback: Text(
initial,
style: context.textTheme.labelSmall?.copyWith(
color: context.colors.onPrimaryContainer,
fontWeight: FontWeight.w600,
),
),
);
}
}
Expand Down
Loading