Compare commits
4 Commits
f487c0d959
...
0a4a35a3cd
Author | SHA1 | Date |
---|---|---|
|
0a4a35a3cd | |
|
34dff0a3aa | |
|
66cccfe9e1 | |
|
a42384fed6 |
|
@ -1,7 +1,7 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- These are the fonts used in the app -->
|
||||
<link
|
||||
|
@ -27,7 +27,14 @@
|
|||
/>
|
||||
<title>JetKVM</title>
|
||||
<link rel="stylesheet" href="/fonts/fonts.css" />
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="JetKVM" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<meta name="theme-color" content="#051946" />
|
||||
<meta name="description" content="A web-based KVM console for managing remote servers." />
|
||||
<script>
|
||||
// Initial theme setup
|
||||
document.documentElement.classList.toggle(
|
||||
|
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 972 B |
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#1D4ED8" d="M0 6a6 6 0 0 1 6-6h12a6 6 0 0 1 6 6v12a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6V6Z"/><path fill="#fff" d="M13.885 12a1.895 1.895 0 1 1-3.79 0 1.895 1.895 0 0 1 3.79 0Z"/><path fill="#fff" fill-rule="evenodd" d="M7.59 9.363c.49.182.74.727.558 1.218A4.103 4.103 0 0 0 12 16.105a4.103 4.103 0 0 0 3.852-5.526.947.947 0 0 1 1.777-.658A5.998 5.998 0 0 1 12 18a5.998 5.998 0 0 1-5.628-8.078.947.947 0 0 1 1.218-.56ZM11.993 7.895c-.628 0-1.22.14-1.75.39a.947.947 0 1 1-.808-1.714A5.985 5.985 0 0 1 11.993 6c.913 0 1.78.204 2.557.57a.947.947 0 1 1-.808 1.715 4.09 4.09 0 0 0-1.75-.39Z" clip-rule="evenodd"/><path fill="#1D4ED8" d="M0 6a6 6 0 0 1 6-6h12a6 6 0 0 1 6 6v12a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6V6Z"/><path fill="#fff" d="M13.885 12a1.895 1.895 0 1 1-3.79 0 1.895 1.895 0 0 1 3.79 0Z"/><path fill="#fff" fill-rule="evenodd" d="M7.59 9.363c.49.182.74.727.558 1.218A4.103 4.103 0 0 0 12 16.105a4.103 4.103 0 0 0 3.852-5.526.947.947 0 0 1 1.777-.658A5.998 5.998 0 0 1 12 18a5.998 5.998 0 0 1-5.628-8.078.947.947 0 0 1 1.218-.56ZM11.993 7.895c-.628 0-1.22.14-1.75.39a.947.947 0 1 1-.808-1.714A5.985 5.985 0 0 1 11.993 6c.913 0 1.78.204 2.557.57a.947.947 0 1 1-.808 1.715 4.09 4.09 0 0 0-1.75-.39Z" clip-rule="evenodd"/></svg><style>@media (prefers-color-scheme:light){:root{filter:none}}@media (prefers-color-scheme:dark){:root{filter:none}}</style></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#1D4ED8" d="M0 6a6 6 0 0 1 6-6h12a6 6 0 0 1 6 6v12a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6V6Z"/><path fill="#fff" d="M13.885 12a1.895 1.895 0 1 1-3.79 0 1.895 1.895 0 0 1 3.79 0Z"/><path fill="#fff" fill-rule="evenodd" d="M7.59 9.363c.49.182.74.727.558 1.218A4.103 4.103 0 0 0 12 16.105a4.103 4.103 0 0 0 3.852-5.526.947.947 0 0 1 1.777-.658A5.998 5.998 0 0 1 12 18a5.998 5.998 0 0 1-5.628-8.078.947.947 0 0 1 1.218-.56ZM11.993 7.895c-.628 0-1.22.14-1.75.39a.947.947 0 1 1-.808-1.714A5.985 5.985 0 0 1 11.993 6c.913 0 1.78.204 2.557.57a.947.947 0 1 1-.808 1.715 4.09 4.09 0 0 0-1.75-.39Z" clip-rule="evenodd"/><path fill="#1D4ED8" d="M0 6a6 6 0 0 1 6-6h12a6 6 0 0 1 6 6v12a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6V6Z"/><path fill="#fff" d="M13.885 12a1.895 1.895 0 1 1-3.79 0 1.895 1.895 0 0 1 3.79 0Z"/><path fill="#fff" fill-rule="evenodd" d="M7.59 9.363c.49.182.74.727.558 1.218A4.103 4.103 0 0 0 12 16.105a4.103 4.103 0 0 0 3.852-5.526.947.947 0 0 1 1.777-.658A5.998 5.998 0 0 1 12 18a5.998 5.998 0 0 1-5.628-8.078.947.947 0 0 1 1.218-.56ZM11.993 7.895c-.628 0-1.22.14-1.75.39a.947.947 0 1 1-.808-1.714A5.985 5.985 0 0 1 11.993 6c.913 0 1.78.204 2.557.57a.947.947 0 1 1-.808 1.715 4.09 4.09 0 0 0-1.75-.39Z" clip-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "JetKVM",
|
||||
"short_name": "JetKVM",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#002b36",
|
||||
"background_color": "#051946",
|
||||
"display": "standalone"
|
||||
}
|
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 7.9 KiB |
|
@ -105,9 +105,6 @@ export interface RTCState {
|
|||
setRpcDataChannel: (channel: RTCDataChannel) => void;
|
||||
rpcDataChannel: RTCDataChannel | null;
|
||||
|
||||
diskChannel: RTCDataChannel | null;
|
||||
setDiskChannel: (channel: RTCDataChannel) => void;
|
||||
|
||||
peerConnectionState: RTCPeerConnectionState | null;
|
||||
setPeerConnectionState: (state: RTCPeerConnectionState) => void;
|
||||
|
||||
|
@ -160,9 +157,6 @@ export const useRTCStore = create<RTCState>(set => ({
|
|||
peerConnectionState: null,
|
||||
setPeerConnectionState: (state: RTCPeerConnectionState) => set({ peerConnectionState: state }),
|
||||
|
||||
diskChannel: null,
|
||||
setDiskChannel: (channel: RTCDataChannel) => set({ diskChannel: channel }),
|
||||
|
||||
mediaStream: null,
|
||||
setMediaStream: (stream: MediaStream) => set({ mediaStream: stream }),
|
||||
|
||||
|
@ -390,9 +384,6 @@ export interface RemoteVirtualMediaState {
|
|||
}
|
||||
|
||||
export interface MountMediaState {
|
||||
localFile: File | null;
|
||||
setLocalFile: (file: MountMediaState["localFile"]) => void;
|
||||
|
||||
remoteVirtualMediaState: RemoteVirtualMediaState | null;
|
||||
setRemoteVirtualMediaState: (state: MountMediaState["remoteVirtualMediaState"]) => void;
|
||||
|
||||
|
@ -410,9 +401,6 @@ export interface MountMediaState {
|
|||
}
|
||||
|
||||
export const useMountMediaStore = create<MountMediaState>(set => ({
|
||||
localFile: null,
|
||||
setLocalFile: (file: MountMediaState["localFile"]) => set({ localFile: file }),
|
||||
|
||||
remoteVirtualMediaState: null,
|
||||
setRemoteVirtualMediaState: (state: MountMediaState["remoteVirtualMediaState"]) => set({ remoteVirtualMediaState: state }),
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
|||
const {
|
||||
modalView,
|
||||
setModalView,
|
||||
setLocalFile,
|
||||
setRemoteVirtualMediaState,
|
||||
errorMessage,
|
||||
setErrorMessage,
|
||||
|
@ -58,7 +57,6 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
|||
const [incompleteFileName, setIncompleteFileName] = useState<string | null>(null);
|
||||
const [mountInProgress, setMountInProgress] = useState(false);
|
||||
function clearMountMediaState() {
|
||||
setLocalFile(null);
|
||||
setRemoteVirtualMediaState(null);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,11 @@ const edids = [
|
|||
"00FFFFFFFFFFFF0010AC132045393639201E0103803C22782ACD25A3574B9F270D5054A54B00714F8180A9C0D1C00101010101010101023A801871382D40582C450056502100001E000000FF00335335475132330A2020202020000000FC0044454C4C204432373231480A20000000FD00384C1E5311000A202020202020018102031AB14F90050403020716010611121513141F65030C001000023A801871382D40582C450056502100001E011D8018711C1620582C250056502100009E011D007251D01E206E28550056502100001E8C0AD08A20E02D10103E960056502100001800000000000000000000000000000000000000000000000000000000004F",
|
||||
label: "DELL D2721H, 1920x1080",
|
||||
},
|
||||
{
|
||||
value:
|
||||
"00ffffffffffff0010ac0100020000000111010380221bff0a00000000000000000000adce0781800101010101010101010101010101000000ff0030303030303030303030303030000000ff0030303030303030303030303030000000fd00384c1f530b000a000000000000000000fc0044454c4c2049445241430a2020000a",
|
||||
label: "DELL IDRAC EDID, 1280x1024",
|
||||
},
|
||||
];
|
||||
|
||||
const streamQualityOptions = [
|
||||
|
@ -140,7 +145,7 @@ export default function SettingsVideoRoute() {
|
|||
title="Video Enhancement"
|
||||
description="Adjust color settings to make the video output more vibrant and colorful"
|
||||
/>
|
||||
|
||||
|
||||
<div className="space-y-4 pl-4">
|
||||
<SettingsItem
|
||||
title="Saturation"
|
||||
|
|
|
@ -29,7 +29,6 @@ import {
|
|||
USBStates,
|
||||
useDeviceStore,
|
||||
useHidStore,
|
||||
useMountMediaStore,
|
||||
useNetworkStateStore,
|
||||
User,
|
||||
useRTCStore,
|
||||
|
@ -132,7 +131,6 @@ export default function KvmIdRoute() {
|
|||
const {
|
||||
peerConnection, setPeerConnection,
|
||||
peerConnectionState, setPeerConnectionState,
|
||||
diskChannel, setDiskChannel,
|
||||
setMediaStream,
|
||||
setRpcDataChannel,
|
||||
isTurnServerInUse, setTurnServerInUse,
|
||||
|
@ -484,18 +482,12 @@ export default function KvmIdRoute() {
|
|||
setRpcDataChannel(rpcDataChannel);
|
||||
};
|
||||
|
||||
const diskDataChannel = pc.createDataChannel("disk");
|
||||
diskDataChannel.onopen = () => {
|
||||
setDiskChannel(diskDataChannel);
|
||||
};
|
||||
|
||||
setPeerConnection(pc);
|
||||
}, [
|
||||
cleanupAndStopReconnecting,
|
||||
iceConfig?.iceServers,
|
||||
legacyHTTPSignaling,
|
||||
sendWebRTCSignal,
|
||||
setDiskChannel,
|
||||
setMediaStream,
|
||||
setPeerConnection,
|
||||
setPeerConnectionState,
|
||||
|
@ -719,25 +711,6 @@ export default function KvmIdRoute() {
|
|||
}
|
||||
}, [navigate, navigateTo, queryParams, setModalView, setQueryParams]);
|
||||
|
||||
const { localFile } = useMountMediaStore();
|
||||
useEffect(() => {
|
||||
if (!diskChannel || !localFile) return;
|
||||
diskChannel.onmessage = async e => {
|
||||
console.debug("Received", e.data);
|
||||
const data = JSON.parse(e.data);
|
||||
const blob = localFile.slice(data.start, data.end);
|
||||
const buf = await blob.arrayBuffer();
|
||||
const header = new ArrayBuffer(16);
|
||||
const headerView = new DataView(header);
|
||||
headerView.setBigUint64(0, BigInt(data.start), false); // start offset, big-endian
|
||||
headerView.setBigUint64(8, BigInt(buf.byteLength), false); // length, big-endian
|
||||
const fullData = new Uint8Array(header.byteLength + buf.byteLength);
|
||||
fullData.set(new Uint8Array(header), 0);
|
||||
fullData.set(new Uint8Array(buf), header.byteLength);
|
||||
diskChannel.send(fullData);
|
||||
};
|
||||
}, [diskChannel, localFile]);
|
||||
|
||||
// System update
|
||||
const [kvmTerminal, setKvmTerminal] = useState<RTCDataChannel | null>(null);
|
||||
const [serialConsole, setSerialConsole] = useState<RTCDataChannel | null>(null);
|
||||
|
|