Merge pull request #913 from pangeachat/pushable-buttons

added press animations to toolbar buttons
pull/1476/head
ggurdin 1 year ago committed by GitHub
commit 7525acfa05
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -25,6 +25,7 @@ abstract class AppConfig {
static const double toolbarMaxHeight = 300.0; static const double toolbarMaxHeight = 300.0;
static const double toolbarMinHeight = 70.0; static const double toolbarMinHeight = 70.0;
static const double toolbarMinWidth = 270.0; static const double toolbarMinWidth = 270.0;
static const double toolbarButtonsHeight = 50.0;
// #Pangea // #Pangea
// static const Color primaryColor = Color(0xFF5625BA); // static const Color primaryColor = Color(0xFF5625BA);
// static const Color primaryColorLight = Color(0xFFCCBDEA); // static const Color primaryColorLight = Color(0xFFCCBDEA);

@ -101,11 +101,7 @@ extension MessageModeExtension on MessageMode {
} }
//unlocked and active //unlocked and active
if (this == currentMode) { if (this == currentMode) return Theme.of(context).colorScheme.primary;
return Theme.of(context).brightness == Brightness.dark
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.primary;
}
//unlocked and inactive //unlocked and inactive
return Theme.of(context).colorScheme.primaryContainer; return Theme.of(context).colorScheme.primaryContainer;

@ -281,9 +281,9 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
return reactionsEvents.where((e) => !e.redacted).isNotEmpty; return reactionsEvents.where((e) => !e.redacted).isNotEmpty;
} }
final double toolbarButtonsHeight = 50;
double get reactionsHeight => hasReactions ? 28 : 0; double get reactionsHeight => hasReactions ? 28 : 0;
double get belowMessageHeight => toolbarButtonsHeight + reactionsHeight; double get belowMessageHeight =>
AppConfig.toolbarButtonsHeight + reactionsHeight;
void setIsPlayingAudio(bool isPlaying) { void setIsPlayingAudio(bool isPlaying) {
if (mounted) { if (mounted) {

@ -6,6 +6,7 @@ import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pangea/enum/message_mode_enum.dart'; import 'package:fluffychat/pangea/enum/message_mode_enum.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart'; import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
import 'package:fluffychat/pangea/widgets/pressable_button.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -31,6 +32,7 @@ class ToolbarButtons extends StatelessWidget {
MatrixState.pangeaController.languageController.userL2?.langCode; MatrixState.pangeaController.languageController.userL2?.langCode;
static const double iconWidth = 36.0; static const double iconWidth = 36.0;
static const buttonSize = 40.0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -44,7 +46,7 @@ class ToolbarButtons extends StatelessWidget {
return SizedBox( return SizedBox(
width: width, width: width,
height: 50, height: AppConfig.toolbarButtonsHeight,
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
@ -75,37 +77,50 @@ class ToolbarButtons extends StatelessWidget {
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: modes children: modes.mapIndexed((index, mode) {
.mapIndexed( final enabled = mode.isUnlocked(
(index, mode) => IconButton( index,
iconSize: 20, pangeaMessageEvent.numberOfActivitiesCompleted,
icon: Icon(mode.icon), totallyDone,
tooltip: mode.tooltip(context), );
color: mode == overlayController.toolbarMode final color = mode.iconButtonColor(
? Colors.white context,
: null, index,
isSelected: mode == overlayController.toolbarMode, overlayController.toolbarMode,
style: ButtonStyle( pangeaMessageEvent.numberOfActivitiesCompleted,
backgroundColor: WidgetStateProperty.all( totallyDone,
mode.iconButtonColor( );
context, return Tooltip(
index, message: mode.tooltip(context),
overlayController.toolbarMode, child: PressableButton(
pangeaMessageEvent.numberOfActivitiesCompleted, width: buttonSize,
totallyDone, height: buttonSize,
), borderRadius: BorderRadius.circular(20),
), enabled: enabled,
depressed: !enabled || mode == overlayController.toolbarMode,
color: color,
onPressed: enabled
? () => overlayController.updateToolbarMode(mode)
: null,
child: AnimatedContainer(
duration: FluffyThemes.animationDuration,
height: buttonSize,
width: buttonSize,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
child: Icon(
mode.icon,
size: 20,
color: mode == overlayController.toolbarMode
? Colors.white
: null,
), ),
onPressed: mode.isUnlocked(
index,
pangeaMessageEvent.numberOfActivitiesCompleted,
totallyDone,
)
? () => overlayController.updateToolbarMode(mode)
: null,
), ),
) ),
.toList(), );
}).toList(),
), ),
], ],
), ),

@ -0,0 +1,106 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class PressableButton extends StatefulWidget {
final double width;
final double height;
final BorderRadius borderRadius;
final bool enabled;
final bool depressed;
final Color color;
final Widget child;
final void Function()? onPressed;
const PressableButton({
required this.width,
required this.height,
required this.borderRadius,
required this.child,
required this.onPressed,
required this.color,
this.enabled = true,
this.depressed = false,
super.key,
});
@override
PressableButtonState createState() => PressableButtonState();
}
class PressableButtonState extends State<PressableButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _tweenAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 100),
vsync: this,
);
_tweenAnimation = Tween<double>(begin: 5, end: 0).animate(_controller);
}
void _onTapDown(TapDownDetails details) {
if (!widget.enabled) return;
_controller.forward();
}
void _onTapUp(TapUpDetails details) {
if (!widget.enabled) return;
_controller.reverse();
widget.onPressed?.call();
HapticFeedback.mediumImpact();
}
void _onTapCancel() {
if (!widget.enabled) return;
_controller.reverse();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: _onTapCancel,
child: SizedBox(
height: 45,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: Color.alphaBlend(
Colors.black.withOpacity(0.25),
widget.color,
),
borderRadius: widget.borderRadius,
),
),
AnimatedBuilder(
animation: _tweenAnimation,
builder: (context, _) {
return Positioned(
bottom: widget.depressed ? 0 : _tweenAnimation.value,
child: widget.child,
);
},
),
],
),
),
);
}
}
Loading…
Cancel
Save