chore: rebuild release package
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
const DIVIDER_TIME_STORAGE_KEY = 'cc-web-show-divider-time';
|
||||
const CCWEB_PROMPT_VIEW_MODE_STORAGE_KEY = 'cc-web-ccweb-prompt-view-mode';
|
||||
const PROJECT_COLLAPSE_STORAGE_KEY = 'cc-web-collapsed-projects';
|
||||
const SIDEBAR_COLLAPSE_STORAGE_KEY = 'cc-web-sidebar-collapsed';
|
||||
const SIDEBAR_DRAWER_MEDIA_QUERY = '(max-width: 768px)';
|
||||
const SIDEBAR_DESKTOP_COLLAPSE_MEDIA_QUERY = '(width > 768px) and (hover: hover) and (pointer: fine)';
|
||||
const CROSS_CONVERSATION_REPLY_COLLAPSE_STORAGE_KEY = 'cc-web-collapsed-cross-replies';
|
||||
const CROSS_CONVERSATION_REPLY_COLLAPSE_LIMIT = 500;
|
||||
const ASSISTANT_LAST_SECTION_BUTTON_CLASS = 'msg-last-section-btn';
|
||||
@@ -278,6 +281,9 @@
|
||||
const sidebar = $('#sidebar');
|
||||
const sidebarOverlay = $('#sidebar-overlay');
|
||||
const menuBtn = $('#menu-btn');
|
||||
const mobileInputMedia = window.matchMedia('(max-width: 768px), (pointer: coarse)');
|
||||
const sidebarDrawerMedia = window.matchMedia(SIDEBAR_DRAWER_MEDIA_QUERY);
|
||||
const sidebarDesktopCollapseMedia = window.matchMedia(SIDEBAR_DESKTOP_COLLAPSE_MEDIA_QUERY);
|
||||
const chatMain = document.querySelector('.chat-main');
|
||||
const newChatSplit = sidebar.querySelector('.new-chat-split');
|
||||
const newChatBtn = $('#new-chat-btn');
|
||||
@@ -8510,17 +8516,67 @@
|
||||
}
|
||||
|
||||
// --- Sidebar ---
|
||||
function readSidebarCollapsedPreference() {
|
||||
try {
|
||||
return localStorage.getItem(SIDEBAR_COLLAPSE_STORAGE_KEY) === 'true';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function persistSidebarCollapsedPreference(collapsed) {
|
||||
try {
|
||||
localStorage.setItem(SIDEBAR_COLLAPSE_STORAGE_KEY, collapsed ? 'true' : 'false');
|
||||
} catch {
|
||||
// 存储不可用时仍保留当前页面内的交互状态。
|
||||
}
|
||||
}
|
||||
|
||||
function syncSidebarButtonState() {
|
||||
const isDrawer = isSidebarDrawerMode();
|
||||
const isDesktopCollapsible = isSidebarDesktopCollapseMode();
|
||||
// aria-expanded 表示按钮控制的固定/抽屉状态;hover/focus 预览不改变用户的固定选择。
|
||||
const expanded = isDrawer
|
||||
? sidebar.classList.contains('open')
|
||||
: (isDesktopCollapsible ? !app.classList.contains('sidebar-collapsed') : true);
|
||||
const label = isDrawer
|
||||
? (expanded ? '关闭左侧菜单' : '打开左侧菜单')
|
||||
: (isDesktopCollapsible
|
||||
? (expanded ? '收起左侧菜单' : '固定展开左侧菜单')
|
||||
: '左侧菜单');
|
||||
menuBtn.setAttribute('aria-expanded', String(expanded));
|
||||
menuBtn.setAttribute('aria-label', label);
|
||||
menuBtn.title = label;
|
||||
}
|
||||
|
||||
function setSidebarCollapsed(collapsed, { persist = false } = {}) {
|
||||
const nextCollapsed = Boolean(collapsed);
|
||||
app.classList.toggle('sidebar-collapsed', nextCollapsed);
|
||||
if (persist) persistSidebarCollapsedPreference(nextCollapsed);
|
||||
syncSidebarButtonState();
|
||||
}
|
||||
|
||||
function openSidebar() {
|
||||
sidebar.classList.add('open');
|
||||
sidebarOverlay.hidden = false;
|
||||
syncSidebarButtonState();
|
||||
}
|
||||
function closeSidebar() {
|
||||
sidebar.classList.remove('open');
|
||||
sidebarOverlay.hidden = true;
|
||||
syncSidebarButtonState();
|
||||
}
|
||||
|
||||
function handleSidebarInputModeChange() {
|
||||
sidebar.classList.remove('open');
|
||||
sidebarOverlay.hidden = true;
|
||||
syncSidebarButtonState();
|
||||
}
|
||||
|
||||
setSidebarCollapsed(readSidebarCollapsedPreference());
|
||||
|
||||
function canOpenSidebarBySwipe(target) {
|
||||
if (!window.matchMedia('(max-width: 768px), (pointer: coarse)').matches) return false;
|
||||
if (!isSidebarDrawerMode()) return false;
|
||||
if (sidebar.classList.contains('open')) return false;
|
||||
if (sessionLoadingOverlay && !sessionLoadingOverlay.hidden) return false;
|
||||
if (!chatMain || !target || !chatMain.contains(target)) return false;
|
||||
@@ -8531,7 +8587,7 @@
|
||||
}
|
||||
|
||||
function canCloseSidebarBySwipe(target) {
|
||||
if (!window.matchMedia('(max-width: 768px), (pointer: coarse)').matches) return false;
|
||||
if (!isSidebarDrawerMode()) return false;
|
||||
if (!sidebar.classList.contains('open')) return false;
|
||||
if (!target) return false;
|
||||
return sidebar.contains(target) || target === sidebarOverlay;
|
||||
@@ -8996,7 +9052,15 @@
|
||||
}
|
||||
|
||||
function isMobileInputMode() {
|
||||
return window.matchMedia('(max-width: 768px), (pointer: coarse)').matches;
|
||||
return mobileInputMedia.matches;
|
||||
}
|
||||
|
||||
function isSidebarDrawerMode() {
|
||||
return sidebarDrawerMedia.matches;
|
||||
}
|
||||
|
||||
function isSidebarDesktopCollapseMode() {
|
||||
return sidebarDesktopCollapseMedia.matches;
|
||||
}
|
||||
|
||||
// --- Event Listeners ---
|
||||
@@ -9018,10 +9082,23 @@
|
||||
});
|
||||
|
||||
menuBtn.addEventListener('click', () => {
|
||||
sidebar.classList.contains('open') ? closeSidebar() : openSidebar();
|
||||
if (isSidebarDrawerMode()) {
|
||||
sidebar.classList.contains('open') ? closeSidebar() : openSidebar();
|
||||
return;
|
||||
}
|
||||
if (isSidebarDesktopCollapseMode()) {
|
||||
setSidebarCollapsed(!app.classList.contains('sidebar-collapsed'), { persist: true });
|
||||
}
|
||||
});
|
||||
|
||||
sidebarOverlay.addEventListener('click', closeSidebar);
|
||||
[sidebarDrawerMedia, sidebarDesktopCollapseMedia].forEach((media) => {
|
||||
if (typeof media.addEventListener === 'function') {
|
||||
media.addEventListener('change', handleSidebarInputModeChange);
|
||||
} else if (typeof media.addListener === 'function') {
|
||||
media.addListener(handleSidebarInputModeChange);
|
||||
}
|
||||
});
|
||||
document.addEventListener('touchstart', handleSidebarSwipeStart, { passive: true });
|
||||
document.addEventListener('touchmove', handleSidebarSwipeMove, { passive: false });
|
||||
document.addEventListener('touchend', handleSidebarSwipeEnd, { passive: true });
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
document.documentElement.dataset.dividerTime = dividerTime;
|
||||
})();
|
||||
</script>
|
||||
<link rel="stylesheet" href="style.css?v=20260717-wasteland-hifi-23">
|
||||
<link rel="stylesheet" href="style.css?v=20260718-wasteland-bg-right-4">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -74,7 +74,7 @@
|
||||
<!-- Chat -->
|
||||
<main class="chat-main">
|
||||
<header class="chat-header">
|
||||
<button id="menu-btn" class="menu-btn" title="菜单">☰</button>
|
||||
<button id="menu-btn" class="menu-btn" type="button" title="收起左侧菜单" aria-label="收起左侧菜单" aria-controls="sidebar" aria-expanded="true">☰</button>
|
||||
<span id="chat-title" class="chat-title">新会话</span>
|
||||
<button id="chat-session-id-btn" class="chat-session-id-btn" type="button" title="复制当前会话 ID" hidden>ID</button>
|
||||
<button id="chat-cwd" class="chat-cwd" type="button" hidden></button>
|
||||
@@ -183,6 +183,6 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.9.1/mermaid.min.js"></script>
|
||||
<script src="app.js?v=20260718-theme-bundle-4"></script>
|
||||
<script src="app.js?v=20260718-wasteland-bg-right-4"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
110
public/style.css
110
public/style.css
@@ -8888,6 +8888,12 @@ html[data-theme='wasteland'] .mode-select {
|
||||
background-position: right 10px center;
|
||||
}
|
||||
|
||||
@media (min-width: 721px) and (max-width: 1100px) {
|
||||
html[data-theme='wasteland'] body {
|
||||
background-position: center, center, 75% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
html[data-theme='wasteland'] {
|
||||
--sidebar-width: min(88vw, 320px);
|
||||
@@ -8899,7 +8905,7 @@ html[data-theme='wasteland'] .mode-select {
|
||||
linear-gradient(90deg, rgba(3, 5, 5, 0.82), rgba(3, 5, 5, 0.46)),
|
||||
linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.48)),
|
||||
url('assets/themes/wasteland/background.webp');
|
||||
background-position: center, center, 70% 50%;
|
||||
background-position: center, center, 75% 50%;
|
||||
}
|
||||
|
||||
html[data-theme='wasteland'] .input-area {
|
||||
@@ -8967,3 +8973,105 @@ html[data-theme='wasteland'] :is(
|
||||
-webkit-backdrop-filter: blur(3px) saturate(1.16) brightness(1.28);
|
||||
backdrop-filter: blur(3px) saturate(1.16) brightness(1.28);
|
||||
}
|
||||
|
||||
/* === 桌面侧栏:固定收起与悬浮预览 === */
|
||||
:root {
|
||||
--sidebar-rail-width: 14px;
|
||||
--sidebar-hover-shadow: 18px 0 40px rgba(45, 31, 20, 0.16);
|
||||
}
|
||||
|
||||
:is(
|
||||
html[data-theme='carbon'],
|
||||
html[data-theme='nocturne'],
|
||||
html[data-theme='cinder'],
|
||||
html[data-theme='gilded'],
|
||||
html[data-theme='wasteland']
|
||||
) {
|
||||
--sidebar-hover-shadow: 22px 0 52px rgba(0, 0, 0, 0.48);
|
||||
}
|
||||
|
||||
html[data-theme='gilded'] {
|
||||
--sidebar-hover-shadow: 20px 0 46px rgba(69, 48, 25, 0.22);
|
||||
}
|
||||
|
||||
.menu-btn:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (width > 768px) and (hover: hover) and (pointer: fine) {
|
||||
.menu-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
flex: 0 0 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.app.sidebar-collapsed .sidebar {
|
||||
position: relative;
|
||||
z-index: 90;
|
||||
width: var(--sidebar-width);
|
||||
min-width: var(--sidebar-width);
|
||||
margin-right: calc(var(--sidebar-rail-width) - var(--sidebar-width));
|
||||
transform: translateX(calc(var(--sidebar-rail-width) - var(--sidebar-width)));
|
||||
box-shadow: none;
|
||||
will-change: transform;
|
||||
transition:
|
||||
transform 180ms ease,
|
||||
margin-right 180ms ease,
|
||||
box-shadow 180ms ease;
|
||||
}
|
||||
|
||||
.app.sidebar-collapsed .sidebar:is(:hover, :focus-within) {
|
||||
transform: translateX(0);
|
||||
box-shadow: var(--sidebar-hover-shadow);
|
||||
}
|
||||
|
||||
.app.sidebar-collapsed .sidebar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 3;
|
||||
width: var(--sidebar-rail-width);
|
||||
pointer-events: none;
|
||||
border-left: 1px solid var(--border-color);
|
||||
background:
|
||||
linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 12%, transparent)),
|
||||
var(--bg-secondary);
|
||||
box-shadow: inset -1px 0 var(--border-color);
|
||||
opacity: 1;
|
||||
transition: opacity 120ms ease;
|
||||
}
|
||||
|
||||
.app.sidebar-collapsed .sidebar:is(:hover, :focus-within)::after {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
html[data-theme='gilded'] .app.sidebar-collapsed .sidebar::after {
|
||||
border-left-color: rgba(138, 97, 37, 0.34);
|
||||
background:
|
||||
linear-gradient(90deg, rgba(255, 247, 234, 0.42), rgba(168, 79, 37, 0.18)),
|
||||
#efe4d2;
|
||||
box-shadow: inset -1px 0 rgba(122, 63, 32, 0.42);
|
||||
}
|
||||
|
||||
html[data-theme='wasteland'] .app.sidebar-collapsed .sidebar::after {
|
||||
border-left-color: rgba(185, 139, 75, 0.38);
|
||||
background:
|
||||
linear-gradient(90deg, rgba(5, 7, 7, 0.82), rgba(196, 154, 90, 0.2)),
|
||||
#080a09;
|
||||
box-shadow: inset -1px 0 rgba(223, 180, 108, 0.32);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.app.sidebar-collapsed .sidebar,
|
||||
.app.sidebar-collapsed .sidebar::after {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user