feat: audio styling

This commit is contained in:
Jacques Doeleman 2022-10-27 11:21:24 +02:00
parent 64fc57a8b9
commit 660549fcf6
2 changed files with 179 additions and 106 deletions

View file

@ -9,3 +9,7 @@
## 0.0.3 ## 0.0.3
- Fixed bug where onTap was not working when header is set - Fixed bug where onTap was not working when header is set
## 0.1.0
- Ability to set styling for the audio input.

View file

@ -15,10 +15,13 @@ class MediaPickerInputAudio implements MediaPickerInput {
this.checkPageSettings, this.checkPageSettings,
this.onComplete, this.onComplete,
required this.audioService, required this.audioService,
this.inputStyling,
}); });
final AudioService audioService; final AudioService audioService;
final AudioInputStyling? inputStyling;
@override @override
String label; String label;
@ -38,6 +41,7 @@ class MediaPickerInputAudio implements MediaPickerInput {
throw Exception("No recording returned"); throw Exception("No recording returned");
} }
}, },
inputStyling: inputStyling ?? AudioInputStyling(),
), ),
), ),
); );
@ -66,12 +70,15 @@ class Recorder extends ConsumerStatefulWidget {
const Recorder({ const Recorder({
required this.onComplete, required this.onComplete,
required this.audioService, required this.audioService,
required this.inputStyling,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
final void Function(MediaResult value) onComplete; final void Function(MediaResult value) onComplete;
final AudioService audioService; final AudioService audioService;
final AudioInputStyling inputStyling;
@override @override
ConsumerState<Recorder> createState() => _RecorderState(); ConsumerState<Recorder> createState() => _RecorderState();
} }
@ -87,6 +94,7 @@ class _RecorderState extends ConsumerState<Recorder> {
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
widget.inputStyling.background ??
Container( Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
gradient: RadialGradient( gradient: RadialGradient(
@ -107,9 +115,8 @@ class _RecorderState extends ConsumerState<Recorder> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
const Spacer( if (widget.inputStyling.pageContent != null)
flex: 5, widget.inputStyling.pageContent!,
),
StreamBuilder( StreamBuilder(
stream: Stream.periodic( stream: Stream.periodic(
recording recording
@ -123,7 +130,8 @@ class _RecorderState extends ConsumerState<Recorder> {
clock.getCurrentTime(), clock.getCurrentTime(),
), ),
), ),
style: Theme.of(context).textTheme.headline5, style: widget.inputStyling.timeTextStyle ??
Theme.of(context).textTheme.headline5,
); );
}, },
), ),
@ -133,6 +141,10 @@ class _RecorderState extends ConsumerState<Recorder> {
Row( Row(
children: [ children: [
const Spacer(), const Spacer(),
widget.inputStyling.playButton?.call(
recording,
playOnTap,
) ??
SizedBox( SizedBox(
width: 82, width: 82,
height: 82, height: 82,
@ -141,7 +153,8 @@ class _RecorderState extends ConsumerState<Recorder> {
Center( Center(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(45), borderRadius:
BorderRadius.circular(45),
gradient: const LinearGradient( gradient: const LinearGradient(
colors: [ colors: [
Color(0xFFF0F0F0), Color(0xFFF0F0F0),
@ -176,24 +189,8 @@ class _RecorderState extends ConsumerState<Recorder> {
iconSize: 65, iconSize: 65,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
splashRadius: 30, splashRadius: 30,
onPressed: () async { onPressed: () {
if (recording) { playOnTap();
widget.audioService.recordStop();
clock.stopClock();
setState(() {
recording = false;
});
} else {
widget.audioService.recordStart();
clock.startClock();
setState(() {
recording = true;
});
}
}, },
icon: Icon( icon: Icon(
recording recording
@ -206,34 +203,37 @@ class _RecorderState extends ConsumerState<Recorder> {
], ],
), ),
), ),
Expanded( widget.inputStyling.nextButton != null
? Expanded(
child: Center(
child: widget.inputStyling.nextButton!.call(
recording,
nextOnTap,
),
),
)
: Expanded(
child: Center( child: Center(
child: GestureDetector( child: GestureDetector(
onTap: () async { onTap: () async {
widget.audioService.recordStop(); nextOnTap();
widget.onComplete(
MediaResult(
fileValue:
await File(directory!).readAsBytes(),
),
);
// ignore: use_build_context_synchronously
Navigator.pop(context);
}, },
child: Container( child: Container(
width: width:
MediaQuery.of(context).size.width * 0.3, MediaQuery.of(context).size.width *
0.3,
height: 45, height: 45,
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFFD8D8D8), color: const Color(0xFFD8D8D8),
borderRadius: BorderRadius.circular(15), borderRadius:
BorderRadius.circular(15),
), ),
child: Center( child: Center(
child: Text( child: Text(
'Next', 'Next',
style: Theme.of(context).textTheme.button, style: Theme.of(context)
.textTheme
.button,
), ),
), ),
), ),
@ -257,6 +257,75 @@ class _RecorderState extends ConsumerState<Recorder> {
), ),
); );
} }
playOnTap() {
if (recording) {
widget.audioService.recordStop();
clock.stopClock();
setState(() {
recording = false;
});
} else {
widget.audioService.recordStart();
clock.startClock();
setState(() {
recording = true;
});
}
}
nextOnTap() async {
widget.audioService.recordStop();
widget.onComplete(
MediaResult(
fileValue: await File(directory!).readAsBytes(),
),
);
// ignore: use_build_context_synchronously
Navigator.pop(context);
}
}
/// Used by [MediaPickerInputAudio] to set styling options.
///
/// background can be set to determine the background of the page.
///
/// pageContent can be set to set any widget at the top of the page.
///
/// timeTextStyle sets the [TextStyle] of the time that shows the recording duration. Defaults to headline5.
///
/// playButton changes the default play/pause button.
///
/// nextButton changes the default next/finish button.
class AudioInputStyling {
AudioInputStyling({
this.background,
this.pageContent,
this.timeTextStyle,
this.playButton,
this.nextButton,
});
/// background can be set to determine the background of the page.
final Widget? background;
/// pageContent can be set to set any widget at the top of the page.
final Widget? pageContent;
/// timeTextStyle sets the [TextStyle] of the time that shows the recording duration. Defaults to headline5.
final TextStyle? timeTextStyle;
/// playButton changes the default play/pause button.
final Widget Function(bool recording, Function onTap)? playButton;
/// nextButton changes the default next/finish button.
final Widget Function(bool recording, Function onTap)? nextButton;
} }
/// Generic clock class can be created and used to keep the time. /// Generic clock class can be created and used to keep the time.