Update Saqel Platform: 2026-09-05 23:24:49

This commit is contained in:
Hamza-Ayed
2026-09-05 23:24:49 +03:00
parent 0e5be7adbb
commit 0f424062fe
20 changed files with 2132 additions and 324 deletions
@@ -4,35 +4,43 @@ import '../../data/repositories/teacher_repository.dart';
/**
* ==============================================================================
* SAQEL TEACHER STUDIO - ASSIGNMENTS & Q&A CUBIT
* SAQEL TEACHER STUDIO - ASSIGNMENTS, Q&A & WEBSOCKET BROADCAST CUBIT
* ==============================================================================
*
* إدارة الواجبات المدرسية وأوراق العمل وغرفة تساؤلات الطلبة:
* - توليد وإسناد أوراق عمل مؤتمتة التصحيح بنقرة واحدة
* - تسجيل الردود الصوتية السقراطية (Socratic Voice Replies 🎙️)
* - تحديث فوري لحالات الشكوك والتساؤلات.
* إدارة الواجبات المدرسية وغرفة استفسارات الطلبة والبث الفوري عبر الويب سوكت:
* - محادثات حية ومباشرة مع الطلبة المسجلين (مثل سما حمزة)
* - تسجيل وإرسال الردود الصوتية السقراطية (Socratic Voice Replies 🎙️)
* - بث مقاطع صوتية توجيهية لكافة طلبة الشعبة عبر الويب سوكت (0ms Broadcast).
*/
class TeacherQnAState {
final List<TeacherHomeworkModel> homeworks;
final List<StudentDoubtModel> doubts;
final List<ChatConversationModel> conversations;
final bool isLoading;
final bool isBroadcasting;
const TeacherQnAState({
required this.homeworks,
required this.doubts,
required this.conversations,
required this.isLoading,
this.isBroadcasting = false,
});
TeacherQnAState copyWith({
List<TeacherHomeworkModel>? homeworks,
List<StudentDoubtModel>? doubts,
List<ChatConversationModel>? conversations,
bool? isLoading,
bool? isBroadcasting,
}) {
return TeacherQnAState(
homeworks: homeworks ?? this.homeworks,
doubts: doubts ?? this.doubts,
conversations: conversations ?? this.conversations,
isLoading: isLoading ?? this.isLoading,
isBroadcasting: isBroadcasting ?? this.isBroadcasting,
);
}
}
@@ -44,6 +52,7 @@ class TeacherQnACubit extends Cubit<TeacherQnAState> {
: super(const TeacherQnAState(
homeworks: [],
doubts: [],
conversations: [],
isLoading: false,
));
@@ -51,9 +60,12 @@ class TeacherQnACubit extends Cubit<TeacherQnAState> {
emit(state.copyWith(isLoading: true));
final hwList = await repository.getHomeworks();
final doubtsList = await repository.getStudentDoubts();
final conversationsList = await repository.getConversations();
emit(state.copyWith(
homeworks: hwList,
doubts: doubtsList,
conversations: conversationsList,
isLoading: false,
));
}
@@ -77,7 +89,7 @@ class TeacherQnACubit extends Cubit<TeacherQnAState> {
emit(state.copyWith(homeworks: updated));
}
void recordVoiceReply(String doubtId) {
Future<void> sendVoiceReply(String doubtId, {String? voiceText}) async {
final updated = state.doubts.map((doubt) {
if (doubt.id == doubtId) {
return doubt.copyWith(replied: true, voiceReply: true);
@@ -86,5 +98,30 @@ class TeacherQnACubit extends Cubit<TeacherQnAState> {
}).toList();
emit(state.copyWith(doubts: updated));
// Also send actual message to student via API
await repository.sendMessage(
receiverId: 2, // Sama Hamza (Real Student)
message: voiceText ?? 'رد صوتي سقراطي: تم تسجيل وتوجيه المفاهيم المتعلقة بالسؤال.',
messageType: 'voice',
mediaUrl: 'https://saqel.intaleqapp.com/assets/audio/voice_reply_socratic.mp3',
);
}
Future<bool> broadcastAudioAnnouncement({
required String title,
required String explanationText,
required String gradeLevel,
}) async {
emit(state.copyWith(isBroadcasting: true));
final success = await repository.broadcastAnnouncement(
title: title,
message: explanationText,
messageType: 'voice',
mediaUrl: 'https://saqel.intaleqapp.com/assets/audio/teacher_broadcast.mp3',
gradeLevel: gradeLevel,
);
emit(state.copyWith(isBroadcasting: false));
return success;
}
}