Merge pull request #77 from yaso-meth/BUG--Mzasni-AI-Settings-Issue

BUG--Mzasni-AI-Settings-Issue
This commit is contained in:
yaso-meth
2025-02-06 10:46:52 +02:00
committed by GitHub

View File

@@ -31,12 +31,14 @@ 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; List<String> _voicesString = [];
List<types.Message> _messages = []; List<types.Message> _messages = [];
late types.User _user; late types.User _user;
late types.User _mihAI; late types.User _mihAI;
@@ -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,9 +388,7 @@ class _AiChatState extends State<AiChat> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Padding( SizedBox(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: SizedBox(
width: 300, width: 300,
child: MIHDropdownField( child: MIHDropdownField(
controller: _modelController, controller: _modelController,
@@ -401,6 +402,49 @@ class _AiChatState extends State<AiChat> {
enableSearch: false, enableSearch: false,
), ),
), ),
],
),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 230,
child: MIHDropdownField(
controller: _ttsVoiceController,
hintText: "AI Voice",
dropdownOptions: _voicesString,
required: true,
editable: true,
enableSearch: false,
),
),
const SizedBox(width: 10),
Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
//color: MzanziInnovationHub.of(context)!.theme.successColor(),
decoration: BoxDecoration(
color: MzanziInnovationHub.of(context)!
.theme
.successColor(),
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
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),
),
),
), ),
], ],
), ),
@@ -445,29 +489,7 @@ class _AiChatState extends State<AiChat> {
), ),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: SizedBox(
width: 300,
child: MIHDropdownField(
controller: _ttsController,
hintText: "AI Voice",
dropdownOptions: _voices
.map((_voice) => _voice["name"] as String)
.toList(),
required: true,
editable: true,
enableSearch: false,
),
),
),
],
),
const SizedBox(height: 10),
], ],
), ),
), ),
@@ -479,18 +501,6 @@ class _AiChatState extends State<AiChat> {
); );
} }
void setTtsVoice(String voiceName) {
_flutterTts.setVoice(
{
"name": voiceName,
"locale": _voices
.where((_voice) => _voice["name"].contains(voiceName))
.first["locale"]
},
);
_ttsController.text = _currentVoice!["name"];
}
void _speakText(String text) async { void _speakText(String text) async {
try { try {
await _flutterTts.stop(); // Stop any ongoing speech await _flutterTts.stop(); // Stop any ongoing speech
@@ -500,31 +510,62 @@ class _AiChatState extends State<AiChat> {
} }
} }
void setTtsVoice(String voiceName) {
_flutterTts.setVoice(
{
"name": voiceName,
"locale": _voices
.where((_voice) => _voice["name"].contains(voiceName))
.first["locale"]
},
);
_ttsVoiceController.text = voiceName;
}
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();
} }
void initTTS() { void initTTS() {
_flutterTts.setVolume(0.7); _flutterTts.setVolume(0.7);
// _flutterTts.setSpeechRate(0.6);
// _flutterTts.setPitch(1.0);
_flutterTts.getVoices.then( _flutterTts.getVoices.then(
(data) { (data) {
try { try {
_voices = List<Map>.from(data); _voices = List<Map>.from(data);
print("=================== Voices ===================\n$_voices");
setState(() { setState(() {
_voices = _voices _voices = _voices
.where((_voice) => _voice["name"].contains("en")) .where(
(_voice) => _voice["name"].toLowerCase().contains("en-us"))
.toList(); .toList();
_currentVoice = _voices.first; _voicesString =
setTtsVoice(_currentVoice!["name"]); _voices.map((_voice) => _voice["name"] as String).toList();
_voicesString.sort();
// print(
// "=================== Voices ===================\n$_voicesString");
setTtsVoice(_voicesString.first);
}); });
} catch (e) { } catch (e) {
print(e); print(e);
@@ -546,6 +587,7 @@ class _AiChatState extends State<AiChat> {
); );
_modelController.text = 'gemma2:2b'; _modelController.text = 'gemma2:2b';
_fontSizeController.text = _chatFrontSize.ceil().toString(); _fontSizeController.text = _chatFrontSize.ceil().toString();
_chatHistory.add( _chatHistory.add(
ollama.Message( ollama.Message(
role: ollama.MessageRole.system, role: ollama.MessageRole.system,
@@ -554,6 +596,7 @@ class _AiChatState extends State<AiChat> {
); );
_loadMessages(); _loadMessages();
initTTS(); initTTS();
_ttsVoiceController.addListener(voiceSelected);
} }
@override @override