diff --git a/www/src/Pages/HomePage.jsx b/www/src/Pages/HomePage.jsx deleted file mode 100644 index 240274c19..000000000 --- a/www/src/Pages/HomePage.jsx +++ /dev/null @@ -1,130 +0,0 @@ -import React, { useEffect, useState, useContext } from 'react'; -import { AppContext } from '../Contexts/AppContext'; -import Http from '../Services/Http'; -import { useTranslation } from 'react-i18next'; - -import Section from '../Components/Section'; - -import WebApi from '../Services/WebApi'; - -const percentage = (x, y) => ((x / y) * 100).toFixed(2); -const toKB = (x) => parseFloat((x / 1024).toFixed(2)); - -export default function HomePage() { - const [latestVersion, setLatestVersion] = useState(''); - const [latestDownloadUrl, setLatestDownloadUrl] = useState(''); - const [currentVersion, setCurrentVersion] = useState(''); - const [boardConfigProperties, setBoardConfigProperties] = useState({}); - const [memoryReport, setMemoryReport] = useState(null); - - const { t } = useTranslation(''); - - const { setLoading } = useContext(AppContext); - - useEffect(() => { - WebApi.getFirmwareVersion(setLoading) - .then( - ({ version, boardConfigLabel, boardConfigFileName, boardConfig }) => { - setCurrentVersion(version); - setBoardConfigProperties({ - label: boardConfigLabel, - fileName: boardConfigFileName, - }); - Http.get( - 'https://api.github.com/repos/OpenStickCommunity/GP2040-CE/releases/latest', - ) - .then((response) => { - const latestTag = response.data.tag_name; - setLatestVersion(latestTag); - setLatestDownloadUrl( - response.data?.assets?.find(({ name }) => { - return ( - name - ?.substring(name.lastIndexOf('_') + 1) - ?.replace('.uf2', '') - ?.toLowerCase() === boardConfig.toLowerCase() - ); - })?.browser_download_url || - `https://github.com/OpenStickCommunity/GP2040-CE/releases/tag/${latestTag}`, - ); - }) - .catch(console.error); - }, - ) - .catch(console.error); - - WebApi.getMemoryReport(setLoading) - .then((response) => { - const { - totalFlash, - usedFlash, - physicalFlash, - staticAllocs, - totalHeap, - usedHeap, - } = response; - setMemoryReport({ - totalFlash: toKB(totalFlash), - usedFlash: toKB(usedFlash), - physicalFlash: toKB(physicalFlash), - staticAllocs: toKB(staticAllocs), - totalHeap: toKB(totalHeap), - usedHeap: toKB(usedHeap), - percentageFlash: percentage(usedFlash, totalFlash), - percentageHeap: percentage(usedHeap, totalHeap), - }); - }) - .catch(console.error); - }, []); - - return ( -
-

{t('HomePage:header-text')}

-

{t('HomePage:sub-header-text')}

-
-
-
- {t('HomePage:version-text')} -
-
{`${boardConfigProperties.label} (${boardConfigProperties.fileName}.uf2)`}
-
{t('HomePage:current-text', { version: currentVersion })}
-
{t('HomePage:latest-text', { version: latestVersion })}
- {latestVersion && - currentVersion?.split('-').length == 1 && - currentVersion !== latestVersion && ( -
- - {t('HomePage:get-update-text')} - -
- )} - {memoryReport && ( -
- {t('HomePage:memory-header-text')} -
- {t('HomePage:memory-flash-text')}: {memoryReport.usedFlash} /{' '} - {memoryReport.totalFlash} ({memoryReport.percentageFlash}%) -
-
- {t('HomePage:memory-heap-text')}: {memoryReport.usedHeap} /{' '} - {memoryReport.totalHeap} ({memoryReport.percentageHeap}%) -
-
- {t('HomePage:memory-static-allocations-text')}:{' '} - {memoryReport.staticAllocs} -
-
- {t('HomePage:memory-board-text')}: {memoryReport.physicalFlash} -
-
- )} -
-
-
- ); -} diff --git a/www/src/Pages/HomePage.tsx b/www/src/Pages/HomePage.tsx new file mode 100644 index 000000000..43ae46638 --- /dev/null +++ b/www/src/Pages/HomePage.tsx @@ -0,0 +1,99 @@ +import React, { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ProgressBar } from 'react-bootstrap'; + +import useSystemStats from '../Store/useSystemStats'; +import Section from '../Components/Section'; + +export default function HomePage() { + const { t } = useTranslation(''); + const { + latestVersion, + latestDownloadUrl, + currentVersion, + boardConfigProperties, + memoryReport, + getSystemStats, + loading, + } = useSystemStats(); + + useEffect(() => { + getSystemStats(); + }, []); + + if (loading) { + return ( +
+
+ {t('Common:loading-text')} +
+
+ ); + } + return ( +
+

{t('HomePage:header-text')}

+

{t('HomePage:sub-header-text')}

+
+
+ {t('HomePage:version-text')} +
{`${boardConfigProperties.label} (${boardConfigProperties.fileName}.uf2)`}
+
+ {t('HomePage:current-text', { version: currentVersion })} +
+
+ {t('HomePage:latest-text', { version: latestVersion })} +
+ {latestVersion && + currentVersion?.split('-').length == 1 && + currentVersion !== latestVersion && ( +
+ + {t('HomePage:get-update-text')} + +
+ )} + + + {t('HomePage:memory-header-text')} + +
+ {t('HomePage:memory-flash-text')}: {memoryReport.usedFlash} /{' '} + {memoryReport.totalFlash} ({memoryReport.percentageFlash}%) +
+
+ {t('HomePage:memory-heap-text')}: {memoryReport.usedHeap} /{' '} + {memoryReport.totalHeap} ({memoryReport.percentageHeap}%) +
+
+ {t('HomePage:memory-static-allocations-text')}:{' '} + {memoryReport.staticAllocs} +
+
+ {t('HomePage:memory-board-text')}: {memoryReport.physicalFlash} +
+ + + +
+
+
+ ); +} diff --git a/www/src/Services/WebApi.js b/www/src/Services/WebApi.js index e6f024405..507380e09 100644 --- a/www/src/Services/WebApi.js +++ b/www/src/Services/WebApi.js @@ -462,7 +462,8 @@ async function getAddonsOptions(setLoading) { const data = response.data; setLoading(false); - response.data.turboLedColor = rgbIntToHex(response.data.turboLedColor) || '#ffffff'; + response.data.turboLedColor = + rgbIntToHex(response.data.turboLedColor) || '#ffffff'; // Merge saved keyMappings with defaults const keyboardHostMap = Object.entries(data.keyboardHostMap).reduce( @@ -615,33 +616,6 @@ async function setPeripheralOptions(mappings) { }); } -async function getFirmwareVersion(setLoading) { - setLoading(true); - - try { - const response = await Http.get(`${baseUrl}/api/getFirmwareVersion`); - console.log('got firmware version:', response.data); - setLoading(false); - return response.data; - } catch (error) { - setLoading(false); - console.error(error); - } -} - -async function getMemoryReport(setLoading) { - setLoading(true); - - try { - const response = await Http.get(`${baseUrl}/api/getMemoryReport`); - setLoading(false); - return response.data; - } catch (error) { - setLoading(false); - console.error(error); - } -} - async function getUsedPins(setLoading) { setLoading(true); @@ -735,8 +709,6 @@ export default { getButtonLayoutDefs, getSplashImage, setSplashImage, - getFirmwareVersion, - getMemoryReport, getUsedPins, getHeldPins, abortGetHeldPins, diff --git a/www/src/Store/useSystemStats.ts b/www/src/Store/useSystemStats.ts new file mode 100644 index 000000000..fd6a2e9e4 --- /dev/null +++ b/www/src/Store/useSystemStats.ts @@ -0,0 +1,110 @@ +import { create } from 'zustand'; +import { baseUrl } from '../Services/WebApi'; + +const percentage = (x, y) => parseFloat(((x / y) * 100).toFixed(2)); +const toKB = (x) => parseFloat((x / 1024).toFixed(2)); + +type State = { + latestVersion: string; + latestDownloadUrl: string; + currentVersion: string; + boardConfigProperties: { + label: string; + fileName: string; + }; + memoryReport: { + percentageFlash: number; + percentageHeap: number; + physicalFlash: number; + staticAllocs: number; + totalFlash: number; + totalHeap: number; + usedFlash: number; + usedHeap: number; + }; + loading: boolean; + error: boolean; +}; + +type Actions = { + getSystemStats: () => void; +}; + +const INITIAL_STATE: State = { + latestVersion: '', + latestDownloadUrl: '', + currentVersion: '', + boardConfigProperties: { + label: '', + fileName: '', + }, + memoryReport: { + percentageFlash: 0, + percentageHeap: 0, + physicalFlash: 0, + staticAllocs: 0, + totalFlash: 0, + totalHeap: 0, + usedFlash: 0, + usedHeap: 0, + }, + loading: false, + error: false, +}; + +const useSystemStats = create()((set) => ({ + ...INITIAL_STATE, + getSystemStats: async () => { + set({ loading: true }); + + try { + const [firmwareVersion, memoryReport, latestRelease] = await Promise.all([ + fetch(`${baseUrl}/api/getFirmwareVersion`).then((res) => res.json()), + fetch(`${baseUrl}/api/getMemoryReport`).then((res) => res.json()), + fetch( + 'https://api.github.com/repos/OpenStickCommunity/GP2040-CE/releases/latest', + ).then((res) => res.json()), + ]); + const latestDownloadUrl = + latestRelease.assets?.find( + ({ name }) => + name + ?.substring(name.lastIndexOf('_') + 1) + ?.replace('.uf2', '') + ?.toLowerCase() === firmwareVersion.boardConfig.toLowerCase(), + )?.browser_download_url || + `https://github.com/OpenStickCommunity/GP2040-CE/releases/tag/${latestRelease.data.tag_name}`; + + set({ + currentVersion: firmwareVersion.version, + latestVersion: latestRelease.tag_name, + latestDownloadUrl, + boardConfigProperties: { + label: firmwareVersion.boardConfigLabel, + fileName: firmwareVersion.boardConfigFileName, + }, + memoryReport: { + physicalFlash: toKB(memoryReport.physicalFlash), + staticAllocs: toKB(memoryReport.staticAllocs), + totalFlash: toKB(memoryReport.totalFlash), + totalHeap: toKB(memoryReport.totalHeap), + usedFlash: toKB(memoryReport.usedFlash), + usedHeap: toKB(memoryReport.usedHeap), + percentageFlash: percentage( + memoryReport.usedFlash, + memoryReport.totalFlash, + ), + percentageHeap: percentage( + memoryReport.usedHeap, + memoryReport.totalHeap, + ), + }, + loading: false, + }); + } catch (error) { + set({ error: true, loading: false }); + } + }, +})); + +export default useSystemStats;