From e4f70b90709d41ad9aa4b0c7371e22d8f98c5026 Mon Sep 17 00:00:00 2001 From: PhilReact Date: Mon, 4 Nov 2024 08:19:14 +0200 Subject: [PATCH] added note status indicator --- src/App.tsx | 3 + src/assets/syncStatus/synced.png | Bin 0 -> 1155 bytes src/assets/syncStatus/synced_minting.png | Bin 0 -> 1168 bytes src/assets/syncStatus/syncing.png | Bin 0 -> 1207 bytes src/components/CoreSyncStatus.css | 59 +++++++++++++ src/components/CoreSyncStatus.tsx | 105 +++++++++++++++++++++++ 6 files changed, 167 insertions(+) create mode 100644 src/assets/syncStatus/synced.png create mode 100644 src/assets/syncStatus/synced_minting.png create mode 100644 src/assets/syncStatus/syncing.png create mode 100644 src/components/CoreSyncStatus.css create mode 100644 src/components/CoreSyncStatus.tsx diff --git a/src/App.tsx b/src/App.tsx index ddc752d..c9df7fc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -116,6 +116,7 @@ import { NotAuthenticated } from "./ExtStates/NotAuthenticated"; import { openIndexedDB, showSaveFilePicker } from "./components/Apps/useQortalMessageListener"; import { fileToBase64 } from "./utils/fileReading"; import { handleGetFileFromIndexedDB } from "./utils/indexedDB"; +import { CoreSyncStatus } from "./components/CoreSyncStatus"; type extStates = @@ -1458,6 +1459,8 @@ function App() { }} /> )} + + ); diff --git a/src/assets/syncStatus/synced.png b/src/assets/syncStatus/synced.png new file mode 100644 index 0000000000000000000000000000000000000000..f944bad97047ff299964b194401bc61e9a105ed9 GIT binary patch literal 1155 zcmWlXdobOl}#87@C<- zn{{VgW?H58tR$k#W=SQ+C6{&NG&V8}GifxQ|BY2eSV`?R(gGqG$r!TyQiIg%d>E>|w-hMXSaLWvY{^|&NK+FkG@I8%(WIpp*rvJ4rWU{)Z$8WE*Pxr?v@aPAX8bTo8u zcDTZJA1oZf8^8%J@z9?|eCK37qAT%JIYG(J8)6NFO8g=wL^>QsU^0$n!ZidUHBwqY z^&uGq3xr6V1TsRaVmpMLDC^fHrE^gXrKIa!DEuHzGarjTOEK@C! zXiq;<$~82_J-sENkR1A9<#n$@s@8mJQMpjfdh|2YU$-jkFUvn`-cny@U{s;lTp2pD zyapf@_<4IV&XUpwGOwPZf-@zVA8n2qYi?|6zNO3Wd)tn)=Cx+4>+Q%AWrHa}h3^$X>T@(`%$OwGhOSOJ=?Cm5OlY9MLu{KEPN>%*su^+I5q7ARY&U9o`*X-m9jP4PONN+;4s|T zWrF45=UEJ9r@tk8t~=NG!WYNx8ad7mwO_GpS?SDtS$Kd*h$M4hyEay4cwsp<41Tjuz``wg4YDZ64P%O@xqViSF16D$3Dj|X+j06(7q K?;HD==l=(8gzk?3 literal 0 HcmV?d00001 diff --git a/src/assets/syncStatus/synced_minting.png b/src/assets/syncStatus/synced_minting.png new file mode 100644 index 0000000000000000000000000000000000000000..567e784ba8520504f89d08bc108e9a13ba21e6a3 GIT binary patch literal 1168 zcmW-fc~BEp5XQdOI%Mdo8%9Y9nKqU%txj*Iok>_^!L<-Fo<+B2NVg^3-~`*3><;R3Lw$}!Rr#5aOj zfx-#oj^Z;5?6b$Mmk2FElnAHuAb5w|zW_M`(vbZpEZmf@oy-D%4oHHN6X+L_+70eB zZafJ&cN%AZj!a-GJ3-kH*U0Ec$Zdoa;>TiK zZbecDqRJ61MtqY}w!*K%sY0`v3yiJ*$oCqR@CR!m@NJe7%k?49A{45m;z*Efe-$S4 zbI!rY8X0{!Ux~9^m{VUq6UzpL;J!gh*UrPP;LqdK&5FD*T$3P-kK;^TJ9j07`1>$* zfm1;qiT&TtPEa#;wtqU7&-ruPmV z3HLedP;qH07;)0tC>*B4@_0ymEROiXiU!hQGkV~VC<4~rW5Xh5Vyqt3|3O=+Oj>5j72Z{+;=lG8|vCFZ=8gSGYf014PoWlEN8&dc0Qf3;Tf#6F|$dP z-X%G*-n4$yKrN@2)Va1`Q8w48zpF|t78?^6BDoso0HMH>>g*Rw;Pj^CggV1*FnF{v z{FAPE*;iq~VT$8uPt5PpwOZ`D=z!&k53PL5=EvL0`(dMyN`h? zp*-t99=PuEM)lzCuK8Q!J&!jB&4yV2-6>h7*xy+#d;yZ<3&F^5`}IZjpMNxWZgMo4 zLlPbk7+HG9jI}oqbdDM61@ts*YUXFvB=%J{5=y)CDeB`psgYG3xnJZpN$%{Rq>_1D zw*66Wjq_K#{JT}IlxXJJG>la+Jak-HZ5$o1>TTPd{CPiBr{A*Lo&RdPrjY2Zdytiq vZbD@h33RW^bYE>{yy(j?xx7Vf)XOHlHEqviHs literal 0 HcmV?d00001 diff --git a/src/assets/syncStatus/syncing.png b/src/assets/syncStatus/syncing.png new file mode 100644 index 0000000000000000000000000000000000000000..82d39bbb40cfdfb51c2eb15802e129a3d9ca79ed GIT binary patch literal 1207 zcmV;o1W5adP)eLaF?E5ZbvyuLOf4rXNWp9MT#~)D^-9(M`o-qFnUg4yIEhuMMgkC zU|eH>xm;saWradlb)-vCbv;RjOj|o*cCJ}sfH_1wOKFfxR$pq0uU%+YZH<^hOxjvn z#YIK0FE0QmIshy}03$TQMMiHjJ#{-nOfNidFgSHTN@6)k03tL1COHKtJK0)V04_wV zF*3hKM*u59qcJlZD?LIkJ+?$fy;N7JFfjltKoToHW;;f!Lq@X1UpYTi3NS_hBsKsfHO*OD05VJ1T3W10PM$nM4>CxiI6bRW zTR}QXA1^-$CN~r-Jjq&J&{$d3T3Y}iF^^AKfJ|4VQ(B=^UR*v(8#hh5MMr#5U~586 z5;RE-Cpd~!VPHm8o=sN6Szf(YTb4;w#6?B6R$HzwFQ80RyIEhYFfp`PUzbKuZ(Sg{<0 zZq{@Np?T_@5Oc4AgCT3~f&oEhMeqL5olvUqn# z@9d$Y8_OL4A!Wl2__ey0QXUYJ@#HRSZ0^J^fY7lAdDKx(aa{!?uO1!6*b5+a68D$> zD)|XvVO0&Wq*zqg4^WzzoeWv||9=w_1W?_dQZt09Wtn;s0w9!@^)DUcFaRkrjvo}Q ztmMIoHRpnW&%=$}w~v>U`0UGDoN?rFe{khB=jhp&7w6f*xYQ4z%NK5P-f8^-LhrBL z1>C}CV4_G!0dAj)Y&TWj{VC{O~Xh^@FZo&Qo4JsgSK5;K5q002ovPDHLkV1j}H@I(Lr literal 0 HcmV?d00001 diff --git a/src/components/CoreSyncStatus.css b/src/components/CoreSyncStatus.css new file mode 100644 index 0000000..00b03e1 --- /dev/null +++ b/src/components/CoreSyncStatus.css @@ -0,0 +1,59 @@ + .lineHeight { + line-height: 33%; + } + + .tooltip { + display: inline-block; + position: relative; + text-align: left; + } + + .tooltip .bottom { + min-width: 200px; + max-width: 250px; + top: 35px; + right: 0px; + /* transform: translate(-50%, 0); */ + padding: 10px 10px; + color: var(--black); + background-color: var(--bg-2); + font-weight: normal; + font-size: 13px; + border-radius: 8px; + position: absolute; + z-index: 99999999; + box-sizing: border-box; + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); + border: 1px solid var(--black); + visibility: hidden; + opacity: 0; + transition: opacity 0.2s; + } + + .tooltip:hover .bottom { + visibility: visible; + opacity: 1; + z-index: 100; + } + + .tooltip .bottom i { + position: absolute; + bottom: 100%; + left: 50%; + margin-left: -12px; + width: 24px; + height: 12px; + overflow: hidden; + } + + .tooltip .bottom i::after { + content: ''; + position: absolute; + width: 12px; + height: 12px; + left: 50%; + transform: translate(-50%, 50%) rotate(45deg); + background-color: var(--white); + border: 1px solid var(--black); + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); + } \ No newline at end of file diff --git a/src/components/CoreSyncStatus.tsx b/src/components/CoreSyncStatus.tsx new file mode 100644 index 0000000..08bd0f6 --- /dev/null +++ b/src/components/CoreSyncStatus.tsx @@ -0,0 +1,105 @@ +import React, { useEffect, useState } from 'react'; +import syncedImg from '../assets/syncStatus/synced.png' +import syncedMintingImg from '../assets/syncStatus/synced.png' +import syncingImg from '../assets/syncStatus/synced.png' +import { getBaseApiReact } from '../App'; +import './CoreSyncStatus.css' +export const CoreSyncStatus = () => { + const [nodeInfos, setNodeInfos] = useState({}); + const [coreInfos, setCoreInfos] = useState({}); + const [isUsingGateway, setIsUsingGateway] = useState(false); + + useEffect(() => { + const getNodeInfos = async () => { + + + try { + setIsUsingGateway(!!getBaseApiReact()?.includes('ext-node.qortal.link')) + const url = `${getBaseApiReact()}/admin/status`; + const response = await fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + const data = await response.json(); + setNodeInfos(data); + } catch (error) { + console.error('Request failed', error); + } + }; + + const getCoreInfos = async () => { + + + try { + const url = `${getBaseApiReact()}/admin/info`; + const response = await fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + const data = await response.json(); + setCoreInfos(data); + } catch (error) { + console.error('Request failed', error); + } + }; + + getNodeInfos(); + getCoreInfos(); + + const interval = setInterval(() => { + getNodeInfos(); + getCoreInfos(); + }, 30000); + + return () => clearInterval(interval); + }, []); + + const renderSyncStatusIcon = () => { + const { isSynchronizing = false, syncPercent = 0, isMintingPossible = false, height = 0, numberOfConnections = 0 } = nodeInfos; + const buildVersion = coreInfos?.buildVersion ? coreInfos?.buildVersion.substring(0, 12) : ''; + + let imagePath = '/img/syncing.png'; + let message = `Synchronizing` + if (isSynchronizing === true && syncPercent === 99) { + imagePath = syncedImg + } else if (isSynchronizing && !isMintingPossible && syncPercent === 100) { + imagePath = syncingImg; + message = `Synchronized (Not Minting)` + } else if (!isSynchronizing && !isMintingPossible && syncPercent === 100) { + imagePath = syncingImg; + message = `Synchronized (Not Minting)` + } else if (isSynchronizing && isMintingPossible && syncPercent === 100) { + imagePath = syncedMintingImg; + message = `Synchronized (Minting)` + } else if (!isSynchronizing && isMintingPossible && syncPercent === 100) { + imagePath = syncedMintingImg; + message = `Synchronized (Minting)` + } + + return ( +
+ sync status +
+

Core Information

+

Core Version: {buildVersion}

+

{message}

+

Block Height: {height || ''}

+

Connected Peers: {numberOfConnections || ''}

+

Using gateway: {isUsingGateway?.toString()}

+ +
+
+ ); + }; + + return ( +
+ {renderSyncStatusIcon()} +
+ ); +}; +