LoaderSpot/docs/index.html
2025-02-23 18:14:47 +03:00

953 lines
30 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Official Spotify full installer</title>
<link rel="preconnect" href="https://raw.githubusercontent.com" crossorigin>
<link rel="preconnect" href="https://upgrade.scdn.co" crossorigin>
<link rel="preload" href="https://encore.scdn.co/1.2.3/CircularSpotify-UI-Latin-OS2v3-Book.woff2" as="font"
type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="https://encore.scdn.co/1.2.3/CircularSpotify-UI-Latin-OS2v3-Bold.woff2" as="font"
type="font/woff2" crossorigin="anonymous" />
<style>
html {
overflow-y: scroll;
/* Всегда показывать вертикальную полосу прокрутки, для более плавного переключения вкладок таблицы */
}
@font-face {
font-family: 'Circular Spotify';
src: url('https://encore.scdn.co/1.2.3/CircularSpotify-UI-Latin-OS2v3-Book.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Circular Spotify';
src: url('https://encore.scdn.co/1.2.3/CircularSpotify-UI-Latin-OS2v3-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Circular Spotify', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
background: #181a1b;
color: #a59d92;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
.nav-container {
background: #000000;
padding: 2rem 2rem;
margin-bottom: 20px;
position: sticky;
top: 0;
z-index: 1000;
display: flex;
justify-content: center;
}
.navbar {
width: 90%;
max-width: 1000px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
}
.nav-brand {
display: flex;
align-items: center;
gap: 5px;
color: #e8e6e3;
position: absolute;
left: 0;
pointer-events: none;
}
.nav-center {
position: absolute;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 30px;
margin: 0;
padding: 0;
list-style: none;
}
.nav-center a {
color: #e8e6e3;
text-decoration: none;
padding: 8px 16px;
border-radius: 20px;
transition: all 0.3s ease;
font-weight: 700;
}
.nav-center a.active {
background: #1db954;
color: #000;
}
.nav-center a:hover:not(.active) {
color: #1db954;
}
header {
padding: 20px;
text-align: center;
}
header h1 {
font-size: 2rem;
margin-bottom: 20px;
color: #e8e6e3;
font-weight: 400;
}
header p {
font-size: 1.2rem;
color: #ccc;
}
.container {
width: 90%;
max-width: 1000px;
margin: 40px auto;
position: relative;
overflow-x: auto;
/* Чтобы таблица прокручивалась при узком экране */
}
/* Стили таблицы */
table.version-table {
width: 100%;
border-collapse: collapse;
min-width: 600px;
/* чтобы колонки не сжимались слишком сильно */
table-layout: fixed;
/* Фиксированная разметка таблицы */
}
/* Добавляем новый стиль для разделения версий */
table.version-table tr:has(.version-cell) {
border-top: 2px solid #444;
}
/* Для первой строки убираем верхнюю границу */
table.version-table tbody tr:first-child {
border-top: none;
border-top: 2px solid #444;
}
/* Добавляем стиль для нижней границы последней версии */
table.version-table tbody tr:last-child {
border-bottom: 2px солидный #444;
}
table.version-table thead th {
text-align: left;
padding: 8px;
border-bottom: 1px солидный #444;
font-weight: 700;
}
/* Задаем ширину для каждого столбца */
table.version-table th:nth-child(1) {
width: 15%;
}
/* Версия */
table.version-table th:nth-child(2) {
width: 10%;
}
/* ОС */
table.version-table th:nth-child(3) {
width: 10%;
}
/* Архитектура */
table.version-table th:nth-child(4) {
width: 10%;
}
/* Дата */
table.version-table th:nth-child(5) {
width: 10%;
}
/* Размер */
table.version-table th:nth-child(6) {
width: 8%;
}
/* Кнопка */
table.version-table tbody td {
padding: 7px;
border-bottom: 1px solid #333;
vertical-align: middle;
font-size: 14px
}
/* Чтобы версия визуально выделялась при наведении/копирование */
.version-cell {
font-weight: 500;
color: #b3b3b3;
}
.version-text {
cursor: pointer;
display: inline-block;
/* Чтобы курсор был только на тексте */
}
.version-text:hover {
color: #fff;
}
.short-version {
font-size: 1.2em;
font-weight: bold;
display: block;
margin-bottom: 4px;
user-select: none;
}
.full-version {
font-size: 0.9em;
color: #777;
display: block;
user-select: none;
}
/* Кнопка скачать (иконка) */
.download-link {
display: inline-flex;
align-items: center;
gap: 4px;
color: #a59d92;
text-decoration: none;
font-weight: 500;
background: #ffffff08;
padding: 6px 10px;
border-radius: 4px;
transition: background 0.2s;
}
.download-link:hover {
background: #ffffff12;
}
.download-icon {
width: 16px;
height: 16px;
fill: currentColor;
transition: fill 0.2s;
}
.download-link:hover .download-icon {
fill: #1db954;
}
/* Тост-уведомление (скопировано в буфер) */
.toast-notification {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: #464746;
color: white;
padding: 12px 24px;
border-radius: 8px;
font-size: 0.9rem;
font-weight: 500;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.toast-notification.show {
opacity: 1;
}
.action-cell {
text-align: center;
/* Выравнивание содержимого ячейки по центру */
}
/* Стили для кнопок фильтрации */
.filter-buttons {
display: flex;
gap: 10px;
padding: 8px;
}
/* Стили для ячейки с кнопками */
table.version-table thead td {
border: none;
padding: 0;
}
/* Кнопки внутри таблицы */
table.version-table .filter-button {
padding: 6px 20px;
/* Изменено с 8px на 6px */
border: 1px solid #474747;
background: transparent;
color: #a6a7a7;
border-radius: 20px;
cursor: pointer;
font-family: inherit;
font-weight: 700;
transition: all 0.3s ease;
height: 34px;
/* Увеличено с 32px до 34px */
}
table.version-table .filter-button.active {
background: #1db954;
color: #000;
}
table.version-table .filter-button:hover:not(.active) {
background: #1db95420;
}
/* Плавный переход для контейнера таблицы */
#versions-container {
transition: opacity 0.3s ease-in-out;
}
/* Стили для Linux-репозитория */
.linux-repo-wrapper {
background: #242628;
border-radius: 8px;
overflow: hidden;
}
.repo-header {
display: grid;
grid-template-columns: 1fr 100px 150px;
gap: 16px;
padding: 12px 16px;
background: #2a2e2f;
border-bottom: 1px solid #333;
font-weight: 700;
color: #e8e6e3;
}
.repo-content {
height: 170px;
overflow-y: auto;
}
.repo-item {
display: grid;
grid-template-columns: 1fr 100px 150px;
gap: 16px;
padding: 8px 16px;
border-bottom: 1px solid #333;
transition: background 0.2s;
text-decoration: none;
color: #a59d92;
}
.repo-item:hover {
background: #2a2e2f;
}
.loading-indicator {
padding: 16px;
text-align: center;
color: #777;
}
.repo-content::-webkit-scrollbar {
width: 8px;
}
.repo-content::-webkit-scrollbar-track {
background: #242628;
}
.repo-content::-webkit-scrollbar-thumb {
background: #444;
border-radius: 4px;
}
.repo-content::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Стили для контейнера поиска */
.search-container {
padding: 4px 12px;
/* Изменено с 5.4px на 4px */
border-radius: 20px;
border: 1px solid #474747;
display: inline-flex;
align-items: center;
gap: 8px;
height: 34px;
/* Увеличено с 32px до 34px */
}
/* Стили для поля поиска */
.search-container input[type="search"] {
border: none;
background: transparent;
outline: none;
color: #b3b3b3 !important;
width: 180px;
font-size: 14px;
padding: 4px 0;
}
/* Крестик очистки для WebKit */
.search-container input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
height: 16px;
width: 16px;
margin-top: 4px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23e8e6e3' viewBox='0 0 20 20'%3E%3Cpath d='M14.348 5.652a1 1 0 10-1.414-1.414L10 7.172 7.066 4.238a1 1 0 10-1.414 1.414L8.586 8.586l-2.934 2.934a1 1 0 101.414 1.414L10 10l2.934 2.934a1 1 0 001.414-1.414L11.414 8.586l2.934-2.934z'/%3E%3C/svg%3E") no-repeat center;
cursor: pointer;
}
/* Стиль для иконки поиска */
.search-icon svg {
width: 16px;
height: 16px;
fill: #e8e6e3;
display: block;
}
/* Правило для подсветки найденного текста */
mark {
background-color: rgba(255, 255, 0, 0.4);
}
</style>
</head>
<body>
<nav class="nav-container">
<div class="navbar">
<div class="nav-brand">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512" width="32" height="32" fill="#1db954">
<path d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8Z" />
<path fill="#282828"
d="M406.6 231.1c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3zm-31 76.2c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm-26.9 65.6c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.2z" />
</svg>
<span>Spotify</span>
</div>
<ul class="nav-center">
<li><a href="index.html" class="active" style="pointer-events: none; cursor: default;">Versions</a></li>
<li><a href="help.html" style="pointer-events: none; cursor: default;">Help</a></li>
<li><a href="links.html" style="pointer-events: none; cursor: default;">Links</a></li>
</ul>
</div>
</nav>
<!-- Заголовок -->
<header>
<h1>Official Spotify full installer</h1>
<p>Site in testing mode...</p>
</header>
<!-- Контейнер с таблицей -->
<div class="container">
<table class="version-table" id="versionsTable">
<thead>
<!-- Обновленный ряд фильтрации: добавлена панель поиска -->
<tr>
<td colspan="5">
<div class="filter-buttons" style="display: inline-flex; align-items: center; gap: 10px;">
<button class="filter-button active" data-os="win">Windows</button>
<button class="filter-button" data-os="mac">Mac</button>
<button class="filter-button" data-os="linux">Linux</button>
<!--блок поиска -->
<div class="search-container">
<span class="search-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path
d="M11.742 10.344a6.5 6.5 0 10-1.398 1.398h-.001l3.85 3.85a1 1 0 001.414-1.414l-3.85-3.85zm-5.242 0a4.5 4.5 0 110-9 4.5 4.5 0 010 9z" />
</svg>
</span>
<input type="search" id="versionSearch" placeholder="Search">
</div>
</div>
</td>
</tr>
<tr class="table-headers">
<th>Version</th>
<th>Architecture</th>
<th>Date</th>
<th>Size</th>
<th> </th>
</tr>
</thead>
<tbody id="versions-container">
<tr>
<td colspan="5">Loading data...</td>
</tr>
</tbody>
</table>
</div>
<!-- Тост-уведомление (копирование) -->
<div class="toast-notification" id="toast">Copied to clipboard</div>
<script>
// Иконка "Скачать"
const downloadIcon = `
<svg class="download-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 15.575c-.183 0-.36-.073-.49-.203l-4.095-4.095a.694.694 0 01.981-.981L12 13.901l3.604-3.604a.694.694 0 01.981.98l-4.095 4.095a.692.692 0 01-.49.203z"/>
<path d="M12 15.575a.694.694 0 01-.694-.694V3.694a.694.694 0 011.388 0v11.187c0 .383-.31.694-.694.694z"/>
<path d="M16.306 20.306H7.694a4.167 4.167 0 01-4.162-4.163v-2.777a.694.694 0 011.388 0v2.777a2.778 2.778 0 002.774 2.775h8.612a2.778 2.778 0 002.775-2.775v-2.777a.694.694 0 011.387 0v2.777a4.167 4.167 0 01-4.162 4.163z"/>
</svg>
`;
// Функция отображения тоста
function showToast(message) {
const toast = document.getElementById('toast');
if (!toast) return;
toast.textContent = message;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 2000);
}
// Функция fallback для копирования текста
function fallbackCopyTextToClipboard(text) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.top = '0';
textArea.style.left = '0';
textArea.style.width = '2em';
textArea.style.height = '2em';
textArea.style.padding = '0';
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
textArea.style.background = 'transparent';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
showToast('Copied to clipboard');
} catch (err) {
showToast('Error while copying');
console.error('Error while copying:', err);
}
document.body.removeChild(textArea);
}
// Глобальный кэш для результатов HEAD-запросов
const headCache = new Map();
// Функция updateLinkInfo с использованием кэша
async function updateLinkInfo(dateCell, sizeCell, url) {
if (headCache.has(url)) {
const cached = headCache.get(url);
dateCell.textContent = cached.date;
sizeCell.textContent = cached.size;
return;
}
try {
const response = await fetch(url, { method: 'HEAD' });
const lastModified = response.headers.get('Last-Modified');
const contentLength = response.headers.get('Content-Length');
let formattedDate = '—';
let sizeMb = '—';
if (lastModified) {
const date = new Date(lastModified);
formattedDate =
String(date.getDate()).padStart(2, '0') + '.' +
String(date.getMonth() + 1).padStart(2, '0') + '.' +
date.getFullYear();
}
if (contentLength) {
sizeMb = (parseInt(contentLength, 10) / (1024 * 1024)).toFixed(2) + ' MB';
}
// Сохраняем результат в кэше
headCache.set(url, { date: formattedDate, size: sizeMb });
dateCell.textContent = formattedDate;
sizeCell.textContent = sizeMb;
} catch (error) {
console.error('Error getting headers', error);
dateCell.textContent = '—';
sizeCell.textContent = '—';
headCache.set(url, { date: '—', size: '—' });
}
}
// Вспомогательная функция для подсветки найденного текста
function highlight(text, term) {
const regex = new RegExp(`(${term})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
// Создаем строки таблицы для одной версии
function createVersionRows(versionKey, data, searchTerm = '') {
const shortVersion = versionKey;
const archCombos = [];
let totalRowsForVersion = 0;
// Фильтруем только по текущей ОС
if (data.links[currentOS]) {
for (const arch of Object.keys(data.links[currentOS])) {
const link = data.links[currentOS][arch];
if (link) {
archCombos.push({ arch, link });
totalRowsForVersion++;
}
}
}
if (totalRowsForVersion === 0) return [];
const rows = [];
let isFirstVersionRow = true;
archCombos.forEach((combo) => {
const row = document.createElement('tr');
if (isFirstVersionRow) {
const versionCell = document.createElement('td');
versionCell.className = 'version-cell';
versionCell.rowSpan = totalRowsForVersion;
// Используем подсветку, если searchTerm непустой
const displayedShort = searchTerm ? highlight(shortVersion, searchTerm) : shortVersion;
const displayedFull = searchTerm ? highlight(data.fullversion, searchTerm) : data.fullversion;
const versionText = document.createElement('div');
versionText.className = 'version-text';
versionText.innerHTML = `<span class="short-version">${displayedShort}</span><span class="full-version">${displayedFull}</span>`;
versionText.addEventListener('click', async () => {
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(data.fullversion);
showToast('Copied to clipboard');
} else {
fallbackCopyTextToClipboard(data.fullversion);
}
} catch (err) {
console.error('Error while copying:', err);
fallbackCopyTextToClipboard(data.fullversion);
}
});
versionCell.appendChild(versionText);
row.appendChild(versionCell);
isFirstVersionRow = false;
}
// Архитектура
const archCell = document.createElement('td');
archCell.textContent = combo.arch;
row.appendChild(archCell);
// Дата
const dateCell = document.createElement('td');
dateCell.textContent = '—';
row.appendChild(dateCell);
// Размер
const sizeCell = document.createElement('td');
sizeCell.textContent = '—';
row.appendChild(sizeCell);
// Кнопка скачать
const actionCell = document.createElement('td');
actionCell.className = 'action-cell';
const downloadLink = document.createElement('a');
downloadLink.className = 'download-link';
downloadLink.href = combo.link;
downloadLink.target = '_blank';
downloadLink.innerHTML = downloadIcon;
actionCell.appendChild(downloadLink);
row.appendChild(actionCell);
// Обновляем инфу о дате и размере
updateLinkInfo(dateCell, sizeCell, combo.link);
rows.push(row);
});
return rows;
}
// Переменные для "ленивой" подгрузки
let allVersions = [];
const ITEMS_PER_BATCH = 5; // по 5 версий за раз
let currentIndex = 0;
const container = document.getElementById('versions-container');
// Функция подгрузки очередной порции версий
function loadMoreRows() {
const endIndex = Math.min(currentIndex + ITEMS_PER_BATCH, allVersions.length);
for (let i = currentIndex; i < endIndex; i++) {
const [versionKey, versionData] = allVersions[i];
const versionRows = createVersionRows(versionKey, versionData);
versionRows.forEach(r => container.appendChild(r));
}
currentIndex = endIndex;
if (currentIndex < allVersions.length) {
container.appendChild(sentinel);
}
}
// Невидимый "сторож" для Intersection Observer
const sentinel = document.createElement('tr');
sentinel.style.height = '1px';
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && currentIndex < allVersions.length) {
observer.unobserve(sentinel);
loadMoreRows();
if (currentIndex < allVersions.length) {
observer.observe(sentinel);
}
}
});
}, { root: null, rootMargin: '100px', threshold: 0 });
// Получаем JSON и строим таблицу
fetch('https://raw.githubusercontent.com/amd64fox/LoaderSpot/refs/heads/main/versions.json')
.then(response => response.json())
.then(data => {
container.innerHTML = ''; // Очищаем "Загрузка данных..."
allVersions = Object.entries(data);
loadMoreRows();
if (currentIndex < allVersions.length) {
observer.observe(sentinel);
}
})
.catch(err => {
console.error('Error loading data:', err);
container.innerHTML = '<tr><td colspan="6">Failed to load version data.</td></tr>';
});
// Переменная для отслеживания текущей ОС
let currentOS = 'win';
// Получаем ссылки на таблицу и Linux-контейнер
const versionsTable = document.getElementById('versionsTable');
// Логика обработки кликов по кнопкам фильтрации
document.querySelectorAll('.filter-button').forEach(button => {
button.addEventListener('click', () => {
document.querySelectorAll('.filter-button').forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
currentOS = button.dataset.os;
// При смене ОС очищаем поле поиска
const versionSearch = document.getElementById('versionSearch');
versionSearch.value = "";
// Скрываем блок поиска, если выбрана Linux, иначе показываем
const searchContainer = document.querySelector('.search-container');
searchContainer.style.display = currentOS === 'linux' ? 'none' : 'inline-flex';
container.style.opacity = "0";
setTimeout(() => {
if (currentOS === 'linux') {
loadLinuxPackages();
} else {
container.innerHTML = "";
currentIndex = 0;
loadMoreRows();
if (currentIndex < allVersions.length) {
observer.observe(sentinel);
}
}
container.style.opacity = "1";
}, 300);
});
});
// Обработчик для поиска по версиям
const versionSearch = document.getElementById('versionSearch');
versionSearch.addEventListener('input', (e) => {
const term = e.target.value.trim().toLowerCase();
container.style.opacity = "0";
setTimeout(() => {
// Если поле пустое, возвращаем исходное поведение
if (term === "") {
if (currentOS === 'linux') {
loadLinuxPackages();
} else {
container.innerHTML = "";
currentIndex = 0;
loadMoreRows();
if (currentIndex < allVersions.length) {
observer.observe(sentinel);
}
}
container.style.opacity = "1";
return;
}
// Отключаем ленивую подгрузку при поиске
observer.unobserve(sentinel);
container.innerHTML = "";
// Фильтруем все версии по короткой или полной версии
const filtered = allVersions.filter(([versionKey, data]) => {
return versionKey.toLowerCase().includes(term) || data.fullversion.toLowerCase().includes(term);
});
if (filtered.length > 0) {
filtered.forEach(([versionKey, data]) => {
const rows = createVersionRows(versionKey, data, term);
rows.forEach(row => container.appendChild(row));
});
} else {
container.innerHTML = '<tr><td colspan="5">No results</td></tr>';
}
container.style.opacity = "1";
}, 300);
});
// Локальные версии для Linux
async function loadLinuxPackages() {
container.innerHTML = '<tr><td colspan="5">Загрузка данных...</td></tr>';
const linuxPackages = [
{
version: {
short: '1.2.56.502',
full: '1.2.56.502.ga68d2d4f'
},
architectures: [
{
arch: 'amd64',
link: 'http://repository.spotify.com/pool/non-free/s/spotify-client/spotify-client_1.2.56.502.ga68d2d4f_amd64.deb',
date: '10.02.2025',
size: '136.36 MB'
}
]
},
{
version: {
short: '1.2.53.440',
full: '1.2.53.440.g7b2f582a'
},
architectures: [
{
arch: 'amd64',
link: 'http://repository.spotify.com/pool/non-free/s/spotify-client/spotify-client_1.2.53.440.g7b2f582a_amd64.deb',
date: '14.01.2025',
size: '136.86 MB'
}
]
}
];
try {
container.innerHTML = '';
linuxPackages.forEach(version => {
const versionCell = document.createElement('td');
versionCell.className = 'version-cell';
versionCell.rowSpan = version.architectures.length;
const versionText = document.createElement('div');
versionText.className = 'version-text';
versionText.innerHTML = `
<span class="short-version">${version.version.short}</span>
<span class="full-version">${version.version.full}</span>
`;
versionText.addEventListener('click', () => {
navigator.clipboard.writeText(version.version.full)
.then(() => showToast('Скопировано в буфер обмена'))
.catch(() => fallbackCopyTextToClipboard(version.version.full));
});
versionCell.appendChild(versionText);
version.architectures.forEach((arch, index) => {
const row = document.createElement('tr');
if (index === 0) {
row.appendChild(versionCell);
}
const archCell = document.createElement('td');
archCell.textContent = arch.arch;
row.appendChild(archCell);
const dateCell = document.createElement('td');
// Записываем вручную полученную дату
dateCell.textContent = arch.date;
row.appendChild(dateCell);
const sizeCell = document.createElement('td');
// Записываем вручную указанный размер
sizeCell.textContent = arch.size;
row.appendChild(sizeCell);
const actionCell = document.createElement('td');
actionCell.className = 'action-cell';
const downloadLink = document.createElement('a');
downloadLink.className = 'download-link';
downloadLink.href = arch.link;
downloadLink.target = '_blank';
downloadLink.innerHTML = downloadIcon;
actionCell.appendChild(downloadLink);
row.appendChild(actionCell);
container.appendChild(row);
// Не вызываем updateLinkInfo, т.к. данные заданы вручную
});
});
} catch (error) {
console.error('Ошибка загрузки Linux пакетов:', error);
container.innerHTML = '<tr><td colspan="5">Ошибка загрузки списка пакетов</td></tr>';
}
}
// Логика для принудительного выбора ОС через URL параметры:
document.addEventListener('DOMContentLoaded', () => {
const query = window.location.search;
let osParam = "";
if (query) {
const params = query.slice(1).split('&').filter(p => p.trim());
if (params.length) {
osParam = params[0].toLowerCase();
}
}
if (osParam && ['win', 'mac', 'linux'].includes(osParam)) {
const button = document.querySelector(`.filter-button[data-os="${osParam}"]`);
if (button) {
button.click();
}
}
});
</script>
<script data-goatcounter="https://loaderspot.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
</body>
</html>