wapadil Claude commited on
Commit ·
02155fe
1
Parent(s): 131b764
[CRITICAL FIX] 修复iPad竖屏抽屉空白与移动端体验优化
Browse files核心修复:
- 修复CSS选择器作用域:.left-panel隐藏规则不再影响抽屉内容
- 优化响应式断点:880px断点提升iPad竖屏体验
- 新增快速输入dock:窄屏底部粘性输入栏,支持就地生成
- 增强抽屉交互:智能显隐dock,首访自动引导
技术改进:
- CSS选择器精确化:.app-container > .left-panel避免过度隐藏
- 响应式分层:≤880px抽屉模式,881-1024px双栏,≥1025px桌面
- 触控友好:所有按钮≥44×44pt,回车键支持,悬停效果优化
- 数据同步:dock输入自动同步主界面并触发生成
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- static/script.js +92 -0
- static/style.css +82 -2
- templates/index.html +8 -0
static/script.js
CHANGED
|
@@ -1792,3 +1792,95 @@ function syncToMainPrompt() {
|
|
| 1792 |
mainPrompt.value = quickPrompt.value;
|
| 1793 |
}
|
| 1794 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1792 |
mainPrompt.value = quickPrompt.value;
|
| 1793 |
}
|
| 1794 |
}
|
| 1795 |
+
|
| 1796 |
+
// Quick Dock functionality for narrow screens
|
| 1797 |
+
function generateFromDock() {
|
| 1798 |
+
const dockPrompt = document.getElementById('dockPrompt');
|
| 1799 |
+
const mainPrompt = document.getElementById('prompt');
|
| 1800 |
+
|
| 1801 |
+
if (!dockPrompt.value.trim()) {
|
| 1802 |
+
showToast('请输入提示词', 'error');
|
| 1803 |
+
return;
|
| 1804 |
+
}
|
| 1805 |
+
|
| 1806 |
+
// Copy dock prompt to main prompt
|
| 1807 |
+
mainPrompt.value = dockPrompt.value;
|
| 1808 |
+
|
| 1809 |
+
// Switch to current results tab
|
| 1810 |
+
switchTab('current');
|
| 1811 |
+
|
| 1812 |
+
// Trigger generation
|
| 1813 |
+
generateEdit();
|
| 1814 |
+
|
| 1815 |
+
// Clear dock input after generation starts
|
| 1816 |
+
setTimeout(() => {
|
| 1817 |
+
dockPrompt.value = '';
|
| 1818 |
+
}, 500);
|
| 1819 |
+
}
|
| 1820 |
+
|
| 1821 |
+
// Enhanced drawer functions with dock visibility control
|
| 1822 |
+
function toggleDrawer() {
|
| 1823 |
+
const drawer = document.getElementById('drawer');
|
| 1824 |
+
const overlay = document.querySelector('.drawer-overlay');
|
| 1825 |
+
const quickDock = document.querySelector('.quick-dock');
|
| 1826 |
+
|
| 1827 |
+
if (drawer.classList.contains('open')) {
|
| 1828 |
+
closeDrawer();
|
| 1829 |
+
} else {
|
| 1830 |
+
openDrawer();
|
| 1831 |
+
}
|
| 1832 |
+
}
|
| 1833 |
+
|
| 1834 |
+
function openDrawer() {
|
| 1835 |
+
const drawer = document.getElementById('drawer');
|
| 1836 |
+
const overlay = document.querySelector('.drawer-overlay');
|
| 1837 |
+
const quickDock = document.querySelector('.quick-dock');
|
| 1838 |
+
|
| 1839 |
+
drawer.classList.add('open');
|
| 1840 |
+
overlay.classList.add('show');
|
| 1841 |
+
document.body.style.overflow = 'hidden';
|
| 1842 |
+
|
| 1843 |
+
// Hide quick dock when drawer is open
|
| 1844 |
+
if (quickDock) {
|
| 1845 |
+
quickDock.style.display = 'none';
|
| 1846 |
+
}
|
| 1847 |
+
}
|
| 1848 |
+
|
| 1849 |
+
function closeDrawer() {
|
| 1850 |
+
const drawer = document.getElementById('drawer');
|
| 1851 |
+
const overlay = document.querySelector('.drawer-overlay');
|
| 1852 |
+
const quickDock = document.querySelector('.quick-dock');
|
| 1853 |
+
|
| 1854 |
+
drawer.classList.remove('open');
|
| 1855 |
+
overlay.classList.remove('show');
|
| 1856 |
+
document.body.style.overflow = '';
|
| 1857 |
+
|
| 1858 |
+
// Restore quick dock visibility on narrow screens
|
| 1859 |
+
if (quickDock && window.innerWidth <= 880) {
|
| 1860 |
+
quickDock.style.display = 'flex';
|
| 1861 |
+
}
|
| 1862 |
+
}
|
| 1863 |
+
|
| 1864 |
+
// Auto-show drawer on first visit for narrow screens
|
| 1865 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 1866 |
+
if (window.innerWidth <= 880 && !localStorage.getItem('seenDrawer')) {
|
| 1867 |
+
setTimeout(() => {
|
| 1868 |
+
openDrawer();
|
| 1869 |
+
localStorage.setItem('seenDrawer', '1');
|
| 1870 |
+
showToast('👈 在侧栏中可以调整更多参数', 'info', 3000);
|
| 1871 |
+
}, 1000);
|
| 1872 |
+
}
|
| 1873 |
+
});
|
| 1874 |
+
|
| 1875 |
+
// Handle Enter key in dock input
|
| 1876 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 1877 |
+
const dockPrompt = document.getElementById('dockPrompt');
|
| 1878 |
+
if (dockPrompt) {
|
| 1879 |
+
dockPrompt.addEventListener('keypress', (e) => {
|
| 1880 |
+
if (e.key === 'Enter' && !e.shiftKey) {
|
| 1881 |
+
e.preventDefault();
|
| 1882 |
+
generateFromDock();
|
| 1883 |
+
}
|
| 1884 |
+
});
|
| 1885 |
+
}
|
| 1886 |
+
});
|
static/style.css
CHANGED
|
@@ -968,17 +968,24 @@ label, .meta {
|
|
| 968 |
/* Container query fallback using viewport queries */
|
| 969 |
|
| 970 |
/* Enhanced breakpoints for different screen sizes */
|
| 971 |
-
|
|
|
|
| 972 |
.app-container {
|
| 973 |
grid-template-columns: 1fr;
|
| 974 |
gap: 0; /* Remove gap in mobile */
|
| 975 |
padding: var(--spacing-4);
|
| 976 |
}
|
| 977 |
|
| 978 |
-
|
|
|
|
| 979 |
display: none;
|
| 980 |
}
|
| 981 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 982 |
.sidebar-toggle {
|
| 983 |
display: flex;
|
| 984 |
}
|
|
@@ -988,6 +995,14 @@ label, .meta {
|
|
| 988 |
}
|
| 989 |
}
|
| 990 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 991 |
@media (min-width: 1025px) and (max-width: 1366px) {
|
| 992 |
.app-container {
|
| 993 |
gap: clamp(16px, 1.5vw, 24px);
|
|
@@ -1801,6 +1816,71 @@ select:focus-visible {
|
|
| 1801 |
outline-offset: -2px;
|
| 1802 |
}
|
| 1803 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1804 |
/* ============================= */
|
| 1805 |
/* Apple HIG Enhanced Progress & Notifications */
|
| 1806 |
/* ============================= */
|
|
|
|
| 968 |
/* Container query fallback using viewport queries */
|
| 969 |
|
| 970 |
/* Enhanced breakpoints for different screen sizes */
|
| 971 |
+
/* Use 880px breakpoint for better iPad portrait support */
|
| 972 |
+
@media (max-width: 880px) {
|
| 973 |
.app-container {
|
| 974 |
grid-template-columns: 1fr;
|
| 975 |
gap: 0; /* Remove gap in mobile */
|
| 976 |
padding: var(--spacing-4);
|
| 977 |
}
|
| 978 |
|
| 979 |
+
/* Only hide main layout left panel, not drawer content */
|
| 980 |
+
.app-container > .left-panel {
|
| 981 |
display: none;
|
| 982 |
}
|
| 983 |
|
| 984 |
+
/* Ensure drawer left panel stays visible */
|
| 985 |
+
.drawer .left-panel {
|
| 986 |
+
display: flex;
|
| 987 |
+
}
|
| 988 |
+
|
| 989 |
.sidebar-toggle {
|
| 990 |
display: flex;
|
| 991 |
}
|
|
|
|
| 995 |
}
|
| 996 |
}
|
| 997 |
|
| 998 |
+
/* iPad and medium screens keep dual-pane layout */
|
| 999 |
+
@media (min-width: 881px) and (max-width: 1024px) {
|
| 1000 |
+
.app-container {
|
| 1001 |
+
grid-template-columns: minmax(280px, 350px) 1fr;
|
| 1002 |
+
gap: clamp(12px, 1.5vw, 20px);
|
| 1003 |
+
}
|
| 1004 |
+
}
|
| 1005 |
+
|
| 1006 |
@media (min-width: 1025px) and (max-width: 1366px) {
|
| 1007 |
.app-container {
|
| 1008 |
gap: clamp(16px, 1.5vw, 24px);
|
|
|
|
| 1816 |
outline-offset: -2px;
|
| 1817 |
}
|
| 1818 |
|
| 1819 |
+
/* Quick Dock for narrow screens */
|
| 1820 |
+
.quick-dock {
|
| 1821 |
+
display: none;
|
| 1822 |
+
position: sticky;
|
| 1823 |
+
bottom: 0;
|
| 1824 |
+
background: color-mix(in oklab, var(--surface) 92%, transparent);
|
| 1825 |
+
backdrop-filter: blur(16px) saturate(1.2);
|
| 1826 |
+
-webkit-backdrop-filter: blur(16px) saturate(1.2);
|
| 1827 |
+
border-top: 1px solid var(--border-light);
|
| 1828 |
+
padding: var(--spacing-3) var(--spacing-4);
|
| 1829 |
+
gap: var(--spacing-3);
|
| 1830 |
+
align-items: stretch;
|
| 1831 |
+
z-index: 20;
|
| 1832 |
+
}
|
| 1833 |
+
|
| 1834 |
+
.quick-dock input {
|
| 1835 |
+
flex: 1;
|
| 1836 |
+
min-height: 44px;
|
| 1837 |
+
padding: var(--spacing-3);
|
| 1838 |
+
border: 1px solid var(--border-light);
|
| 1839 |
+
border-radius: var(--radius-lg);
|
| 1840 |
+
background: var(--surface);
|
| 1841 |
+
color: var(--text-primary);
|
| 1842 |
+
font-size: 16px;
|
| 1843 |
+
transition: all 0.2s ease;
|
| 1844 |
+
}
|
| 1845 |
+
|
| 1846 |
+
.quick-dock input:focus {
|
| 1847 |
+
outline: none;
|
| 1848 |
+
border-color: var(--brand-primary);
|
| 1849 |
+
box-shadow: 0 0 0 3px var(--brand-bg);
|
| 1850 |
+
}
|
| 1851 |
+
|
| 1852 |
+
.dock-generate-btn {
|
| 1853 |
+
min-height: 44px;
|
| 1854 |
+
min-width: 80px;
|
| 1855 |
+
padding: var(--spacing-3) var(--spacing-4);
|
| 1856 |
+
background: var(--brand-primary);
|
| 1857 |
+
color: white;
|
| 1858 |
+
border: none;
|
| 1859 |
+
border-radius: var(--radius-lg);
|
| 1860 |
+
font-size: 16px;
|
| 1861 |
+
font-weight: 600;
|
| 1862 |
+
cursor: pointer;
|
| 1863 |
+
transition: all 0.2s ease;
|
| 1864 |
+
white-space: nowrap;
|
| 1865 |
+
}
|
| 1866 |
+
|
| 1867 |
+
.dock-generate-btn:hover {
|
| 1868 |
+
background: var(--brand-hover);
|
| 1869 |
+
transform: translateY(-1px);
|
| 1870 |
+
}
|
| 1871 |
+
|
| 1872 |
+
/* Show quick dock only on narrow screens */
|
| 1873 |
+
@media (max-width: 880px) {
|
| 1874 |
+
.quick-dock {
|
| 1875 |
+
display: flex;
|
| 1876 |
+
}
|
| 1877 |
+
|
| 1878 |
+
/* Hide dock when drawer is open */
|
| 1879 |
+
.drawer.open ~ .app-container .quick-dock {
|
| 1880 |
+
display: none;
|
| 1881 |
+
}
|
| 1882 |
+
}
|
| 1883 |
+
|
| 1884 |
/* ============================= */
|
| 1885 |
/* Apple HIG Enhanced Progress & Notifications */
|
| 1886 |
/* ============================= */
|
templates/index.html
CHANGED
|
@@ -215,6 +215,14 @@
|
|
| 215 |
</div>
|
| 216 |
</div>
|
| 217 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
</div>
|
| 219 |
</div>
|
| 220 |
|
|
|
|
| 215 |
</div>
|
| 216 |
</div>
|
| 217 |
</div>
|
| 218 |
+
|
| 219 |
+
<!-- Quick Dock for narrow screens -->
|
| 220 |
+
<div class="quick-dock">
|
| 221 |
+
<input id="dockPrompt" placeholder="快速描述想要的图像...">
|
| 222 |
+
<button class="dock-generate-btn" onclick="generateFromDock()" aria-label="快速生成">
|
| 223 |
+
生成
|
| 224 |
+
</button>
|
| 225 |
+
</div>
|
| 226 |
</div>
|
| 227 |
</div>
|
| 228 |
|