feat: mark video as watched after a certain duration

This commit is contained in:
Gus Libens 2025-11-07 00:25:16 +01:00
parent 5cfe294063
commit c9adc5e7e0
No known key found for this signature in database
GPG Key ID: 032E49D0FE9D51EA

View File

@ -2,6 +2,8 @@
var player_data = JSON.parse(document.getElementById('player_data').textContent); var player_data = JSON.parse(document.getElementById('player_data').textContent);
var video_data = JSON.parse(document.getElementById('video_data').textContent); var video_data = JSON.parse(document.getElementById('video_data').textContent);
const STORAGE_MARK_WATCHED_AFTER_DURATION = "mark_watched_after_duration";
var options = { var options = {
liveui: true, liveui: true,
playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
@ -127,12 +129,41 @@ function addCurrentTimeToURL(url, base) {
var timeupdate_last_ts = 5; var timeupdate_last_ts = 5;
/** /**
* Callback that updates the timestamp on all external links * Global variable to save the total video time watched (in seconds).
*/
let time_watched = 0;
/**
* The duration of a short video (in seconds).
* This value is used to determine whether the video should be watched fully before
* being marked as watched.
*
* @default 30
*/
const SHORT_VIDEO_DURATION = 30;
/**
* The duration (in seconds) after which a video should be marked as watched.
*
* @default 30
*/
const MARK_WATCHED_AFTER_DURATION = SHORT_VIDEO_DURATION;
/**
* Callback that updates the timestamp on all external links and marks the video as watched after:
* - fully watching short videos (<=30 seconds)
* - time watched reaches 30 seconds for long videos (>30 seconds)
*/ */
player.on('timeupdate', function () { player.on('timeupdate', function () {
// Only update once every second // Only update once every second
let current_ts = Math.floor(player.currentTime()); let current_ts = Math.floor(player.currentTime());
if (current_ts > timeupdate_last_ts) timeupdate_last_ts = current_ts; const last_player_time = timeupdate_last_ts;
if (
// Seek forward
current_ts > timeupdate_last_ts ||
// Seek backward
current_ts < timeupdate_last_ts
) timeupdate_last_ts = current_ts;
else return; else return;
// YouTube links // YouTube links
@ -166,6 +197,50 @@ player.on('timeupdate', function () {
let base_url_iv_other = elem_iv_other.getAttribute('data-base-url'); let base_url_iv_other = elem_iv_other.getAttribute('data-base-url');
elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain); elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain);
} }
// Only increase time watched when the time difference is one second or the video is not already marked as watched
const isOneSecondDifference = current_ts - last_player_time === 1;
const exceedsMarkWatchedAfterDuration = time_watched > MARK_WATCHED_AFTER_DURATION;
const markWatchedAfterDuration = helpers.storage.get(STORAGE_MARK_WATCHED_AFTER_DURATION) ?? false;
if (!isOneSecondDifference || exceedsMarkWatchedAfterDuration || markWatchedAfterDuration === false) return;
time_watched += 1
// Check if time watched exceeds 30 seconds or the video is fully watched
const absolute_video_duration = Math.floor(player.duration());
const watched_at_timestamp = absolute_video_duration > SHORT_VIDEO_DURATION
? MARK_WATCHED_AFTER_DURATION
: absolute_video_duration;
if (time_watched !== watched_at_timestamp) return;
const video_id = document.querySelector('[name="id"]').value;
const $csrfToken = document.querySelector('[name="csrf_token"]');
// User is not logged in
if ($csrfToken === null) return;
// Mark the video as watched
const csrf_token = $csrfToken.value;
const params = new URLSearchParams({
action: "mark_watched",
redirect: false,
id: video_id
});
const url = `/watch_ajax?${params}`
helpers.xhr('POST', url, { payload: `csrf_token=${csrf_token}` }, {
on200: () => {
console.info(`Marked video ${video_id} as watched`);
},
onNon200: ({ response }) => {
console.error(`Something went wrong while marking video ${video_id} as watched:`, response);
}
});
}); });