chore: cherry pick

This commit is contained in:
jingyuexing
2025-07-14 14:52:48 +08:00
parent 32c81f220d
commit 61ea4bd385
9 changed files with 134 additions and 24 deletions

View File

@@ -11,8 +11,10 @@ type HWVersion int
const (
HWVersionAlpha HWVersion = iota
HWVersionPro
HWVersionBeta
HWVersionPcie
HWVersionATX
HWVersionFile = "/etc/kvm/hw"
)
@@ -41,6 +43,14 @@ var HWPcie = Hardware{
GPIOHDDLed: "",
}
var HWPro = Hardware{
Version: HWVersionPro,
GPIOReset: "/sys/class/gpio/gpio35/value",
GPIOPower: "/sys/class/gpio/gpio7/value",
GPIOPowerLED: "/sys/class/gpio/gpio75/value",
GPIOHDDLed: "/sys/class/gpio/gpio74/value",
}
func (h HWVersion) String() string {
switch h {
case HWVersionAlpha:
@@ -49,29 +59,38 @@ func (h HWVersion) String() string {
return "Beta"
case HWVersionPcie:
return "PCIE"
case HWVersionPro:
return "Pro"
default:
return "Unknown"
}
}
func getHwVersion() HWVersion {
func GetHwVersion() HWVersion {
content, err := os.ReadFile(HWVersionFile)
if err != nil {
return HWVersionAlpha
}
version := strings.ReplaceAll(string(content), "\n", "")
if version == "beta" {
switch version {
case "alpha":
return HWVersionAlpha
case "beta":
return HWVersionBeta
} else if version == "pcie" {
case "pcie":
return HWVersionPcie
case "atx":
return HWVersionATX
case "pro":
return HWVersionPro
default:
return HWVersionAlpha
}
return HWVersionAlpha
}
func getHardware() (h Hardware) {
version := getHwVersion()
version := GetHwVersion()
switch version {
case HWVersionAlpha:
@@ -83,10 +102,12 @@ func getHardware() (h Hardware) {
case HWVersionPcie:
h = HWPcie
case HWVersionPro:
h = HWPro
default:
h = HWAlpha
log.Errorf("Unsupported hardware version: %s", version)
}
return
return h
}

View File

@@ -16,4 +16,8 @@ func applicationRouter(r *gin.Engine) {
api.GET("/application/preview", service.GetPreview) // get preview updates state
api.POST("/application/preview", service.SetPreview) // set preview updates state
api.GET("/application/settings/disabled-items", service.GetDisableItems) // get disable items list
api.GET("/application/menu/disabled-items", service.GetDisableMenus)
}

View File

@@ -0,0 +1,63 @@
package application
import (
"NanoKVM-Server/config"
"NanoKVM-Server/proto"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
const (
DeviceTLS = "device:tls"
DeviceSSH = "device:ssh"
DeviceMDNS = "device:mdns"
DeviceHDMI = "device:hdmi"
DeviceWIFI = "device:wifi"
DeviceMouse = "device:mouse"
DeviceReboot = "device:reboot"
DeviceOLED = "device:oled"
DeviceAdvance = "device:advance"
DeviceAdvancedSwap = "device:advance:swap"
)
const (
MenuScript = "script"
MenuImage = "image"
MenuDownload = "download"
MenuTerminal = "terminal"
MenuScreen = "screen"
MenuScreenResolution = "screen:resolution"
)
func (s *Service) GetDisableItems(ctx *gin.Context) {
var rsp proto.Response
switch config.GetHwVersion() {
case config.HWVersionPcie, config.HWVersionATX:
rsp.OkRspWithData(ctx, []string{
DeviceAdvancedSwap,
DeviceAdvance,
MenuScreenResolution,
})
log.Debugf("disable menus items %s", DeviceAdvancedSwap)
return
default:
rsp.OkRspWithData(ctx, []string{})
}
}
func (s *Service) GetDisableMenus(ctx *gin.Context) {
var rsp proto.Response
switch config.GetHwVersion() {
case config.HWVersionPcie, config.HWVersionATX:
rsp.OkRspWithData(ctx, []string{
DeviceAdvancedSwap,
DeviceAdvance,
MenuScreenResolution,
})
log.Debugf("disable menus items %s", DeviceAdvancedSwap)
return
default:
rsp.OkRspWithData(ctx, []string{})
}
}

View File

@@ -26,3 +26,11 @@ export function setPreviewUpdates(enable: boolean) {
export function getPreviewUpdates() {
return http.get('/api/application/preview');
}
export function getSettingsDisabledItems() {
return http.get('/api/application/settings/disabled-items');
}
export function getMenuDisableItems(){
return http.get("/api/application/menu/disabled-items")
}

View File

@@ -3,5 +3,7 @@ import { atom } from 'jotai';
// menu bar disabled items
export const menuDisabledItemsAtom = atom<string[]>([]);
// web title
export const webTitleAtom = atom('');

View File

@@ -20,6 +20,7 @@ import { Script } from './script';
import { Settings } from './settings';
import { Terminal } from './terminal';
import { Wol } from './wol';
import { getMenuDisableItems } from '@/api/application.ts';
export const Menu = () => {
const { t } = useTranslation();
@@ -34,7 +35,13 @@ export const Menu = () => {
// disabled menu items
const items = getMenuDisabledItems();
setMenuDisabledItems(items);
getMenuDisableItems().then(res=>{
let disableItems = new Set<string>(items)
if(res.code === 0){
(res.data as string[]).forEach((ele)=>disableItems.add(ele))
}
setMenuDisabledItems([...disableItems.values()])
})
// react-draggable bounds
const handleResize = () => {
if (!nodeRef.current) return;

View File

@@ -16,13 +16,14 @@ import { Quality } from './quality';
import { Reset } from './reset.tsx';
import { Resolution } from './resolution';
import { VideoMode } from './video-mode.tsx';
import { menuDisabledItemsAtom } from '@/jotai/settings.ts';
export const Screen = () => {
const { t } = useTranslation();
const videoMode = useAtomValue(videoModeAtom);
const resolution = useAtomValue(resolutionAtom);
const menuDisabledItems = useAtomValue(menuDisabledItemsAtom);
const [fps, setFps] = useState(30);
const [quality, setQuality] = useState(2);
const [gop, setGop] = useState(30);
@@ -71,9 +72,9 @@ export const Screen = () => {
const content = (
<div className="flex flex-col space-y-1">
<VideoMode />
<Resolution />
<Quality quality={quality} setQuality={setQuality} />
<Fps fps={fps} setFps={setFps} />
{!menuDisabledItems.includes('screen:resolution') && <Resolution />}
{!menuDisabledItems.includes('screen:quality') && <Quality quality={quality} setQuality={setQuality} />}
{!menuDisabledItems.includes('screen:fps') && <Fps fps={fps} setFps={setFps} />}
{videoMode === 'mjpeg' ? <FrameDetect /> : <Gop gop={gop} setGop={setGop} />}
<Reset />
</div>

View File

@@ -9,12 +9,13 @@ const children = (
</div>
);
export const Advanced = () => {
export const Advanced = ({disable = false}:{disable?:boolean}) => {
const { t } = useTranslation();
return (
<Collapse
ghost
collapsible={disable? 'disabled': 'header'}
expandIconPosition="end"
items={[{ key: 'advanced', label: t('settings.device.advanced'), children }]}
/>

View File

@@ -1,6 +1,6 @@
import { useEffect } from 'react';
import { Divider } from 'antd';
import { useAtom } from 'jotai';
import { useAtom, useAtomValue } from 'jotai';
import { useTranslation } from 'react-i18next';
import * as api from '@/api/hid.ts';
@@ -17,10 +17,11 @@ import { Ssh } from './ssh.tsx';
import { Tls } from './tls.tsx';
import { VirtualDevices } from './virtual-devices.tsx';
import { Wifi } from './wifi.tsx';
import { menuDisabledItemsAtom } from '@/jotai/settings.ts';
export const Device = () => {
const { t } = useTranslation();
const disableMenus = useAtomValue(menuDisabledItemsAtom)
const [hidMode, setHidMode] = useAtom(hidModeAtom);
useEffect(() => {
@@ -37,23 +38,25 @@ export const Device = () => {
<Divider />
<div className="flex flex-col space-y-6">
<Tls />
<Ssh />
<Mdns />
<Hdmi />
{!disableMenus.includes('device:tls') && <Tls />}
{!disableMenus.includes('device:ssh') && <Ssh />}
{!disableMenus.includes('device:mdns') && <Mdns />}
{!disableMenus.includes('device:hdmi') && <Hdmi />}
{hidMode === 'normal' ? <VirtualDevices /> : <HidMode />}
</div>
<Divider />
<div className="flex flex-col space-y-6">
<Oled />
<Wifi />
<MouseJiggler />
{!disableMenus.includes('device:oled') && <Oled />}
{!disableMenus.includes('device:wifi') && <Wifi />}
{!disableMenus.includes('device:mouse') && <MouseJiggler />}
</div>
<Divider />
<Advanced />
<Advanced disable={disableMenus.includes("device:advance")} />
<Divider />
<Reboot />