Инструменты пользователя

Инструменты сайта


tmp_27.06.2026

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
tmp_27.06.2026 [2026/06/27 15:29] VladPolskiytmp_27.06.2026 [2026/06/27 15:35] (текущий) VladPolskiy
Строка 1: Строка 1:
 +// assets/js/app.js
 +
 document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
      // --- НАДЕЖНОЕ УПРАВЛЕНИЕ МОДАЛКОЙ С ДЕБАГ-МАЯКОМ ---      // --- НАДЕЖНОЕ УПРАВЛЕНИЕ МОДАЛКОЙ С ДЕБАГ-МАЯКОМ ---
Строка 107: Строка 109:
                 }                 }
             } catch (error) {             } catch (error) {
 +                // Возвращаем кнопку в исходное рабочее состояние
                 btnModalSubmit.disabled = false;                 btnModalSubmit.disabled = false;
                 btnModalSubmit.textContent = "Загрузить";                 btnModalSubmit.textContent = "Загрузить";
-                alert("Ошибка отправки файлов на сервер+ error.message);+                 
 +                // КРАСИВО ВЫВОДИМ ОШИБКУ СЕТИ В ТВОЮ ПЛАШКУ БЕЗ ВСЯКИХ АЛЕРТОВ 
 +                if (modalErrorBox) { 
 +                    modalErrorBox.textContent = "Критическая ошибка отправки файлов на сервер."
 +                    modalErrorBox.classList.remove('hidden'); 
 +                }
             }             }
         });         });
     }     }
 +
 +
 +
 +
 +
 +
 +
 +    // Локальное хранилище для текстов текущего выбранного релиза,
 +    // чтобы переключать вкладки мгновенно без повторных запросов к серверу
 +    let currentReleaseTexts = {
 +        readme: '',
 +        license: '',
 +        comment: '',
 +        log: 'Здесь будет выводиться лог действий (100 строк)...'
 +    };
 +
 +    /**
 +     * Отрисовка таблицы файлов в верхнем окне
 +     * @param {Array} files Массив файлов из JSON
 +     */
 +    function renderFilesTable(files) {
 +        if (!files || files.length === 0) {
 +            filesList.innerHTML = `<tr><td colspan="4" class="text-center text-muted">В данном релизе нет файлов для скачивания.</td></tr>`;
 +            return;
 +        }
 +
 +        let html = '';
 +        files.forEach(file => {
 +            const icon = file.is_dir ? '📁' : '📄';
 +            html += `
 +                <tr>
 +                    <td><span style="margin-right: 8px;">${icon}</span> ${escapeHtml(file.name)}</td>
 +                    <td class="text-muted">—</td> <!-- Примечания (коммиты) прикрутим позже через .meta.json -->
 +                    <td class="text-muted">${file.date}</td>
 +                    <td style="text-align: right;"><span class="text-muted" style="font-size: 12px;">${file.size}</span></td>
 +                </tr>
 +            `;
 +        });
 +        filesList.innerHTML = html;
 +    }
 +
 +    // Вспомогательная функция защиты от XSS при отрисовке имен файлов
 +    function escapeHtml(string) {
 +        return String(string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
 +    }
 +
 +    // 1. СЛУШАЕМ ВЫБОР РЕЛИЗА В ВЫПАДАЮЩЕМ СПИСКЕ
 +    releasesDropdown.addEventListener('change', async function() {
 +        const selectedRelease = this.value;
 +
 +        if (!selectedRelease) {
 +            // Если сбросили выбор — возвращаем интерфейс в исходное состояние
 +            btnDownloadZip.disabled = true;
 +            filesList.innerHTML = `<tr><td colspan="4" class="text-center text-muted">Выберите релиз из списка выше для просмотра файлов...</td></tr>`;
 +            textEditor.value = 'Текст файла отсутствует или релиз не выбран...';
 +            return;
 +        }
 +
 +        filesList.innerHTML = `<tr><td colspan="4" class="text-center text-muted">Загрузка данных релиза...</td></tr>`;
 +
 +        // Дергаем наш апи-модуль
 +        const result = await Api.getReleaseData(selectedRelease);
 +
 +        if (result.success) {
 +            // Активируем кнопку ZIP
 +            btnDownloadZip.disabled = false;
 +            
 +            // Сохраняем тексты в память для вкладок
 +            currentReleaseTexts.readme = result.texts.readme || 'Файл README.txt пуст.';
 +            currentReleaseTexts.license = result.texts.license || 'Файл LICENSE.txt пуст.';
 +            currentReleaseTexts.comment = result.texts.comment || 'Файл COMMENT.txt пуст.';
 +            
 +            // Отрисовываем файлы в таблице верхнего окна
 +            renderFilesTable(result.files);
 +
 +            // Автоматически показываем текст той вкладки, которая сейчас активна (по умолчанию README)
 +            const activeTab = document.querySelector('.tab-btn.active').getAttribute('data-target');
 +            textEditor.value = currentReleaseTexts[activeTab];
 +        } else {
 +            alert("Ошибка загрузки: " + result.error);
 +            filesList.innerHTML = `<tr><td colspan="4" class="text-center" style="color: #cf222e;">${result.error}</td></tr>`;
 +        }
 +    });
 +
 +    // 2. СЛУШАЕМ ПЕРЕКЛЮЧЕНИЕ ВКЛАДОК НИЖНЕГО ОКНА
 +    tabButtons.forEach(button => {
 +        button.addEventListener('click', function() {
 +            tabButtons.forEach(btn => btn.classList.remove('active'));
 +            this.classList.add('active');
 +            
 +            const targetTab = this.getAttribute('data-target');
 +            
 +            // Вытаскиваем текст из памяти без лишних запросов к PHP
 +            textEditor.value = currentReleaseTexts[targetTab] || `Текст для вкладки ${targetTab.toUpperCase()} отсутствует.`;
 +        });
 +    });
 +});
 +
 +
tmp_27.06.2026.txt · Последнее изменение: VladPolskiy

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: Public Domain
Public Domain Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki