fix(playback): enable authentic video playback for Intro and Lesson 2 across student app and backend
This commit is contained in:
@@ -234,24 +234,19 @@ class CurriculumLessonItemModel {
|
||||
: 'lesson_${(json['title']?.toString() ?? 'default').hashCode.abs()}');
|
||||
|
||||
// Video availability:
|
||||
// 1. Explicitly false for introductory/project overviews
|
||||
// 2. Physics & other subjects currently have no video -> false
|
||||
// 3. Math 10 Lesson 1 ("حل معادلات خاصة") has the authentic lesson video -> true
|
||||
final bool isIntroOrProject = (jsonId == 'intro_and_project') ||
|
||||
(filePath?.contains('intro_and_project') ?? false) ||
|
||||
// 1. Live server enriched: json['has_video'] == true or json['video_url'] is present
|
||||
// 2. Unit 1 Math 10 lessons (Intro, Lesson 1, Lesson 2) uploaded by teacher are fully available
|
||||
final bool hasVideoExplicit = (json['has_video'] == true) ||
|
||||
(json['video_url'] != null && json['video_url'].toString().isNotEmpty) ||
|
||||
(filePath != null && (
|
||||
filePath.contains('math_10/semester_1/unit_01') ||
|
||||
filePath.contains('intro_and_project') ||
|
||||
filePath.contains('lesson_01') ||
|
||||
filePath.contains('lesson_02')
|
||||
)) ||
|
||||
((json['title']?.toString() ?? '').contains('معادلات')) ||
|
||||
((json['title']?.toString() ?? '').contains('مقدمة ومشروع'));
|
||||
|
||||
final bool isMath10Lesson1 = !isIntroOrProject && (
|
||||
(filePath != null && filePath.contains('math_10/semester_1/unit_01/lesson_01')) ||
|
||||
((json['title']?.toString() ?? '').contains('معادلاتٍ خاصّةٍ'))
|
||||
);
|
||||
|
||||
final bool hasVideoExplicit = !isIntroOrProject && (
|
||||
(json['has_video'] == true) ||
|
||||
(json['video_url'] != null && json['video_url'].toString().isNotEmpty) ||
|
||||
isMath10Lesson1
|
||||
);
|
||||
|
||||
return CurriculumLessonItemModel(
|
||||
id: stableId,
|
||||
title: json['title']?.toString() ?? 'درس بدون عنوان',
|
||||
|
||||
@@ -121,10 +121,14 @@ class CurriculumRepository {
|
||||
}
|
||||
|
||||
/// Fetch lesson playback details (streams, checkpoints, and versions) from Live API
|
||||
Future<LessonPlaybackData> getLessonPlayback(String curriculumKey, {String? subjectId, String? unitId}) async {
|
||||
AppLogger.log('Fetching live playback data for curriculum key $curriculumKey...', tag: 'CURRICULUM_REPO');
|
||||
Future<LessonPlaybackData> getLessonPlayback(String curriculumKey, {String? subjectId, String? unitId, String? title}) async {
|
||||
AppLogger.log('Fetching live playback data for curriculum key $curriculumKey (title: $title)...', tag: 'CURRICULUM_REPO');
|
||||
|
||||
final res = await _api.get('/api/lessons/playback', queryParams: {'curriculum_key': curriculumKey});
|
||||
final Map<String, String> queryParams = {'curriculum_key': curriculumKey};
|
||||
if (title != null && title.isNotEmpty) {
|
||||
queryParams['title'] = title;
|
||||
}
|
||||
final res = await _api.get('/api/lessons/playback', queryParams: queryParams);
|
||||
if (res is Map && res['data'] != null) {
|
||||
return LessonPlaybackData.fromJson(Map<String, dynamic>.from(res['data']));
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class VideoPlaybackCubit extends Cubit<VideoPlaybackState> {
|
||||
|
||||
try {
|
||||
final cleanKey = (lesson.markdownFilePath ?? lesson.id).replaceAll(RegExp(r'\.md$'), '');
|
||||
var playback = await _repo.getLessonPlayback(cleanKey, subjectId: subject?.id);
|
||||
var playback = await _repo.getLessonPlayback(cleanKey, subjectId: subject?.id, title: lesson.title);
|
||||
if (playback.videoUrl.isEmpty) {
|
||||
throw StateError('لم يربط الخادم فيديو R2 بهذا الدرس بعد.');
|
||||
}
|
||||
|
||||
@@ -814,13 +814,8 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
);
|
||||
}
|
||||
|
||||
/// Direct Launch of Socratic Video Player or Transparent No-Video Sheet
|
||||
/// Direct Launch of Socratic Video Player
|
||||
void _showLessonVideoSelector(BuildContext context, CurriculumLessonItemModel lesson) {
|
||||
if (!lesson.hasVideo) {
|
||||
_showNoVideoAvailableSheet(context, lesson);
|
||||
return;
|
||||
}
|
||||
|
||||
// Direct authentic launch: zero mockups, zero fake teacher names
|
||||
Navigator.of(context).push(
|
||||
CupertinoPageRoute(
|
||||
|
||||
Reference in New Issue
Block a user