component updates + restructuring
This commit is contained in:
parent
a17f6f5ba5
commit
4ccd50b683
|
|
@ -0,0 +1,179 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/studio_details_data.dart';
|
||||||
|
import 'package:didvan/services/media/media.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/audio/audio_slider.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/bookmark_button.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AudioPlayerWidget extends StatelessWidget {
|
||||||
|
final StudioDetailsData podcast;
|
||||||
|
const AudioPlayerWidget({Key? key, required this.podcast}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.vertical(top: Radius.circular(8)),
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 20),
|
||||||
|
height: 3,
|
||||||
|
width: 50,
|
||||||
|
color: Theme.of(context).colorScheme.hint,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
child: SkeletonImage(
|
||||||
|
imageUrl: podcast.image,
|
||||||
|
aspectRatio: 1 / 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
DidvanText(
|
||||||
|
podcast.title,
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: AudioSlider(
|
||||||
|
tag: podcast.media,
|
||||||
|
showTimer: true,
|
||||||
|
duration: podcast.duration,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
DidvanIconButton(
|
||||||
|
icon: DidvanIcons.sleep_timer_regular,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
DidvanIconButton(
|
||||||
|
size: 32,
|
||||||
|
icon: DidvanIcons.media_forward_solid,
|
||||||
|
onPressed: () {
|
||||||
|
MediaService.audioPlayer.seek(
|
||||||
|
Duration(
|
||||||
|
seconds:
|
||||||
|
MediaService.audioPlayer.position.inSeconds + 30,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const DidvanText('30', isEnglishFont: true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_PlayPouseAnimatedIcon(
|
||||||
|
audioSource: podcast.media,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
DidvanIconButton(
|
||||||
|
size: 32,
|
||||||
|
icon: DidvanIcons.media_backward_solid,
|
||||||
|
onPressed: () {
|
||||||
|
MediaService.audioPlayer.seek(
|
||||||
|
Duration(
|
||||||
|
seconds:
|
||||||
|
MediaService.audioPlayer.position.inSeconds - 10,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const DidvanText('10', isEnglishFont: true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
BookmarkButton(
|
||||||
|
gestureSize: 48,
|
||||||
|
value: podcast.marked,
|
||||||
|
onMarkChanged: (value) {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
DidvanIconButton(
|
||||||
|
size: 32,
|
||||||
|
icon: DidvanIcons.angle_down_regular,
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PlayPouseAnimatedIcon extends StatefulWidget {
|
||||||
|
final String audioSource;
|
||||||
|
const _PlayPouseAnimatedIcon({Key? key, required this.audioSource})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_PlayPouseAnimatedIcon> createState() => __PlayPouseAnimatedIconState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class __PlayPouseAnimatedIconState extends State<_PlayPouseAnimatedIcon>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late final AnimationController _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_animationController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
|
);
|
||||||
|
if (MediaService.audioPlayer.playing) {
|
||||||
|
_animationController.forward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWrapper(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
onPressed: () {
|
||||||
|
MediaService.handleAudioPlayback(
|
||||||
|
audioSource: widget.audioSource,
|
||||||
|
isVoiceMessage: false,
|
||||||
|
);
|
||||||
|
if (MediaService.audioPlayer.playing) {
|
||||||
|
_animationController.forward();
|
||||||
|
} else {
|
||||||
|
_animationController.reverse();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: AnimatedIcon(
|
||||||
|
size: 40,
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
icon: AnimatedIcons.play_pause,
|
||||||
|
progress: _animationController,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_animationController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/services/media/media.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AudioSlider extends StatelessWidget {
|
||||||
|
final String tag;
|
||||||
|
final bool showTimer;
|
||||||
|
final int? duration;
|
||||||
|
final bool disableThumb;
|
||||||
|
const AudioSlider({
|
||||||
|
Key? key,
|
||||||
|
required this.tag,
|
||||||
|
this.showTimer = false,
|
||||||
|
this.duration,
|
||||||
|
this.disableThumb = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
bool get _isPlaying => MediaService.audioPlayerTag == tag;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IgnorePointer(
|
||||||
|
ignoring: MediaService.audioPlayerTag != tag,
|
||||||
|
child: Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: StreamBuilder<Duration>(
|
||||||
|
stream: _isPlaying ? MediaService.audioPlayer.positionStream : null,
|
||||||
|
builder: (context, snapshot) => ProgressBar(
|
||||||
|
thumbColor: Theme.of(context).colorScheme.title,
|
||||||
|
progressBarColor: DesignConfig.isDark
|
||||||
|
? Theme.of(context).colorScheme.title
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
|
baseBarColor: Theme.of(context).colorScheme.border,
|
||||||
|
bufferedBarColor: Theme.of(context).colorScheme.splash,
|
||||||
|
total: MediaService.audioPlayer.duration ??
|
||||||
|
Duration(seconds: duration ?? 0),
|
||||||
|
progress: snapshot.data ?? Duration.zero,
|
||||||
|
buffered: _isPlaying
|
||||||
|
? MediaService.audioPlayer.bufferedPosition
|
||||||
|
: Duration.zero,
|
||||||
|
thumbRadius: disableThumb ? 0 : 6,
|
||||||
|
barHeight: 3,
|
||||||
|
timeLabelTextStyle: TextStyle(
|
||||||
|
fontSize: showTimer ? null : 0,
|
||||||
|
height: showTimer ? 3 : 0,
|
||||||
|
fontFamily: DesignConfig.fontFamily.replaceAll(
|
||||||
|
'-FA',
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onSeek: (value) => _onSeek(value.inMilliseconds),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSeek(int value) {
|
||||||
|
MediaService.audioPlayer.seek(Duration(milliseconds: value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,314 @@
|
||||||
|
// import 'dart:io';
|
||||||
|
// import 'dart:math';
|
||||||
|
|
||||||
|
// import 'package:didvan/config/design_config.dart';
|
||||||
|
// import 'package:didvan/config/theme_data.dart';
|
||||||
|
// import 'package:didvan/constants/app_icons.dart';
|
||||||
|
// import 'package:didvan/constants/assets.dart';
|
||||||
|
// import 'package:didvan/pages/home/direct/direct_state.dart';
|
||||||
|
// import 'package:didvan/services/media/media.dart';
|
||||||
|
// import 'package:didvan/services/storage/storage.dart';
|
||||||
|
// import 'package:didvan/utils/date_time.dart';
|
||||||
|
// import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||||
|
// import 'package:didvan/widgets/didvan/text.dart';
|
||||||
|
// import 'package:flutter/foundation.dart';
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
// import 'package:just_waveform/just_waveform.dart';
|
||||||
|
// import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
// class AudioVisualizer extends StatefulWidget {
|
||||||
|
// final File? audioFile;
|
||||||
|
// final Waveform? waveform;
|
||||||
|
// final String? audioUrl;
|
||||||
|
// final int? duration;
|
||||||
|
// final Color? backgroundColor;
|
||||||
|
|
||||||
|
// const AudioVisualizer({
|
||||||
|
// Key? key,
|
||||||
|
// this.audioFile,
|
||||||
|
// this.waveform,
|
||||||
|
// this.audioUrl,
|
||||||
|
// this.duration,
|
||||||
|
// this.backgroundColor,
|
||||||
|
// }) : super(key: key);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// State<AudioVisualizer> createState() => _AudioVisualizerState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _AudioVisualizerState extends State<AudioVisualizer> {
|
||||||
|
// Stream<WaveformProgress>? waveDataStream;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// if (!kIsWeb && widget.audioFile != null) {
|
||||||
|
// waveDataStream = JustWaveform.extract(
|
||||||
|
// audioInFile: widget.audioFile!,
|
||||||
|
// waveOutFile: File(StorageService.appTempsDir + '/rec-wave.wave'),
|
||||||
|
// zoom: const WaveformZoom.pixelsPerSecond(100),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// super.initState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool get _nowPlaying =>
|
||||||
|
// MediaService.lastAudioPath == widget.audioFile ||
|
||||||
|
// MediaService.lastAudioPath == widget.audioUrl;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Container(
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: widget.backgroundColor ??
|
||||||
|
// (DesignConfig.isDark
|
||||||
|
// ? Theme.of(context).colorScheme.black
|
||||||
|
// : Theme.of(context).colorScheme.background),
|
||||||
|
// borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
|
// ),
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// const SizedBox(width: 12),
|
||||||
|
// StreamBuilder<Duration>(
|
||||||
|
// stream:
|
||||||
|
// _nowPlaying ? MediaService.audioPlayer.positionStream : null,
|
||||||
|
// builder: (context, snapshot) {
|
||||||
|
// String text = '';
|
||||||
|
// if (MediaService.audioPlayer.duration == null) {
|
||||||
|
// Future.delayed(Duration.zero, () {
|
||||||
|
// if (mounted) {
|
||||||
|
// setState(() {});
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// if (snapshot.data == null || snapshot.data == Duration.zero) {
|
||||||
|
// text = DateTimeUtils.normalizeTimeDuration(
|
||||||
|
// MediaService.audioPlayer.duration ??
|
||||||
|
// widget.waveform?.duration ??
|
||||||
|
// Duration.zero);
|
||||||
|
// } else {
|
||||||
|
// text = DateTimeUtils.normalizeTimeDuration(snapshot.data!);
|
||||||
|
// }
|
||||||
|
// return DidvanText(
|
||||||
|
// text,
|
||||||
|
// color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
// isEnglishFont: true,
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// const SizedBox(width: 12),
|
||||||
|
// Expanded(
|
||||||
|
// child: Builder(
|
||||||
|
// builder: (context) {
|
||||||
|
// if (kIsWeb) {
|
||||||
|
// return SvgPicture.asset(Assets.record);
|
||||||
|
// }
|
||||||
|
// if (widget.audioFile != null) {
|
||||||
|
// return StreamBuilder<WaveformProgress>(
|
||||||
|
// stream: waveDataStream,
|
||||||
|
// builder: (context, snapshot) {
|
||||||
|
// if (snapshot.data == null ||
|
||||||
|
// snapshot.data!.waveform == null) {
|
||||||
|
// return const SizedBox();
|
||||||
|
// }
|
||||||
|
// final waveform = snapshot.data!.waveform!;
|
||||||
|
// context.read<DirectState>().waveform = waveform;
|
||||||
|
// return _waveWidget(waveform);
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if (widget.waveform == null && waveDataStream == null) {
|
||||||
|
// return SvgPicture.asset(Assets.record);
|
||||||
|
// }
|
||||||
|
// return _waveWidget(widget.waveform!);
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// StreamBuilder<bool>(
|
||||||
|
// stream: _nowPlaying ? MediaService.audioPlayer.playingStream : null,
|
||||||
|
// builder: (context, snapshot) {
|
||||||
|
// return DidvanIconButton(
|
||||||
|
// icon: snapshot.data == true
|
||||||
|
// ? DidvanIcons.pause_circle_solid
|
||||||
|
// : DidvanIcons.play_circle_solid,
|
||||||
|
// color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
// onPressed: () {
|
||||||
|
// MediaService.handleAudioPlayback(
|
||||||
|
// audioSource: widget.audioFile ?? widget.audioUrl,
|
||||||
|
// isNetworkAudio: widget.audioFile == null,
|
||||||
|
// );
|
||||||
|
// setState(() {});
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Widget _waveWidget(Waveform waveform) => IgnorePointer(
|
||||||
|
// ignoring: !_nowPlaying,
|
||||||
|
// child: GestureDetector(
|
||||||
|
// onHorizontalDragUpdate: _changePosition,
|
||||||
|
// onTapDown: _changePosition,
|
||||||
|
// child: SizedBox(
|
||||||
|
// height: double.infinity,
|
||||||
|
// width: double.infinity,
|
||||||
|
// child: _AudioWaveformWidget(
|
||||||
|
// waveform: waveform,
|
||||||
|
// start: Duration.zero,
|
||||||
|
// scale: 2,
|
||||||
|
// strokeWidth: 3,
|
||||||
|
// nowPlaying: _nowPlaying,
|
||||||
|
// duration: waveform.duration,
|
||||||
|
// waveColor: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// void _changePosition(details) {
|
||||||
|
// if (MediaService.audioPlayer.audioSource == null) return;
|
||||||
|
// double posper =
|
||||||
|
// details.localPosition.dx / (MediaQuery.of(context).size.width - 200);
|
||||||
|
// if (posper >= 1 || posper < 0) return;
|
||||||
|
// final position = MediaService.audioPlayer.duration!.inMilliseconds;
|
||||||
|
// MediaService.audioPlayer.seek(
|
||||||
|
// Duration(milliseconds: (posper * position).toInt()),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _AudioWaveformWidget extends StatelessWidget {
|
||||||
|
// final Color waveColor;
|
||||||
|
// final double scale;
|
||||||
|
// final double strokeWidth;
|
||||||
|
// final double pixelsPerStep;
|
||||||
|
// final Waveform waveform;
|
||||||
|
// final Duration start;
|
||||||
|
// final bool nowPlaying;
|
||||||
|
// final Duration duration;
|
||||||
|
|
||||||
|
// const _AudioWaveformWidget({
|
||||||
|
// Key? key,
|
||||||
|
// required this.waveform,
|
||||||
|
// required this.start,
|
||||||
|
// required this.duration,
|
||||||
|
// required this.nowPlaying,
|
||||||
|
// this.waveColor = Colors.blue,
|
||||||
|
// this.scale = 1.0,
|
||||||
|
// this.strokeWidth = 5.0,
|
||||||
|
// this.pixelsPerStep = 8.0,
|
||||||
|
// }) : super(key: key);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return ClipRect(
|
||||||
|
// child: StreamBuilder<Duration?>(
|
||||||
|
// stream: nowPlaying ? MediaService.audioPlayer.positionStream : null,
|
||||||
|
// builder: (context, snapshot) {
|
||||||
|
// double progress = 0;
|
||||||
|
// if (snapshot.data == null ||
|
||||||
|
// MediaService.audioPlayer.duration == null) {
|
||||||
|
// progress = 0;
|
||||||
|
// } else {
|
||||||
|
// progress = snapshot.data!.inMilliseconds /
|
||||||
|
// MediaService.audioPlayer.duration!.inMilliseconds *
|
||||||
|
// 100;
|
||||||
|
// }
|
||||||
|
// if (progress >= 100) {
|
||||||
|
// progress = 0;
|
||||||
|
// MediaService.audioPlayer.stop();
|
||||||
|
// MediaService.audioPlayer.seek(Duration.zero);
|
||||||
|
// }
|
||||||
|
// return CustomPaint(
|
||||||
|
// painter: _AudioWaveformPainter(
|
||||||
|
// waveColor: waveColor,
|
||||||
|
// waveform: waveform,
|
||||||
|
// start: start,
|
||||||
|
// duration: duration,
|
||||||
|
// scale: scale,
|
||||||
|
// strokeWidth: strokeWidth,
|
||||||
|
// pixelsPerStep: pixelsPerStep,
|
||||||
|
// progressPercentage: progress,
|
||||||
|
// progressColor: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
// color: Theme.of(context).colorScheme.border,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _AudioWaveformPainter extends CustomPainter {
|
||||||
|
// final double scale;
|
||||||
|
// final double strokeWidth;
|
||||||
|
// final double pixelsPerStep;
|
||||||
|
// final Waveform waveform;
|
||||||
|
// final Duration start;
|
||||||
|
// final Duration duration;
|
||||||
|
// final double progressPercentage;
|
||||||
|
// final Color progressColor;
|
||||||
|
// final Color color;
|
||||||
|
|
||||||
|
// _AudioWaveformPainter({
|
||||||
|
// required this.waveform,
|
||||||
|
// required this.start,
|
||||||
|
// required this.duration,
|
||||||
|
// required this.progressPercentage,
|
||||||
|
// required this.color,
|
||||||
|
// required this.progressColor,
|
||||||
|
// Color waveColor = Colors.blue,
|
||||||
|
// this.scale = 1.0,
|
||||||
|
// this.strokeWidth = 5.0,
|
||||||
|
// this.pixelsPerStep = 8.0,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void paint(Canvas canvas, Size size) {
|
||||||
|
// if (duration == Duration.zero) return;
|
||||||
|
// double width = size.width;
|
||||||
|
// double height = size.height;
|
||||||
|
|
||||||
|
// final waveformPixelsPerWindow = waveform.positionToPixel(duration).toInt();
|
||||||
|
// final waveformPixelsPerDevicePixel = waveformPixelsPerWindow / width;
|
||||||
|
// final waveformPixelsPerStep = waveformPixelsPerDevicePixel * pixelsPerStep;
|
||||||
|
// final sampleOffset = waveform.positionToPixel(start);
|
||||||
|
// final sampleStart = -sampleOffset % waveformPixelsPerStep;
|
||||||
|
// final totalLength = waveformPixelsPerWindow;
|
||||||
|
// final wavePaintB = Paint()
|
||||||
|
// ..style = PaintingStyle.stroke
|
||||||
|
// ..strokeWidth = strokeWidth
|
||||||
|
// ..strokeCap = StrokeCap.round
|
||||||
|
// ..color = progressColor;
|
||||||
|
// final wavePaintA = Paint()
|
||||||
|
// ..style = PaintingStyle.stroke
|
||||||
|
// ..strokeWidth = strokeWidth
|
||||||
|
// ..strokeCap = StrokeCap.round
|
||||||
|
// ..color = color;
|
||||||
|
// for (var i = sampleStart.toDouble();
|
||||||
|
// i <= waveformPixelsPerWindow + 1.0;
|
||||||
|
// i += waveformPixelsPerStep) {
|
||||||
|
// final sampleIdx = (sampleOffset + i).toInt();
|
||||||
|
// final x = i / waveformPixelsPerDevicePixel;
|
||||||
|
// final minY = normalise(waveform.getPixelMin(sampleIdx), height);
|
||||||
|
// final maxY = normalise(waveform.getPixelMax(sampleIdx), height);
|
||||||
|
// canvas.drawLine(
|
||||||
|
// Offset(x + strokeWidth / 2, max(strokeWidth * 0.75, minY)),
|
||||||
|
// Offset(x + strokeWidth / 2, min(height - strokeWidth * 0.75, maxY)),
|
||||||
|
// i / totalLength < progressPercentage / 100 ? wavePaintB : wavePaintA,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// bool shouldRepaint(covariant _AudioWaveformPainter oldDelegate) {
|
||||||
|
// return oldDelegate.progressPercentage != progressPercentage;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// double normalise(int s, double height) {
|
||||||
|
// final y = 32768 + (scale * s).clamp(-32768.0, 32767.0).toDouble();
|
||||||
|
// return height - 1 - y * height / 65536;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
@ -8,14 +8,14 @@ import 'package:flutter/material.dart';
|
||||||
class BookmarkButton extends StatefulWidget {
|
class BookmarkButton extends StatefulWidget {
|
||||||
final bool value;
|
final bool value;
|
||||||
final void Function(bool value) onMarkChanged;
|
final void Function(bool value) onMarkChanged;
|
||||||
final bool bigGestureSize;
|
|
||||||
final bool askForConfirmation;
|
final bool askForConfirmation;
|
||||||
|
final double gestureSize;
|
||||||
const BookmarkButton({
|
const BookmarkButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.value,
|
required this.value,
|
||||||
this.bigGestureSize = false,
|
|
||||||
required this.onMarkChanged,
|
required this.onMarkChanged,
|
||||||
this.askForConfirmation = false,
|
this.askForConfirmation = false,
|
||||||
|
required this.gestureSize,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -40,7 +40,7 @@ class _BookmarkButtonState extends State<BookmarkButton> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DidvanIconButton(
|
return DidvanIconButton(
|
||||||
gestureSize: widget.bigGestureSize ? 32 : 28,
|
gestureSize: widget.gestureSize,
|
||||||
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
bool confirm = false;
|
bool confirm = false;
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bigGestureSize: true,
|
gestureSize: 32,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 60,
|
width: 60,
|
||||||
|
|
@ -151,7 +151,7 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bigGestureSize: true,
|
gestureSize: 32,
|
||||||
),
|
),
|
||||||
if (widget.isRadar)
|
if (widget.isRadar)
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ class DidvanAppBar extends StatelessWidget {
|
||||||
appBarData.title!,
|
appBarData.title!,
|
||||||
style: Theme.of(context).textTheme.headline3,
|
style: Theme.of(context).textTheme.headline3,
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
if (appBarData.subtitle != null)
|
if (appBarData.subtitle != null)
|
||||||
DidvanText(
|
DidvanText(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
import 'package:didvan/utils/date_time.dart';
|
||||||
import 'package:didvan/views/home/widgets/multitype_overview.dart';
|
import 'package:didvan/views/home/widgets/overview/multitype.dart';
|
||||||
import 'package:didvan/views/home/widgets/tag_item.dart';
|
import 'package:didvan/views/home/widgets/tag_item.dart';
|
||||||
import 'package:didvan/views/widgets/animated_visibility.dart';
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/card.dart';
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
|
|
|
||||||
|
|
@ -42,17 +42,14 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
||||||
slivers: [
|
slivers: [
|
||||||
if (!widget.reverse && widget.appBarData != null)
|
if (!widget.reverse && widget.appBarData != null)
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
toolbarHeight: widget.appBarData!.isSmall ? 56 : 72,
|
toolbarHeight: (widget.appBarData!.isSmall ? 56 : 72) -
|
||||||
|
statusBarHeight,
|
||||||
backgroundColor: widget.backgroundColor ??
|
backgroundColor: widget.backgroundColor ??
|
||||||
Theme.of(context).colorScheme.background,
|
Theme.of(context).colorScheme.background,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
flexibleSpace: DidvanAppBar(appBarData: widget.appBarData!),
|
flexibleSpace: DidvanAppBar(appBarData: widget.appBarData!),
|
||||||
),
|
),
|
||||||
if (!widget.reverse)
|
|
||||||
const SliverToBoxAdapter(
|
|
||||||
child: SizedBox(height: 16),
|
|
||||||
),
|
|
||||||
if (widget.children != null)
|
if (widget.children != null)
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue