Statistics page redesign #60
@@ -1935,11 +1935,6 @@ window.onload = async function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vod_link && !video_src && !video_file && !embed_src) {
|
|
||||||
showResponse('warning', 'Ajoute au moins une source (VOD / video_src / video_file / embed_src).');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/movies/add', {
|
const res = await fetch('/api/movies/add', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -2187,11 +2182,6 @@ window.onload = async function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vod_link && !video_src && !video_file && !embed_src) {
|
|
||||||
showResponse('warning', 'Ajoute au moins une source (VOD / video_src / video_file / embed_src).');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
imdb_id,
|
imdb_id,
|
||||||
year: yearRaw === '' ? null : year,
|
year: yearRaw === '' ? null : year,
|
||||||
|
|||||||
@@ -444,13 +444,27 @@ window.addEventListener('DOMContentLoaded', async function () {
|
|||||||
const watchedLabel = formatWatchedDate(movie?.watchedDate);
|
const watchedLabel = formatWatchedDate(movie?.watchedDate);
|
||||||
const posterUrl = normalizePosterUrl(movie?.poster);
|
const posterUrl = normalizePosterUrl(movie?.poster);
|
||||||
|
|
||||||
|
const cleanUrl = (v) => {
|
||||||
|
const s = (typeof v === 'string' ? v.trim() : '');
|
||||||
|
if (!s || s === '#' || s.toLowerCase() === 'about:blank') return '';
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Click behavior (requested):
|
||||||
|
// - If vod_link is set => go to it
|
||||||
|
// - Else if any playable source exists => go to player
|
||||||
|
// - Else => not clickable
|
||||||
|
const vodLink = cleanUrl(movie?.vod_link);
|
||||||
|
const hasPlayableSource = !!cleanUrl(movie?.video_src) || !!cleanUrl(movie?.embed_src) || !!cleanUrl(movie?.video_file);
|
||||||
|
const isClickable = !!vodLink || (!!movieId && hasPlayableSource);
|
||||||
|
|
||||||
const item = document.createElement('div');
|
const item = document.createElement('div');
|
||||||
item.className = 'stats-movie-item';
|
item.className = 'stats-movie-item';
|
||||||
if (movieId) {
|
if (isClickable) {
|
||||||
item.classList.add('stats-movie-item--clickable');
|
item.classList.add('stats-movie-item--clickable');
|
||||||
item.setAttribute('role', 'link');
|
item.setAttribute('role', 'link');
|
||||||
item.setAttribute('tabindex', '0');
|
item.setAttribute('tabindex', '0');
|
||||||
item.setAttribute('aria-label', `Ouvrir le lecteur: ${title}`);
|
item.setAttribute('aria-label', vodLink ? `Ouvrir le lien: ${title}` : `Ouvrir le lecteur: ${title}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const poster = document.createElement('img');
|
const poster = document.createElement('img');
|
||||||
@@ -468,22 +482,36 @@ window.addEventListener('DOMContentLoaded', async function () {
|
|||||||
try { poster.removeAttribute('src'); } catch (_) {}
|
try { poster.removeAttribute('src'); } catch (_) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
function openPlayerIfPossible(evt) {
|
function openIfPossible(evt) {
|
||||||
if (!movieId) return;
|
if (!isClickable) return;
|
||||||
// Don't hijack clicks inside controls (IMDb button, details summary, etc.)
|
// Don't hijack clicks inside controls (IMDb button, details summary, etc.)
|
||||||
const target = evt?.target;
|
const target = evt?.target;
|
||||||
if (target && typeof target.closest === 'function') {
|
if (target && typeof target.closest === 'function') {
|
||||||
if (target.closest('a, button, summary, details')) return;
|
if (target.closest('a, button, summary, details')) return;
|
||||||
}
|
}
|
||||||
window.location.href = `/player.html?id=${encodeURIComponent(movieId)}`;
|
|
||||||
|
if (vodLink) {
|
||||||
|
// Use a new tab (keeps the app state intact)
|
||||||
|
try {
|
||||||
|
const w = window.open(vodLink, '_blank', 'noopener,noreferrer');
|
||||||
|
if (!w) window.location.href = vodLink;
|
||||||
|
} catch (_) {
|
||||||
|
window.location.href = vodLink;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movieId && hasPlayableSource) {
|
||||||
|
window.location.href = `/player.html?id=${encodeURIComponent(movieId)}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movieId) {
|
if (isClickable) {
|
||||||
item.addEventListener('click', openPlayerIfPossible);
|
item.addEventListener('click', openIfPossible);
|
||||||
item.addEventListener('keydown', (e) => {
|
item.addEventListener('keydown', (e) => {
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
openPlayerIfPossible(e);
|
openIfPossible(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -130,7 +130,7 @@ router.get("/stats", verifyToken, async (req, res) => {
|
|||||||
|
|
||||||
// Fetch movies (optionally filtered by year)
|
// Fetch movies (optionally filtered by year)
|
||||||
const allMovies = await Movie.find({ year })
|
const allMovies = await Movie.find({ year })
|
||||||
.select("imdb_id title poster rating category year")
|
.select("imdb_id title poster rating category year vod_link player_mode video_src embed_src video_file")
|
||||||
.lean();
|
.lean();
|
||||||
const totalMoviesCount = allMovies.length;
|
const totalMoviesCount = allMovies.length;
|
||||||
|
|
||||||
@@ -158,6 +158,11 @@ router.get("/stats", verifyToken, async (req, res) => {
|
|||||||
rating: movie.rating || "",
|
rating: movie.rating || "",
|
||||||
category: movie.category || "",
|
category: movie.category || "",
|
||||||
year: Number.isInteger(movie.year) ? movie.year : year,
|
year: Number.isInteger(movie.year) ? movie.year : year,
|
||||||
|
vod_link: movie.vod_link || "",
|
||||||
|
player_mode: movie.player_mode || "auto",
|
||||||
|
video_src: movie.video_src || "",
|
||||||
|
embed_src: movie.embed_src || "",
|
||||||
|
video_file: movie.video_file || "",
|
||||||
watchedDate: wm?.watchedDate ? new Date(wm.watchedDate).toISOString() : null,
|
watchedDate: wm?.watchedDate ? new Date(wm.watchedDate).toISOString() : null,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user