diff --git a/src/components/Debug/SnapshotPing.css b/src/components/Debug/SnapshotPing.css new file mode 100644 index 000000000..50417ad91 --- /dev/null +++ b/src/components/Debug/SnapshotPing.css @@ -0,0 +1,11 @@ +.Toast--info { + background-color: var(--aqua-800) !important; +} + +.Toast--warn { + background-color: var(--orange-800) !important; +} + +.Toast--error { + background-color: var(--red-800) !important; +} diff --git a/src/components/Debug/SnapshotPing.tsx b/src/components/Debug/SnapshotPing.tsx new file mode 100644 index 000000000..78944967c --- /dev/null +++ b/src/components/Debug/SnapshotPing.tsx @@ -0,0 +1,113 @@ +import React, { useEffect, useState } from 'react' + +import { Toast, ToastType, Toasts } from 'decentraland-ui' +import fetch from 'isomorphic-fetch' + +import { getQueryTimestamp } from '../../clients/SnapshotGraphql' +import { SNAPSHOT_SPACE } from '../../entities/Snapshot/constants' +import Time from '../../utils/date/Time' + +import './SnapshotPing.css' + +async function pingSnapshot(): Promise { + const startTime = new Date().getTime() + try { + const query = ` + query getVotes($space: String!, $start: Int!, $end: Int!, $first: Int!) { + votes(where: {space: $space, created_gte: $start, created_lt: $end}, orderBy: "created", orderDirection: asc, first: $first) { + id + voter + created + vp + choice + proposal { + id + choices + } + } + } + ` + + await fetch('https://hub.snapshot.org/graphql/', { + method: 'post', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + query, + variables: { + space: SNAPSHOT_SPACE, + first: 10, + start: 1684534478, + end: getQueryTimestamp(Time().getTime()), + }, + }), + }) + + const endTime = new Date().getTime() + const responseTime = endTime - startTime + console.log('responseTime', responseTime) + return responseTime // Calculate the response time in milliseconds + } catch (error) { + return -1 // Return -1 to indicate API failure + } +} + +const getToastType = (serviceStatus: ServiceStatus) => { + switch (serviceStatus) { + case 'slow': + return ToastType.WARN + case 'failing': + return ToastType.ERROR + default: + return ToastType.INFO + } +} + +type ServiceStatus = 'normal' | 'slow' | 'failing' + +function getMessage(serviceStatus: ServiceStatus) { + switch (serviceStatus) { + case 'slow': + return 'Voting and creating proposals might take some time' + case 'failing': + return 'Voting and creating proposals is currently unavailable' + default: + return 'All good!' + } +} + +export default function SnapshotPing() { + const [serviceStatus, setServiceStatus] = useState('normal') + const [showToast, setShowToast] = useState(false) + + const updateServiceStatus = async () => { + const responseTime = await pingSnapshot() + if (responseTime === -1) { + setServiceStatus('failing') + } else if (responseTime > 200) { + setServiceStatus('slow') + } else { + setServiceStatus('failing') + } + setShowToast(true) + } + + useEffect(() => { + // const intervalId = setInterval(updateServiceStatus, PING_INTERVAL) + // return () => clearInterval(intervalId) + updateServiceStatus() + }, []) + + return ( + + {showToast && ( + setShowToast(false)} + /> + )} + + ) +} diff --git a/src/components/Debug/SnapshotStatus.tsx b/src/components/Debug/SnapshotStatus.tsx index 1d57d6d81..d9d3765ff 100644 --- a/src/components/Debug/SnapshotStatus.tsx +++ b/src/components/Debug/SnapshotStatus.tsx @@ -11,6 +11,8 @@ import Text from '../Common/Typography/Text' import ErrorMessage from '../Error/ErrorMessage' import { ContentSection } from '../Layout/ContentLayout' +import SnapshotPing from './SnapshotPing' + interface Props { className?: string } @@ -50,6 +52,7 @@ export default function SnapshotStatus({ className }: Props) { {JSON.stringify(snapshotSpace)} {!!errorMessage && } + ) }