Add compact voice progress grid
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 2m6s
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 2m6s
This commit is contained in:
@@ -1090,7 +1090,7 @@ class _VoiceStep extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final showNext = canContinue && !isRecording;
|
final canFinish = canContinue;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -1106,8 +1106,11 @@ class _VoiceStep extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
],
|
],
|
||||||
|
_VoiceProgressGrid(progress: informationProgress),
|
||||||
|
const SizedBox(height: 18),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Center(
|
child: Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
child: _LibraryWaveSurface(
|
child: _LibraryWaveSurface(
|
||||||
controller: waveController,
|
controller: waveController,
|
||||||
active: isRecording,
|
active: isRecording,
|
||||||
@@ -1125,40 +1128,76 @@ class _VoiceStep extends StatelessWidget {
|
|||||||
size: 22,
|
size: 22,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
AnimatedSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 180),
|
|
||||||
child: showNext
|
|
||||||
? Padding(
|
|
||||||
key: const ValueKey('next'),
|
|
||||||
padding: const EdgeInsets.only(bottom: 14),
|
|
||||||
child: FilledButton(
|
|
||||||
style: FilledButton.styleFrom(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
foregroundColor: const Color(0xFF090613),
|
|
||||||
),
|
|
||||||
onPressed: isSubmitting ? null : onNext,
|
|
||||||
child: Text(isSubmitting ? 'Отправляем' : 'Далее'),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(key: ValueKey('empty-next')),
|
|
||||||
),
|
|
||||||
_VoiceRecordButton(
|
_VoiceRecordButton(
|
||||||
progress: informationProgress,
|
progress: informationProgress,
|
||||||
liveLevel: liveLevel,
|
liveLevel: liveLevel,
|
||||||
isRecording: isRecording,
|
isRecording: isRecording,
|
||||||
|
canFinish: canFinish,
|
||||||
enabled: hasTelegramAuth && !isSubmitting,
|
enabled: hasTelegramAuth && !isSubmitting,
|
||||||
onPressed: onToggleRecording,
|
onPressed: canFinish ? onNext : onToggleRecording,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _VoiceProgressGrid extends StatelessWidget {
|
||||||
|
const _VoiceProgressGrid({required this.progress});
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const columns = 14;
|
||||||
|
const rows = 3;
|
||||||
|
const total = columns * rows;
|
||||||
|
final filled = (progress.clamp(0.0, 1.0) * total).round();
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: 230,
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 5,
|
||||||
|
runSpacing: 5,
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
children: [
|
||||||
|
for (var index = 0; index < total; index++)
|
||||||
|
AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 180),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _gridOrder(index, total) < filled
|
||||||
|
? const Color(0xFFFF2D75)
|
||||||
|
: Colors.white.withValues(alpha: 0.11),
|
||||||
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
boxShadow: _gridOrder(index, total) < filled
|
||||||
|
? [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color(
|
||||||
|
0xFFFF2D75,
|
||||||
|
).withValues(alpha: 0.34),
|
||||||
|
blurRadius: 12,
|
||||||
|
spreadRadius: 1,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _gridOrder(int index, int total) => ((index + 7) * 29) % total;
|
||||||
|
}
|
||||||
|
|
||||||
class _VoiceRecordButton extends StatefulWidget {
|
class _VoiceRecordButton extends StatefulWidget {
|
||||||
const _VoiceRecordButton({
|
const _VoiceRecordButton({
|
||||||
required this.progress,
|
required this.progress,
|
||||||
required this.liveLevel,
|
required this.liveLevel,
|
||||||
required this.isRecording,
|
required this.isRecording,
|
||||||
|
required this.canFinish,
|
||||||
required this.enabled,
|
required this.enabled,
|
||||||
required this.onPressed,
|
required this.onPressed,
|
||||||
});
|
});
|
||||||
@@ -1166,8 +1205,9 @@ class _VoiceRecordButton extends StatefulWidget {
|
|||||||
final double progress;
|
final double progress;
|
||||||
final double liveLevel;
|
final double liveLevel;
|
||||||
final bool isRecording;
|
final bool isRecording;
|
||||||
|
final bool canFinish;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final Future<void> Function() onPressed;
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_VoiceRecordButton> createState() => _VoiceRecordButtonState();
|
State<_VoiceRecordButton> createState() => _VoiceRecordButtonState();
|
||||||
@@ -1264,7 +1304,7 @@ class _VoiceRecordButtonState extends State<_VoiceRecordButton>
|
|||||||
width: 120,
|
width: 120,
|
||||||
height: 120,
|
height: 120,
|
||||||
child: FilledButton(
|
child: FilledButton(
|
||||||
onPressed: widget.enabled ? () => widget.onPressed() : null,
|
onPressed: widget.enabled ? widget.onPressed : null,
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
foregroundColor: const Color(0xFF090613),
|
foregroundColor: const Color(0xFF090613),
|
||||||
@@ -1275,7 +1315,11 @@ class _VoiceRecordButtonState extends State<_VoiceRecordButton>
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
widget.isRecording ? Icons.pause_rounded : Icons.mic_rounded,
|
widget.canFinish
|
||||||
|
? Icons.check_rounded
|
||||||
|
: widget.isRecording
|
||||||
|
? Icons.pause_rounded
|
||||||
|
: Icons.mic_rounded,
|
||||||
size: 48,
|
size: 48,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user