72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
// Engagement heatmap tracking
|
|
// Samples the user's current time while playing and sends batched segment data to the server.
|
|
// Only tracks segment >= 1 (excludes 0-10s).
|
|
// Only calls the endpoint when the user is logged in.
|
|
|
|
let engagementInterval;
|
|
let engagementSegments = new Set();
|
|
let engagementReportInterval;
|
|
const SEGMENT_DURATION = 10; // seconds per segment
|
|
const SAMPLE_INTERVAL = 5000; // sample every 5s
|
|
const REPORT_INTERVAL = 15000; // send batch every 15s
|
|
|
|
function isAuthenticated() {
|
|
const el = document.getElementById('auth_check');
|
|
return el && el.value === '1';
|
|
}
|
|
|
|
function sendEngagement(episodeId, segments) {
|
|
if (!isAuthenticated()) return;
|
|
|
|
window.axios.post('/player/engagement', {
|
|
episode_id: episodeId,
|
|
segments: segments,
|
|
}).catch(() => {
|
|
// Fire-and-forget: silently ignore network errors
|
|
});
|
|
}
|
|
|
|
export function startEngagementTracking(episodeId) {
|
|
engagementSegments.clear();
|
|
|
|
// Sample current time while playing
|
|
engagementInterval = setInterval(() => {
|
|
const video = document.querySelector('video');
|
|
if (!video || video.paused) return;
|
|
|
|
const segment = Math.floor(video.currentTime / SEGMENT_DURATION);
|
|
// Skip segment 0 (0-10s) — no need to track the very start
|
|
if (segment >= 1) {
|
|
engagementSegments.add(segment);
|
|
}
|
|
}, SAMPLE_INTERVAL);
|
|
|
|
// Batch report to server
|
|
engagementReportInterval = setInterval(() => {
|
|
if (engagementSegments.size === 0) return;
|
|
|
|
const segments = Array.from(engagementSegments);
|
|
engagementSegments.clear();
|
|
|
|
sendEngagement(episodeId, segments);
|
|
}, REPORT_INTERVAL);
|
|
|
|
// Flush remaining segments & cleanup on page unload
|
|
const cleanup = () => {
|
|
clearInterval(engagementInterval);
|
|
clearInterval(engagementReportInterval);
|
|
|
|
if (engagementSegments.size > 0) {
|
|
const segments = Array.from(engagementSegments);
|
|
engagementSegments.clear();
|
|
sendEngagement(episodeId, segments);
|
|
}
|
|
};
|
|
|
|
window.addEventListener('beforeunload', cleanup);
|
|
}
|
|
|
|
export function stopEngagementTracking() {
|
|
if (engagementInterval) clearInterval(engagementInterval);
|
|
if (engagementReportInterval) clearInterval(engagementReportInterval);
|
|
} |