Fix student_question_answers table creation, clean manifest duplicate units, and calibrate Socratic timeline seeking

This commit is contained in:
Hamza-Ayed
2026-09-03 14:04:39 +03:00
parent b41db82537
commit 7e0aae023a
5 changed files with 141 additions and 128 deletions
@@ -435,52 +435,63 @@ class _SocraticVideoPlayerScreenState extends State<SocraticVideoPlayerScreen> w
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Understanding checkpoints on the timeline
Stack(
alignment: Alignment.centerLeft,
children: [
SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 5,
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 7),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 14),
activeTrackColor: AppColors.saqelCyan,
inactiveTrackColor: Colors.white24,
thumbColor: AppColors.saqelCyan,
),
child: Slider(
value: progress,
onChanged: (val) {
final targetSec = (val * duration).toInt();
context.read<VideoPlaybackCubit>().seekTo(targetSec);
},
),
),
// Checkpoint markers on the progress track
...state.playbackData.checkpoints.map((cp) {
final posFraction = (cp.timestampSeconds / duration).clamp(0.0, 1.0);
final isPassed = state.passedCheckpointIds.contains(cp.id);
return Positioned(
left: (MediaQuery.of(context).size.width * 0.85 * posFraction).clamp(20.0, 700.0),
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: isPassed ? AppColors.emeraldGreen : AppColors.guardianAmber,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 1.5),
boxShadow: [
BoxShadow(
color: (isPassed ? AppColors.emeraldGreen : AppColors.guardianAmber).withAlpha(120),
blurRadius: 6,
),
],
),
),
);
}),
],
),
LayoutBuilder(
builder: (context, constraints) {
const double horizontalPadding = 24.0;
final double trackWidth = (constraints.maxWidth - (horizontalPadding * 2)).clamp(10.0, 4000.0);
return Stack(
alignment: Alignment.centerLeft,
children: [
SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 5,
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 7),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 14),
activeTrackColor: AppColors.saqelCyan,
inactiveTrackColor: Colors.white24,
thumbColor: AppColors.saqelCyan,
),
child: Slider(
value: progress,
onChanged: (val) {
final targetSec = (val * duration).toInt();
context.read<VideoPlaybackCubit>().seekTo(targetSec);
},
),
),
// Checkpoint markers on the progress track
if (duration > 0)
...state.playbackData.checkpoints.map((cp) {
final posFraction = (cp.timestampSeconds / duration).clamp(0.0, 1.0);
final isPassed = state.passedCheckpointIds.contains(cp.id);
final dotLeft = horizontalPadding + (trackWidth * posFraction) - 5.0;
return Positioned(
left: dotLeft,
child: IgnorePointer(
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: isPassed ? AppColors.emeraldGreen : AppColors.guardianAmber,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 1.5),
boxShadow: [
BoxShadow(
color: (isPassed ? AppColors.emeraldGreen : AppColors.guardianAmber).withAlpha(120),
blurRadius: 6,
),
],
),
),
),
);
}),
],
);
},
),
Row(
children: [
IconButton(