mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-21 18:19:03 +08:00
请输入文本
This commit is contained in:
@@ -6,7 +6,6 @@ import { ContentArea } from './components/ContentArea'
|
||||
import { Wizard } from './components/Wizard'
|
||||
import { ThemeProvider } from './contexts/ThemeContext'
|
||||
import { ThemeEditorProvider } from './contexts/ThemeEditorContext'
|
||||
import { GlobalSidebar } from './components/GlobalSidebar'
|
||||
import { ThemeEditor } from './components/ThemeEditor'
|
||||
|
||||
function MainContent(): React.JSX.Element {
|
||||
@@ -148,7 +147,6 @@ function App(): React.JSX.Element {
|
||||
<ThemeEditorProvider>
|
||||
<HashRouter>
|
||||
<Routes>
|
||||
<Route path="/global-sidebar" element={<GlobalSidebar />} />
|
||||
<Route path="/*" element={<MainContent />} />
|
||||
</Routes>
|
||||
</HashRouter>
|
||||
|
||||
@@ -105,70 +105,3 @@ html[theme-mode='dark'] .ss-sidebar .t-menu__item.t-is-active svg:not([fill='non
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Global Sidebar Toggle Button */
|
||||
.global-sidebar-toggle {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: var(--ss-bg-color);
|
||||
border-radius: 0px 0 0 0px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
box-shadow: -2px 0 8px rgba(0,0,0,0.1);
|
||||
border: 1px solid var(--ss-border-color);
|
||||
border-right: none;
|
||||
color: var(--ss-text-main);
|
||||
z-index: 10;
|
||||
flex-shrink: 0;
|
||||
animation: twinkle-animation 3s infinite ease-in-out;
|
||||
transition: opacity 0.07s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
.global-sidebar-toggle.hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
|
||||
.sidebar-content-area {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--ss-card-bg);
|
||||
border-radius: 12px 0 0 12px;
|
||||
box-shadow: -4px 0 16px rgba(0,0,0,0.15);
|
||||
border: 1px solid var(--ss-border-color);
|
||||
border-right: none;
|
||||
padding: 12px 8px;
|
||||
gap: 12px;
|
||||
width: 60px;
|
||||
transition: opacity 0.1s ease, transform 0.1s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
backface-visibility: hidden;
|
||||
transform: translateZ(0);
|
||||
contain: paint; /* 性能优化:限制重绘范围 */
|
||||
}
|
||||
|
||||
.sidebar-content-area.hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.sidebar-content-area.visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
@keyframes twinkle-animation {
|
||||
0%, 100% {
|
||||
box-shadow: -2px 0 8px rgba(0,0,0,0.1);
|
||||
filter: brightness(1);
|
||||
}
|
||||
50% {
|
||||
box-shadow: -4px 0 12px var(--td-brand-color-light), 0 0 15px var(--td-brand-color-focus);
|
||||
filter: brightness(1.2);
|
||||
color: var(--td-brand-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Button, Tooltip } from 'tdesign-react'
|
||||
import {
|
||||
HomeIcon,
|
||||
ViewListIcon,
|
||||
UserAddIcon,
|
||||
ChevronRightIcon,
|
||||
ChevronLeftIcon,
|
||||
SettingIcon,
|
||||
CodeIcon
|
||||
} from 'tdesign-icons-react'
|
||||
|
||||
export const GlobalSidebar: React.FC = () => {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const [showToggle, setShowToggle] = useState(true)
|
||||
const [zoom, setZoom] = useState(1.0)
|
||||
|
||||
useEffect(() => {
|
||||
if (!(window as any).api) return
|
||||
|
||||
// 加载初始缩放值
|
||||
const loadZoom = async () => {
|
||||
const res = await (window as any).api.getSetting('window_zoom')
|
||||
if (res.success && res.data) {
|
||||
setZoom(res.data)
|
||||
}
|
||||
}
|
||||
loadZoom()
|
||||
|
||||
// 监听缩放变化
|
||||
const unsubscribe = (window as any).api.onSettingChanged((change: any) => {
|
||||
if (change?.key === 'window_zoom') {
|
||||
setZoom(change.value)
|
||||
// 缩放变化时,重新应用当前展开/收缩状态的窗口大小
|
||||
if ((window as any).api) {
|
||||
if (expanded) {
|
||||
const width = Math.round(84 * change.value)
|
||||
const height = Math.round(300 * change.value)
|
||||
;(window as any).api.windowResize(width, height)
|
||||
} else {
|
||||
const width = Math.round(24 * change.value)
|
||||
const height = Math.round(300 * change.value)
|
||||
;(window as any).api.windowResize(width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
if (typeof unsubscribe === 'function') unsubscribe()
|
||||
}
|
||||
}, [expanded])
|
||||
|
||||
const handleExpand = () => {
|
||||
// 1. 先隐藏三角
|
||||
setShowToggle(false)
|
||||
|
||||
// 2. 稍后扩大窗口
|
||||
setTimeout(() => {
|
||||
if ((window as any).api) {
|
||||
const width = Math.round(60 * zoom)
|
||||
const height = Math.round(300 * zoom)
|
||||
;(window as any).api.windowResize(width, height)
|
||||
}
|
||||
// 3. 最后显示侧边栏内容
|
||||
setTimeout(() => {
|
||||
setExpanded(true)
|
||||
}, 20)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
const handleCollapse = () => {
|
||||
// 1. 先隐藏侧边栏内容
|
||||
setExpanded(false)
|
||||
|
||||
// 2. 稍后缩小窗口
|
||||
setTimeout(() => {
|
||||
if ((window as any).api) {
|
||||
const width = Math.round(24 * zoom)
|
||||
const height = Math.round(58 * zoom)
|
||||
;(window as any).api.windowResize(width, height)
|
||||
}
|
||||
// 3. 最后重新显示三角(等待透明度动画完成)
|
||||
setTimeout(() => {
|
||||
setShowToggle(true)
|
||||
}, 150)
|
||||
}, 150)
|
||||
}
|
||||
|
||||
const openMain = () => {
|
||||
if (!(window as any).api) return
|
||||
;(window as any).api.openWindow({ key: 'main', route: '/' })
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: '100vh',
|
||||
width: `84px`,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
overflow: 'hidden',
|
||||
background: 'transparent'
|
||||
}}
|
||||
>
|
||||
{/* 日常展示的三角 */}
|
||||
<div
|
||||
onClick={handleExpand}
|
||||
className={`global-sidebar-toggle ${!showToggle ? 'hidden' : ''}`}
|
||||
style={{
|
||||
willChange: 'opacity, transform',
|
||||
width: `${!expanded ? '100vw' : '0px'}`,
|
||||
height: `100vh`
|
||||
}}
|
||||
hidden={!expanded}
|
||||
>
|
||||
<ChevronLeftIcon />
|
||||
</div>
|
||||
|
||||
{/* 侧边栏内容 */}
|
||||
<div
|
||||
className={`sidebar-content-area ${expanded ? 'visible' : 'hidden'}`}
|
||||
style={{
|
||||
backgroundColor: 'var(--ss-bg-color)',
|
||||
height: 'fit-content',
|
||||
willChange: 'opacity, transform',
|
||||
width: `60px`,
|
||||
gap: `12px`
|
||||
}}
|
||||
>
|
||||
{/* 顶部的关闭/收起按钮 */}
|
||||
<Button
|
||||
shape="circle"
|
||||
variant="text"
|
||||
onClick={handleCollapse}
|
||||
style={{ marginBottom: '8px', color: 'var(--td-brand-color)' }}
|
||||
>
|
||||
<ChevronRightIcon size="20px" />
|
||||
</Button>
|
||||
|
||||
<Tooltip content="主界面" placement="top">
|
||||
<Button shape="circle" variant="text" onClick={openMain}>
|
||||
<HomeIcon size="24px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="积分操作" placement="top">
|
||||
<Button shape="circle" variant="text" onClick={() => openMain()}>
|
||||
<UserAddIcon size="24px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="排行榜" placement="top">
|
||||
<Button
|
||||
shape="circle"
|
||||
variant="text"
|
||||
onClick={() => (window as any).api.openWindow({ key: 'main', route: '/leaderboard' })}
|
||||
>
|
||||
<ViewListIcon size="24px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="设置" placement="top">
|
||||
<Button
|
||||
shape="circle"
|
||||
variant="text"
|
||||
onClick={() => (window as any).api.openWindow({ key: 'main', route: '/settings' })}
|
||||
>
|
||||
<SettingIcon size="24px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
{import.meta.env.DEV && (
|
||||
<Tooltip content="开发者工具" placement="top">
|
||||
<Button
|
||||
shape="circle"
|
||||
variant="text"
|
||||
onClick={() => (window as any).api?.toggleDevTools()}
|
||||
>
|
||||
<CodeIcon size="24px" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -543,7 +543,13 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
||||
URL 协议 (secscore://)
|
||||
</div>
|
||||
<Divider />
|
||||
<div style={{ marginBottom: '12px', fontSize: '13px', color: 'var(--ss-text-secondary)' }}>
|
||||
<div
|
||||
style={{
|
||||
marginBottom: '12px',
|
||||
fontSize: '13px',
|
||||
color: 'var(--ss-text-secondary)'
|
||||
}}
|
||||
>
|
||||
可以通过 URL 链接唤起 SecScore 并执行操作,例如:
|
||||
</div>
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user