Fix student_question_answers table creation, clean manifest duplicate units, and calibrate Socratic timeline seeking
This commit is contained in:
+57
-46
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user