Update Web UI: Add server management scripts and improve UX

UI improvements:
- Add icon-based Execute/Edit/Delete buttons for scripts and callbacks
- Add execution result dialog with stdout/stderr and execution time
- Add favicon with media player icon
- Disable background scrolling when dialogs are open
- Add footer with author information and source code link

Backend enhancements:
- Add execution time tracking to script and callback execution
- Add /api/callbacks/execute endpoint for debugging callbacks
- Return detailed execution results (stdout, stderr, exit_code, execution_time)

Server management:
- Add scripts/start-server.bat - Start server with console window
- Add scripts/start-server-background.vbs - Start server silently
- Add scripts/stop-server.bat - Stop running server instances
- Add scripts/restart-server.bat - Restart the server

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 18:18:59 +03:00
parent 4f8f59dc89
commit 29e0618b9f
5 changed files with 116 additions and 0 deletions

View File

@@ -55,6 +55,11 @@
opacity: 1;
}
/* Prevent scrolling when dialog is open */
body.dialog-open {
overflow: hidden;
}
.container {
max-width: 800px;
margin: 0 auto;
@@ -883,6 +888,32 @@
font-size: 1.5rem;
}
}
/* Footer */
footer {
text-align: center;
padding: 2rem 1rem;
margin-top: 3rem;
border-top: 1px solid var(--border);
color: var(--text-secondary);
font-size: 0.875rem;
}
footer a {
color: var(--accent);
text-decoration: none;
transition: color 0.2s;
}
footer a:hover {
color: var(--accent-hover);
text-decoration: underline;
}
footer .separator {
margin: 0 0.5rem;
color: var(--text-muted);
}
</style>
</head>
<body class="loading-translations">
@@ -1171,6 +1202,17 @@
<!-- Toast Notification -->
<div class="toast" id="toast"></div>
<!-- Footer -->
<footer>
<div>
Created by <strong>Alexei Dolgolyov</strong>
<span class="separator"></span>
<a href="mailto:dolgolyov.alexei@gmail.com">dolgolyov.alexei@gmail.com</a>
<span class="separator"></span>
<a href="https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server" target="_blank" rel="noopener noreferrer">Source Code</a>
</div>
</footer>
<script>
// Theme management
function initTheme() {
@@ -1925,6 +1967,7 @@
// Reset dirty state
scriptFormDirty = false;
document.body.classList.add('dialog-open');
dialog.showModal();
}
@@ -1967,6 +2010,7 @@
// Reset dirty state
scriptFormDirty = false;
document.body.classList.add('dialog-open');
dialog.showModal();
} catch (error) {
console.error('Error loading script for edit:', error);
@@ -1985,6 +2029,7 @@
const dialog = document.getElementById('scriptDialog');
scriptFormDirty = false; // Reset dirty state
dialog.close();
document.body.classList.remove('dialog-open');
}
async function saveScript(event) {
@@ -2129,6 +2174,7 @@
// Reset dirty state
callbackFormDirty = false;
document.body.classList.add('dialog-open');
dialog.showModal();
}
@@ -2168,6 +2214,7 @@
// Reset dirty state
callbackFormDirty = false;
document.body.classList.add('dialog-open');
dialog.showModal();
} catch (error) {
console.error('Error loading callback for edit:', error);
@@ -2186,6 +2233,7 @@
const dialog = document.getElementById('callbackDialog');
callbackFormDirty = false; // Reset dirty state
dialog.close();
document.body.classList.remove('dialog-open');
}
async function saveCallback(event) {
@@ -2268,6 +2316,7 @@
function closeExecutionDialog() {
const dialog = document.getElementById('executionDialog');
dialog.close();
document.body.classList.remove('dialog-open');
}
function showExecutionResult(name, result, type = 'script') {
@@ -2346,6 +2395,7 @@
`;
document.getElementById('outputSection').style.display = 'none';
document.getElementById('errorSection').style.display = 'none';
document.body.classList.add('dialog-open');
dialog.showModal();
try {
@@ -2397,6 +2447,7 @@
`;
document.getElementById('outputSection').style.display = 'none';
document.getElementById('errorSection').style.display = 'none';
document.body.classList.add('dialog-open');
dialog.showModal();
try {

View File

@@ -0,0 +1,24 @@
@echo off
REM Media Server Restart Script
REM This script restarts the media server
echo Restarting Media Server...
echo.
REM Stop the server first
echo [1/2] Stopping server...
call "%~dp0\stop-server.bat"
REM Wait a moment
timeout /t 2 /nobreak >nul
REM Change to parent directory (media-server root)
cd /d "%~dp0\.."
REM Start the server
echo.
echo [2/2] Starting server...
python -m media_server.main
REM If the server exits, pause to show any error messages
pause

View File

@@ -0,0 +1,7 @@
Set WshShell = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
' Get parent folder of scripts folder (media-server root)
WshShell.CurrentDirectory = FSO.GetParentFolderName(FSO.GetParentFolderName(WScript.ScriptFullName))
WshShell.Run "python -m media_server.main", 0, False
Set FSO = Nothing
Set WshShell = Nothing

15
scripts/start-server.bat Normal file
View File

@@ -0,0 +1,15 @@
@echo off
REM Media Server Startup Script
REM This script starts the media server
echo Starting Media Server...
echo.
REM Change to the media-server directory (parent of scripts folder)
cd /d "%~dp0\.."
REM Start the media server
python -m media_server.main
REM If the server exits, pause to show any error messages
pause

19
scripts/stop-server.bat Normal file
View File

@@ -0,0 +1,19 @@
@echo off
REM Media Server Stop Script
REM This script stops the running media server
echo Stopping Media Server...
echo.
REM Find and kill Python processes running media_server.main
for /f "tokens=2" %%i in ('tasklist /FI "IMAGENAME eq python.exe" /FO LIST ^| findstr /B "PID:"') do (
wmic process where "ProcessId=%%i" get CommandLine 2>nul | findstr /C:"media_server.main" >nul
if not errorlevel 1 (
taskkill /PID %%i /F
echo Media server process (PID %%i) terminated.
)
)
echo.
echo Done! Media server stopped.
pause