From 5b2cd4158cfe21aa659f8a287e818cbb7a6cc731 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Wed, 13 May 2026 17:59:30 +0700 Subject: [PATCH] Hide voice waveform visualization --- lib/screens/mapflow_shell.dart | 207 ++++----------------------------- 1 file changed, 21 insertions(+), 186 deletions(-) diff --git a/lib/screens/mapflow_shell.dart b/lib/screens/mapflow_shell.dart index 3c96c6b..c741bdd 100644 --- a/lib/screens/mapflow_shell.dart +++ b/lib/screens/mapflow_shell.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:latlong2/latlong.dart' hide Path; -import 'package:waveform_flutter/waveform_flutter.dart'; +import 'package:waveform_flutter/waveform_flutter.dart' show Amplitude; import 'package:waveform_recorder/waveform_recorder.dart'; import '../api/mapflow_api.dart'; @@ -870,7 +870,6 @@ class _AddExperienceFlowState extends ConsumerState { isRecording: _recording, isSubmitting: _submitting, micAllowed: _micAllowed, - waveController: _waveController, liveLevel: _liveLevel, canContinue: widget.hasTelegramAuth && informationProgress >= 1, onToggleRecording: _toggleRecording, @@ -1069,7 +1068,6 @@ class _VoiceStep extends StatelessWidget { required this.isRecording, required this.isSubmitting, required this.micAllowed, - required this.waveController, required this.liveLevel, required this.canContinue, required this.onToggleRecording, @@ -1082,7 +1080,6 @@ class _VoiceStep extends StatelessWidget { final bool isRecording; final bool isSubmitting; final bool micAllowed; - final WaveformRecorderController waveController; final double liveLevel; final bool canContinue; final Future Function() onToggleRecording; @@ -1106,23 +1103,7 @@ class _VoiceStep extends StatelessWidget { ), const SizedBox(height: 10), ], - Expanded( - flex: 5, - child: _VoiceProgressGrid(progress: informationProgress), - ), - const SizedBox(height: 10), - Expanded( - flex: 3, - child: SizedBox( - width: double.infinity, - child: _LibraryWaveSurface( - controller: waveController, - active: isRecording, - progress: informationProgress, - liveLevel: liveLevel, - ), - ), - ), + Expanded(child: _VoiceProgressGrid(progress: informationProgress)), if (!micAllowed) const Padding( padding: EdgeInsets.only(bottom: 10), @@ -1152,20 +1133,20 @@ class _VoiceProgressGrid extends StatelessWidget { @override Widget build(BuildContext context) { - const columns = 20; - const rows = 10; + const columns = 24; + const rows = 14; const total = columns * rows; final filled = (progress.clamp(0.0, 1.0) * total).round(); return LayoutBuilder( builder: (context, constraints) { - const gap = 5.0; + const gap = 4.0; final maxCellWidth = (constraints.maxWidth - gap * (columns - 1)) / columns; final maxCellHeight = (constraints.maxHeight - gap * (rows - 1)) / rows; final cellSize = math.max( 6.0, - math.min(maxCellWidth, maxCellHeight).clamp(6.0, 18.0), + math.min(maxCellWidth, maxCellHeight).clamp(5.0, 16.0), ); final gridWidth = columns * cellSize + gap * (columns - 1); final gridHeight = rows * cellSize + gap * (rows - 1); @@ -1180,7 +1161,7 @@ class _VoiceProgressGrid extends StatelessWidget { children: [ for (var index = 0; index < total; index++) _VoiceProgressCell( - filled: _gridOrder(index, total) < filled, + filled: _gridOrder(index, columns, rows) < filled, size: cellSize, ), ], @@ -1191,7 +1172,20 @@ class _VoiceProgressGrid extends StatelessWidget { ); } - static int _gridOrder(int index, int total) => ((index + 7) * 29) % total; + static int _gridOrder(int index, int columns, int rows) { + final row = index ~/ columns; + final column = index % columns; + final centerX = (columns - 1) / 2; + final centerY = (rows - 1) / 2; + final dx = column - centerX; + final dy = row - centerY; + final radius = math.sqrt(dx * dx + dy * dy); + final angle = math.atan2(dy, dx); + final shell = (radius * 7.0 + angle * 5.0).floor(); + final noise = (math.sin((column + 1) * 37.17 + (row + 1) * 91.43) * 10000) + .abs(); + return ((shell * 31 + noise.floor()) % (columns * rows)); + } } class _VoiceProgressCell extends StatelessWidget { @@ -1363,165 +1357,6 @@ class _VoiceRecordButtonState extends State<_VoiceRecordButton> } } -class _LibraryWaveSurface extends StatelessWidget { - const _LibraryWaveSurface({ - required this.controller, - required this.active, - required this.progress, - required this.liveLevel, - }); - - final WaveformRecorderController controller; - final bool active; - final double progress; - final double liveLevel; - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.center, - children: [ - Positioned.fill( - child: DecoratedBox( - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: const Color( - 0xFFFF2D75, - ).withValues(alpha: active ? 0.16 + liveLevel * 0.16 : 0.04), - blurRadius: 96, - spreadRadius: 10, - ), - BoxShadow( - color: const Color( - 0xFF38F5D3, - ).withValues(alpha: active ? 0.08 + liveLevel * 0.10 : 0.03), - blurRadius: 120, - spreadRadius: 8, - ), - ], - ), - ), - ), - Positioned.fill( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 0), - child: active - ? AnimatedWaveList( - key: ValueKey(controller.startTime), - stream: controller.amplitudeStream, - barBuilder: (animation, amplitude) => _VoiceWaveBar( - animation: animation, - amplitude: amplitude, - progress: progress, - ), - ) - : _IdleWaveBars(progress: progress), - ), - ), - ], - ); - } -} - -class _VoiceWaveBar extends StatelessWidget { - const _VoiceWaveBar({ - required this.animation, - required this.amplitude, - required this.progress, - }); - - final Animation animation; - final Amplitude amplitude; - final double progress; - - @override - Widget build(BuildContext context) { - final level = _amplitudeLevel(amplitude.current); - final height = 18 + level * 180; - final color = Color.lerp( - Colors.white.withValues(alpha: 0.28), - const Color(0xFFFF2D75), - progress.clamp(0.0, 1.0), - )!; - - return SizeTransition( - sizeFactor: animation, - axis: Axis.horizontal, - child: Align( - alignment: Alignment.center, - child: Container( - width: 6, - height: height, - margin: const EdgeInsets.symmetric(horizontal: 3), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [ - color.withValues(alpha: 0.42), - color, - const Color(0xFFFF7A90), - ], - ), - boxShadow: [ - BoxShadow( - color: color.withValues(alpha: 0.38), - blurRadius: 18, - spreadRadius: 1, - ), - ], - ), - ), - ), - ); - } - - double _amplitudeLevel(double db) { - final normalized = ((db.clamp(-76.0, -6.0) + 76.0) / 70.0).clamp(0.0, 1.0); - return math.pow(normalized, 0.62).toDouble(); - } -} - -class _IdleWaveBars extends StatelessWidget { - const _IdleWaveBars({required this.progress}); - - final double progress; - - @override - Widget build(BuildContext context) { - final color = Color.lerp( - Colors.white.withValues(alpha: 0.18), - const Color(0xFFFF2D75), - progress.clamp(0.0, 1.0), - )!; - - return Center( - child: SizedBox( - height: 210, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: List.generate(26, (index) { - final distance = (index - 12.5).abs(); - final height = 22 + math.max(0.0, 1 - distance / 13) * 94; - return Container( - width: 6, - height: height, - margin: const EdgeInsets.symmetric(horizontal: 3), - decoration: BoxDecoration( - color: color, - borderRadius: BorderRadius.circular(20), - ), - ); - }), - ), - ), - ); - } -} - class _StepLayout extends StatelessWidget { const _StepLayout({required this.body, this.action});