design: Add scale animation hover effects on navrail and story buttons

This commit is contained in:
Krille 2023-08-16 07:18:59 +02:00
parent bc74167bc7
commit f051fc1851
No known key found for this signature in database
2 changed files with 94 additions and 65 deletions

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart';
import '../../config/themes.dart';
class NaviRailItem extends StatelessWidget {
class NaviRailItem extends StatefulWidget {
final String toolTip;
final bool isSelected;
final void Function() onTap;
@ -19,8 +19,23 @@ class NaviRailItem extends StatelessWidget {
Key? key,
}) : super(key: key);
@override
State<NaviRailItem> createState() => _NaviRailItemState();
}
class _NaviRailItemState extends State<NaviRailItem> {
bool _hovered = false;
void _onHover(bool hover) {
if (hover == _hovered) return;
setState(() {
_hovered = hover;
});
}
@override
Widget build(BuildContext context) {
final borderRadius = BorderRadius.circular(AppConfig.borderRadius);
return SizedBox(
height: 64,
width: 64,
@ -31,7 +46,7 @@ class NaviRailItem extends StatelessWidget {
bottom: 16,
left: 0,
child: AnimatedContainer(
width: isSelected ? 4 : 0,
width: widget.isSelected ? 4 : 0,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
decoration: BoxDecoration(
@ -44,20 +59,31 @@ class NaviRailItem extends StatelessWidget {
),
),
Center(
child: IconButton(
onPressed: onTap,
tooltip: toolTip,
icon: Material(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
color: isSelected
child: AnimatedScale(
scale: _hovered ? 1.2 : 1.0,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Material(
borderRadius: borderRadius,
color: widget.isSelected
? Theme.of(context).colorScheme.primaryContainer
: Theme.of(context).colorScheme.background,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 8.0,
child: Tooltip(
message: widget.toolTip,
child: InkWell(
borderRadius: borderRadius,
onTap: widget.onTap,
onHover: _onHover,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 8.0,
),
child: widget.isSelected
? widget.selectedIcon ?? widget.icon
: widget.icon,
),
),
child: isSelected ? selectedIcon ?? icon : icon,
),
),
),

View file

@ -10,6 +10,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../config/themes.dart';
enum ContextualRoomAction {
mute,
@ -108,7 +109,7 @@ class StoriesHeader extends StatelessWidget {
...client.storiesRooms..remove(ownStoryRoom),
];
return SizedBox(
height: 96,
height: 104,
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 12),
scrollDirection: Axis.horizontal,
@ -157,7 +158,7 @@ extension on Room {
}
}
class _StoryButton extends StatelessWidget {
class _StoryButton extends StatefulWidget {
final Profile profile;
final bool showEditFab;
final bool unread;
@ -177,27 +178,44 @@ class _StoryButton extends StatelessWidget {
Key? key,
}) : super(key: key);
@override
State<_StoryButton> createState() => _StoryButtonState();
}
class _StoryButtonState extends State<_StoryButton> {
bool _hovered = false;
void _onHover(bool hover) {
if (hover == _hovered) return;
setState(() {
_hovered = hover;
});
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 78,
child: InkWell(
borderRadius: BorderRadius.circular(7),
onTap: onPressed,
onLongPress: onLongPressed,
child: Opacity(
opacity: hasPosts ? 1 : 0.4,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Column(
children: [
const SizedBox(height: 8),
Material(
return InkWell(
onHover: _onHover,
borderRadius: BorderRadius.circular(7),
onTap: widget.onPressed,
onLongPress: widget.onLongPressed,
child: Opacity(
opacity: widget.hasPosts ? 1 : 0.4,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Column(
children: [
const SizedBox(height: 8),
AnimatedScale(
scale: _hovered ? 1.15 : 1.0,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Material(
borderRadius: BorderRadius.circular(Avatar.defaultSize),
child: Container(
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
gradient: unread
gradient: widget.unread
? const LinearGradient(
colors: [
Colors.red,
@ -208,38 +226,23 @@ class _StoryButton extends StatelessWidget {
end: Alignment.bottomRight,
)
: null,
color: unread
color: widget.unread
? null
: Theme.of(context).colorScheme.surfaceVariant,
borderRadius: BorderRadius.circular(Avatar.defaultSize),
),
child: Stack(
children: [
Material(
color: Theme.of(context).colorScheme.surface,
borderRadius:
BorderRadius.circular(Avatar.defaultSize),
child: Padding(
padding: const EdgeInsets.all(2.0),
child: CircleAvatar(
radius: 30,
backgroundColor:
Theme.of(context).colorScheme.surface,
foregroundColor:
Theme.of(context).textTheme.bodyLarge?.color,
child: Hero(
tag: heroTag,
child: Avatar(
mxContent: profile.avatarUrl,
name: profile.displayName,
size: 100,
fontSize: 24,
),
),
),
Hero(
tag: widget.heroTag,
child: Avatar(
mxContent: widget.profile.avatarUrl,
name: widget.profile.displayName,
size: 72,
fontSize: 26,
),
),
if (showEditFab)
if (widget.showEditFab)
Positioned(
right: 0,
bottom: 0,
@ -261,19 +264,19 @@ class _StoryButton extends StatelessWidget {
),
),
),
Center(
child: Text(
profile.displayName ?? '',
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: unread ? FontWeight.bold : null,
),
),
Center(
child: Text(
widget.profile.displayName ?? '',
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: widget.unread ? FontWeight.bold : null,
),
),
],
),
),
],
),
),
),