Skip to content

Commit 0c06596

Browse files
authored
Feature/mobile (#46)
## Enhanced Chart System and Mobile Responsiveness ### Chart System Redesign - Completely refactored chart architecture (42% code reduction) - Pre-fill charts with historical data for instant visualization on startup - Fixed chart glitching during tab switches and page transitions ### Visual Improvements - Larger graphs with more space for actual data visualization - Compact stat badges to maximize chart area - Better spacing between charts for easier scanning - Cleaner design with refined borders and layout ### Smart Features - **Auto unit conversion**: PCIe stats automatically display as MB/s for values over 1000 KB/s - **Version checker**: Shows current version and notifies about updates - **Auto-reconnect**: WebSocket automatically reconnects after mobile lock/unlock - **Desktop zoom**: Default 75% zoom for better overview ### Mobile Fixes - Fixed charts not rendering on mobile devices - Fixed GPU utilization percentage not displaying correctly - Improved touch interactions and responsive layout ### Reliability - Better error handling and input validation - Improved memory management for long-running sessions - More robust chart rendering **Breaking Changes:** None --- Co-authored-by: Panos <>
1 parent 98d5330 commit 0c06596

File tree

14 files changed

+1855
-1572
lines changed

14 files changed

+1855
-1572
lines changed

app.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
import asyncio
55
import logging
6+
import aiohttp
67
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
78
from fastapi.staticfiles import StaticFiles
8-
from fastapi.responses import HTMLResponse
9+
from fastapi.responses import HTMLResponse, JSONResponse
910
from core import config
11+
from version import __version__
1012

1113
# Setup logging
1214
logging.basicConfig(
@@ -15,7 +17,7 @@
1517
)
1618
logger = logging.getLogger(__name__)
1719

18-
app = FastAPI(title="GPU Hot", version="2.0")
20+
app = FastAPI(title="GPU Hot", version=__version__)
1921

2022
# Serve static files
2123
app.mount("/static", StaticFiles(directory="static"), name="static")
@@ -68,6 +70,66 @@ async def api_gpu_data():
6870
return {"gpus": {}, "timestamp": "no_data"}
6971

7072

73+
def compare_versions(current, latest):
74+
"""Compare semantic versions. Returns True if latest > current"""
75+
try:
76+
current_parts = [int(x) for x in current.split('.')]
77+
latest_parts = [int(x) for x in latest.split('.')]
78+
79+
# Pad to same length
80+
max_len = max(len(current_parts), len(latest_parts))
81+
current_parts += [0] * (max_len - len(current_parts))
82+
latest_parts += [0] * (max_len - len(latest_parts))
83+
84+
# Compare each part
85+
for c, l in zip(current_parts, latest_parts):
86+
if l > c:
87+
return True
88+
elif l < c:
89+
return False
90+
91+
return False # Versions are equal
92+
except (ValueError, AttributeError):
93+
return False
94+
95+
96+
@app.get("/api/version")
97+
async def api_version():
98+
"""Get current version and check for updates from GitHub"""
99+
current_version = __version__
100+
101+
try:
102+
# Check GitHub for latest release
103+
async with aiohttp.ClientSession() as session:
104+
async with session.get(
105+
"https://api.github.com/repos/psalias2006/gpu-hot/releases/latest",
106+
timeout=aiohttp.ClientTimeout(total=5)
107+
) as response:
108+
if response.status == 200:
109+
data = await response.json()
110+
latest_version = data.get("tag_name", "").lstrip("v")
111+
112+
# Only show update if latest > current
113+
update_available = compare_versions(current_version, latest_version) if latest_version else False
114+
115+
return JSONResponse({
116+
"current": current_version,
117+
"latest": latest_version,
118+
"update_available": update_available,
119+
"release_url": data.get("html_url", "")
120+
})
121+
except Exception as e:
122+
logger.debug(f"Failed to check for updates: {e}")
123+
124+
# Return current version even if GitHub check fails
125+
return JSONResponse({
126+
"current": current_version,
127+
"latest": None,
128+
"update_available": False,
129+
"release_url": None
130+
})
131+
132+
71133
if __name__ == '__main__':
72134
import uvicorn
73135
try:

docs/demo.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ <h1>🔥 GPU Hot</h1>
9292
</div>
9393

9494
<!-- Load the EXACT same JavaScript files from the real application via CDN -->
95-
<script src="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/charts.js"></script>
95+
<script src="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/chart-config.js"></script>
96+
<script src="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/chart-manager.js"></script>
9697
<script src="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/gpu-cards.js"></script>
9798
<script src="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/ui.js"></script>
9899

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ websockets==12.0
44
psutil==5.9.6
55
nvidia-ml-py==13.580.82
66
requests==2.31.0
7-
websocket-client==1.6.3
7+
websocket-client==1.6.3
8+
aiohttp==3.9.1

0 commit comments

Comments
 (0)