Add avatar widget

This commit is contained in:
shilangyu 2021-02-18 09:19:00 +01:00
parent 5326eda8f6
commit ae33e277a8
9 changed files with 79 additions and 175 deletions

View File

@ -1,8 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:lemmy_api_client/v2.dart';
import '../util/goto.dart';
import '../widgets/avatar.dart';
import '../widgets/markdown_text.dart';
import '../widgets/sortable_infinite_list.dart';
@ -64,20 +64,6 @@ class CommunitiesListItem extends StatelessWidget {
: null,
onTap: () => goToCommunity.byId(
context, community.instanceHost, community.community.id),
leading: community.community.icon != null
? CachedNetworkImage(
height: 50,
width: 50,
imageUrl: community.community.icon,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover, image: imageProvider),
),
),
errorWidget: (_, __, ___) => const SizedBox(width: 50),
)
: const SizedBox(width: 50),
leading: Avatar(url: community.community.icon),
);
}

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@ -14,6 +13,7 @@ import '../util/extensions/api.dart';
import '../util/extensions/iterators.dart';
import '../util/goto.dart';
import '../util/text_color.dart';
import '../widgets/avatar.dart';
/// List of subscribed communities per instance
class CommunitiesTab extends HookWidget {
@ -178,24 +178,7 @@ class CommunitiesTab extends HookWidget {
onTap: () => goToInstance(context,
accountsStore.loggedInInstances.elementAt(i)),
onLongPress: () => toggleCollapse(i),
leading: instances[i].icon != null
? CachedNetworkImage(
height: 50,
width: 50,
imageUrl: instances[i].icon,
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider),
),
),
errorWidget: (_, __, ___) =>
const SizedBox(width: 50),
)
: const SizedBox(width: 50),
leading: Avatar(url: instances[i].icon),
title: Text(
instances[i].name,
style: theme.textTheme.headline6,
@ -223,26 +206,10 @@ class CommunitiesTab extends HookWidget {
),
title: Row(
children: [
if (comm.community.icon != null)
CachedNetworkImage(
height: 30,
width: 30,
imageUrl: comm.community.icon,
imageBuilder:
(context, imageProvider) =>
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider),
),
),
errorWidget: (_, __, ___) =>
const SizedBox(width: 30),
)
else
const SizedBox(width: 30),
Avatar(
radius: 15,
url: comm.community.icon,
),
const SizedBox(width: 10),
Text(
'!${comm.community.name}${comm.community.local ? '' : '@${comm.community.originInstanceHost}'}',

View File

@ -3,7 +3,6 @@ import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmur/pages/modlog_page.dart';
import 'package:lemmy_api_client/v2.dart';
import 'package:url_launcher/url_launcher.dart' as ul;
@ -16,11 +15,13 @@ import '../util/extensions/spaced.dart';
import '../util/goto.dart';
import '../util/intl.dart';
import '../util/more_icon.dart';
import '../widgets/avatar.dart';
import '../widgets/bottom_modal.dart';
import '../widgets/fullscreenable_image.dart';
import '../widgets/info_table_popup.dart';
import '../widgets/markdown_text.dart';
import '../widgets/sortable_infinite_list.dart';
import 'modlog_page.dart';
/// Displays posts, comments, and general info about the given community
class CommunityPage extends HookWidget {
@ -244,24 +245,11 @@ class _CommunityOverview extends StatelessWidget {
],
),
),
SizedBox(
width: 83,
height: 83,
child: FullscreenableImage(
FullscreenableImage(
url: community.community.icon,
child: Avatar(
url: community.community.icon,
child: CachedNetworkImage(
imageUrl: community.community.icon,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
errorWidget: (_, __, ___) => const Icon(Icons.warning),
),
radius: 83 / 2,
),
),
],

View File

@ -3,7 +3,6 @@ import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmur/pages/modlog_page.dart';
import 'package:lemmy_api_client/v2.dart';
import 'package:url_launcher/url_launcher.dart' as ul;
@ -13,12 +12,14 @@ import '../util/extensions/spaced.dart';
import '../util/goto.dart';
import '../util/more_icon.dart';
import '../util/text_color.dart';
import '../widgets/avatar.dart';
import '../widgets/bottom_modal.dart';
import '../widgets/fullscreenable_image.dart';
import '../widgets/info_table_popup.dart';
import '../widgets/markdown_text.dart';
import '../widgets/sortable_infinite_list.dart';
import 'communities_list.dart';
import 'modlog_page.dart';
import 'users_list.dart';
/// Displays posts, comments, and general info about the given instance
@ -291,24 +292,7 @@ class _AboutTab extends HookWidget {
onTap: () => goToCommunity.byId(
context, c.instanceHost, c.community.id),
title: Text(c.community.name),
leading: c.community.icon != null
? CachedNetworkImage(
height: 50,
width: 50,
imageUrl: c.community.icon,
errorWidget: (_, __, ___) =>
const SizedBox(width: 50, height: 50),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
)
: const SizedBox(width: 50),
leading: Avatar(url: c.community.icon),
)
else if (commSnap.hasError)
Padding(
@ -340,22 +324,7 @@ class _AboutTab extends HookWidget {
? MarkdownText(u.user.bio, instanceHost: instanceHost)
: null,
onTap: () => goToUser.byId(context, instanceHost, u.user.id),
leading: u.user.avatar != null
? CachedNetworkImage(
height: 50,
width: 50,
imageUrl: u.user.avatar,
errorWidget: (_, __, ___) =>
const SizedBox(width: 50, height: 50),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover, image: imageProvider),
),
),
)
: const SizedBox(width: 50),
leading: Avatar(url: u.user.avatar),
),
const _Divider(),
ListTile(

View File

@ -1,9 +1,9 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:lemmy_api_client/v2.dart';
import '../util/extensions/api.dart';
import '../util/goto.dart';
import '../widgets/avatar.dart';
import '../widgets/markdown_text.dart';
/// Infinite list of Users fetched by the given fetcher
@ -53,21 +53,6 @@ class UsersListItem extends StatelessWidget {
)
: null,
onTap: () => goToUser.byId(context, user.instanceHost, user.user.id),
leading: user.user.avatar != null
? CachedNetworkImage(
height: 50,
width: 50,
imageUrl: user.user.avatar,
errorWidget: (_, __, ___) =>
const SizedBox(height: 50, width: 50),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover, image: imageProvider),
),
),
)
: const SizedBox(width: 50),
leading: Avatar(url: user.user.avatar),
);
}

44
lib/widgets/avatar.dart Normal file
View File

@ -0,0 +1,44 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
/// User's avatar.
/// If passed url is null, a blank box is displayed to prevent weird indents
/// Can be disabled with `noBlank`
class Avatar extends StatelessWidget {
const Avatar({
Key key,
@required this.url,
this.radius = 25,
this.noBlank = false,
}) : super(key: key);
final String url;
final double radius;
final bool noBlank;
@override
Widget build(BuildContext context) {
final blankWidget = () {
if (noBlank) return const SizedBox.shrink();
return SizedBox(
width: radius * 2,
height: radius * 2,
);
}();
if (url == null) {
return blankWidget;
}
return ClipOval(
child: CachedNetworkImage(
height: radius * 2,
width: radius * 2,
imageUrl: url,
fit: BoxFit.cover,
errorWidget: (_, __, ___) => blankWidget,
),
);
}
}

View File

@ -1,4 +1,3 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -16,6 +15,7 @@ import '../util/extensions/datetime.dart';
import '../util/goto.dart';
import '../util/intl.dart';
import '../util/text_color.dart';
import 'avatar.dart';
import 'bottom_modal.dart';
import 'info_table_popup.dart';
import 'markdown_text.dart';
@ -337,20 +337,10 @@ class CommentWidget extends HookWidget {
child: InkWell(
onTap: () => goToUser.byId(
context, comment.instanceHost, comment.creator.id),
child: CachedNetworkImage(
imageUrl: comment.creator.avatar,
height: 20,
width: 20,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
errorWidget: (_, __, ___) => const SizedBox.shrink(),
child: Avatar(
url: comment.creator.avatar,
radius: 10,
noBlank: true,
),
),
),

View File

@ -17,6 +17,7 @@ import '../util/extensions/api.dart';
import '../util/extensions/datetime.dart';
import '../util/goto.dart';
import '../util/more_icon.dart';
import 'avatar.dart';
import 'bottom_modal.dart';
import 'fullscreenable_image.dart';
import 'info_table_popup.dart';
@ -125,24 +126,10 @@ class PostWidget extends HookWidget {
child: InkWell(
onTap: () => goToCommunity.byId(
context, instanceHost, post.community.id),
child: SizedBox(
height: 40,
width: 40,
child: CachedNetworkImage(
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
),
imageUrl: post.community.icon,
errorWidget: (context, url, error) =>
Text(error.toString()),
),
child: Avatar(
url: post.community.icon,
noBlank: true,
radius: 20,
),
),
),

View File

@ -12,6 +12,7 @@ import '../util/extensions/datetime.dart';
import '../util/goto.dart';
import '../util/intl.dart';
import '../util/text_color.dart';
import 'avatar.dart';
import 'fullscreenable_image.dart';
import 'markdown_text.dart';
import 'sortable_infinite_list.dart';
@ -340,23 +341,10 @@ class _AboutTab extends HookWidget {
dense: true,
onTap: () => goToCommunity.byId(context, instanceHost, id),
title: Text('!$name'),
leading: icon != null
? CachedNetworkImage(
height: 40,
width: 40,
imageUrl: icon,
errorWidget: (_, __, ___) =>
const SizedBox(width: 40, height: 40),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: imageProvider,
),
),
))
: const SizedBox(width: 40),
leading: Avatar(
url: icon,
radius: 20,
),
);
return ListView(