commit
						47bcfd763e
					
				@ -0,0 +1,67 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>Playlist download</title>
 | 
			
		||||
    <link rel="stylesheet" href="../assets/css/index.css">
 | 
			
		||||
    <script src="../src/playlist.js" defer></script>
 | 
			
		||||
    <script src="../src/common.js" defer></script>
 | 
			
		||||
    <!-- Translating -->
 | 
			
		||||
    <script>window.i18n = new (require('../translations/i18n'));</script>
 | 
			
		||||
    <style>
 | 
			
		||||
        #playlistName {
 | 
			
		||||
            padding: 30px;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
    <!-- Theme toggle -->
 | 
			
		||||
    <div id="themeToggle" onclick="toggle()">
 | 
			
		||||
        <div id="themeToggleInside"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Menu icon -->
 | 
			
		||||
    <img src="../assets/images/menu.png" alt="menu" id="menuIcon">
 | 
			
		||||
 | 
			
		||||
    <!-- Menu -->
 | 
			
		||||
    <div id="menu">
 | 
			
		||||
        <a id="homeWin" class="menuItem">Homepage</a>
 | 
			
		||||
        <a id="preferenceWin" class="menuItem">Preferences</a>
 | 
			
		||||
        <a id="aboutWin" class="menuItem">About</a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <button class="submitBtn" id="pasteLink">Click to paste playlist link from clipboard [Ctrl + V]</button>
 | 
			
		||||
 | 
			
		||||
    <div id="options">
 | 
			
		||||
        <br>
 | 
			
		||||
        <strong>Link:</strong><span id="link"></span>
 | 
			
		||||
        <br><br>
 | 
			
		||||
 | 
			
		||||
        <label>Select Format</label>
 | 
			
		||||
        <select id="select">
 | 
			
		||||
            <option value="144">144p</option>
 | 
			
		||||
            <option value="240">240p</option>
 | 
			
		||||
            <option value="360">360p</option>
 | 
			
		||||
            <option value="480">480p</option>
 | 
			
		||||
            <option value="720">720p (HD)</option>
 | 
			
		||||
            <option value="1080">1080p (FHD)</option>
 | 
			
		||||
            <option value="1440">1440p</option>
 | 
			
		||||
            <option value="2160">2160p (4k)</option>
 | 
			
		||||
        </select>
 | 
			
		||||
 | 
			
		||||
        <button class="submitBtn" id="download">Download</button>
 | 
			
		||||
 | 
			
		||||
        <p id="incorrectMsg"></p>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <h2 id="playlistName"></h2>
 | 
			
		||||
    <div id="list">
 | 
			
		||||
    </div>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
@ -0,0 +1,100 @@
 | 
			
		||||
function getId(id) {
 | 
			
		||||
	return document.getElementById(id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let menuIsOpen = false;
 | 
			
		||||
 | 
			
		||||
getId("menuIcon").addEventListener("click", (event) => {
 | 
			
		||||
	if (menuIsOpen) {
 | 
			
		||||
		getId("menuIcon").style.transform = "rotate(0deg)";
 | 
			
		||||
		menuIsOpen = false;
 | 
			
		||||
		let count = 0;
 | 
			
		||||
		let opacity = 1;
 | 
			
		||||
		const fade = setInterval(() => {
 | 
			
		||||
			if (count >= 10) {
 | 
			
		||||
				getId("menu").style.display = "none"
 | 
			
		||||
				clearInterval(fade);
 | 
			
		||||
			} else {
 | 
			
		||||
				opacity -= 0.1;
 | 
			
		||||
				getId("menu").style.opacity = opacity;
 | 
			
		||||
				count++;
 | 
			
		||||
			}
 | 
			
		||||
		}, 50);
 | 
			
		||||
	} else {
 | 
			
		||||
		getId("menuIcon").style.transform = "rotate(90deg)";
 | 
			
		||||
		menuIsOpen = true;
 | 
			
		||||
 | 
			
		||||
		setTimeout(() => {
 | 
			
		||||
			getId("menu").style.display = "flex";
 | 
			
		||||
			getId("menu").style.opacity = 1;
 | 
			
		||||
		}, 150);
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Toggle theme
 | 
			
		||||
let circle = getId("themeToggleInside");
 | 
			
		||||
let darkTheme = true;
 | 
			
		||||
circle.style.left = "25px";
 | 
			
		||||
 | 
			
		||||
const root = document.querySelector(":root");
 | 
			
		||||
 | 
			
		||||
let enabledTransparent = localStorage.getItem("enabledTransparent");
 | 
			
		||||
let bgColor = "";
 | 
			
		||||
if (enabledTransparent == "true") {
 | 
			
		||||
	bgColor = "rgba(40,40,40, .9)";
 | 
			
		||||
} else {
 | 
			
		||||
	bgColor = "rgb(40,40,40)";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function toggle() {
 | 
			
		||||
	if (darkTheme == false) {
 | 
			
		||||
		// Switching to dark theme
 | 
			
		||||
		circle.style.left = "25px";
 | 
			
		||||
 | 
			
		||||
		root.style.setProperty("--background", bgColor);
 | 
			
		||||
		root.style.setProperty("--text", "white");
 | 
			
		||||
		root.style.setProperty("--box-main", "rgb(80,80,80)");
 | 
			
		||||
		root.style.setProperty("--box-toggle", "rgb(70,70,70)");
 | 
			
		||||
		root.style.setProperty("--theme-toggle", "rgb(80, 193, 238)");
 | 
			
		||||
		root.style.setProperty("--item-bg", "rgb(75, 75, 75)");
 | 
			
		||||
 | 
			
		||||
		darkTheme = true;
 | 
			
		||||
		localStorage.setItem("theme", "dark");
 | 
			
		||||
	} else {
 | 
			
		||||
		// Switching to light theme
 | 
			
		||||
		circle.style.left = "0px";
 | 
			
		||||
 | 
			
		||||
		root.style.setProperty("--background", "whitesmoke");
 | 
			
		||||
		root.style.setProperty("--text", "rgb(45, 45, 45)");
 | 
			
		||||
		root.style.setProperty("--box-main", "rgb(174 249 224)");
 | 
			
		||||
		root.style.setProperty("--box-toggle", "rgb(108, 231, 190)");
 | 
			
		||||
		root.style.setProperty("--theme-toggle", "rgb(147, 174, 185)");
 | 
			
		||||
		root.style.setProperty("--item-bg", "#dddddd");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		darkTheme = false;
 | 
			
		||||
		localStorage.setItem("theme", "light");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const storageTheme = localStorage.getItem("theme");
 | 
			
		||||
 | 
			
		||||
if (storageTheme == "dark") {
 | 
			
		||||
	darkTheme = false;
 | 
			
		||||
	toggle();
 | 
			
		||||
} else if (storageTheme == "light") {
 | 
			
		||||
	darkTheme = true;
 | 
			
		||||
	toggle();
 | 
			
		||||
}
 | 
			
		||||
////
 | 
			
		||||
let advancedHidden = true;
 | 
			
		||||
 | 
			
		||||
function advancedToggle() {
 | 
			
		||||
	if (advancedHidden) {
 | 
			
		||||
		getId("advanced").style.display = "block";
 | 
			
		||||
		advancedHidden = false;
 | 
			
		||||
	} else {
 | 
			
		||||
		getId("advanced").style.display = "none";
 | 
			
		||||
		advancedHidden = true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,145 @@
 | 
			
		||||
const { clipboard, shell, ipcRenderer } = require("electron");
 | 
			
		||||
const { default: YTDlpWrap } = require("yt-dlp-wrap-extended");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
let url;
 | 
			
		||||
const ytDlp = localStorage.getItem("ytdlp");
 | 
			
		||||
const ytdlp = new YTDlpWrap(ytDlp);
 | 
			
		||||
const downloadDir = localStorage.getItem("downloadPath");
 | 
			
		||||
const i18n = new (require("../translations/i18n"))();
 | 
			
		||||
 | 
			
		||||
function getId(id) {
 | 
			
		||||
	return document.getElementById(id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function pasteLink() {
 | 
			
		||||
	url = clipboard.readText();
 | 
			
		||||
	getId("link").textContent = " " + url;
 | 
			
		||||
	getId("options").style.display = "block";
 | 
			
		||||
	getId("incorrectMsg").textContent = "";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
getId("pasteLink").addEventListener("click", () => {
 | 
			
		||||
	pasteLink();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
document.addEventListener("keydown", (event) => {
 | 
			
		||||
	if (event.ctrlKey && event.key == "v") {
 | 
			
		||||
		pasteLink();
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Patterns
 | 
			
		||||
const playlistTxt = "Downloading playlist: ";
 | 
			
		||||
const videoIndex = "Downloading video ";
 | 
			
		||||
//  Downloading playlist: Inkscape Tutorials
 | 
			
		||||
// Downloading video 1 of 82
 | 
			
		||||
 | 
			
		||||
getId("download").addEventListener("click", () => {
 | 
			
		||||
	let count = 0;
 | 
			
		||||
	let playlistName;
 | 
			
		||||
 | 
			
		||||
	getId("options").style.display = "none";
 | 
			
		||||
	getId("pasteLink").style.display = "none";
 | 
			
		||||
	getId("playlistName").textContent = i18n.__("Processing") + "..."
 | 
			
		||||
	const quality = getId("select").value;
 | 
			
		||||
	const format = `"mp4[height<=${quality}]+m4a/mp4[height<=${quality}]/bv[height<=${quality}]+ba/best[height<=${quality}]/best"`;
 | 
			
		||||
	const controller = new AbortController();
 | 
			
		||||
 | 
			
		||||
	const downloadProcess = ytdlp.exec(
 | 
			
		||||
		[
 | 
			
		||||
			"-f",
 | 
			
		||||
			format,
 | 
			
		||||
			"--yes-playlist",
 | 
			
		||||
			"-o",
 | 
			
		||||
			`"${path.join(
 | 
			
		||||
				downloadDir,
 | 
			
		||||
				"%(playlist_title)s",
 | 
			
		||||
				"%(title)s_%(playlist_index)s.%(ext)s"
 | 
			
		||||
			)}"`,
 | 
			
		||||
 | 
			
		||||
			`"${url}"`,
 | 
			
		||||
		],
 | 
			
		||||
		{ shell: true, detached: false },
 | 
			
		||||
		controller.signal
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	downloadProcess.on("ytDlpEvent", (eventType, eventData) => {
 | 
			
		||||
		console.log(eventData);
 | 
			
		||||
 | 
			
		||||
		if (eventData.includes(playlistTxt)) {
 | 
			
		||||
			playlistName = eventData.split(":")[1].slice(1)
 | 
			
		||||
			getId("playlistName").textContent = i18n.__("Downloading playlist:") + " "+ playlistName;
 | 
			
		||||
			console.log(playlistName);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (eventData.includes(videoIndex)) {
 | 
			
		||||
			count += 1;
 | 
			
		||||
			const itemTitle = i18n.__("Video") + " " + eventData.split(" ")[3];
 | 
			
		||||
 | 
			
		||||
			if (count > 1) {
 | 
			
		||||
				getId(`p${count - 1}`).textContent = i18n.__("File saved. Click to Open")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			const item = `<div class="playlistItem">
 | 
			
		||||
			<p class="itemTitle">${itemTitle}</p>
 | 
			
		||||
			<p class="itemProgress" onclick="openFolder('${path.join(downloadDir, playlistName)}')" id="p${count}">${i18n.__("Downloading...")}</p>
 | 
			
		||||
			</div>`;
 | 
			
		||||
			getId("list").innerHTML += item;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	downloadProcess.on("progress", (progress) => {
 | 
			
		||||
		if (getId(`p${count}`)) {
 | 
			
		||||
			getId(`p${count}`).textContent = `${i18n.__("Progress")} ${progress.percent}% | ${i18n.__("Speed")} ${progress.currentSpeed}`
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	downloadProcess.on("error", (error) => {
 | 
			
		||||
		getId("pasteLink").style.display = "inline-block"
 | 
			
		||||
		getId("options").style.display = "block";
 | 
			
		||||
		getId("playlistName").textContent = ""
 | 
			
		||||
		getId("incorrectMsg").textContent = error;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	downloadProcess.on("close", ()=>{
 | 
			
		||||
		getId("pasteLink").style.display = "inline-block";
 | 
			
		||||
 | 
			
		||||
	})
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function openFolder(location){
 | 
			
		||||
	shell.openPath(location)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function closeMenu() {
 | 
			
		||||
	getId("menuIcon").style.transform = "rotate(0deg)";
 | 
			
		||||
	menuIsOpen = false;
 | 
			
		||||
	let count = 0;
 | 
			
		||||
	let opacity = 1;
 | 
			
		||||
	const fade = setInterval(() => {
 | 
			
		||||
		if (count >= 10) {
 | 
			
		||||
			clearInterval(fade);
 | 
			
		||||
		} else {
 | 
			
		||||
			opacity -= 0.1;
 | 
			
		||||
			getId("menu").style.opacity = opacity;
 | 
			
		||||
			count++;
 | 
			
		||||
		}
 | 
			
		||||
	}, 50);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
getId("preferenceWin").addEventListener("click", () => {
 | 
			
		||||
	closeMenu();
 | 
			
		||||
	ipcRenderer.send("load-page", __dirname + "/preferences.html");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
getId("aboutWin").addEventListener("click", () => {
 | 
			
		||||
	closeMenu();
 | 
			
		||||
	ipcRenderer.send("load-page", __dirname + "/about.html");
 | 
			
		||||
});
 | 
			
		||||
getId("homeWin").addEventListener("click", ()=>{
 | 
			
		||||
	closeMenu();
 | 
			
		||||
	ipcRenderer.send("load-win", __dirname + "/index.html");
 | 
			
		||||
})
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue