diff --git a/assets/css/index.css b/assets/css/index.css index bb6b5d3..79e0b36 100644 --- a/assets/css/index.css +++ b/assets/css/index.css @@ -1293,11 +1293,11 @@ input[type="range"]::-webkit-slider-thumb:hover { } .video-grid-extended { - grid-template-columns: 85px 65px 60px 1fr auto; + grid-template-columns: 85px 65px 60px 1fr 120px; } .video-grid-compact { - grid-template-columns: 85px 65px 1fr auto; + grid-template-columns: 85px 65px 1fr 120px; } .audio-grid { @@ -1340,25 +1340,41 @@ input[type="range"]::-webkit-slider-thumb:hover { color: var(--text); } -.audio-indicator { +.audio-indicator, +.audio-placeholder { + width: 120px; + box-sizing: border-box; display: inline-flex; align-items: center; - gap: 4px; + justify-content: flex-start; + gap: 6px; + border-radius: 8px; +} + +.audio-indicator { font-size: 11px; - padding: 2px 6px; - border-radius: 4px; - background-color: transparent; + padding: 2px 4px; color: #10b981; font-weight: 500; + background-color: #29974513; } + .audio-indicator svg { - width: 20px; - height: 20px; + width: 18px; + height: 18px; + flex-shrink: 0; fill: currentColor; } -.audio-placeholder { - width: 53px; + +.audio-indicator .lang-text { + font-size: 12px; + color: var(--text); + opacity: 0.9; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } + /* Resolution */ .ss-option .main-text { color: var(--text) !important; diff --git a/src/renderer.js b/src/renderer.js index e642567..f4ae7f9 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -3,7 +3,14 @@ const {default: YTDlpWrap} = require("yt-dlp-wrap-plus"); const {constants} = require("fs/promises"); const {homedir, platform} = require("os"); const {join} = require("path"); -const {mkdirSync, accessSync, promises, existsSync, cpSync, copyFileSync} = require("fs"); +const { + mkdirSync, + accessSync, + promises, + existsSync, + cpSync, + copyFileSync, +} = require("fs"); const {execSync, spawn} = require("child_process"); const CONSTANTS = { @@ -564,7 +571,6 @@ class YtDownloaderApp { const ffmpegName = isWin ? "ffmpeg.exe" : "ffmpeg"; const targetFfmpegFile = join(targetDir, "bin", ffmpegName); - // Check if the folder has already been copied if (!existsSync(targetFfmpegFile)) { if (existsSync(bundledDir)) { @@ -684,7 +690,6 @@ class YtDownloaderApp { return `${exeName}:${targetNodeFile}`; } - return ""; } @@ -1500,6 +1505,25 @@ class YtDownloaderApp { const speakerIconSvg = ``; + // Convert en -> English + const langFormatter = new Intl.DisplayNames( + [navigator.language || "en"], + {type: "language"}, + ); + const getLanguageName = (code) => { + if (!code) return ""; + try { + // Split cases like "en-US" + const baseCode = code.split("-")[0]; + const name = langFormatter.of(baseCode); + return name + ? name.charAt(0).toUpperCase() + name.slice(1) + : code; + } catch (e) { + return code; + } + }; + // Find the ideal match height boundary formats.forEach((f) => { if ( @@ -1571,10 +1595,19 @@ class YtDownloaderApp { const quality = `${format.height || "???"}p${format.fps === 60 ? "60" : ""}`; const vcodecText = format.vcodec?.split(".")[0] || ""; - const audioMarkup = - format.acodec !== "none" - ? `