Files
Ensemble/lib/widgets/animated_icon_button.dart
Your NameandClaude c791c4e527 Fix playback controls and add button animations
Playback Control Fix:
- Changed from player_command to player_queues API
  - Use player_queues/play, pause, next, previous
  - Changed player_id to queue_id parameter
  - Fixes "Invalid command: player_command/*" errors
- Playback controls (play/pause/next/previous) now work correctly

Button Animations:
- Created AnimatedIconButton widget with scale-down animation
- Added press animations to all playback control buttons
  - Mini player: previous, play/pause, next buttons
  - Now playing screen: previous, play/pause, next buttons
  - Buttons scale to 85% when pressed for tactile feedback
- Custom _AnimatedPlayButton for the circular play/pause button
  - Maintains white circular background
  - Smooth scale animation on press

Buttons now feel responsive and provide visual feedback on tap.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 08:49:12 +00:00

74 lines
1.7 KiB
Dart

import 'package:flutter/material.dart';
/// An IconButton that scales down when pressed for tactile feedback
class AnimatedIconButton extends StatefulWidget {
final IconData icon;
final VoidCallback? onPressed;
final Color? color;
final double? iconSize;
const AnimatedIconButton({
super.key,
required this.icon,
this.onPressed,
this.color,
this.iconSize,
});
@override
State<AnimatedIconButton> createState() => _AnimatedIconButtonState();
}
class _AnimatedIconButtonState extends State<AnimatedIconButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 100),
vsync: this,
);
_scaleAnimation = Tween<double>(begin: 1.0, end: 0.85).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<void> _handleTap() async {
if (widget.onPressed == null) return;
// Animate press
await _controller.forward();
await _controller.reverse();
// Call the callback
widget.onPressed!();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => _controller.forward(),
onTapUp: (_) => _controller.reverse(),
onTapCancel: () => _controller.reverse(),
child: ScaleTransition(
scale: _scaleAnimation,
child: IconButton(
icon: Icon(widget.icon),
color: widget.color,
iconSize: widget.iconSize,
onPressed: _handleTap,
),
),
);
}
}