Skip to content

Commit 9e67279

Browse files
committed
Make bitcoin chain status light update
1 parent 9d69d16 commit 9e67279

File tree

5 files changed

+72
-42
lines changed

5 files changed

+72
-42
lines changed

public/electron.js

+9
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ function setupIPCHandlers() {
199199
}
200200
});
201201

202+
ipcMain.handle("get-chain-block-count", async (event, chainId) => {
203+
try {
204+
return await chainManager.getChainBlockCount(chainId);
205+
} catch (error) {
206+
console.error("Failed to get chain block count:", error);
207+
return 0;
208+
}
209+
});
210+
202211
ipcMain.handle("reset-chain", async (event, chainId) => {
203212
try {
204213
return await chainManager.resetChain(chainId);

public/modules/bitcoinMonitor.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class BitcoinMonitor {
1414
};
1515
}
1616

17-
async makeRpcCall(method, params = []) {
17+
async makeRpcCall(method, params = [], quiet_mode = false) {
1818
try {
1919
const response = await axios.post(`http://${this.rpcConfig.host}:${this.rpcConfig.port}`, {
2020
jsonrpc: '1.0',
@@ -29,7 +29,8 @@ class BitcoinMonitor {
2929
});
3030
return response.data.result;
3131
} catch (error) {
32-
console.error(`RPC call failed (${method}):`, error.message);
32+
if (!quiet_mode)
33+
console.error(`RPC call failed (${method}):`, error.message);
3334
throw error;
3435
}
3536
}

public/modules/chainManager.js

+15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ class ChainManager {
1818
this.processCheckers = new Map(); // Track process check intervals
1919
}
2020

21+
async getChainBlockCount(chainId) {
22+
const status = this.chainStatuses.get(chainId);
23+
if (status !== 'running') return -1;
24+
25+
if (chainId === 'bitcoin') {
26+
try {
27+
return await this.bitcoinMonitor.makeRpcCall('getblockcount', [], true);
28+
} catch (error) {
29+
return -1;
30+
}
31+
}
32+
33+
return -1;
34+
}
35+
2136
async isChainReady(chainId) {
2237
const status = this.chainStatuses.get(chainId);
2338
if (status !== 'running') return false;

public/preload.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ contextBridge.exposeInMainWorld("electronAPI", {
1515
getMnemonicPath: (chainId) => ipcRenderer.invoke("get-mnemonic-path", chainId),
1616
stopChain: (chainId) => ipcRenderer.invoke("stop-chain", chainId),
1717
getChainStatus: (chainId) => ipcRenderer.invoke("get-chain-status", chainId),
18+
getChainBlockCount: (chainId) => ipcRenderer.invoke("get-chain-block-count", chainId),
1819
openDataDir: (chainId) => ipcRenderer.invoke("open-data-dir", chainId),
1920
getFullDataDir: (chainId) => ipcRenderer.invoke("get-full-data-dir", chainId),
2021
getWalletDir: (chainId) => ipcRenderer.invoke("get-wallet-dir", chainId),

src/components/Card.js

+44-40
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState, useCallback, useEffect, useRef } from 'react';
22
import { useTheme } from '../contexts/ThemeContext';
33
import ChainSettingsModal from './ChainSettingsModal';
4-
import './StatusLight.css'; // Will create this next
4+
import './StatusLight.css';
55
import ForceStopModal from './ForceStopModal';
66
import SettingsIcon from './SettingsIcon';
77
import Tooltip from './Tooltip';
@@ -24,50 +24,48 @@ const Card = ({
2424
const [lastActionTime, setLastActionTime] = useState(0);
2525
const [tooltipVisible, setTooltipVisible] = useState(false);
2626
const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
27-
const [processHealth, setProcessHealth] = useState('healthy'); // 'healthy', 'warning', 'error', 'offline'
27+
const [processHealth, setProcessHealth] = useState('offline'); // 'healthy', 'warning', 'error', 'offline'
28+
const [blockCount, setBlockCount] = useState(-1);
2829
const buttonRef = useRef(null);
2930

30-
// Demo effect to cycle through status colors
31+
// Periodic chain status / health check
3132
useEffect(() => {
32-
const statuses = ['healthy', 'warning', 'error', 'offline'];
33-
let currentIndex = 0;
34-
35-
const interval = setInterval(() => {
36-
currentIndex = (currentIndex + 1) % statuses.length;
37-
setProcessHealth(statuses[currentIndex]);
38-
}, 2000);
33+
const fetchBlockCount = async () => {
34+
try {
35+
const count = await window.electronAPI.getChainBlockCount(chain.id);
36+
console.log("new count: ", count)
37+
setBlockCount(count);
38+
} catch (error) {
39+
setBlockCount(-1)
40+
console.error('Failed to fetch block count:', error);
41+
}
42+
};
3943

40-
return () => clearInterval(interval);
41-
}, []);
44+
// Initial fetch
45+
fetchBlockCount();
4246

43-
// TODO: Set up IPC/RPC communication for real process health updates
44-
// Example implementation:
45-
/*
46-
useEffect(() => {
47-
// Subscribe to process health updates
48-
const unsubscribe = window.electronAPI.onProcessHealthUpdate(chain.id, (health) => {
49-
// health object might contain:
50-
// - memory usage
51-
// - CPU usage
52-
// - error counts
53-
// - response times
54-
// - connection status
55-
56-
// Determine status based on health metrics
57-
if (health.error_count > threshold) {
58-
setProcessHealth('error');
59-
} else if (health.memory_usage > warningThreshold) {
60-
setProcessHealth('warning');
61-
} else if (!health.connected) {
47+
const interval = setInterval(() => {
48+
fetchBlockCount();
49+
50+
if (chain.status === 'stopping' || chain.status === 'stopped') {
6251
setProcessHealth('offline');
63-
} else {
64-
setProcessHealth('healthy');
52+
}
53+
else
54+
if (blockCount === -1) {
55+
setProcessHealth('offline');
6556
}
66-
});
57+
else
58+
if (blockCount === 0) {
59+
setProcessHealth('warning');
60+
}
61+
else
62+
if (blockCount > 0) {
63+
setProcessHealth('healthy');
64+
}
65+
}, 1000);
6766

68-
return () => unsubscribe();
69-
}, [chain.id]);
70-
*/
67+
return () => clearInterval(interval);
68+
}, [chain.id, chain.status, blockCount]);
7169

7270
const checkDependencies = () => {
7371
if (!chain.dependencies || chain.dependencies.length === 0) return true;
@@ -139,6 +137,7 @@ const Card = ({
139137
console.log(`Stopping chain ${chain.id}`);
140138
// Update UI immediately to show stopping state
141139
onUpdateChain(chain.id, { status: 'stopping' });
140+
setProcessHealth('offline');
142141
await onStop(chain.id);
143142
} catch (error) {
144143
console.error('Stop failed:', error);
@@ -240,9 +239,14 @@ const Card = ({
240239
return (
241240
<div style={{ display: 'flex', flexDirection: 'column', flex: 1, minWidth: '300px' }}>
242241
<div className={`card ${isDarkMode ? 'dark' : 'light'}`}>
243-
<div className="card-header" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', position: 'relative' }}>
244-
<h2 style={{ margin: 0, lineHeight: 1.2 }}>{chain.display_name}</h2>
245-
<div className={`status-light ${processHealth}`} title={`Process Status: ${processHealth}`} />
242+
<div className="card-header" style={{ position: 'relative' }}>
243+
<div style={{ display: 'flex', alignItems: 'center' }}>
244+
<div className={`status-light ${processHealth}`} title={`Process Status: ${processHealth}`} style={{ marginRight: '10px' }} />
245+
<h2 style={{ margin: 0, lineHeight: 1.2 }}>{chain.display_name}</h2>
246+
</div>
247+
<div style={{ fontSize: '1em', color: isDarkMode ? '#fff' : '#333', marginTop: '4px', marginLeft: '24px', fontWeight: 500 }}>
248+
{processHealth === 'healthy' && blockCount >= 0 ? `#Blocks: ${blockCount}` : 'Chain not started'}
249+
</div>
246250
</div>
247251
<div className="card-content">
248252
<p>{chain.description}</p>

0 commit comments

Comments
 (0)