Commentary + Custom PATH

This commit is contained in:
MasterAcnolo
2025-07-02 16:50:52 +02:00
parent 2a8d307bc8
commit 751f3d5c3e
11 changed files with 354 additions and 97 deletions

View File

@@ -1,3 +1,21 @@
/*
This file is part of Freedom Loader.
Copyright (C) 2025 MasterAcnolo
Freedom Loader is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License.
Freedom Loader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function Chirac(){
const title = document.getElementById("title");
title.innerHTML = "Chirac Loader";
@@ -12,5 +30,4 @@ function Chirac(){
document.body.style.backgroundAttachment = "fixed";
console.log("Je serai le président de tous les français");
}

View File

@@ -0,0 +1,39 @@
/*
Ce script attend que le DOM soit complètement chargé pour initialiser
l'affichage et la gestion du chemin de sauvegarde personnalisé.
1. Récupère le chemin de téléchargement par défaut depuis le main process via l'API exposée.
2. Met à jour le texte affiché dans l'élément avec l'id "savePath".
3. Crée un input caché nommé "savePath" dans le formulaire pour envoyer ce chemin lors du submit.
4. Ajoute un écouteur sur le bouton "changePath" pour permettre à l'utilisateur
de choisir un dossier via une boîte de dialogue native.
5. Met à jour l'affichage et la valeur cachée du chemin sélectionné.
*/
window.addEventListener("DOMContentLoaded", async () => {
const defaultPath = await window.electronAPI.getDefaultDownloadPath();
const savePathElem = document.getElementById("savePath");
if (savePathElem) {
savePathElem.textContent = defaultPath;
}
// Vérifie si l'input caché existe déjà, sinon le crée et l'ajoute au formulaire
let hidden = document.getElementById("savePathInput");
if (!hidden) {
hidden = document.createElement("input");
hidden.type = "hidden";
hidden.name = "savePath";
hidden.id = "savePathInput";
document.getElementById("downloadForm").appendChild(hidden);
}
hidden.value = defaultPath;
// Gestion du clic sur le bouton pour changer le dossier de téléchargement
document.getElementById("changePath").addEventListener("click", async () => {
const selectedPath = await window.electronAPI.selectDownloadFolder();
if (selectedPath) {
savePathElem.textContent = selectedPath;
hidden.value = selectedPath;
}
});
});

View File

@@ -19,53 +19,53 @@
// Récupération du formulaire de téléchargement
const form = document.getElementById("downloadForm");
// Div où on affiche l'état de progression (en cours, erreur, succès)
// Élément où on affichera létat du téléchargement (en cours, erreur, succès)
const statusDiv = document.getElementById("downloadStatus");
// Récupération du bouton de validation pour pouvoir le désactiver pendant la requête
// Récupération du bouton de soumission pour pouvoir le désactiver pendant la requête
const button = form.querySelector("button");
// On intercepte la soumission du formulaire
// Écouteur dévénement pour intercepter la soumission du formulaire
form.addEventListener("submit", async (e) => {
e.preventDefault(); // empêche le rechargement de la page par le navigateur
e.preventDefault(); // Empêche le rechargement automatique de la page
// On désactive le bouton pour éviter les clics multiples
// Désactive le bouton pour éviter les clics multiples pendant la requête
button.disabled = true;
// Affiche un message d'attente à l'utilisateur
// Affiche un message dattente pour informer lutilisateur
statusDiv.textContent = "Téléchargement en cours...";
// Prépare les données du formulaire sous forme URL-encoded
// Prépare les données du formulaire au format URL-encoded
const formData = new FormData(form);
const params = new URLSearchParams(formData);
try {
// Envoi de la requête POST vers /download avec les données du formulaire
// Envoie la requête POST vers /download avec les données du formulaire
const res = await fetch("/download", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: params,
});
// Si la réponse n'est pas un succès (code 4xx ou 5xx)
// Si la réponse nest pas un succès (code HTTP 4xx ou 5xx)
if (!res.ok) {
statusDiv.textContent = "❌ Erreur pendant le téléchargement.";
return;
}
// On récupère le texte de la réponse du serveur
// Récupère le texte envoyé par le serveur (message de succès ou erreur)
const text = await res.text();
// Affiche le message de fin de téléchargement (par exemple « Téléchargement terminé »)
// Affiche le message retourné par le serveur
statusDiv.textContent = text;
} catch {
// Gestion d'erreur en cas de problème réseau ou autre
// Gestion des erreurs réseau ou autres exceptions
statusDiv.textContent = "❌ Une erreur sest produite.";
} finally {
// Réactive le bouton pour autoriser d'autres soumissions
// Réactive le bouton pour permettre dautres soumissions
button.disabled = false;
// Efface le message de status après 5 secondes pour garder l'UI propre
// Efface le message d’état après 5 secondes pour garder linterface propre
setTimeout(() => {
statusDiv.textContent = "";
}, 5000);

View File

@@ -16,17 +16,25 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// On attend que le DOM soit complètement chargé
document.addEventListener("DOMContentLoaded", () => {
// Récupération des éléments du DOM pour interaction
const urlInput = document.getElementById("UrlInput");
const infoDiv = document.getElementById("videoInfo");
// Stocke la dernière URL fetchée pour éviter les requêtes répétées inutiles
let lastFetchedUrl = "";
// Active les logs DEBUG pour le développement
const DEBUG = true;
// Écoute les changements dans l'input URL
urlInput.addEventListener("input", async () => {
const url = urlInput.value.trim();
if (DEBUG) console.log("[DEBUG] Input détecté :", url);
// Si l'URL est vide ou trop courte, on reset l'affichage
if (!url || url.length < 5) {
if (DEBUG) console.log("[DEBUG] URL vide ou trop courte, reset affichage.");
infoDiv.innerHTML = "";
@@ -35,15 +43,19 @@ document.addEventListener("DOMContentLoaded", () => {
return;
}
// Si l'URL est identique à la dernière requêtée, on ne refait pas la requête
if (url === lastFetchedUrl) {
if (DEBUG) console.log("[DEBUG] Même URL que précédemment, pas de fetch.");
return;
}
// Mémorise l'URL actuelle comme dernière URL traitée
lastFetchedUrl = url;
try {
if (DEBUG) console.log("[DEBUG] Envoi requête POST vers /info avec URL:", url);
// Envoi de la requête POST pour récupérer les infos de la vidéo
const res = await fetch("/info", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
@@ -52,6 +64,7 @@ document.addEventListener("DOMContentLoaded", () => {
if (DEBUG) console.log("[DEBUG] Réponse status:", res.status);
// Si la réponse HTTP est une erreur, on affiche un message
if (!res.ok) {
console.error(`[ERROR] Réponse HTTP ${res.status}: ${res.statusText}`);
infoDiv.innerHTML = "❌ Impossible de récupérer les infos (erreur serveur).";
@@ -59,10 +72,11 @@ document.addEventListener("DOMContentLoaded", () => {
return;
}
// Parse la réponse JSON contenant les infos vidéo
const data = await res.json();
if (DEBUG) console.log("[DEBUG] Données reçues:", data);
// Vérification minimaliste
// Vérification simple que les données attendues sont présentes
if (!data || !data.title || !data.thumbnail) {
console.warn("[WARNING] Données incomplètes", data);
infoDiv.innerHTML = "❌ Données incomplètes reçues.";
@@ -70,23 +84,28 @@ document.addEventListener("DOMContentLoaded", () => {
return;
}
// Formatage de la durée en minutes et secondes
const minutes = Math.floor(data.duration / 60);
const seconds = data.duration % 60;
const durationStr = `${minutes}m ${seconds.toString().padStart(2, "0")}s`;
// Formatage de la date d'upload au format JJ/MM/AAAA
const date = data.upload_date || "";
const readableDate = date
? `${date.slice(6, 8)}/${date.slice(4, 6)}/${date.slice(0, 4)}`
: "Inconnue";
// Conversion taille approximative en Mo
const sizeMB = data.filesize_approx
? (data.filesize_approx / (1024 * 1024)).toFixed(2) + " Mo"
: "Inconnue";
// Gestion des catégories, affichage par défaut si absentes
const categories = data.categories
? data.categories.join(", ")
: "Non spécifiées";
// Construction du HTML pour afficher les informations de la vidéo
infoDiv.innerHTML = `
<h3>${data.title}</h3>
<img src="${data.thumbnail}" width="320" alt="Thumbnail">
@@ -102,10 +121,13 @@ document.addEventListener("DOMContentLoaded", () => {
<li><strong>Catégories :</strong> ${categories}</li>
</ul>
`;
// Affiche la div contenant les infos
infoDiv.classList.add("visible");
if (DEBUG) console.log("[DEBUG] Info affichée avec succès.");
} catch (e) {
// En cas d'erreur réseau ou JSON, on affiche un message d'erreur
console.error("[CRITICAL] Erreur lors de la récupération:", e);
infoDiv.innerHTML = "❌ Erreur réseau ou JSON.";
infoDiv.classList.remove("visible");