chore: Add fancy hero animations

This commit is contained in:
Christian Pauly 2022-07-08 10:41:36 +02:00
parent b76453483e
commit d25d8cc1c2
5 changed files with 71 additions and 53 deletions

View File

@ -39,10 +39,13 @@ class ChatAppBarTitle extends StatelessWidget {
: () => VRouter.of(context).toSegments(['rooms', room.id, 'details']), : () => VRouter.of(context).toSegments(['rooms', room.id, 'details']),
child: Row( child: Row(
children: [ children: [
Avatar( Hero(
mxContent: room.avatar, tag: 'content_banner',
name: room.displayname, child: Avatar(
size: 32, mxContent: room.avatar,
name: room.displayname,
size: 32,
),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(

View File

@ -119,7 +119,7 @@ class StoriesHeader extends StatelessWidget {
...client.storiesRooms..remove(ownStoryRoom), ...client.storiesRooms..remove(ownStoryRoom),
]; ];
return SizedBox( return SizedBox(
height: 106, height: 98,
child: ListView.builder( child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 2), padding: const EdgeInsets.symmetric(horizontal: 2),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -145,6 +145,7 @@ class StoriesHeader extends StatelessWidget {
avatarUrl: avatarUrl, avatarUrl: avatarUrl,
userId: userId ?? 'Unknown', userId: userId ?? 'Unknown',
), ),
heroTag: 'stories_${room.id}',
hasPosts: room.hasPosts || room == ownStoryRoom, hasPosts: room.hasPosts || room == ownStoryRoom,
showEditFab: userId == client.userID, showEditFab: userId == client.userID,
unread: room.membership == Membership.invite || unread: room.membership == Membership.invite ||
@ -186,10 +187,12 @@ class _StoryButton extends StatelessWidget {
final bool hasPosts; final bool hasPosts;
final void Function() onPressed; final void Function() onPressed;
final void Function()? onLongPressed; final void Function()? onLongPressed;
final String heroTag;
const _StoryButton({ const _StoryButton({
required this.profile, required this.profile,
required this.onPressed, required this.onPressed,
required this.heroTag,
this.showEditFab = false, this.showEditFab = false,
this.hasPosts = true, this.hasPosts = true,
this.unread = false, this.unread = false,
@ -246,11 +249,14 @@ class _StoryButton extends StatelessWidget {
Theme.of(context).colorScheme.surface, Theme.of(context).colorScheme.surface,
foregroundColor: foregroundColor:
Theme.of(context).textTheme.bodyText1?.color, Theme.of(context).textTheme.bodyText1?.color,
child: Avatar( child: Hero(
mxContent: profile.avatarUrl, tag: heroTag,
name: profile.displayName, child: Avatar(
size: 100, mxContent: profile.avatarUrl,
fontSize: 24, name: profile.displayName,
size: 100,
fontSize: 24,
),
), ),
), ),
), ),

View File

@ -83,9 +83,12 @@ class StoryView extends StatelessWidget {
), ),
) )
: null, : null,
leading: Avatar( leading: Hero(
mxContent: controller.avatar, tag: 'stories_${controller.roomId}',
name: controller.title, child: Avatar(
mxContent: controller.avatar,
name: controller.title,
),
), ),
), ),
actions: currentEvent == null actions: currentEvent == null

View File

@ -54,39 +54,40 @@ class Avatar extends StatelessWidget {
), ),
); );
final borderRadius = BorderRadius.circular(size / 2); final borderRadius = BorderRadius.circular(size / 2);
return InkWell( final container = Container(
onTap: onTap, decoration: BoxDecoration(
borderRadius: borderRadius, border: Border.all(color: Theme.of(context).dividerColor),
child: Container( borderRadius: borderRadius,
decoration: BoxDecoration( ),
border: Border.all(color: Theme.of(context).dividerColor), child: ClipRRect(
borderRadius: borderRadius, borderRadius: borderRadius,
), child: Container(
child: ClipRRect( width: size,
borderRadius: borderRadius, height: size,
child: Container( color:
width: size, noPic ? name?.lightColor : Theme.of(context).secondaryHeaderColor,
height: size, child: noPic
color: noPic ? textWidget
? name?.lightColor : CachedNetworkImage(
: Theme.of(context).secondaryHeaderColor, imageUrl: src.toString(),
child: noPic fit: BoxFit.cover,
? textWidget width: size,
: CachedNetworkImage( height: size,
imageUrl: src.toString(), placeholder: (c, s) => textWidget,
fit: BoxFit.cover, errorWidget: (c, s, d) => Stack(
width: size, children: [
height: size, textWidget,
placeholder: (c, s) => textWidget, ],
errorWidget: (c, s, d) => Stack(
children: [
textWidget,
],
),
), ),
), ),
), ),
), ),
); );
if (onTap == null) return container;
return InkWell(
onTap: onTap,
borderRadius: borderRadius,
child: container,
);
} }
} }

View File

@ -15,6 +15,7 @@ class ContentBanner extends StatelessWidget {
final void Function()? onEdit; final void Function()? onEdit;
final Client? client; final Client? client;
final double opacity; final double opacity;
final String heroTag;
const ContentBanner( const ContentBanner(
{this.mxContent, {this.mxContent,
@ -24,6 +25,7 @@ class ContentBanner extends StatelessWidget {
this.onEdit, this.onEdit,
this.client, this.client,
this.opacity = 0.75, this.opacity = 0.75,
this.heroTag = 'content_banner',
Key? key}) Key? key})
: super(key: key); : super(key: key);
@ -62,16 +64,19 @@ class ContentBanner extends StatelessWidget {
method: ThumbnailMethod.scale, method: ThumbnailMethod.scale,
animated: true, animated: true,
); );
return CachedNetworkImage( return Hero(
imageUrl: src.toString(), tag: heroTag,
height: 300, child: CachedNetworkImage(
fit: BoxFit.cover, imageUrl: src.toString(),
errorWidget: (c, m, e) => Icon( height: 300,
defaultIcon, fit: BoxFit.cover,
size: 200, errorWidget: (c, m, e) => Icon(
color: Theme.of(context) defaultIcon,
.colorScheme size: 200,
.onSecondaryContainer, color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
),
), ),
); );
}) })