Merge pull request #927 from pangeachat/pressable-messages

don't rely on fixed dimensions to render pressable buttons, animate i…
pull/1476/head
ggurdin 1 year ago committed by GitHub
commit 889dba298c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -35,6 +35,7 @@ abstract class AppConfig {
static const Color activeToggleColor = Color(0xFF33D057);
static const Color success = Color(0xFF33D057);
static const Color warning = Color.fromARGB(255, 210, 124, 12);
static const int overlayAnimationDuration = 250;
// static String _privacyUrl =
// 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md';
static String _privacyUrl = "https://www.pangeachat.com/privacy";

@ -1699,7 +1699,7 @@ class ChatController extends State<ChatPageWithRoom>
context: context,
child: overlayEntry,
transformTargetId: "",
backgroundColor: const Color.fromRGBO(0, 0, 0, 1).withAlpha(150),
backgroundColor: Colors.black,
closePrevOverlay:
MatrixState.pangeaController.subscriptionController.isSubscribed,
position: OverlayPositionEnum.centered,

@ -1,6 +1,7 @@
import 'dart:developer';
import 'dart:ui';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/utils/any_state_holder.dart';
import 'package:fluffychat/pangea/widgets/common_widgets/overlay_container.dart';
import 'package:flutter/foundation.dart';
@ -219,7 +220,7 @@ class OverlayUtil {
static bool get isOverlayOpen => MatrixState.pAnyState.entries.isNotEmpty;
}
class TransparentBackdrop extends StatelessWidget {
class TransparentBackdrop extends StatefulWidget {
final Color? backgroundColor;
final Function? onDismiss;
final bool blurBackground;
@ -231,34 +232,91 @@ class TransparentBackdrop extends StatelessWidget {
this.blurBackground = false,
});
@override
TransparentBackdropState createState() => TransparentBackdropState();
}
class TransparentBackdropState extends State<TransparentBackdrop>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _opacityTween;
late Animation<double> _blurTween;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration:
const Duration(milliseconds: AppConfig.overlayAnimationDuration),
vsync: this,
);
_opacityTween = Tween<double>(begin: 0.0, end: 0.8).animate(
CurvedAnimation(
parent: _controller,
curve: FluffyThemes.animationCurve,
),
);
_blurTween = Tween<double>(begin: 0.0, end: 2.5).animate(
CurvedAnimation(
parent: _controller,
curve: FluffyThemes.animationCurve,
),
);
Future.delayed(const Duration(milliseconds: 100), () {
if (mounted) _controller.forward();
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Material(
borderOnForeground: false,
color: backgroundColor ?? Colors.transparent,
clipBehavior: Clip.antiAlias,
child: InkWell(
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () {
if (onDismiss != null) {
onDismiss!();
}
MatrixState.pAnyState.closeOverlay();
},
child: BackdropFilter(
filter: blurBackground
? ImageFilter.blur(sigmaX: 2.5, sigmaY: 2.5)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: Container(
height: double.infinity,
width: double.infinity,
color: Colors.transparent,
return AnimatedBuilder(
animation: _opacityTween,
builder: (context, _) {
return Material(
borderOnForeground: false,
color: widget.backgroundColor?.withOpacity(_opacityTween.value) ??
Colors.transparent,
clipBehavior: Clip.antiAlias,
child: InkWell(
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () {
if (widget.onDismiss != null) {
widget.onDismiss!();
}
MatrixState.pAnyState.closeOverlay();
},
child: AnimatedBuilder(
animation: _blurTween,
builder: (context, _) {
return BackdropFilter(
filter: widget.blurBackground
? ImageFilter.blur(
sigmaX: _blurTween.value,
sigmaY: _blurTween.value,
)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: Container(
height: double.infinity,
width: double.infinity,
color: Colors.transparent,
),
);
},
),
),
),
),
// ),
);
},
);
}
}

@ -80,7 +80,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
super.initState();
_animationController = AnimationController(
vsync: this,
duration: FluffyThemes.animationDuration,
duration:
const Duration(milliseconds: AppConfig.overlayAnimationDuration),
);
activitiesLeftToComplete = activitiesLeftToComplete -
@ -372,7 +373,8 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
widget.chatController.scrollController.animateTo(
widget.chatController.scrollController.offset - scrollOffset,
duration: FluffyThemes.animationDuration,
duration:
const Duration(milliseconds: AppConfig.overlayAnimationDuration),
curve: FluffyThemes.animationCurve,
);
_animationController.forward();

@ -94,8 +94,6 @@ class ToolbarButtons extends StatelessWidget {
return Tooltip(
message: mode.tooltip(context),
child: PressableButton(
width: buttonSize,
height: buttonSize,
borderRadius: BorderRadius.circular(20),
enabled: enabled,
depressed: !enabled || mode == overlayController.toolbarMode,

@ -75,7 +75,8 @@ class OverlayMessage extends StatelessWidget {
);
final displayEvent = pangeaMessageEvent.event.getDisplayEvent(timeline);
var color = theme.colorScheme.surfaceContainerHighest;
// ignore: deprecated_member_use
var color = theme.colorScheme.surfaceVariant;
if (ownMessage) {
color = displayEvent.status.isError
? Colors.redAccent

@ -4,21 +4,15 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class PressableButton extends StatefulWidget {
final double width;
final double height;
final BorderRadius borderRadius;
final double buttonHeight;
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,
@ -53,6 +47,7 @@ class PressableButtonState extends State<PressableButton>
void _onTapDown(TapDownDetails details) {
if (!widget.enabled) return;
_animationCompleter = Completer<void>();
if (!mounted) return;
_controller.forward().then((_) {
_animationCompleter?.complete();
_animationCompleter = null;
@ -61,17 +56,17 @@ class PressableButtonState extends State<PressableButton>
Future<void> _onTapUp(TapUpDetails details) async {
if (!widget.enabled) return;
widget.onPressed?.call();
if (_animationCompleter != null) {
await _animationCompleter!.future;
}
_controller.reverse();
widget.onPressed?.call();
if (mounted) _controller.reverse();
HapticFeedback.mediumImpact();
}
void _onTapCancel() {
if (!widget.enabled) return;
_controller.reverse();
if (mounted) _controller.reverse();
}
@override
@ -86,28 +81,31 @@ class PressableButtonState extends State<PressableButton>
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: _onTapCancel,
child: Stack(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: Color.alphaBlend(
Colors.black.withOpacity(0.25),
widget.color,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
AnimatedBuilder(
animation: _tweenAnimation,
builder: (context, _) {
return Container(
padding: EdgeInsets.only(bottom: _tweenAnimation.value),
decoration: BoxDecoration(
color: Color.alphaBlend(
Colors.black.withOpacity(0.25),
widget.color,
),
borderRadius: widget.borderRadius,
),
child: widget.child,
);
},
),
borderRadius: widget.borderRadius,
),
),
AnimatedBuilder(
animation: _tweenAnimation,
builder: (context, _) {
return Positioned(
bottom: widget.depressed ? 0 : _tweenAnimation.value,
child: widget.child,
);
},
],
),
],
),

Loading…
Cancel
Save