A framework for building convergent cross-platform Nextcloud clients using Flutter.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.1 KiB

part of '../neon.dart';
2 years ago
const kAvatarSize = 40.0;
class AccountAvatar extends StatelessWidget {
const AccountAvatar({
required this.account,
required this.requestManager,
super.key,
});
final Account account;
final RequestManager requestManager;
@override
Widget build(final BuildContext context) => Stack(
children: [
ResultStreamBuilder<Uint8List>(
// TODO: See TODO in cached_url_image.dart
stream: requestManager.wrapBytes(
account.client.id,
'accounts-avatar-${account.id}',
() async => account.client.core.getAvatar(
userId: account.username,
size: (kAvatarSize * MediaQuery.of(context).devicePixelRatio).toInt(),
),
2 years ago
preferCache: true,
),
builder: (
final context,
final avatarData,
final avatarError,
final avatarLoading,
) =>
Stack(
children: [
if (avatarData != null) ...[
CircleAvatar(
radius: kAvatarSize / 2,
backgroundImage: MemoryImage(avatarData),
),
],
if (avatarError != null) ...[
Icon(
Icons.error_outline,
size: 30,
color: Theme.of(context).colorScheme.onBackground,
),
],
if (avatarLoading) ...[
const CircularProgressIndicator(
strokeWidth: 2,
),
],
],
),
),
StandardRxResultBuilder<UserStatusBloc, UserStatus?>(
bloc: RxBlocProvider.of<AccountsBloc>(context).getUserStatusBloc(account),
state: (final bloc) => bloc.userStatus,
builder: (
final context,
final userStatusData,
final userStatusError,
final userStatusLoading,
final _,
) =>
SizedBox(
height: kAvatarSize,
width: kAvatarSize,
child: Align(
alignment: Alignment.bottomRight,
child: Container(
height: kAvatarSize / 3,
width: kAvatarSize / 3,
decoration: userStatusLoading || userStatusError != null || userStatusData == null
? null
: BoxDecoration(
shape: BoxShape.circle,
color: _userStatusToColor(userStatusData),
border: userStatusData.status != UserStatusType.offline &&
userStatusData.status != UserStatusType.invisible
2 years ago
? Border.all(
color: Theme.of(context).colorScheme.onPrimary,
)
: null,
),
child: userStatusLoading
? CircularProgressIndicator(
strokeWidth: 1.5,
color: Theme.of(context).colorScheme.onPrimary,
)
: userStatusError != null &&
(userStatusError is! ApiException || userStatusError.statusCode != 404)
2 years ago
? const Icon(
Icons.error_outline,
size: kAvatarSize / 3,
color: Colors.red,
)
: null,
),
),
),
),
],
);
Color _userStatusToColor(final UserStatus userStatus) {
switch (userStatus.status) {
case UserStatusType.online:
2 years ago
return const Color(0xFF49B382);
case UserStatusType.away:
2 years ago
return const Color(0xFFF4A331);
case UserStatusType.dnd:
2 years ago
return const Color(0xFFED484C);
default:
2 years ago
return Colors.transparent;
}
}
}