feat: add toggle to lock sider cards in place

Closes #1957
This commit is contained in:
zjdndjf
2026-07-01 05:50:33 +08:00
parent f030a7c003
commit c9bf199b06
8 changed files with 38 additions and 4 deletions

View File

@@ -13,7 +13,9 @@ import {
PointerSensor,
useSensor,
useSensors,
DragEndEvent
DragEndEvent,
Modifier,
CollisionDetection
} from '@dnd-kit/core'
import { SortableContext } from '@dnd-kit/sortable'
import ProfileCard from '@renderer/components/sider/profile-card'
@@ -58,7 +60,8 @@ const App: React.FC = () => {
siderWidth = 250,
siderOrder = DEFAULT_SIDER_ORDER,
lastSelectedSiderCard = 'proxy',
rememberSelectedSiderCard = false
rememberSelectedSiderCard = false,
lockSiderCards = false
} = appConfig || {}
useTrafficLogger(enableTrafficLogger)
const narrowWidth = platform === 'darwin' ? 70 : 60
@@ -146,7 +149,7 @@ const App: React.FC = () => {
const onDragEnd = async (event: DragEndEvent): Promise<void> => {
const { active, over } = event
const activeId = active.id as SiderCardKey
if (over) {
if (over && !lockSiderCards) {
if (active.id !== over.id) {
const overId = over.id as SiderCardKey
const newOrder = order.slice()
@@ -164,6 +167,16 @@ const App: React.FC = () => {
if (dest) navigate(dest)
}
const lockTransform: Modifier = (args) => {
if (lockSiderCards) return { ...args.transform, x: 0, y: 0 }
return args.transform
}
const collisionDetection: CollisionDetection = (args) => {
if (lockSiderCards) return []
return closestCorners(args)
}
const componentMap: Record<SiderCardKey, React.FC<{ iconOnly?: boolean }>> = {
sysproxy: SysproxySwitcher,
tun: TunSwitcher,
@@ -259,7 +272,12 @@ const App: React.FC = () => {
<OutboundModeSwitcher />
</div>
<div style={{ overflowX: 'clip' }}>
<DndContext sensors={sensors} collisionDetection={closestCorners} onDragEnd={onDragEnd}>
<DndContext
sensors={sensors}
collisionDetection={collisionDetection}
onDragEnd={onDragEnd}
modifiers={[lockTransform]}
>
<div className="grid grid-cols-2 gap-2 m-2">
<SortableContext items={order}>
{order.map((key) => {

View File

@@ -84,6 +84,7 @@ const GeneralConfig: React.FC = () => {
disableHardwareAcceleration = false,
useWindowFrame = false,
rememberSelectedSiderCard = false,
lockSiderCards = false,
autoQuitWithoutCore = false,
autoQuitWithoutCoreDelay = 60,
autoQuitWithoutCoreMode = 'core',
@@ -647,6 +648,15 @@ const GeneralConfig: React.FC = () => {
}}
/>
</SettingItem>
<SettingItem title={t('settings.lockSiderCards')} divider>
<Switch
size="sm"
isSelected={lockSiderCards}
onValueChange={async (v) => {
await patchAppConfig({ lockSiderCards: v })
}}
/>
</SettingItem>
<SettingItem title={t('settings.disableAnimations')} divider>
<Switch
size="sm"

View File

@@ -118,6 +118,7 @@
"settings.showDockIcon": "Show Dock Icon",
"settings.useWindowFrame": "Use System Title Bar",
"settings.rememberSelectedSiderCard": "Remember Selected Sidebar Card",
"settings.lockSiderCards": "Lock Sidebar Card Positions",
"settings.triggerMainWindowBehavior": "Tray Window Trigger Behavior",
"settings.triggerMainWindowBehaviorShow": "Always Show",
"settings.triggerMainWindowBehaviorToggle": "Toggle Show/Hide",

View File

@@ -112,6 +112,7 @@
"settings.showDockIcon": "نمایش آیکون Dock",
"settings.useWindowFrame": "استفاده از نوار عنوان سیستم",
"settings.rememberSelectedSiderCard": "به خاطر سپردن کارت انتخاب شده",
"settings.lockSiderCards": "قفل کردن موقعیت کارت‌های نوار کناری",
"settings.disableHardwareAcceleration": "غیرفعال کردن شتاب سخت‌افزاری",
"settings.disableHardwareAccelerationTooltip": "غیرفعال کردن شتاب سخت‌افزاری می‌تواند مشکلات رندرینگ یا کرش ناشی از مشکلات درایور گرافیک را حل کند، اما ممکن است عملکرد را کاهش دهد. نیاز به راه‌اندازی مجدد برنامه دارد",
"settings.hardwareAcceleration.confirm.title": "تایید راه‌اندازی مجدد برنامه",

View File

@@ -114,6 +114,7 @@
"settings.showDockIcon": "Показывать значок в доке",
"settings.useWindowFrame": "Использовать системную рамку окна",
"settings.rememberSelectedSiderCard": "Запомнить выбранную вкладку",
"settings.lockSiderCards": "Зафиксировать положение карточек",
"settings.disableHardwareAcceleration": "Отключить аппаратное ускорение",
"settings.disableHardwareAccelerationTooltip": "Отключение аппаратного ускорения может решить проблемы с рендерингом или сбоями, вызванными проблемами драйверов графики, но может снизить производительность. Требует перезапуска приложения",
"settings.hardwareAcceleration.confirm.title": "Подтверждение перезапуска приложения",

View File

@@ -118,6 +118,7 @@
"settings.showDockIcon": "显示 Dock 图标",
"settings.useWindowFrame": "使用系统标题栏",
"settings.rememberSelectedSiderCard": "记住所选侧边卡片",
"settings.lockSiderCards": "锁定侧边卡片位置",
"settings.triggerMainWindowBehavior": "托盘窗口触发行为",
"settings.triggerMainWindowBehaviorShow": "总是显示",
"settings.triggerMainWindowBehaviorToggle": "切换显示/隐藏",

View File

@@ -118,6 +118,7 @@
"settings.showDockIcon": "顯示 Dock 圖標",
"settings.useWindowFrame": "使用系統標題欄",
"settings.rememberSelectedSiderCard": "記住已選側邊卡片",
"settings.lockSiderCards": "鎖定側邊卡片位置",
"settings.triggerMainWindowBehavior": "托盤窗口觸發行為",
"settings.triggerMainWindowBehaviorShow": "總是顯示",
"settings.triggerMainWindowBehaviorToggle": "切換顯示/隱藏",

View File

@@ -339,6 +339,7 @@ interface IAppConfig {
siderOrder: string[]
lastSelectedSiderCard?: SiderCardKey
rememberSelectedSiderCard?: boolean
lockSiderCards?: boolean
siderWidth: number
appTheme: AppTheme
customTheme?: string