Compare commits

...

5 Commits

Author SHA1 Message Date
Aveline 36138c90d3
Merge 7c188d73d0 into fe77acd5f0 2025-09-22 13:28:17 +00:00
Siyuan Miao 7c188d73d0 fix linting issues 2025-09-22 13:27:58 +00:00
Siyuan Miao b3d354e949 add no network screen 2025-09-22 13:24:33 +00:00
Siyuan Miao d8dc2a809a update development guide 2025-09-22 12:15:08 +00:00
Siyuan Miao fe77acd5f0 chore: bump to 0.4.8 2025-09-22 12:51:19 +02:00
5 changed files with 399 additions and 9 deletions

View File

@ -103,7 +103,15 @@ tail -f /var/log/jetkvm.log
├── ui/ # React frontend
│ ├── src/routes/ # Pages (login, settings, etc.)
│ └── src/components/ # UI components
└── internal/ # Internal Go packages
├── internal/ # Internal Go packages
│ ├── native/ # CGO / Native code glue layer
│ ├── native/cgo/ # C files for the native library (HDMI, Touchscreen, etc.)
│ ├── native/eez/ # EEZ Studio Project files (for Touchscreen)
│ ├── hidrpc/ # HIDRPC implementation for HID devices (keyboard, mouse, etc.)
│ ├── logging/ # Logging implementation
│ ├── usbgadget/ # USB gadget
│ └── websecurity/ # TLS certificate management
└── resource # netboot iso and other resources
```
**Key files for beginners:**
@ -136,6 +144,10 @@ npm install
./dev_device.sh <YOUR_DEVICE_IP>
```
### Touchscreen Changes
Please click the `Build` button in EEZ Studio then run `./dev_deploy.sh -r <YOUR_DEVICE_IP> --skip-ui-build` to deploy the changes to your device. Initial build might take more than 10 minutes as it will also need to fetch and build LVGL and other dependencies.
### Quick Backend Changes
*Best for: API or backend logic changes*

View File

@ -2,8 +2,8 @@ BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
BUILDDATE := $(shell date -u +%FT%T%z)
BUILDTS := $(shell date -u +%s)
REVISION := $(shell git rev-parse HEAD)
VERSION_DEV := 0.4.8-dev$(shell date +%Y%m%d%H%M)
VERSION := 0.4.7
VERSION_DEV := 0.4.9-dev$(shell date +%Y%m%d%H%M)
VERSION := 0.4.8
PROMETHEUS_TAG := github.com/prometheus/common/version
KVM_PKG_NAME := github.com/jetkvm/kvm
@ -106,7 +106,7 @@ dev_release: frontend build_dev
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app.sha256
build_release: frontend hash_resource
build_release: frontend
@echo "Building release..."
$(GO_CMD) build \
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION)" \

View File

@ -14,7 +14,6 @@ import (
)
var (
currentScreen = "boot_screen"
backlightState = 0 // 0 - NORMAL, 1 - DIMMED, 2 - OFF
)
@ -32,8 +31,8 @@ func updateDisplay() {
nativeInstance.UpdateLabelIfChanged("home_info_ipv4_addr", networkState.IPv4String())
nativeInstance.UpdateLabelAndChangeVisibility("home_info_ipv6_addr", networkState.IPv6String())
nativeInstance.UIObjHide("menu_btn_network")
nativeInstance.UIObjHide("menu_btn_access")
_, _ = nativeInstance.UIObjHide("menu_btn_network")
_, _ = nativeInstance.UIObjHide("menu_btn_access")
nativeInstance.UpdateLabelIfChanged("home_info_mac_addr", networkState.MACString())
@ -71,7 +70,7 @@ func updateDisplay() {
stopCloudBlink()
case CloudConnectionStateConnecting:
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
startCloudBlink()
restartCloudBlink()
case CloudConnectionStateConnected:
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
stopCloudBlink()

View File

@ -5976,6 +5976,386 @@
"isUsedAsUserWidget": false,
"createAtStart": true,
"deleteOnScreenUnload": false
},
{
"objID": "45fba80c-2048-4122-d7ea-015bcdc3a86d",
"components": [
{
"objID": "4b3bf4b1-1890-42f6-ebe0-eedb99177d80",
"type": "LVGLScreenWidget",
"left": 0,
"top": 0,
"width": 300,
"height": 240,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "b5c8e545-e419-4345-a5ca-ee3b4c3430ab",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [
{
"objID": "e1cea438-2bfe-4eec-dd26-57e974fef03f",
"eventName": "LONG_PRESSED",
"handlerType": "action",
"action": "SwitchToMenu",
"userData": 0
},
{
"objID": "579597ea-9d3e-470c-e70d-8c419b87e608",
"eventName": "GESTURE",
"handlerType": "action",
"action": "HomeScreenGesture",
"userData": 0
}
],
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "px",
"heightUnit": "px",
"children": [
{
"objID": "0130cfb9-f59f-4e9c-f429-64afe26b9a74",
"type": "LVGLContainerWidget",
"left": 0,
"top": 0,
"width": 100,
"height": 100,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "b4da6831-67a7-4428-e3c6-da9fd41ae6f3",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
"heightUnit": "%",
"children": [
{
"objID": "7188a7f1-cc07-4c61-b9f6-ef44e78765c9",
"type": "LVGLContainerWidget",
"left": 0,
"top": 0,
"width": 100,
"height": 32,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "bc43eb60-61a2-488c-ebb6-c2a8ad8c0747",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "NoNetworkHeaderContainer",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
"heightUnit": "content",
"children": [
{
"objID": "85582d3d-e2b3-4b7a-8eb8-7834bf73210b",
"type": "LVGLImageWidget",
"left": 0,
"top": 0,
"width": 116,
"height": 32,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "a397b1ff-432a-4ca2-a997-b65ce40bb425",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "NoNetworkHeaderLogo",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "content",
"heightUnit": "content",
"children": [],
"widgetFlags": "ADV_HITTEST|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"localStyles": {
"objID": "e0115d07-4f97-47f6-8944-ba0e406b5a07",
"definition": {
"MAIN": {
"DEFAULT": {
"transform_width": 174,
"transform_height": 49
}
}
}
},
"group": "",
"groupIndex": 0,
"image": "jetkvm",
"setPivot": false,
"pivotX": 0,
"pivotY": 0,
"zoom": 256,
"angle": 0,
"innerAlign": "CENTER"
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlag": false,
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "FlowRowSpaceBetween",
"localStyles": {
"objID": "39c292c9-be8f-4df1-a90a-b98a4fec2ff0"
},
"group": "",
"groupIndex": 0
},
{
"objID": "06bed1cd-f7c9-4044-a7bf-769d252a3eba",
"type": "LVGLContainerWidget",
"left": 0,
"top": 0,
"width": 100,
"height": 60,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "290d8d0b-8b56-4035-efb6-456d3312a10c",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "NoNetworkContentContainer",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
"heightUnit": "%",
"children": [
{
"objID": "b1168e8a-aa45-4048-b61e-7572894467f4",
"type": "LVGLImageWidget",
"left": 227,
"top": 50,
"width": 32,
"height": 32,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "afadcec5-006c-4df3-8328-ed7a5704f640",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "content",
"heightUnit": "content",
"children": [],
"widgetFlags": "ADV_HITTEST|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"localStyles": {
"objID": "bf675fc4-3aae-40b1-85f9-f15b907798b1"
},
"group": "",
"groupIndex": 0,
"image": "ethernet",
"setPivot": false,
"pivotX": 0,
"pivotY": 0,
"zoom": 256,
"angle": 0,
"innerAlign": "CENTER"
},
{
"objID": "d9e5f6b7-1e95-415d-9fd0-2d532cf11e86",
"type": "LVGLLabelWidget",
"left": 0,
"top": 0,
"width": 171,
"height": 31,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "3a3ab91b-aae4-4ee6-87d6-ab177b91007c",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "NoNetworkTitle",
"leftUnit": "%",
"topUnit": "%",
"widthUnit": "content",
"heightUnit": "content",
"children": [],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlagType": "literal",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "LabelFontBold30",
"localStyles": {
"objID": "e2f48223-dc29-4983-bd27-32d3a0a0942c"
},
"groupIndex": 0,
"text": "No Network",
"textType": "literal",
"longMode": "WRAP",
"recolor": false,
"previewValue": "169.254.169.254"
},
{
"objID": "749af7be-38c8-4ca0-c317-bcd1ae3cf372",
"type": "LVGLLabelWidget",
"left": 0,
"top": 0,
"width": 173,
"height": 17,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "33aac33f-d850-44ca-d7d1-6a5b31dcdbba",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"timeline": [],
"eventHandlers": [],
"identifier": "HomeInfoIPv6Addr_1",
"leftUnit": "%",
"topUnit": "%",
"widthUnit": "content",
"heightUnit": "content",
"children": [],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlagType": "literal",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "LabelFont16",
"localStyles": {
"objID": "b904b337-313e-4972-df91-81a6cf53a309"
},
"groupIndex": 0,
"text": "Connect Ethernet cable",
"textType": "literal",
"longMode": "DOT",
"recolor": false
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_VER|SNAPPABLE|SCROLL_ELASTIC|SCROLL_WITH_ARROW|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLLABLE",
"hiddenFlagType": "literal",
"clickableFlag": false,
"clickableFlagType": "literal",
"flagScrollbarMode": "off",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "FlexColumnStart",
"localStyles": {
"objID": "6d2f6255-c50c-4146-fbc7-8a61d2de438f",
"definition": {
"MAIN": {
"DEFAULT": {
"flex_main_place": "CENTER",
"flex_cross_place": "CENTER",
"flex_track_place": "CENTER"
}
}
}
},
"group": "",
"groupIndex": 0
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlag": false,
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "FlexStart",
"localStyles": {
"objID": "ad328009-7550-4b76-9cf1-f3fd4e2a9f4b"
},
"group": "",
"groupIndex": 0
}
],
"widgetFlags": "CLICKABLE|PRESS_LOCK|CLICK_FOCUSABLE|GESTURE_BUBBLE|SNAPPABLE|SCROLLABLE|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER",
"hiddenFlagType": "literal",
"clickableFlag": true,
"clickableFlagType": "literal",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "FlexScreen",
"localStyles": {
"objID": "46cc15c4-12a7-4cb1-d22a-cc3eee92567e"
},
"groupIndex": 0
}
],
"connectionLines": [],
"localVariables": [],
"userProperties": [],
"name": "NoNetworkScreen",
"left": 0,
"top": 0,
"width": 300,
"height": 240,
"isUsedAsUserWidget": false,
"createAtStart": true,
"deleteOnScreenUnload": false
}
],
"userWidgets": [],

View File

@ -11,7 +11,6 @@ import (
var nativeInstance *native.Native
func initNative(systemVersion *semver.Version, appVersion *semver.Version) {
nativeInstance = native.NewNative(native.NativeOptions{
SystemVersion: systemVersion,
AppVersion: appVersion,