Update Saqel Platform: 2026-09-02 08:59:54

This commit is contained in:
Hamza-Ayed
2026-09-02 08:59:54 +03:00
parent 5ecfaafa48
commit 8c62d81f04
@@ -31,6 +31,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
late AnimationController _watermarkController;
VideoPlayerController? _videoController;
bool _isVideoInitialized = false;
int _lastSyncedPosition = -1;
@override
void initState() {
@@ -43,14 +44,21 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
duration: const Duration(seconds: 18),
)..repeat(reverse: true);
// Read the real player clock and periodically persist progress.
// Keep the UI clock responsive, but sync progress to the API every 15s.
_playbackTicker = Timer.periodic(const Duration(seconds: 1), (timer) {
final cubit = context.read<VideoPlaybackCubit>();
final state = cubit.state;
if (state is VideoPlaybackReady && _videoController?.value.isInitialized == true) {
final position = _videoController!.value.position.inSeconds;
if (state.activeCheckpoint == null) cubit.updatePosition(position);
cubit.saveProgress(positionSeconds: position, watchedSeconds: position);
final duration = _videoController!.value.duration.inSeconds;
final shouldSync = _lastSyncedPosition < 0 ||
position - _lastSyncedPosition >= 15 ||
(duration > 0 && position >= duration - 1);
if (shouldSync && position != _lastSyncedPosition) {
_lastSyncedPosition = position;
cubit.saveProgress(positionSeconds: position, watchedSeconds: position);
}
}
});
}
@@ -104,7 +112,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
Icon(CupertinoIcons.shield_lefthalf_fill, color: AppColors.saqelCyan, size: 14),
SizedBox(width: 6),
Text(
'حماية جنائية DRM',
'محتوى محمي',
style: TextStyle(color: AppColors.saqelCyan, fontSize: 11, fontWeight: FontWeight.w700),
),
],
@@ -150,7 +158,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
onOptionSelected: (opt) {
final isCorrect = context.read<VideoPlaybackCubit>().submitCheckpointAnswer(opt);
if (isCorrect) {
SaqelToast.showSuccess(context, 'إجابة نموذجية! تم تعزيز الجاهزية (+0.5%)', title: 'فحص الفهم السقراطي ✨');
SaqelToast.showSuccess(context, 'إجابة صحيحة، تم تسجيل تقدمك.', title: 'نقاط الفهم ✨');
} else {
SaqelToast.showError(context, 'تم إرجاع الفيديو لإعادة الاستماع للنقطة الجوهرية 🔄', title: 'سد الثغرة العلاجية');
}
@@ -321,7 +329,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
),
const SizedBox(width: 8),
Text(
state.isPlaying ? 'جاري البث والشرح التفاعلي ⚡' : 'الشرح متوقف مؤقتاً',
state.isPlaying ? 'جاري الشرح التفاعلي ⚡' : 'الفيديو متوقف مؤقتاً',
style: const TextStyle(
color: AppColors.textSecondaryDark,
fontSize: 12,
@@ -350,7 +358,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
Icon(CupertinoIcons.sparkles, color: AppColors.saqelCyan, size: 12),
SizedBox(width: 6),
Text(
'الشرح السقراطي المعزز 🤖',
'نقاط الفهم',
style: TextStyle(color: AppColors.saqelCyan, fontSize: 11, fontWeight: FontWeight.w700),
),
],
@@ -404,7 +412,7 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Socratic Timeline Progress Bar with Checkpoint Markers
// Understanding checkpoints on the timeline
Stack(
alignment: Alignment.centerLeft,
children: [