You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			190 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			190 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Dart
		
	
import 'dart:math';
 | 
						|
import 'package:audio_waveforms/audio_waveforms.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:mohem_flutter_app/classes/colors.dart';
 | 
						|
 | 
						|
class SeekBar extends StatefulWidget {
 | 
						|
  final Duration duration;
 | 
						|
  final Duration position;
 | 
						|
  final Duration bufferedPosition;
 | 
						|
  final ValueChanged<Duration>? onChanged;
 | 
						|
  final ValueChanged<Duration>? onChangeEnd;
 | 
						|
 | 
						|
  const SeekBar({
 | 
						|
    Key? key,
 | 
						|
    required this.duration,
 | 
						|
    required this.position,
 | 
						|
    required this.bufferedPosition,
 | 
						|
    this.onChanged,
 | 
						|
    this.onChangeEnd,
 | 
						|
  }) : super(key: key);
 | 
						|
 | 
						|
  @override
 | 
						|
  SeekBarState createState() => SeekBarState();
 | 
						|
}
 | 
						|
 | 
						|
class SeekBarState extends State<SeekBar> {
 | 
						|
  double? _dragValue;
 | 
						|
  late SliderThemeData _sliderThemeData;
 | 
						|
 | 
						|
  @override
 | 
						|
  void didChangeDependencies() {
 | 
						|
    super.didChangeDependencies();
 | 
						|
    _sliderThemeData = SliderTheme.of(context).copyWith(
 | 
						|
      // trackHeight: 2.0,
 | 
						|
      thumbColor: MyColors.lightGreenColor,
 | 
						|
      activeTrackColor: MyColors.lightGreenColor,
 | 
						|
      inactiveTrackColor: MyColors.grey57Color.withOpacity(0.4),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return Stack(
 | 
						|
      children: [
 | 
						|
        SliderTheme(
 | 
						|
          data: _sliderThemeData.copyWith(
 | 
						|
            thumbShape: HiddenThumbComponentShape(),
 | 
						|
          ),
 | 
						|
          child: ExcludeSemantics(
 | 
						|
            child: Slider(
 | 
						|
              min: 0.0,
 | 
						|
              max: widget.duration.inMilliseconds.toDouble(),
 | 
						|
              value: min(widget.bufferedPosition.inMilliseconds.toDouble(), widget.duration.inMilliseconds.toDouble()),
 | 
						|
              onChanged: (value) {
 | 
						|
                setState(() {
 | 
						|
                  _dragValue = value;
 | 
						|
                });
 | 
						|
                if (widget.onChanged != null) {
 | 
						|
                  widget.onChanged!(Duration(milliseconds: value.round()));
 | 
						|
                }
 | 
						|
              },
 | 
						|
              onChangeEnd: (value) {
 | 
						|
                if (widget.onChangeEnd != null) {
 | 
						|
                  widget.onChangeEnd!(Duration(milliseconds: value.round()));
 | 
						|
                }
 | 
						|
                _dragValue = null;
 | 
						|
              },
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
        SliderTheme(
 | 
						|
          data: _sliderThemeData.copyWith(
 | 
						|
            inactiveTrackColor: Colors.transparent,
 | 
						|
          ),
 | 
						|
          child: Slider(
 | 
						|
            min: 0.0,
 | 
						|
            max: widget.duration.inMilliseconds.toDouble(),
 | 
						|
            value: min(_dragValue ?? widget.position.inMilliseconds.toDouble(), widget.duration.inMilliseconds.toDouble()),
 | 
						|
            onChanged: (value) {
 | 
						|
              setState(() {
 | 
						|
                _dragValue = value;
 | 
						|
              });
 | 
						|
              if (widget.onChanged != null) {
 | 
						|
                widget.onChanged!(Duration(milliseconds: value.round()));
 | 
						|
              }
 | 
						|
            },
 | 
						|
            onChangeEnd: (value) {
 | 
						|
              if (widget.onChangeEnd != null) {
 | 
						|
                widget.onChangeEnd!(Duration(milliseconds: value.round()));
 | 
						|
              }
 | 
						|
              _dragValue = null;
 | 
						|
            },
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ],
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class PositionData {
 | 
						|
  final Duration position;
 | 
						|
  final Duration bufferedPosition;
 | 
						|
  final Duration duration;
 | 
						|
 | 
						|
  PositionData(this.position, this.bufferedPosition, this.duration);
 | 
						|
}
 | 
						|
 | 
						|
class HiddenThumbComponentShape extends SliderComponentShape {
 | 
						|
  @override
 | 
						|
  Size getPreferredSize(bool isEnabled, bool isDiscrete) => Size.zero;
 | 
						|
 | 
						|
  @override
 | 
						|
  void paint(
 | 
						|
    PaintingContext context,
 | 
						|
    Offset center, {
 | 
						|
    required Animation<double> activationAnimation,
 | 
						|
    required Animation<double> enableAnimation,
 | 
						|
    required bool isDiscrete,
 | 
						|
    required TextPainter labelPainter,
 | 
						|
    required RenderBox parentBox,
 | 
						|
    required SliderThemeData sliderTheme,
 | 
						|
    required TextDirection textDirection,
 | 
						|
    required double value,
 | 
						|
    required double textScaleFactor,
 | 
						|
    required Size sizeWithOverflow,
 | 
						|
  }) {}
 | 
						|
}
 | 
						|
 | 
						|
class WaveBubble extends StatelessWidget {
 | 
						|
  final PlayerController playerController;
 | 
						|
  final VoidCallback onTap;
 | 
						|
  final bool isPlaying;
 | 
						|
 | 
						|
  const WaveBubble({
 | 
						|
    Key? key,
 | 
						|
    required this.playerController,
 | 
						|
    required this.onTap,
 | 
						|
    required this.isPlaying,
 | 
						|
  }) : super(key: key);
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return Container(
 | 
						|
      margin: const EdgeInsets.all(10),
 | 
						|
      decoration: BoxDecoration(
 | 
						|
        borderRadius: BorderRadius.circular(30),
 | 
						|
        gradient: const LinearGradient(
 | 
						|
          transform: GradientRotation(.83),
 | 
						|
          begin: Alignment.topRight,
 | 
						|
          end: Alignment.bottomLeft,
 | 
						|
          colors: <Color>[
 | 
						|
            MyColors.gradiantEndColor,
 | 
						|
            MyColors.gradiantStartColor,
 | 
						|
          ],
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
      child: Row(
 | 
						|
        mainAxisSize: MainAxisSize.min,
 | 
						|
        children: [
 | 
						|
          IconButton(
 | 
						|
            onPressed: onTap,
 | 
						|
            icon: Icon(isPlaying ? Icons.stop : Icons.play_arrow),
 | 
						|
            color: Colors.white,
 | 
						|
            splashColor: Colors.transparent,
 | 
						|
            highlightColor: Colors.transparent,
 | 
						|
          ),
 | 
						|
          AudioFileWaveforms(
 | 
						|
            size: Size(MediaQuery.of(context).size.width / 2, 10),
 | 
						|
            playerController: playerController,
 | 
						|
            padding: EdgeInsets.zero,
 | 
						|
            margin: EdgeInsets.zero,
 | 
						|
            enableSeekGesture: true,
 | 
						|
            density: 1,
 | 
						|
            playerWaveStyle: const PlayerWaveStyle(
 | 
						|
              fixedWaveColor: Colors.white,
 | 
						|
              liveWaveColor: MyColors.greenColor,
 | 
						|
              showTop: true,
 | 
						|
              showBottom: true,
 | 
						|
              waveCap: StrokeCap.round,
 | 
						|
              seekLineThickness: 2,
 | 
						|
              visualizerHeight: 4,
 | 
						|
              backgroundColor: Colors.transparent,
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |