feat: 完善按配置隐藏控制台菜单选项

This commit is contained in:
mofeng-git
2026-07-16 21:02:23 +08:00
parent 50dd419e5a
commit 0482987bf1
6 changed files with 41 additions and 7 deletions

View File

@@ -58,6 +58,7 @@ const isCh9329Backend = computed(() => hidBackend.value.includes('ch9329'))
const showMsd = computed(() => {
return !!systemStore.msd?.available && !isCh9329Backend.value
})
const showAtx = computed(() => systemStore.atx?.available === true)
const props = defineProps<{
mouseMode?: 'absolute' | 'relative'
@@ -65,8 +66,10 @@ const props = defineProps<{
ttydRunning?: boolean
showTerminal?: boolean
showComputerUse?: boolean
showPasteText?: boolean
}>()
const showStats = computed(() => (props.videoMode ?? 'mjpeg') !== 'mjpeg')
const showPasteText = computed(() => props.showPasteText !== false)
const emit = defineEmits<{
(e: 'toggleFullscreen'): void
@@ -108,11 +111,13 @@ const openFromOverflow = (setter: () => void) => {
}
const openMobileAtx = () => openFromOverflow(() => {
if (!showAtx.value) return
mobileAtxOpen.value = true
mobileAtxOpenTime.value = Date.now()
})
const openMobilePaste = () => openFromOverflow(() => {
if (!showPasteText.value) return
mobilePasteOpen.value = true
mobilePasteOpenTime.value = Date.now()
})
@@ -192,11 +197,27 @@ watch(locale, () => {
measureButtonWidths()
})
watch(showAtx, (visible) => {
if (!visible) {
atxOpen.value = false
mobileAtxOpen.value = false
}
})
watch(showPasteText, (visible) => {
if (!visible) {
pasteOpen.value = false
mobilePasteOpen.value = false
}
})
const RIGHT_FIXED_PX = 120
const collapsibleItems = computed(() => {
const items = ITEM_SPECS.slice(3).filter(item => {
if (item.id === 'msd' && !showMsd.value) return false
if (item.id === 'atx' && !showAtx.value) return false
if (item.id === 'paste' && !showPasteText.value) return false
if (item.id === 'stats' && !showStats.value) return false
if (item.id === 'terminal' && props.showTerminal === false) return false
return true
@@ -294,7 +315,7 @@ const hasRightOverflow = computed(() => {
</div>
<!-- ATX Power Control - Adaptive -->
<div v-if="isVisible('atx')">
<div v-if="showAtx && isVisible('atx')">
<Popover v-model:open="atxOpen">
<PopoverTrigger as-child>
<Button variant="ghost" size="sm" class="h-8 gap-1.5 text-xs">
@@ -315,7 +336,7 @@ const hasRightOverflow = computed(() => {
</div>
<!-- Paste Text - Adaptive -->
<div v-if="isVisible('paste')">
<div v-if="showPasteText && isVisible('paste')">
<Popover v-model:open="pasteOpen">
<PopoverTrigger as-child>
<Button variant="ghost" size="sm" class="h-8 gap-1.5 text-xs">
@@ -466,13 +487,13 @@ const hasRightOverflow = computed(() => {
</DropdownMenuItem>
<!-- ATX -->
<DropdownMenuItem v-if="!isVisible('atx')" @click="openMobileAtx">
<DropdownMenuItem v-if="showAtx && !isVisible('atx')" @click="openMobileAtx">
<Power class="h-4 w-4 mr-2" />
{{ t('actionbar.power') }}
</DropdownMenuItem>
<!-- Paste -->
<DropdownMenuItem v-if="!isVisible('paste')" @click="openMobilePaste">
<DropdownMenuItem v-if="showPasteText && !isVisible('paste')" @click="openMobilePaste">
<ClipboardPaste class="h-4 w-4 mr-2" />
{{ t('actionbar.paste') }}
</DropdownMenuItem>
@@ -511,7 +532,7 @@ const hasRightOverflow = computed(() => {
<!-- Mobile ATX Sheet used when ATX is opened from the overflow menu.
A Sheet avoids the Popover anchor-positioning issues on mobile. -->
<Sheet v-model:open="mobileAtxOpen">
<Sheet v-if="showAtx" v-model:open="mobileAtxOpen">
<SheetContent
side="bottom"
class="max-h-[90dvh] overflow-y-auto"
@@ -532,7 +553,7 @@ const hasRightOverflow = computed(() => {
</Sheet>
<!-- Mobile Paste Sheet — used when Paste is opened from the overflow menu. -->
<Sheet v-model:open="mobilePasteOpen">
<Sheet v-if="showPasteText" v-model:open="mobilePasteOpen">
<SheetContent
side="bottom"
class="max-h-[90dvh] overflow-y-auto"

View File

@@ -1,12 +1,13 @@
import { useLocalStorage } from '@vueuse/core'
import type { RemovableRef } from '@vueuse/core'
export type FeatureVisibilityKey = 'webTerminal' | 'computerUse'
export type FeatureVisibilityKey = 'webTerminal' | 'computerUse' | 'pasteText'
export type FeatureVisibility = Record<FeatureVisibilityKey, boolean>
const DEFAULT_FEATURE_VISIBILITY: FeatureVisibility = {
webTerminal: true,
computerUse: true,
pasteText: true,
}
const featureVisibility = useLocalStorage<FeatureVisibility>(

View File

@@ -715,6 +715,7 @@ export default {
featureVisibility: 'Feature Visibility',
featureVisibilityDesc: 'Control which feature entry points are shown on the console page',
computerUseAgent: 'Computer Use Agent',
pasteText: 'Paste Text',
videoSettings: 'Video Capture',
videoSettingsDesc: 'Configure capture device format, resolution and frame rate',
videoDevice: 'Video Device',

View File

@@ -714,6 +714,7 @@ export default {
featureVisibility: '功能展示',
featureVisibilityDesc: '控制控制台页面显示的功能入口',
computerUseAgent: 'Computer Use Agent',
pasteText: '粘贴文本',
videoSettings: '视频采集',
videoSettingsDesc: '配置视频采集设备的格式、分辨率与帧率',
videoDevice: '视频设备',

View File

@@ -190,6 +190,7 @@ const featureVisibility = useFeatureVisibility()
const terminalAvailable = computed(() => ttydStatus.value?.available !== false)
const showTerminal = computed(() => terminalAvailable.value && featureVisibility.value.webTerminal)
const showComputerUse = computed(() => featureVisibility.value.computerUse)
const showPasteText = computed(() => featureVisibility.value.pasteText)
const isDark = ref(document.documentElement.classList.contains('dark'))
@@ -2838,6 +2839,7 @@ onUnmounted(() => {
:ttyd-running="ttydStatus?.running"
:show-terminal="showTerminal"
:show-computer-use="showComputerUse"
:show-paste-text="showPasteText"
@toggle-fullscreen="toggleFullscreen"
@toggle-stats="openStatsSheet"
@toggle-virtual-keyboard="handleToggleVirtualKeyboard"

View File

@@ -117,6 +117,7 @@ import {
Loader2,
AlertTriangle,
Bot,
ClipboardPaste,
TimerReset,
} from 'lucide-vue-next'
@@ -2851,6 +2852,13 @@ watch(isWindows, () => {
</Label>
<Switch id="feature-computer-use" v-model="featureVisibility.computerUse" />
</div>
<div class="flex items-center justify-between gap-4 px-3 py-3">
<Label for="feature-paste-text" class="flex min-w-0 items-center gap-2 font-normal">
<ClipboardPaste class="h-4 w-4 shrink-0 text-muted-foreground" />
<span class="truncate">{{ t('settings.pasteText') }}</span>
</Label>
<Switch id="feature-paste-text" v-model="featureVisibility.pasteText" />
</div>
</CardContent>
</Card>
</div>