mirror of
https://github.com/foss42/apidash.git
synced 2025-06-17 20:16:27 +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 kHeaderHeight = 32.0;
|
||||||
const kSegmentHeight = 24.0;
|
const kSegmentHeight = 24.0;
|
||||||
const kTextButtonMinWidth = 36.0;
|
const kTextButtonMinWidth = 36.0;
|
||||||
const kSliderWidth = 160.0;
|
|
||||||
|
|
||||||
const kRandMax = 100000;
|
const kRandMax = 100000;
|
||||||
|
|
||||||
|
@ -39,9 +39,9 @@ class _PreviewerState extends State<Previewer> {
|
|||||||
if (widget.type == kTypeAudio) {
|
if (widget.type == kTypeAudio) {
|
||||||
return Uint8AudioPlayer(
|
return Uint8AudioPlayer(
|
||||||
bytes: widget.bytes,
|
bytes: widget.bytes,
|
||||||
type: widget.type,
|
type: widget.type!,
|
||||||
subtype: widget.subtype,
|
subtype: widget.subtype!,
|
||||||
errorBuilder: (context, _, stacktrace) {
|
errorBuilder: (context, error, stacktrace) {
|
||||||
return const ErrorMessage(message: kAudioError);
|
return const ErrorMessage(message: kAudioError);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -12,11 +12,10 @@ typedef AudioErrorWidgetBuilder = Widget Function(
|
|||||||
|
|
||||||
// Uint8List AudioSource for just_audio
|
// Uint8List AudioSource for just_audio
|
||||||
class Uint8AudioSource extends StreamAudioSource {
|
class Uint8AudioSource extends StreamAudioSource {
|
||||||
Uint8AudioSource(this.bytes, {this.type = 'audio', this.subtype = 'mpeg'});
|
Uint8AudioSource(this.bytes, {required this.contentType});
|
||||||
|
|
||||||
final List<int> bytes;
|
final List<int> bytes;
|
||||||
final String? type;
|
final String contentType;
|
||||||
final String? subtype;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<StreamAudioResponse> request([int? start, int? end]) async {
|
Future<StreamAudioResponse> request([int? start, int? end]) async {
|
||||||
@ -27,7 +26,7 @@ class Uint8AudioSource extends StreamAudioSource {
|
|||||||
contentLength: end - start,
|
contentLength: end - start,
|
||||||
offset: start,
|
offset: start,
|
||||||
stream: Stream.value(bytes.sublist(start, end)),
|
stream: Stream.value(bytes.sublist(start, end)),
|
||||||
contentType: '$type/$subtype',
|
contentType: contentType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,14 +36,14 @@ class Uint8AudioPlayer extends StatefulWidget {
|
|||||||
const Uint8AudioPlayer({
|
const Uint8AudioPlayer({
|
||||||
super.key,
|
super.key,
|
||||||
required this.bytes,
|
required this.bytes,
|
||||||
this.type,
|
required this.type,
|
||||||
this.subtype,
|
required this.subtype,
|
||||||
required this.errorBuilder,
|
required this.errorBuilder,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Uint8List bytes;
|
final Uint8List bytes;
|
||||||
final String? type;
|
final String type;
|
||||||
final String? subtype;
|
final String subtype;
|
||||||
final AudioErrorWidgetBuilder errorBuilder;
|
final AudioErrorWidgetBuilder errorBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -56,8 +55,10 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
player.setAudioSource(Uint8AudioSource(widget.bytes,
|
player.setAudioSource(Uint8AudioSource(
|
||||||
type: widget.type, subtype: widget.subtype));
|
widget.bytes,
|
||||||
|
contentType: '${widget.type}/${widget.subtype}',
|
||||||
|
));
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,29 +86,32 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// Audio Player
|
// Audio Player
|
||||||
Row(
|
Padding(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
padding: kPh20v10,
|
||||||
children: [
|
child: Row(
|
||||||
// Duration Position Builder (time elapsed)
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
_buildDuration(
|
children: [
|
||||||
player.positionStream,
|
// Duration Position Builder (time elapsed)
|
||||||
maxDuration: player.duration,
|
_buildDuration(
|
||||||
),
|
player.positionStream,
|
||||||
|
maxDuration: player.duration,
|
||||||
|
),
|
||||||
|
|
||||||
// Slider to view & change Duration Position
|
// Slider to view & change Duration Position
|
||||||
_buildPositionBar(
|
_buildPositionBar(
|
||||||
player.positionStream,
|
player.positionStream,
|
||||||
maxDuration: player.duration,
|
maxDuration: player.duration,
|
||||||
onChanged: (value) =>
|
onChanged: (value) =>
|
||||||
player.seek(Duration(seconds: value.toInt())),
|
player.seek(Duration(seconds: value.toInt())),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Total Duration
|
// Total Duration
|
||||||
Text(
|
Text(
|
||||||
audioPosition(player.duration),
|
audioPosition(player.duration),
|
||||||
style: TextStyle(fontFamily: kCodeStyle.fontFamily),
|
style: TextStyle(fontFamily: kCodeStyle.fontFamily),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Audio Player Controls
|
// 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 {
|
} else {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
@ -197,8 +208,7 @@ class _Uint8AudioPlayerState extends State<Uint8AudioPlayer> {
|
|||||||
return StreamBuilder<Duration>(
|
return StreamBuilder<Duration>(
|
||||||
stream: stream,
|
stream: stream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return SizedBox(
|
return Flexible(
|
||||||
width: kSliderWidth,
|
|
||||||
child: SliderTheme(
|
child: SliderTheme(
|
||||||
data: SliderTheme.of(context).copyWith(
|
data: SliderTheme.of(context).copyWith(
|
||||||
trackShape: const RectangularSliderTrackShape(),
|
trackShape: const RectangularSliderTrackShape(),
|
||||||
|
@ -34,6 +34,8 @@ dependencies:
|
|||||||
flutter_markdown: ^0.6.14
|
flutter_markdown: ^0.6.14
|
||||||
markdown: ^7.1.0
|
markdown: ^7.1.0
|
||||||
just_audio: ^0.9.34
|
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:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -118,4 +118,21 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.text(kImageError), findsOneWidget);
|
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