change tts voice on select and fix spacing of settings display

This commit is contained in:
2025-02-06 09:27:11 +02:00
parent d1eb96b546
commit 7a9f975ebd

View File

@@ -31,9 +31,11 @@ class AiChat extends StatefulWidget {
class _AiChatState extends State<AiChat> { class _AiChatState extends State<AiChat> {
final TextEditingController _modelController = TextEditingController(); final TextEditingController _modelController = TextEditingController();
final TextEditingController _fontSizeController = TextEditingController(); final TextEditingController _fontSizeController = TextEditingController();
final TextEditingController _ttsController = TextEditingController(); final TextEditingController _ttsVoiceController = TextEditingController();
final ValueNotifier<bool> _showModelOptions = ValueNotifier(false); final ValueNotifier<bool> _showModelOptions = ValueNotifier(false);
FlutterTts _flutterTts = FlutterTts(); FlutterTts _flutterTts = FlutterTts();
final ValueNotifier<String> _ttsVoiceName = ValueNotifier("");
// bool _ttsOn = false;
String? textStream; String? textStream;
List<Map> _voices = []; List<Map> _voices = [];
Map? _currentVoice; Map? _currentVoice;
@@ -138,8 +140,9 @@ class _AiChatState extends State<AiChat> {
child: IconButton( child: IconButton(
color: color:
MzanziInnovationHub.of(context)!.theme.primaryColor(), MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPressed: () { onPressed: () async {
print("Start TTS now"); print("Start TTS now");
_speakText(snapshot.requireData); _speakText(snapshot.requireData);
}, },
icon: const Icon(Icons.volume_up), icon: const Icon(Icons.volume_up),
@@ -351,7 +354,7 @@ class _AiChatState extends State<AiChat> {
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: FittedBox( child: FittedBox(
child: Container( child: Container(
padding: const EdgeInsets.only(top: 5.0), padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color:
MzanziInnovationHub.of(context)!.theme.primaryColor(), MzanziInnovationHub.of(context)!.theme.primaryColor(),
@@ -385,21 +388,18 @@ class _AiChatState extends State<AiChat> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Padding( SizedBox(
padding: const EdgeInsets.symmetric(horizontal: 25), width: 300,
child: SizedBox( child: MIHDropdownField(
width: 300, controller: _modelController,
child: MIHDropdownField( hintText: "AI Model",
controller: _modelController, dropdownOptions: const [
hintText: "AI Model", 'deepseek-r1:1.5b',
dropdownOptions: const [ 'gemma2:2b'
'deepseek-r1:1.5b', ],
'gemma2:2b' required: true,
], editable: true,
required: true, enableSearch: false,
editable: true,
enableSearch: false,
),
), ),
), ),
], ],
@@ -445,29 +445,53 @@ class _AiChatState extends State<AiChat> {
), ),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 15),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
SizedBox(
width: 230,
child: MIHDropdownField(
controller: _ttsVoiceController,
hintText: "AI Voice",
dropdownOptions: _voices
.map((_voice) => _voice["name"] as String)
.toList(),
required: true,
editable: true,
enableSearch: false,
),
),
const SizedBox(width: 10),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 25), padding: const EdgeInsets.all(5.0),
child: SizedBox( child: Container(
width: 300, //color: MzanziInnovationHub.of(context)!.theme.successColor(),
child: MIHDropdownField( decoration: BoxDecoration(
controller: _ttsController, color: MzanziInnovationHub.of(context)!
hintText: "AI Voice", .theme
dropdownOptions: _voices .successColor(),
.map((_voice) => _voice["name"] as String) borderRadius: const BorderRadius.all(
.toList(), Radius.circular(100),
required: true, ),
editable: true, ),
enableSearch: false, child: IconButton(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
onPressed: () {
print("Start TTS now");
_speakText(
"This is the sample of the Mzansi A.I Voice.");
},
icon: const Icon(Icons.volume_up),
), ),
), ),
), ),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 15),
], ],
), ),
), ),
@@ -488,7 +512,7 @@ class _AiChatState extends State<AiChat> {
.first["locale"] .first["locale"]
}, },
); );
_ttsController.text = _currentVoice!["name"]; _ttsVoiceController.text = _currentVoice!["name"];
} }
void _speakText(String text) async { void _speakText(String text) async {
@@ -500,13 +524,25 @@ class _AiChatState extends State<AiChat> {
} }
} }
void voiceSelected() {
if (_ttsVoiceController.text.isNotEmpty) {
_ttsVoiceName.value = _ttsVoiceController.text;
print(
"======================================== Voice Set ========================================");
setTtsVoice(_ttsVoiceController.text);
} else {
_ttsVoiceName.value = "";
}
}
@override @override
void dispose() { void dispose() {
// TODO: implement dispose // TODO: implement dispose
super.dispose(); super.dispose();
_modelController.dispose(); _modelController.dispose();
_fontSizeController.dispose(); _fontSizeController.dispose();
_ttsController.dispose(); _ttsVoiceController.dispose();
_ttsVoiceController.removeListener(voiceSelected);
client.endSession(); client.endSession();
_flutterTts.stop(); _flutterTts.stop();
} }
@@ -521,7 +557,7 @@ class _AiChatState extends State<AiChat> {
print("=================== Voices ===================\n$_voices"); print("=================== Voices ===================\n$_voices");
setState(() { setState(() {
_voices = _voices _voices = _voices
.where((_voice) => _voice["name"].contains("en")) .where((_voice) => _voice["name"].contains("en-us"))
.toList(); .toList();
_currentVoice = _voices.first; _currentVoice = _voices.first;
setTtsVoice(_currentVoice!["name"]); setTtsVoice(_currentVoice!["name"]);
@@ -546,6 +582,7 @@ class _AiChatState extends State<AiChat> {
); );
_modelController.text = 'gemma2:2b'; _modelController.text = 'gemma2:2b';
_fontSizeController.text = _chatFrontSize.ceil().toString(); _fontSizeController.text = _chatFrontSize.ceil().toString();
_ttsVoiceController.addListener(voiceSelected);
_chatHistory.add( _chatHistory.add(
ollama.Message( ollama.Message(
role: ollama.MessageRole.system, role: ollama.MessageRole.system,