mirror of
https://github.com/foss42/apidash.git
synced 2025-06-01 06:42:07 +08:00
Add test and made fixes
This commit is contained in:
@ -78,7 +78,6 @@ const kTabHeight = 45.0;
|
||||
const kHeaderHeight = 32.0;
|
||||
const kSegmentHeight = 24.0;
|
||||
const kTextButtonMinWidth = 36.0;
|
||||
const kSliderWidth = 160.0;
|
||||
|
||||
const kRandMax = 100000;
|
||||
|
||||
|
@ -39,9 +39,9 @@ class _PreviewerState extends State<Previewer> {
|
||||
if (widget.type == kTypeAudio) {
|
||||
return Uint8AudioPlayer(
|
||||
bytes: widget.bytes,
|
||||
type: widget.type,
|
||||
subtype: widget.subtype,
|
||||
errorBuilder: (context, _, stacktrace) {
|
||||
type: widget.type!,
|
||||
subtype: widget.subtype!,
|
||||
errorBuilder: (context, error, stacktrace) {
|
||||
return const ErrorMessage(message: kAudioError);
|
||||
},
|
||||
);
|
||||
|
@ -12,11 +12,10 @@ typedef AudioErrorWidgetBuilder = Widget Function(
|
||||
|
||||
// Uint8List AudioSource for just_audio
|
||||
class Uint8AudioSource extends StreamAudioSource {
|
||||
Uint8AudioSource(this.bytes, {this.type = 'audio', this.subtype = 'mpeg'});
|
||||
Uint8AudioSource(this.bytes, {required this.contentType});
|
||||
|
||||
final List<int> bytes;
|
||||
final String? type;
|
||||
final String? subtype;
|
||||
final String contentType;
|
||||
|
||||
@override
|
||||
Future<StreamAudioResponse> request([int? start, int? end]) async {
|
||||
@ -27,7 +26,7 @@ class Uint8AudioSource extends StreamAudioSource {
|
||||
contentLength: end - start,
|
||||
offset: start,
|
||||
stream: Stream.value(bytes.sublist(start, end)),
|
||||
contentType: '$type/$subtype',
|
||||
contentType: contentType,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -37,14 +36,14 @@ class Uint8AudioPlayer extends StatefulWidget {
|
||||
const Uint8AudioPlayer({
|
||||
super.key,
|
||||
required this.bytes,
|
||||
this.type,
|
||||
this.subtype,
|
||||
required this.type,
|
||||
required this.subtype,
|
||||
required this.errorBuilder,
|
||||
});
|
||||
|
||||
final Uint8List bytes;
|
||||
final String? type;
|
||||
final String? subtype;
|
||||
final String type;
|
||||
final String subtype;
|
||||
final AudioErrorWidgetBuilder errorBuilder;
|
||||
|
||||
@override
|
||||
@ -56,8 +55,10 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
player.setAudioSource(Uint8AudioSource(widget.bytes,
|
||||
type: widget.type, subtype: widget.subtype));
|
||||
player.setAudioSource(Uint8AudioSource(
|
||||
widget.bytes,
|
||||
contentType: '${widget.type}/${widget.subtype}',
|
||||
));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -85,29 +86,32 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Audio Player
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Duration Position Builder (time elapsed)
|
||||
_buildDuration(
|
||||
player.positionStream,
|
||||
maxDuration: player.duration,
|
||||
),
|
||||
Padding(
|
||||
padding: kPh20v10,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Duration Position Builder (time elapsed)
|
||||
_buildDuration(
|
||||
player.positionStream,
|
||||
maxDuration: player.duration,
|
||||
),
|
||||
|
||||
// Slider to view & change Duration Position
|
||||
_buildPositionBar(
|
||||
player.positionStream,
|
||||
maxDuration: player.duration,
|
||||
onChanged: (value) =>
|
||||
player.seek(Duration(seconds: value.toInt())),
|
||||
),
|
||||
// Slider to view & change Duration Position
|
||||
_buildPositionBar(
|
||||
player.positionStream,
|
||||
maxDuration: player.duration,
|
||||
onChanged: (value) =>
|
||||
player.seek(Duration(seconds: value.toInt())),
|
||||
),
|
||||
|
||||
// Total Duration
|
||||
Text(
|
||||
audioPosition(player.duration),
|
||||
style: TextStyle(fontFamily: kCodeStyle.fontFamily),
|
||||
),
|
||||
],
|
||||
// Total Duration
|
||||
Text(
|
||||
audioPosition(player.duration),
|
||||
style: TextStyle(fontFamily: kCodeStyle.fontFamily),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Audio Player Controls
|
||||
@ -134,6 +138,13 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (processingState == ProcessingState.idle) {
|
||||
// Error in Loading AudioSource
|
||||
return widget.errorBuilder(
|
||||
context,
|
||||
ErrorDescription('${player.audioSource} Loading Error'),
|
||||
snapshot.stackTrace,
|
||||
);
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
@ -197,8 +208,7 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
||||
return StreamBuilder<Duration>(
|
||||
stream: stream,
|
||||
builder: (context, snapshot) {
|
||||
return SizedBox(
|
||||
width: kSliderWidth,
|
||||
return Flexible(
|
||||
child: SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
trackShape: const RectangularSliderTrackShape(),
|
||||
|
@ -34,6 +34,8 @@ dependencies:
|
||||
flutter_markdown: ^0.6.14
|
||||
markdown: ^7.1.0
|
||||
just_audio: ^0.9.34
|
||||
# just_audio_mpv: ^0.1.6 # Uncomment for linux support of just_audio package
|
||||
# just_audio_windows: ^0.2.0 # Uncomment for windows support of just_audio package
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -118,4 +118,21 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(kImageError), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Testing when type/subtype is audio/mpeg corrupted',
|
||||
(tester) async {
|
||||
Uint8List bytesAudioCorrupt =
|
||||
Uint8List.fromList(List.generate(100, (index) => index));
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
title: 'Previewer',
|
||||
home: Scaffold(
|
||||
body: Previewer(
|
||||
type: 'audio', subtype: 'mpeg', bytes: bytesAudioCorrupt),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(kAudioError), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user