MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 13: | Line 13: | ||
var videoEl = $video[0]; | var videoEl = $video[0]; | ||
var filename = $video.attr('data-file'); | var filename = $video.attr('data-file'); | ||
console.log('Training video init. Filename:', filename); | |||
if (filename) { | if (filename) { | ||
$.ajax({ | $.ajax({ | ||
url: | url: '/wiki/api.php', | ||
data: { | data: { | ||
action: 'query', | action: 'query', | ||
| Line 28: | Line 28: | ||
dataType: 'json', | dataType: 'json', | ||
success: function (data) { | success: function (data) { | ||
console.log('API response received'); | |||
var pages = data.query.pages; | var pages = data.query.pages; | ||
var page = pages[Object.keys(pages)[0]]; | var page = pages[Object.keys(pages)[0]]; | ||
if (page.imageinfo && page.imageinfo[0]) { | if (page.imageinfo && page.imageinfo[0]) { | ||
var url = page.imageinfo[0].url; | var url = page.imageinfo[0].url; | ||
videoEl.src | console.log('Setting video src to:', url); | ||
videoEl.setAttribute('src', url); | |||
videoEl.load(); | videoEl.load(); | ||
} else { | |||
console.log('No imageinfo found in response:', JSON.stringify(data)); | |||
} | } | ||
}, | |||
error: function (err) { | |||
console.log('API error:', err); | |||
} | } | ||
}); | }); | ||
} else { | |||
console.log('No filename found in data-file attribute'); | |||
} | } | ||
Revision as of 01:43, 23 April 2026
/* Any JavaScript here will be loaded for all users on every page load. */
/* ============================================================
Training Video – Video source loader + Synced Transcript
============================================================ */
$(function () {
if ($('.training-video-wrap').length === 0) return;
var $video = $('.training-video-wrap video');
if ($video.length === 0) return;
var videoEl = $video[0];
var filename = $video.attr('data-file');
console.log('Training video init. Filename:', filename);
if (filename) {
$.ajax({
url: '/wiki/api.php',
data: {
action: 'query',
titles: 'File:' + filename,
prop: 'imageinfo',
iiprop: 'url',
format: 'json'
},
dataType: 'json',
success: function (data) {
console.log('API response received');
var pages = data.query.pages;
var page = pages[Object.keys(pages)[0]];
if (page.imageinfo && page.imageinfo[0]) {
var url = page.imageinfo[0].url;
console.log('Setting video src to:', url);
videoEl.setAttribute('src', url);
videoEl.load();
} else {
console.log('No imageinfo found in response:', JSON.stringify(data));
}
},
error: function (err) {
console.log('API error:', err);
}
});
} else {
console.log('No filename found in data-file attribute');
}
/* ── Format seconds → m:ss ── */
function fmt(s) {
s = Math.floor(s);
return Math.floor(s / 60) + ':' + ('0' + (s % 60)).slice(-2);
}
var $entries = $('.ts-entry');
var $body = $('.ts-scroll-body');
var $markers = $('.ts-progress-marker');
var $fill = $('.ts-progress-fill');
var $timeDisp = $('.ts-time-display');
/* ── Collect timestamp data from DOM ── */
var timestamps = [];
$entries.each(function () {
timestamps.push(parseInt($(this).data('time'), 10));
});
/* ── Highlight the active transcript entry ── */
function highlightActive() {
var cur = videoEl.currentTime;
var activeIdx = 0;
for (var i = 0; i < timestamps.length; i++) {
if (cur >= timestamps[i]) activeIdx = i;
}
$entries.each(function (i) {
$(this).toggleClass('ts-active', i === activeIdx);
});
var $active = $entries.eq(activeIdx);
if ($active.length && $body.length) {
var entryTop = $active.position().top;
var bodyScrollTop = $body.scrollTop();
var bodyHeight = $body.height();
if (entryTop < 0 || entryTop > bodyHeight - 60) {
$body.animate({ scrollTop: bodyScrollTop + entryTop - 60 }, 200);
}
}
}
/* ── Update progress bar ── */
function updateProgress() {
if (!videoEl.duration) return;
var pct = (videoEl.currentTime / videoEl.duration) * 100;
$fill.css('width', pct + '%');
$timeDisp.text(fmt(videoEl.currentTime) + ' / ' + fmt(videoEl.duration));
}
/* ── Bind native video events ── */
$video.on('timeupdate', function () {
highlightActive();
updateProgress();
});
$video.on('loadedmetadata', function () {
$timeDisp.text('0:00 / ' + fmt(videoEl.duration));
$markers.each(function () {
var t = parseInt($(this).data('time'), 10);
$(this).css('left', ((t / videoEl.duration) * 100) + '%');
});
});
/* ── Transcript entry click → seek video ── */
$entries.on('click', function () {
var t = parseInt($(this).data('time'), 10);
videoEl.currentTime = t;
if (videoEl.paused) videoEl.play();
highlightActive();
});
/* ── Progress bar click → seek ── */
$('.ts-progress-track').on('click', function (e) {
var rect = this.getBoundingClientRect();
var ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
videoEl.currentTime = ratio * videoEl.duration;
});
/* ── Marker click → seek ── */
$markers.on('click', function (e) {
e.stopPropagation();
var t = parseInt($(this).data('time'), 10);
videoEl.currentTime = t;
if (videoEl.paused) videoEl.play();
});
});
/* ============================================================ */