Tabbed UI, browse caching, and bottom mini player

- Convert stacked sections to tabbed interface (Player, Browser, Actions, Scripts, Callbacks) with localStorage persistence
- Add in-memory directory listing cache (5-min TTL) with nocache bypass for refresh
- Defer stat()/duration calls to paginated items only for faster browse
- Move mini player from top to bottom with footer padding fix
- Always show scrollbar to prevent layout shift between tabs
- Add tab localization keys (en/ru)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-09 02:34:29 +03:00
parent 8db40d3ee9
commit 98a33bca54
7 changed files with 237 additions and 55 deletions

View File

@@ -83,7 +83,31 @@
</div>
</header>
<div class="player-container">
<!-- Tab Bar -->
<div class="tab-bar" id="tabBar">
<button class="tab-btn active" data-tab="player" onclick="switchTab('player')">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
<span data-i18n="tab.player">Player</span>
</button>
<button class="tab-btn" data-tab="browser" onclick="switchTab('browser')">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg>
<span data-i18n="tab.browser">Browser</span>
</button>
<button class="tab-btn" data-tab="quick-actions" onclick="switchTab('quick-actions')">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M7 2v11h3v9l7-12h-4l4-8z"/></svg>
<span data-i18n="tab.quick_actions">Actions</span>
</button>
<button class="tab-btn" data-tab="scripts" onclick="switchTab('scripts')">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>
<span data-i18n="tab.scripts">Scripts</span>
</button>
<button class="tab-btn" data-tab="callbacks" onclick="switchTab('callbacks')">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>
<span data-i18n="tab.callbacks">Callbacks</span>
</button>
</div>
<div class="player-container" data-tab-content="player">
<div class="album-art-container">
<img id="album-art" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 300'%3E%3Crect fill='%23282828' width='300' height='300'/%3E%3Cpath fill='%236a6a6a' d='M150 80c-38.66 0-70 31.34-70 70s31.34 70 70 70 70-31.34 70-70-31.34-70-70-70zm0 20c27.614 0 50 22.386 50 50s-22.386 50-50 50-50-22.386-50-50 22.386-50 50-50zm0 30a20 20 0 100 40 20 20 0 000-40z'/%3E%3C/svg%3E" alt="Album Art">
</div>
@@ -144,7 +168,7 @@
</div>
<!-- Media Browser Section -->
<div class="browser-container">
<div class="browser-container" data-tab-content="browser" >
<h2 data-i18n="browser.title">Media Browser</h2>
<!-- Breadcrumb Navigation -->
@@ -203,8 +227,8 @@
</div>
</div>
<!-- Scripts Section -->
<div class="scripts-container" id="scripts-container" style="display: none;">
<!-- Scripts Section (Quick Actions) -->
<div class="scripts-container" id="scripts-container" data-tab-content="quick-actions" >
<h2 data-i18n="scripts.quick_actions">Quick Actions</h2>
<div class="scripts-grid" id="scripts-grid">
<div class="scripts-empty" data-i18n="scripts.no_scripts">No scripts configured</div>
@@ -212,7 +236,7 @@
</div>
<!-- Script Management Section -->
<div class="script-management">
<div class="script-management" data-tab-content="scripts" >
<div class="script-management-header">
<h2 data-i18n="scripts.management">Script Management</h2>
<button class="add-script-btn" onclick="showAddScriptDialog()" data-i18n="scripts.add">+ Add</button>
@@ -236,7 +260,7 @@
</div>
<!-- Callback Management Section -->
<div class="script-management">
<div class="script-management" id="callbacksSection" data-tab-content="callbacks" >
<div class="script-management-header">
<h2 data-i18n="callbacks.management">Callback Management</h2>
<button class="add-script-btn" onclick="showAddCallbackDialog()" data-i18n="callbacks.add">+ Add</button>