QOL: Mzansi AI Chat Look and Feel & Startup question pt4
This commit is contained in:
@@ -8,12 +8,14 @@ import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|||||||
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
||||||
|
|
||||||
class MzansiAiProvider extends ChangeNotifier {
|
class MzansiAiProvider extends ChangeNotifier {
|
||||||
|
bool ttsOn;
|
||||||
int toolIndex;
|
int toolIndex;
|
||||||
String? startUpQuestion;
|
String? startUpQuestion;
|
||||||
late OllamaProvider ollamaProvider;
|
late OllamaProvider ollamaProvider;
|
||||||
|
|
||||||
MzansiAiProvider({
|
MzansiAiProvider({
|
||||||
this.toolIndex = 0,
|
this.toolIndex = 0,
|
||||||
|
this.ttsOn = false,
|
||||||
}) {
|
}) {
|
||||||
ollamaProvider = OllamaProvider(
|
ollamaProvider = OllamaProvider(
|
||||||
baseUrl: "${AppEnviroment.baseAiUrl}/api",
|
baseUrl: "${AppEnviroment.baseAiUrl}/api",
|
||||||
@@ -35,6 +37,7 @@ class MzansiAiProvider extends ChangeNotifier {
|
|||||||
"- Mzansi Directory: A place to search and find out more about the people and businesses across Mzansi.\n" +
|
"- Mzansi Directory: A place to search and find out more about the people and businesses across Mzansi.\n" +
|
||||||
"- Calendar: Integrated calendar for managing personal and business appointments.\n" +
|
"- Calendar: Integrated calendar for managing personal and business appointments.\n" +
|
||||||
"- Calculator: Simple calculator with tip and forex calculation functionality.\n" +
|
"- Calculator: Simple calculator with tip and forex calculation functionality.\n" +
|
||||||
|
"- MIH Minesweeper: The first game from MIH! It's the classic brain-teaser ready to entertain you no matter where you are.\n" +
|
||||||
"- MIH Access: Manage and view profile access security.\n" +
|
"- MIH Access: Manage and view profile access security.\n" +
|
||||||
"**Core Rules and Guidelines:**\n" +
|
"**Core Rules and Guidelines:**\n" +
|
||||||
"- **Accuracy First:** Always prioritize providing correct information.\n" +
|
"- **Accuracy First:** Always prioritize providing correct information.\n" +
|
||||||
@@ -59,6 +62,11 @@ class MzansiAiProvider extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTTSstate(bool ttsOn) {
|
||||||
|
this.ttsOn = ttsOn;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void setStartUpQuestion(String? question) {
|
void setStartUpQuestion(String? question) {
|
||||||
startUpQuestion = question;
|
startUpQuestion = question;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -244,6 +252,7 @@ class MzansiAiProvider extends ChangeNotifier {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
color: MihColors.getPrimaryColor(
|
color: MihColors.getPrimaryColor(
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
|||||||
import 'package:flutter_tts/flutter_tts.dart';
|
import 'package:flutter_tts/flutter_tts.dart';
|
||||||
import 'package:ken_logger/ken_logger.dart';
|
import 'package:ken_logger/ken_logger.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
|
||||||
@@ -18,7 +19,6 @@ class MihAiChat extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MihAiChatState extends State<MihAiChat> {
|
class _MihAiChatState extends State<MihAiChat> {
|
||||||
bool ttsOn = false;
|
|
||||||
final FlutterTts _flutterTts = FlutterTts();
|
final FlutterTts _flutterTts = FlutterTts();
|
||||||
|
|
||||||
Widget noMessagescDisplay() {
|
Widget noMessagescDisplay() {
|
||||||
@@ -123,9 +123,9 @@ class _MihAiChatState extends State<MihAiChat> {
|
|||||||
_flutterTts.stop();
|
_flutterTts.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initTts() async {
|
Future<void> initTts(MzansiAiProvider aiProvider) async {
|
||||||
try {
|
try {
|
||||||
await _flutterTts.setSpeechRate(1);
|
await _flutterTts.setSpeechRate(0.55);
|
||||||
// await _flutterTts.setLanguage("en-US");
|
// await _flutterTts.setLanguage("en-US");
|
||||||
|
|
||||||
// Safer voice selection with error handling
|
// Safer voice selection with error handling
|
||||||
@@ -153,25 +153,19 @@ class _MihAiChatState extends State<MihAiChat> {
|
|||||||
|
|
||||||
_flutterTts.setStartHandler(() {
|
_flutterTts.setStartHandler(() {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
aiProvider.setTTSstate(true);
|
||||||
ttsOn = true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_flutterTts.setCompletionHandler(() {
|
_flutterTts.setCompletionHandler(() {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
aiProvider.setTTSstate(false);
|
||||||
ttsOn = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_flutterTts.setErrorHandler((message) {
|
_flutterTts.setErrorHandler((message) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
aiProvider.setTTSstate(false);
|
||||||
ttsOn = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -192,7 +186,8 @@ class _MihAiChatState extends State<MihAiChat> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
initTts();
|
MzansiAiProvider aiProvider = context.read<MzansiAiProvider>();
|
||||||
|
initTts(aiProvider);
|
||||||
initStartQuestion();
|
initStartQuestion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,102 +200,84 @@ class _MihAiChatState extends State<MihAiChat> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<MzansiAiProvider>(
|
return Consumer<MzansiAiProvider>(
|
||||||
builder: (BuildContext context, MzansiAiProvider mzansiAiProvider,
|
builder:
|
||||||
Widget? child) {
|
(BuildContext context, MzansiAiProvider aiProvider, Widget? child) {
|
||||||
// final startupQuestion = mzansiAiProvider.startUpQuestion;
|
bool hasHistory = aiProvider.ollamaProvider.history.isNotEmpty;
|
||||||
// if (startupQuestion != null) {
|
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
// mzansiAiProvider.ollamaProvider.sendMessageStream(startupQuestion);
|
|
||||||
// mzansiAiProvider.setStartUpQuestion(null);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
bool hasHistory = mzansiAiProvider.ollamaProvider.history.isNotEmpty;
|
|
||||||
KenLogger.success("has history: $hasHistory");
|
|
||||||
KenLogger.success(
|
|
||||||
"length: ${mzansiAiProvider.ollamaProvider.history.length}");
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
LlmChatView(
|
LlmChatView(
|
||||||
provider: mzansiAiProvider.ollamaProvider,
|
provider: aiProvider.ollamaProvider,
|
||||||
messageSender: mzansiAiProvider.ollamaProvider.sendMessageStream,
|
messageSender: aiProvider.ollamaProvider.sendMessageStream,
|
||||||
// welcomeMessage:
|
// welcomeMessage:
|
||||||
// "Mzansi AI is here to help. Send us a messahe and we'll try our best to assist you.",
|
// "Mzansi AI is here to help. Send us a messahe and we'll try our best to assist you.",
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
enableAttachments: false,
|
enableAttachments: false,
|
||||||
enableVoiceNotes: false,
|
enableVoiceNotes: false,
|
||||||
style: mzansiAiProvider.getChatStyle(context),
|
style: aiProvider.getChatStyle(context),
|
||||||
// suggestions: [
|
suggestions: [
|
||||||
// "What is mih all about?",
|
"What is mih all about?",
|
||||||
// "What are the features of MIH?"
|
"What are the features of MIH?"
|
||||||
// ],
|
],
|
||||||
),
|
),
|
||||||
if (hasHistory)
|
if (hasHistory)
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 10,
|
|
||||||
bottom: 80,
|
bottom: 80,
|
||||||
child: MihFloatingMenu(
|
left: 10,
|
||||||
animatedIcon: AnimatedIcons.menu_close,
|
child: MihButton(
|
||||||
children: [
|
width: 35,
|
||||||
SpeedDialChild(
|
height: 35,
|
||||||
child: Icon(
|
onPressed: () {
|
||||||
Icons.refresh,
|
if (!aiProvider.ttsOn) {
|
||||||
color: MihColors.getPrimaryColor(
|
speakLastMessage(aiProvider);
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
} else {
|
||||||
"Dark"),
|
stopTTS();
|
||||||
),
|
}
|
||||||
label: "New Chat",
|
},
|
||||||
labelBackgroundColor: MihColors.getGreenColor(
|
buttonColor: !aiProvider.ttsOn
|
||||||
|
? MihColors.getGreenColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
|
||||||
|
: MihColors.getRedColor(
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
"Dark"),
|
"Dark"),
|
||||||
labelStyle: TextStyle(
|
child: Icon(
|
||||||
color: MihColors.getPrimaryColor(
|
!aiProvider.ttsOn ? Icons.volume_up : Icons.volume_off,
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
color: MihColors.getPrimaryColor(
|
||||||
"Dark"),
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
),
|
|
||||||
backgroundColor: MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
onTap: () {
|
|
||||||
resetChat(mzansiAiProvider);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SpeedDialChild(
|
|
||||||
child: Icon(
|
|
||||||
!ttsOn ? Icons.volume_up : Icons.volume_off,
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
label: !ttsOn ? "Read last Message" : "Stop Reading",
|
|
||||||
labelBackgroundColor: MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
labelStyle: TextStyle(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
backgroundColor: !ttsOn
|
|
||||||
? MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")
|
|
||||||
: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
onTap: () {
|
|
||||||
KenLogger.success("Button pressed: TtsOn - $ttsOn");
|
|
||||||
if (!ttsOn) {
|
|
||||||
speakLastMessage(mzansiAiProvider);
|
|
||||||
} else {
|
|
||||||
stopTTS();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Positioned(
|
||||||
|
right: 10,
|
||||||
|
bottom: 80,
|
||||||
|
child: MihFloatingMenu(
|
||||||
|
animatedIcon: AnimatedIcons.menu_close,
|
||||||
|
children: [
|
||||||
|
SpeedDialChild(
|
||||||
|
child: Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
color: MihColors.getPrimaryColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
|
"Dark"),
|
||||||
|
),
|
||||||
|
label: "New Chat",
|
||||||
|
labelBackgroundColor: MihColors.getGreenColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: MihColors.getPrimaryColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
|
"Dark"),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
backgroundColor: MihColors.getGreenColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||||
|
onTap: () {
|
||||||
|
resetChat(aiProvider);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
if (!hasHistory) noMessagescDisplay(),
|
if (!hasHistory) noMessagescDisplay(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user