Add CI/CD pipelines, NSIS installer, ES module bundling, and ruff linting
- Add Gitea Actions workflows: test.yml (lint + test on push/PR) and release.yml (build + NSIS installer + upload on v* tags) - Add NSIS installer with optional desktop shortcut and auto-start - Add esbuild bundler: ES module migration with IIFE bundle output - Add build-dist-windows.sh for cross-building Windows distribution - Fix all ruff lint errors (import sorting, unused imports, line length) - Remove redundant scripts (start-server.bat, stop-server.bat, start-server-background.vbs) - Update CLAUDE.md with CI/CD and release documentation
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
// ============================================================
|
||||
// Display Brightness & Power Control
|
||||
// Display Brightness & Power Control + Links Management
|
||||
// ============================================================
|
||||
|
||||
import { t, showToast, escapeHtml, closeDialog, showConfirm, resolveMdiIcons, fetchMdiIcon } from './core.js';
|
||||
|
||||
let displayBrightnessTimers = {};
|
||||
const DISPLAY_THROTTLE_MS = 50;
|
||||
|
||||
async function loadDisplayMonitors() {
|
||||
export async function loadDisplayMonitors() {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
if (!token) return;
|
||||
|
||||
@@ -86,7 +88,7 @@ async function loadDisplayMonitors() {
|
||||
}
|
||||
}
|
||||
|
||||
function onDisplayBrightnessInput(monitorId, value) {
|
||||
export function onDisplayBrightnessInput(monitorId, value) {
|
||||
const label = document.getElementById(`brightness-val-${monitorId}`);
|
||||
if (label) label.textContent = `${value}%`;
|
||||
|
||||
@@ -97,7 +99,7 @@ function onDisplayBrightnessInput(monitorId, value) {
|
||||
}, DISPLAY_THROTTLE_MS);
|
||||
}
|
||||
|
||||
function onDisplayBrightnessChange(monitorId, value) {
|
||||
export function onDisplayBrightnessChange(monitorId, value) {
|
||||
if (displayBrightnessTimers[monitorId]) {
|
||||
clearTimeout(displayBrightnessTimers[monitorId]);
|
||||
displayBrightnessTimers[monitorId] = null;
|
||||
@@ -121,7 +123,7 @@ async function sendDisplayBrightness(monitorId, brightness) {
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleDisplayPower(monitorId, monitorName) {
|
||||
export async function toggleDisplayPower(monitorId, monitorName) {
|
||||
const btn = document.getElementById(`power-btn-${monitorId}`);
|
||||
const isOn = btn && btn.classList.contains('on');
|
||||
const newState = !isOn;
|
||||
@@ -157,7 +159,7 @@ async function toggleDisplayPower(monitorId, monitorName) {
|
||||
// Header Quick Links
|
||||
// ============================================================
|
||||
|
||||
async function loadHeaderLinks() {
|
||||
export async function loadHeaderLinks() {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
if (!token) return;
|
||||
|
||||
@@ -197,9 +199,10 @@ async function loadHeaderLinks() {
|
||||
// ============================================================
|
||||
|
||||
let _loadLinksPromise = null;
|
||||
let linkFormDirty = false;
|
||||
export let linkFormDirty = false;
|
||||
export function setLinkFormDirty(value) { linkFormDirty = value; }
|
||||
|
||||
async function loadLinksTable() {
|
||||
export async function loadLinksTable() {
|
||||
if (_loadLinksPromise) return _loadLinksPromise;
|
||||
_loadLinksPromise = _loadLinksTableImpl();
|
||||
_loadLinksPromise.finally(() => { _loadLinksPromise = null; });
|
||||
@@ -251,7 +254,7 @@ async function _loadLinksTableImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
function showAddLinkDialog() {
|
||||
export function showAddLinkDialog() {
|
||||
const dialog = document.getElementById('linkDialog');
|
||||
const form = document.getElementById('linkForm');
|
||||
const title = document.getElementById('linkDialogTitle');
|
||||
@@ -269,7 +272,7 @@ function showAddLinkDialog() {
|
||||
dialog.showModal();
|
||||
}
|
||||
|
||||
async function showEditLinkDialog(linkName) {
|
||||
export async function showEditLinkDialog(linkName) {
|
||||
const token = localStorage.getItem('media_server_token');
|
||||
const dialog = document.getElementById('linkDialog');
|
||||
const title = document.getElementById('linkDialogTitle');
|
||||
@@ -320,7 +323,7 @@ async function showEditLinkDialog(linkName) {
|
||||
}
|
||||
}
|
||||
|
||||
async function closeLinkDialog() {
|
||||
export async function closeLinkDialog() {
|
||||
if (linkFormDirty) {
|
||||
if (!await showConfirm(t('links.confirm.unsaved'))) {
|
||||
return;
|
||||
@@ -333,7 +336,7 @@ async function closeLinkDialog() {
|
||||
document.body.classList.remove('dialog-open');
|
||||
}
|
||||
|
||||
async function saveLink(event) {
|
||||
export async function saveLink(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const submitBtn = event.target.querySelector('button[type="submit"]');
|
||||
@@ -385,7 +388,7 @@ async function saveLink(event) {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteLinkConfirm(linkName) {
|
||||
export async function deleteLinkConfirm(linkName) {
|
||||
if (!await showConfirm(t('links.confirm.delete').replace('{name}', linkName))) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user