-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Speech Profile Page Improvements #971
Changes from all commits
a5d8db8
e69da43
5038176
8ab232d
dd1af99
c812cd4
31ea9cb
b4a1151
489ea45
8e88769
2c8eb42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ import 'dart:async'; | |
import 'package:flutter/material.dart'; | ||
import 'package:flutter_provider_utilities/flutter_provider_utilities.dart'; | ||
import 'package:friend_private/backend/preferences.dart'; | ||
import 'package:friend_private/pages/speech_profile/percentage_bar_progress.dart'; | ||
import 'package:friend_private/providers/capture_provider.dart'; | ||
import 'package:friend_private/providers/speech_profile_provider.dart'; | ||
import 'package:friend_private/widgets/dialog.dart'; | ||
|
@@ -138,6 +139,23 @@ class _SpeechProfileWidgetState extends State<SpeechProfileWidget> with TickerPr | |
), | ||
barrierDismissible: false, | ||
); | ||
} else if (error == "NO_SPEECH") { | ||
showDialog( | ||
context: context, | ||
builder: (c) => getDialog( | ||
context, | ||
() { | ||
Navigator.pop(context); | ||
// Navigator.pop(context); | ||
}, | ||
() {}, | ||
'Are you there?', | ||
'We could not detect any speech. Please make sure to speak for at least 10 seconds and not more than 3 minutes.', | ||
okButtonText: 'Ok', | ||
singleButton: true, | ||
), | ||
barrierDismissible: false, | ||
); | ||
Comment on lines
+142
to
+158
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error handling for "NO_SPEECH" has been improved. The new dialog provides a clearer message to the user about what went wrong and how to fix it. However, consider using a constant or enum for the error string "NO_SPEECH" to avoid potential typos and improve maintainability. - } else if (error == "NO_SPEECH") {
+ } else if (error == SpeechErrors.NO_SPEECH) { |
||
} | ||
}, | ||
child: Container( | ||
|
@@ -148,17 +166,23 @@ class _SpeechProfileWidgetState extends State<SpeechProfileWidget> with TickerPr | |
height: 10, | ||
), | ||
Padding( | ||
padding: const EdgeInsets.fromLTRB(40, 20, 40, 20), | ||
padding: EdgeInsets.fromLTRB(40, !provider.startedRecording ? 20 : 0, 40, 20), | ||
child: !provider.startedRecording | ||
? const Text( | ||
'Now, Omi needs to learn your voice to be able to recognise you.', | ||
textAlign: TextAlign.center, | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: 20, | ||
height: 1.4, | ||
fontWeight: FontWeight.w400, | ||
), | ||
? const Column( | ||
children: [ | ||
Text( | ||
'Omi needs to learn your voice to recognize you', | ||
textAlign: TextAlign.center, | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: 20, | ||
height: 1.4, | ||
fontWeight: FontWeight.w400, | ||
), | ||
), | ||
SizedBox(height: 14), | ||
Text("Note: This only works in English", style: TextStyle(color: Colors.white)), | ||
], | ||
Comment on lines
+169
to
+185
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The padding and text have been updated to provide more information to the user before they start recording. This is a good change as it improves the user experience by setting clear expectations. However, consider extracting the |
||
) | ||
: LayoutBuilder( | ||
builder: (context, constraints) { | ||
|
@@ -200,128 +224,118 @@ class _SpeechProfileWidgetState extends State<SpeechProfileWidget> with TickerPr | |
}, | ||
), | ||
), | ||
Padding( | ||
padding: const EdgeInsets.fromLTRB(24, 0, 24, 0), | ||
child: !provider.startedRecording | ||
? (provider.isInitialising | ||
? const CircularProgressIndicator( | ||
color: Colors.white, | ||
) | ||
: Column( | ||
mainAxisAlignment: MainAxisAlignment.end, | ||
children: [ | ||
const SizedBox(height: 20), | ||
Container( | ||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), | ||
decoration: BoxDecoration( | ||
border: const GradientBoxBorder( | ||
gradient: LinearGradient(colors: [ | ||
Color.fromARGB(127, 208, 208, 208), | ||
Color.fromARGB(127, 188, 99, 121), | ||
Color.fromARGB(127, 86, 101, 182), | ||
Color.fromARGB(127, 126, 190, 236) | ||
]), | ||
width: 2, | ||
), | ||
borderRadius: BorderRadius.circular(12), | ||
), | ||
child: TextButton( | ||
onPressed: () async { | ||
await stopDeviceRecording(); | ||
await provider.initialise(finalizedCallback: restartDeviceRecording); | ||
provider.forceCompletionTimer = | ||
Timer(Duration(seconds: provider.maxDuration), () async { | ||
provider.finalize(); | ||
}); | ||
provider.updateStartedRecording(true); | ||
}, | ||
child: const Text( | ||
'Get Started', | ||
style: TextStyle(color: Colors.white, fontSize: 16), | ||
), | ||
!provider.startedRecording | ||
? (provider.isInitialising | ||
? const CircularProgressIndicator( | ||
color: Colors.white, | ||
) | ||
: Column( | ||
mainAxisAlignment: MainAxisAlignment.end, | ||
children: [ | ||
const SizedBox(height: 20), | ||
Container( | ||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), | ||
decoration: BoxDecoration( | ||
border: const GradientBoxBorder( | ||
gradient: LinearGradient(colors: [ | ||
Color.fromARGB(127, 208, 208, 208), | ||
Color.fromARGB(127, 188, 99, 121), | ||
Color.fromARGB(127, 86, 101, 182), | ||
Color.fromARGB(127, 126, 190, 236) | ||
]), | ||
width: 2, | ||
), | ||
borderRadius: BorderRadius.circular(12), | ||
), | ||
const SizedBox(height: 10), | ||
], | ||
)) | ||
: provider.profileCompleted | ||
? Container( | ||
margin: const EdgeInsets.only(top: 40), | ||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 0), | ||
decoration: BoxDecoration( | ||
border: const GradientBoxBorder( | ||
gradient: LinearGradient(colors: [ | ||
Color.fromARGB(127, 208, 208, 208), | ||
Color.fromARGB(127, 188, 99, 121), | ||
Color.fromARGB(127, 86, 101, 182), | ||
Color.fromARGB(127, 126, 190, 236) | ||
]), | ||
width: 2, | ||
child: TextButton( | ||
onPressed: () async { | ||
await stopDeviceRecording(); | ||
await provider.initialise(finalizedCallback: restartDeviceRecording); | ||
provider.forceCompletionTimer = | ||
Timer(Duration(seconds: provider.maxDuration), () async { | ||
provider.finalize(); | ||
}); | ||
provider.updateStartedRecording(true); | ||
}, | ||
child: const Text( | ||
'Get Started', | ||
style: TextStyle(color: Colors.white, fontSize: 16), | ||
), | ||
), | ||
borderRadius: BorderRadius.circular(12), | ||
), | ||
child: TextButton( | ||
onPressed: () { | ||
provider.close(); | ||
widget.goNext(); | ||
}, | ||
child: const Text( | ||
"All done!", | ||
style: TextStyle(color: Colors.white, fontSize: 16), | ||
), | ||
const SizedBox(height: 10), | ||
], | ||
)) | ||
: provider.profileCompleted | ||
? Container( | ||
margin: const EdgeInsets.only(top: 40), | ||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 0), | ||
decoration: BoxDecoration( | ||
border: const GradientBoxBorder( | ||
gradient: LinearGradient(colors: [ | ||
Color.fromARGB(127, 208, 208, 208), | ||
Color.fromARGB(127, 188, 99, 121), | ||
Color.fromARGB(127, 86, 101, 182), | ||
Color.fromARGB(127, 126, 190, 236) | ||
]), | ||
width: 2, | ||
), | ||
) | ||
: provider.uploadingProfile | ||
? Padding( | ||
padding: const EdgeInsets.only(top: 40.0), | ||
child: Row( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: [ | ||
const SizedBox( | ||
height: 24, | ||
width: 24, | ||
child: Center( | ||
child: CircularProgressIndicator( | ||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), | ||
), | ||
), | ||
), | ||
const SizedBox(width: 24), | ||
Text(provider.loadingText, | ||
style: const TextStyle(color: Colors.white, fontSize: 18)), | ||
], | ||
), | ||
) | ||
: Column( | ||
mainAxisSize: MainAxisSize.min, | ||
borderRadius: BorderRadius.circular(12), | ||
), | ||
child: TextButton( | ||
onPressed: () { | ||
widget.goNext(); | ||
}, | ||
child: const Text( | ||
"All done!", | ||
style: TextStyle(color: Colors.white, fontSize: 16), | ||
), | ||
), | ||
) | ||
: provider.uploadingProfile | ||
? Padding( | ||
padding: const EdgeInsets.only(top: 40.0), | ||
child: Row( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: [ | ||
const SizedBox(height: 30), | ||
Text( | ||
provider.message, | ||
style: TextStyle(color: Colors.grey.shade300, fontSize: 14, height: 1.4), | ||
textAlign: TextAlign.center, | ||
), | ||
const SizedBox(height: 18), | ||
Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 32), | ||
child: Stack( | ||
children: [ | ||
LinearProgressIndicator( | ||
value: provider.percentageCompleted, | ||
backgroundColor: Colors.grey.shade300, | ||
valueColor: const AlwaysStoppedAnimation<Color>(Colors.deepPurple), | ||
), | ||
], | ||
const SizedBox( | ||
height: 24, | ||
width: 24, | ||
child: Center( | ||
child: CircularProgressIndicator( | ||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), | ||
), | ||
), | ||
), | ||
const SizedBox(height: 12), | ||
Text( | ||
'${(provider.percentageCompleted * 100).toInt()}%', | ||
style: const TextStyle(color: Colors.white), | ||
), | ||
const SizedBox(width: 24), | ||
Text(provider.loadingText, | ||
style: const TextStyle(color: Colors.white, fontSize: 18)), | ||
], | ||
), | ||
), | ||
) | ||
: Column( | ||
mainAxisSize: MainAxisSize.min, | ||
children: [ | ||
const SizedBox(height: 20), | ||
provider.percentageCompleted > 0 | ||
? const SizedBox() | ||
: const Text( | ||
"Introduce\nyourself", | ||
style: TextStyle(color: Colors.white, fontSize: 24, height: 1.4), | ||
textAlign: TextAlign.center, | ||
), | ||
const SizedBox(height: 12), | ||
SizedBox( | ||
width: MediaQuery.sizeOf(context).width * 0.9, | ||
child: ProgressBarWithPercentage(progressValue: provider.percentageCompleted)), | ||
const SizedBox(height: 14), | ||
Text( | ||
provider.message, | ||
style: TextStyle(color: Colors.grey.shade300, fontSize: 14, height: 1.4), | ||
textAlign: TextAlign.center, | ||
), | ||
], | ||
), | ||
Comment on lines
+227
to
+338
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for displaying different UI elements based on the state of the speech profile provider has been significantly refactored. The changes appear to be mostly related to UI layout and styling, with some minor adjustments to the logic. It's important to ensure that all possible states are handled correctly to avoid unexpected behavior. Consider breaking down this large block of code into smaller, more manageable functions or widgets to improve readability and maintainability. |
||
(!provider.startedRecording) | ||
? TextButton( | ||
onPressed: () { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Entelligence.AI
The import of
percentage_bar_progress.dart
is new. Ensure that this file exists and is accessible from the current file's location. If it doesn't exist or isn't accessible, it will cause a compilation error.+ import 'package:friend_private/pages/speech_profile/percentage_bar_progress.dart';