feat(ui): Show an indicator for the swipe gesture

This commit is contained in:
PapaTutuWawa 2022-12-03 18:26:06 +01:00
parent adcfdc1a73
commit e5553699c5
3 changed files with 87 additions and 11 deletions

View File

@ -1,13 +1,27 @@
import 'package:flutter/material.dart';
class BlinkingMicrophoneIcon extends StatefulWidget {
const BlinkingMicrophoneIcon({ super.key });
class BlinkingIcon extends StatefulWidget {
const BlinkingIcon({
required this.icon,
required this.duration,
required this.start,
required this.end,
this.size,
this.delay = Duration.zero,
super.key,
});
final IconData icon;
final double? size;
final Duration delay;
final Duration duration;
final Color start;
final Color end;
@override
BlinkingMicrophoneIconState createState() => BlinkingMicrophoneIconState();
BlinkingIconState createState() => BlinkingIconState();
}
class BlinkingMicrophoneIconState extends State<BlinkingMicrophoneIcon> with TickerProviderStateMixin {
class BlinkingIconState extends State<BlinkingIcon> with TickerProviderStateMixin {
late final AnimationController _recordingBlinkController;
late final Animation<Color?> _recordingBlink;
bool _blinkForward = true;
@ -17,13 +31,13 @@ class BlinkingMicrophoneIconState extends State<BlinkingMicrophoneIcon> with Tic
super.initState();
_recordingBlinkController = AnimationController(
duration: const Duration(milliseconds: 600),
duration: widget.duration,
vsync: this,
);
_recordingBlink = ColorTween(
begin: Colors.white,
end: Colors.red.shade600,
begin: widget.start,
end: widget.end,
).animate(_recordingBlinkController)
..addStatusListener((status) {
if (status == AnimationStatus.completed ||
@ -38,9 +52,14 @@ class BlinkingMicrophoneIconState extends State<BlinkingMicrophoneIcon> with Tic
}
});
_recordingBlinkController.forward();
_startBlinking();
}
Future<void> _startBlinking() async {
await Future<void>.delayed(widget.delay);
await _recordingBlinkController.forward();
}
@override
void dispose() {
_recordingBlinkController.dispose();
@ -53,8 +72,9 @@ class BlinkingMicrophoneIconState extends State<BlinkingMicrophoneIcon> with Tic
animation: _recordingBlink,
builder: (_, __) {
return Icon(
Icons.mic,
widget.icon,
color: _recordingBlink.value,
size: widget.size,
);
},
);

View File

@ -290,7 +290,12 @@ class ConversationBottomRowState extends State<ConversationBottomRow> {
onPressed: null,
heroTag: 'fabDragged',
backgroundColor: Colors.red.shade600,
child: const BlinkingMicrophoneIcon(),
child: BlinkingIcon(
icon: Icons.mic,
duration: const Duration(milliseconds: 600),
start: Colors.white,
end: Colors.red.shade600,
),
),
),
childWhenDragging: SizedBox(

View File

@ -461,6 +461,52 @@ class ConversationPageState extends State<ConversationPage> with TickerProviderS
),
),
// Indicator for the swipe to lock gesture
Positioned(
right: 8,
bottom: 100,
child: IgnorePointer(
child: BlocBuilder<ConversationBloc, ConversationState>(
builder: (context, state) {
return AnimatedScale(
scale: state.isRecording && !state.isLocked ? 1 : 0,
duration: const Duration(milliseconds: 200),
child: SizedBox(
height: 24 * 3,
width: 47,
child: Stack(
clipBehavior: Clip.none,
children: const [
Positioned(
bottom: 0,
child: Icon(
Icons.keyboard_arrow_up,
size: 48,
),
),
Positioned(
bottom: 12,
child: Icon(
Icons.keyboard_arrow_up,
size: 48,
),
),
Positioned(
bottom: 24,
child: Icon(
Icons.keyboard_arrow_up,
size: 48,
),
),
],
),
),
);
},
),
),
),
Positioned(
right: 8,
bottom: 250,
@ -493,7 +539,12 @@ class ConversationPageState extends State<ConversationPage> with TickerProviderS
Colors.red.shade600 :
Colors.grey,
child: state.isLocked ?
const BlinkingMicrophoneIcon() :
BlinkingIcon(
icon: Icons.mic,
duration: const Duration(milliseconds: 600),
start: Colors.white,
end: Colors.red.shade600,
) :
const Icon(Icons.lock, color: Colors.white),
),
),