Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,35 @@ ta.addEventListener("keydown", (e) => {
});
$("#send-btn").addEventListener("click", generate);

// Hamburger menu (mobile)
(() => {
const hamburger = $("#hamburger");
const sidebar = $("#sidebar");
const overlay = $("#sidebar-overlay");
if (!hamburger || !sidebar) return;

function openSidebar() {
sidebar.classList.add("open");
overlay.classList.add("open");
}
function closeSidebar() {
sidebar.classList.remove("open");
overlay.classList.remove("open");
}

hamburger.addEventListener("click", () => {
sidebar.classList.contains("open") ? closeSidebar() : openSidebar();
});
overlay.addEventListener("click", closeSidebar);

// Close sidebar when avatar is selected (mobile convenience)
document.addEventListener("click", (e) => {
if (e.target.closest(".avatar-card") && window.innerWidth < 768) {
setTimeout(closeSidebar, 150);
}
});
})();

// Init
(async () => {
await loadVoices();
Expand Down
10 changes: 7 additions & 3 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数字人直播</title>
<link rel="stylesheet" href="style.css?v=8">
<link rel="stylesheet" href="style.css?v=9">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600&display=swap" rel="stylesheet">
</head>
<body>
<div class="app">
<aside class="sidebar">
<button id="hamburger" class="hamburger" aria-label="菜单">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
</button>
<div id="sidebar-overlay" class="sidebar-overlay"></div>
<aside class="sidebar" id="sidebar">
<div class="logo">
<div class="logo-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="5"/><path d="M20 21a8 8 0 0 0-16 0"/></svg>
Expand Down Expand Up @@ -86,6 +90,6 @@

<div id="toast" class="toast hidden"></div>

<script src="app.js?v=8"></script>
<script src="app.js?v=9"></script>
</body>
</html>
92 changes: 92 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,95 @@ body {
transform: translateX(-50%) translateY(0);
}
.toast.hidden { display: none; }

/* ── Hamburger (hidden on desktop) ── */
.hamburger {
display: none;
position: fixed;
top: 12px; left: 12px;
z-index: 200;
width: 40px; height: 40px;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 10px;
cursor: pointer;
align-items: center; justify-content: center;
box-shadow: var(--shadow2);
color: var(--accent);
transition: background 0.15s;
}
.hamburger:hover { background: var(--accent-light); }

.sidebar-overlay {
display: none;
position: fixed; inset: 0;
background: rgba(0,0,0,0.3);
z-index: 99;
}

/* ── Mobile ── */
@media (max-width: 767px) {
.hamburger { display: flex; }

.app { flex-direction: column; height: 100vh; }

.sidebar {
position: fixed;
top: 0; left: 0;
width: 280px;
height: 100vh;
z-index: 100;
transform: translateX(-100%);
transition: transform 0.25s ease;
overflow-y: auto;
padding-top: 56px;
}
.sidebar.open {
transform: translateX(0);
}
.sidebar-overlay.open {
display: block;
}

.avatar-grid {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;
max-height: none;
gap: 8px;
padding: 4px 2px;
-webkit-overflow-scrolling: touch;
}
.avatar-card {
flex: 0 0 68px;
min-width: 68px;
}

.main {
flex: 1;
min-height: 0;
padding-top: 48px;
}

.tabs { padding: 8px 14px 0; }

.stage {
padding: 12px 14px;
justify-content: flex-start;
}

.video-wrap { max-width: 100%; min-height: 200px; }

.input-bar {
position: fixed;
bottom: 0; left: 0; right: 0;
padding: 10px 12px calc(env(safe-area-inset-bottom, 8px) + 8px);
background: var(--bg-sidebar);
border-top: 1px solid var(--border);
z-index: 50;
}
.input-bar textarea { max-width: none; flex: 1; }

.llm-box, .samples { max-width: 100%; }
}
Loading