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 toolbarMinHeight = 70.0;
static const double toolbarMinWidth = 270.0;
static const double toolbarButtonsHeight = 50.0;
// #Pangea
// static const Color primaryColor = Color(0xFF5625BA);
// static const Color primaryColorLight = Color(0xFFCCBDEA);

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

@ -281,9 +281,9 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
return reactionsEvents.where((e) => !e.redacted).isNotEmpty;
}
final double toolbarButtonsHeight = 50;
double get reactionsHeight => hasReactions ? 28 : 0;
double get belowMessageHeight => toolbarButtonsHeight + reactionsHeight;
double get belowMessageHeight =>
AppConfig.toolbarButtonsHeight + reactionsHeight;
void setIsPlayingAudio(bool isPlaying) {
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/matrix_event_wrappers/pangea_message_event.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:flutter/material.dart';
@ -31,6 +32,7 @@ class ToolbarButtons extends StatelessWidget {
MatrixState.pangeaController.languageController.userL2?.langCode;
static const double iconWidth = 36.0;
static const buttonSize = 40.0;
@override
Widget build(BuildContext context) {
@ -44,7 +46,7 @@ class ToolbarButtons extends StatelessWidget {
return SizedBox(
width: width,
height: 50,
height: AppConfig.toolbarButtonsHeight,
child: Stack(
alignment: Alignment.center,
children: [
@ -75,37 +77,50 @@ class ToolbarButtons extends StatelessWidget {
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: modes
.mapIndexed(
(index, mode) => IconButton(
iconSize: 20,
icon: Icon(mode.icon),
tooltip: mode.tooltip(context),
color: mode == overlayController.toolbarMode
? Colors.white
: null,
isSelected: mode == overlayController.toolbarMode,
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(
mode.iconButtonColor(
context,
children: modes.mapIndexed((index, mode) {
final enabled = mode.isUnlocked(
index,
overlayController.toolbarMode,
pangeaMessageEvent.numberOfActivitiesCompleted,
totallyDone,
),
),
),
onPressed: mode.isUnlocked(
);
final color = mode.iconButtonColor(
context,
index,
overlayController.toolbarMode,
pangeaMessageEvent.numberOfActivitiesCompleted,
totallyDone,
)
);
return Tooltip(
message: mode.tooltip(context),
child: PressableButton(
width: buttonSize,
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,
),
),
)
.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