mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-09-12 10:34:24 +08:00
fix: 修复设置页页眉回弹和状态色辨识度 #281
- 在侧栏布局滚动容器统一阻止纵向 overscroll - 拆分状态指示色与成功文本色,提升在线状态辨识度 - 统一连接、运行及键盘 LED 等状态点样式
This commit is contained in:
@@ -48,13 +48,13 @@ const keysDisplay = computed(() => {
|
||||
<div class="flex items-center justify-between text-xs px-2 py-0.5">
|
||||
<div v-if="keyboardLedEnabled" class="flex items-center gap-1">
|
||||
<Badge variant="outline" class="h-4 gap-1 px-1 text-[10px] text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="capsLock ? 'bg-success' : 'bg-warning'" />C
|
||||
<span class="size-1.5 rounded-full" :class="capsLock ? 'bg-status-active' : 'bg-warning'" />C
|
||||
</Badge>
|
||||
<Badge variant="outline" class="h-4 gap-1 px-1 text-[10px] text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="numLock ? 'bg-success' : 'bg-warning'" />N
|
||||
<span class="size-1.5 rounded-full" :class="numLock ? 'bg-status-active' : 'bg-warning'" />N
|
||||
</Badge>
|
||||
<Badge variant="outline" class="h-4 gap-1 px-1 text-[10px] text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="scrollLock ? 'bg-success' : 'bg-warning'" />S
|
||||
<span class="size-1.5 rounded-full" :class="scrollLock ? 'bg-status-active' : 'bg-warning'" />S
|
||||
</Badge>
|
||||
</div>
|
||||
<div v-else class="text-[10px] text-muted-foreground/60">
|
||||
@@ -87,15 +87,15 @@ const keysDisplay = computed(() => {
|
||||
<Separator orientation="vertical" class="h-5" />
|
||||
<template v-if="keyboardLedEnabled">
|
||||
<Badge variant="outline" class="mx-1 gap-1.5 text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="capsLock ? 'bg-success' : 'bg-warning'" />
|
||||
<span class="size-1.5 rounded-full" :class="capsLock ? 'bg-status-active' : 'bg-warning'" />
|
||||
{{ t('infobar.caps') }}
|
||||
</Badge>
|
||||
<Badge variant="outline" class="mx-1 gap-1.5 text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="numLock ? 'bg-success' : 'bg-warning'" />
|
||||
<span class="size-1.5 rounded-full" :class="numLock ? 'bg-status-active' : 'bg-warning'" />
|
||||
{{ t('infobar.num') }}
|
||||
</Badge>
|
||||
<Badge variant="outline" class="mx-1 gap-1.5 text-foreground">
|
||||
<span class="size-1.5 rounded-full" :class="scrollLock ? 'bg-success' : 'bg-warning'" />
|
||||
<span class="size-1.5 rounded-full" :class="scrollLock ? 'bg-status-active' : 'bg-warning'" />
|
||||
{{ t('infobar.scroll') }}
|
||||
</Badge>
|
||||
</template>
|
||||
|
||||
@@ -714,8 +714,8 @@ onUnmounted(() => {
|
||||
<span class="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1">
|
||||
<span :class="msdConnected ? 'text-success' : 'text-muted-foreground'" class="flex items-center gap-1.5">
|
||||
<span class="relative flex size-2">
|
||||
<span v-if="msdConnected" class="absolute inline-flex h-full w-full animate-ping rounded-full bg-success opacity-75"></span>
|
||||
<span :class="msdConnected ? 'bg-success' : 'bg-muted-foreground'" class="relative inline-flex size-2 rounded-full"></span>
|
||||
<span v-if="msdConnected" class="absolute inline-flex size-full animate-ping rounded-full bg-status-active opacity-75"></span>
|
||||
<span :class="msdConnected ? 'bg-status-active' : 'bg-muted-foreground'" class="relative inline-flex size-2 rounded-full"></span>
|
||||
</span>
|
||||
{{ msdConnected ? t('common.connected') : t('common.disconnected') }}
|
||||
</span>
|
||||
|
||||
@@ -529,8 +529,8 @@ onUnmounted(() => {
|
||||
<Item variant="muted" size="sm"><ItemContent><ItemDescription>{{ t('stats.connectionType') }}</ItemDescription><ItemTitle class="flex items-center gap-1.5">
|
||||
<span
|
||||
:class="[
|
||||
'inline-block w-2 h-2 rounded-full',
|
||||
currentStats.isRelay ? 'bg-warning' : 'bg-success'
|
||||
'inline-block size-2 rounded-full',
|
||||
currentStats.isRelay ? 'bg-warning' : 'bg-status-active'
|
||||
]"
|
||||
/>
|
||||
{{ currentStats.isRelay ? t('stats.relay') : t('stats.p2p') }}
|
||||
|
||||
@@ -51,7 +51,7 @@ onMounted(() => {
|
||||
const statusColor = computed(() => {
|
||||
switch (props.status) {
|
||||
case 'connected':
|
||||
return 'bg-success'
|
||||
return 'bg-status-active'
|
||||
case 'connecting':
|
||||
return 'bg-warning animate-pulse'
|
||||
case 'disconnected':
|
||||
|
||||
@@ -11,7 +11,7 @@ const props = defineProps<{
|
||||
<div
|
||||
data-slot="sidebar-content"
|
||||
data-sidebar="content"
|
||||
:class="cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)"
|
||||
:class="cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto overscroll-y-none group-data-[collapsible=icon]:overflow-hidden', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ const props = defineProps<{
|
||||
<main
|
||||
data-slot="sidebar-inset"
|
||||
:class="cn(
|
||||
'bg-background relative flex w-full flex-1 flex-col',
|
||||
'bg-background relative flex min-h-0 w-full flex-1 flex-col overflow-y-auto overscroll-y-none',
|
||||
'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
|
||||
props.class,
|
||||
)"
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
--destructive-foreground: oklch(98.48% 0 0);
|
||||
--success: oklch(52.7% 0.154 150.07);
|
||||
--success-foreground: oklch(98.48% 0 0);
|
||||
/* Compact state indicators need stronger luminance separation than success text. */
|
||||
--status-active: oklch(72.3% 0.219 149.58);
|
||||
--warning: oklch(55.4% 0.135 66.44);
|
||||
--warning-foreground: oklch(98.48% 0 0);
|
||||
--info: oklch(54.6% 0.245 262.88);
|
||||
@@ -111,6 +113,7 @@
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-success: var(--success);
|
||||
--color-success-foreground: var(--success-foreground);
|
||||
--color-status-active: var(--status-active);
|
||||
--color-warning: var(--warning);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
--color-info: var(--info);
|
||||
|
||||
@@ -368,7 +368,7 @@ function watchdogRequestError(error: unknown, action: 'enable' | 'disable'): str
|
||||
|
||||
const watchdogStatusClass = computed(() => {
|
||||
switch (watchdogStatusKey.value) {
|
||||
case 'running': return 'bg-success'
|
||||
case 'running': return 'bg-status-active'
|
||||
case 'error': return 'bg-destructive'
|
||||
default: return 'bg-muted-foreground'
|
||||
}
|
||||
@@ -819,7 +819,7 @@ function otgCheckStatusText(level: OtgSelfCheckLevel): string {
|
||||
function otgGroupStatusClass(status: OtgCheckGroupStatus): string {
|
||||
if (status === 'error') return 'bg-destructive'
|
||||
if (status === 'warn') return 'bg-warning'
|
||||
if (status === 'ok') return 'bg-success'
|
||||
if (status === 'ok') return 'bg-status-active'
|
||||
return 'bg-muted-foreground/40'
|
||||
}
|
||||
|
||||
@@ -1778,7 +1778,7 @@ function getExtStatusClass(status: ExtensionStatus | undefined): string {
|
||||
switch (status.state) {
|
||||
case 'unavailable': return 'bg-muted-foreground'
|
||||
case 'stopped': return 'bg-muted-foreground'
|
||||
case 'running': return 'bg-success'
|
||||
case 'running': return 'bg-status-active'
|
||||
default: return 'bg-muted-foreground'
|
||||
}
|
||||
}
|
||||
@@ -2470,7 +2470,7 @@ function getRustdeskStatusClass(status: string | null | undefined): string {
|
||||
switch (status) {
|
||||
case 'running':
|
||||
case 'registered':
|
||||
case 'connected': return 'bg-success'
|
||||
case 'connected': return 'bg-status-active'
|
||||
case 'starting':
|
||||
case 'connecting': return 'bg-warning'
|
||||
case 'stopped':
|
||||
@@ -2648,7 +2648,7 @@ function getVncServiceStatusText(status: string | undefined): string {
|
||||
|
||||
function getVncStatusClass(status: string | undefined): string {
|
||||
switch (status) {
|
||||
case 'running': return 'bg-success'
|
||||
case 'running': return 'bg-status-active'
|
||||
case 'starting': return 'bg-warning'
|
||||
case 'stopped': return 'bg-muted-foreground'
|
||||
default:
|
||||
@@ -2671,7 +2671,7 @@ function getRtspServiceStatusText(status: string | undefined): string {
|
||||
|
||||
function getRtspStatusClass(status: string | undefined): string {
|
||||
switch (status) {
|
||||
case 'running': return 'bg-success'
|
||||
case 'running': return 'bg-status-active'
|
||||
case 'starting': return 'bg-warning'
|
||||
case 'stopped': return 'bg-muted-foreground'
|
||||
default:
|
||||
@@ -2761,7 +2761,7 @@ watch(isWindows, () => {
|
||||
</SidebarContent>
|
||||
</Sidebar>
|
||||
|
||||
<SidebarInset class="min-w-0 overflow-y-auto">
|
||||
<SidebarInset class="min-w-0">
|
||||
<!-- Mobile Header -->
|
||||
<div class="md:hidden sticky top-0 z-20 flex items-center px-3 sm:px-4 py-2 sm:py-3 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/70">
|
||||
<SidebarTrigger class="mr-1.5 size-8 sm:mr-2 sm:size-9" />
|
||||
@@ -4362,7 +4362,7 @@ watch(isWindows, () => {
|
||||
<!-- Status and controls -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getExtStatusClass(extensions?.ttyd?.status)]" />
|
||||
<div :class="['size-2 rounded-full', getExtStatusClass(extensions?.ttyd?.status)]" />
|
||||
<span class="text-sm">{{ getExtStatusText(extensions?.ttyd?.status) }}</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@@ -4453,7 +4453,7 @@ watch(isWindows, () => {
|
||||
<!-- Status and controls -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getExtStatusClass(extensions?.gostc?.status)]" />
|
||||
<div :class="['size-2 rounded-full', getExtStatusClass(extensions?.gostc?.status)]" />
|
||||
<span class="text-sm">{{ getExtStatusText(extensions?.gostc?.status) }}</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@@ -4548,7 +4548,7 @@ watch(isWindows, () => {
|
||||
<!-- Status and controls -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getExtStatusClass(extensions?.easytier?.status)]" />
|
||||
<div :class="['size-2 rounded-full', getExtStatusClass(extensions?.easytier?.status)]" />
|
||||
<span class="text-sm">{{ getExtStatusText(extensions?.easytier?.status) }}</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@@ -4654,7 +4654,7 @@ watch(isWindows, () => {
|
||||
<template v-else>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getExtStatusClass(extensions?.frpc?.status)]" />
|
||||
<div :class="['size-2 rounded-full', getExtStatusClass(extensions?.frpc?.status)]" />
|
||||
<span class="text-sm">{{ getExtStatusText(extensions?.frpc?.status) }}</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
@@ -4828,7 +4828,7 @@ watch(isWindows, () => {
|
||||
<CardContent class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getRtspStatusClass(rtspStatus?.service_status)]" />
|
||||
<div :class="['size-2 rounded-full', getRtspStatusClass(rtspStatus?.service_status)]" />
|
||||
<span class="text-sm">{{ getRtspServiceStatusText(rtspStatus?.service_status) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -4954,7 +4954,7 @@ watch(isWindows, () => {
|
||||
<CardContent class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getVncStatusClass(vncStatus?.service_status)]" />
|
||||
<div :class="['size-2 rounded-full', getVncStatusClass(vncStatus?.service_status)]" />
|
||||
<span class="text-sm">{{ getVncServiceStatusText(vncStatus?.service_status) }}</span>
|
||||
<template v-if="vncStatus?.connection_count">
|
||||
<span class="text-muted-foreground">|</span>
|
||||
@@ -5077,11 +5077,11 @@ watch(isWindows, () => {
|
||||
<!-- Status and controls -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div :class="['w-2 h-2 rounded-full', getRustdeskStatusClass(rustdeskStatus?.service_status)]" />
|
||||
<div :class="['size-2 rounded-full', getRustdeskStatusClass(rustdeskStatus?.service_status)]" />
|
||||
<span class="text-sm">{{ getRustdeskServiceStatusText(rustdeskStatus?.service_status) }}</span>
|
||||
<template v-if="rustdeskStatus?.rendezvous_status">
|
||||
<span class="text-muted-foreground">|</span>
|
||||
<div :class="['w-2 h-2 rounded-full', getRustdeskStatusClass(rustdeskStatus?.rendezvous_status)]" />
|
||||
<div :class="['size-2 rounded-full', getRustdeskStatusClass(rustdeskStatus?.rendezvous_status)]" />
|
||||
<span class="text-sm text-muted-foreground">{{ getRustdeskRendezvousStatusText(rustdeskStatus?.rendezvous_status) }}</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user