Skip to content

Commit

Permalink
Add messages
Browse files Browse the repository at this point in the history
  • Loading branch information
usr-icon-foundation committed May 29, 2024
1 parent 901adfe commit c2d09f7
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 51 deletions.
90 changes: 51 additions & 39 deletions components/topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,60 @@

import React, { useEffect, useState } from "react";
import { InfiniteMovingCards } from "./ui/infinite-moving-cards";
import { useData } from "../contexts/APIDataContext";

const chainDetailsMapping = {
arbitrum: { displayName: "Arbitrum", imageName: "Arbitrum.svg" },
avax: { displayName: "Avalanche", imageName: "Avalanche.svg" },
base: { displayName: "Base", imageName: "Base.svg" },
bsc: { displayName: "BNB Chain", imageName: "Binance-Smart-Chain.svg" },
eth2: { displayName: "Ethereum", imageName: "Ethereum.svg" },
havah: { displayName: "Havah", imageName: "Havah.svg" },
ibc_archway: { displayName: "Archway", imageName: "Archway.svg" },
ibc_injective: { displayName: "Injective", imageName: "Injective.svg" },
ibc_neutron: { displayName: "Neutron", imageName: "Neutron.svg" },
icon: { displayName: "ICON", imageName: "ICON.svg" },
optimism: { displayName: "Optimism", imageName: "Optimism.svg" },
};

export function Topbar() {
const { networkMessages, loading } = useData();
const [chainmessages, setChainMessages] = useState([]);
const [isLoaded, setIsLoaded] = useState(false);

useEffect(() => {
if (!loading) {
const generateChainMessages = () => {
const messages = [];
for (const [key, value] of Object.entries(networkMessages)) {
const chainDetails = chainDetailsMapping[key];
if (chainDetails) {
messages.push(
{ messages: value.src, chain: chainDetails.displayName, role: "src", image: chainDetails.imageName },
{ messages: value.dest, chain: chainDetails.displayName, role: "dest", image: chainDetails.imageName }
);
}
}
return messages;
};
setChainMessages(generateChainMessages());
setIsLoaded(true);
}
}, [loading, networkMessages]);

return (
<div className="h-fit rounded-md flex flex-col antialiased bg-transparent w-full dark:bg-grid-white/[0.05] items-center justify-center relative overflow-hidden">
<InfiniteMovingCards
items={testimonials}
direction="right"
speed="slow"
/>
<div
className={`h-fit rounded-md flex flex-col antialiased bg-transparent w-full dark:bg-grid-white/[0.05] items-center justify-center relative overflow-hidden transition-all duration-1000 ease-in-out transform ${
isLoaded ? "max-h-64 opacity-100 translate-y-0" : "max-h-0 opacity-0 -translate-y-10"
}`}
>
{isLoaded && (
<InfiniteMovingCards
items={chainmessages}
direction="right"
speed="slow"
/>
)}
</div>
);
}

const testimonials = [
{
messages: 2110,
chain: "ICON",
role: "src",
},
{
messages: 1926,
chain: "ICON",
role: "dest",
},
{
messages: 1092,
chain: "Archway",
role: "src",
},
{
messages: 1292,
chain: "Archway",
role: "dest",
},
{
messages: 78,
chain: "Injective",
role: "src",
},
{
messages: 54,
chain: "Injective",
role: "dest",
},
];
7 changes: 4 additions & 3 deletions components/ui/infinite-moving-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const InfiniteMovingCards = ({
messages: number;
chain: string;
role: string;
image: string;
}[];
direction?: "left" | "right";
speed?: "fast" | "normal" | "slow";
Expand Down Expand Up @@ -82,7 +83,7 @@ export const InfiniteMovingCards = ({
<ul
ref={scrollerRef}
className={cn(
" flex min-w-full shrink-0 gap-4 py-2 w-max flex-nowrap",
" flex min-w-full shrink-0 gap-4 pt-2 pb-1 w-max flex-nowrap",
start && "animate-scroll ",
pauseOnHover && "hover:[animation-play-state:paused]"
)}
Expand All @@ -100,8 +101,8 @@ export const InfiniteMovingCards = ({
<div className=" relative z-20 text-sm leading-[1.6] text-gray-400 font-normal flex flex-row items-center">
<span className="mr-1 text-gray-800 dark:text-gray-100 ">{item.messages} messages </span> {item.role === "src" ? "have left" : "have arrived on"}
<div className="flex flex-row items-center ml-2 space-x-2">
<Image className="w-4" src={`/chainlogos/${item.chain}.svg`} alt={item.chain} height={40} width={40}/>
<span className=" text-sm leading-[1.6] text-gray-400 font-normal">
<Image className="w-4" src={`/chainlogos/${item.image}`} alt={item.chain} height={40} width={40}/>
<span className=" text-sm leading-[1.6] text-gray-800 dark:text-gray-100 font-normal">
{item.chain}
</span>
</div>
Expand Down
69 changes: 69 additions & 0 deletions contexts/APIDataContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client";

import { createContext, useContext, ReactNode, useState, useEffect } from "react";
import { DataContextType } from "../types/DataTypes";

const APIDataContext = createContext<DataContextType | undefined>(undefined);

const XCALLTRACKER_ENDPOINT = '/api/statistics/total_messages'

const networks = [
'icon', 'bsc', 'eth2', 'havah', 'ibc_archway', 'ibc_neutron', 'ibc_injective',
'avax', 'base', 'arbitrum', 'optimism'
];

export const APIDataContextProvider = ({ children }: { children: ReactNode }) => {

const [loading, setLoading] = useState(true);
const [totalMessages, setTotalMessages] = useState(0);
const [networkMessages, setNetworkMessages] = useState<Record<string, { src: number, dest: number }>>({});

useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {

const responseTracker = await fetch(XCALLTRACKER_ENDPOINT, { cache: 'no-store' });
const responseTrackerData = await responseTracker.json();
setTotalMessages(responseTrackerData.data.total)

const networkPromises = networks.map(async (network) => {
const srcResponse = await fetch(`/api/statistics/total_messages?src_network=${network}`, { cache: 'no-store' });
const srcData = await srcResponse.json();
const destResponse = await fetch(`/api/statistics/total_messages?dest_network=${network}`, { cache: 'no-store' });
const destData = await destResponse.json();
return { network, src: srcData.data.total, dest: destData.data.total };
});

const networkData = await Promise.all(networkPromises);
const networkMessages = networkData.reduce((acc, { network, src, dest }) => {
acc[network] = { src, dest };
return acc;
}, {} as Record<string, { src: number, dest: number }>);

setNetworkMessages(networkMessages);
} catch (error) {
console.error('Error fetching xcall fees:', error);
} finally {
setLoading(false);
}
};

fetchData();
}, []);


return (
<APIDataContext.Provider value={{ loading, totalMessages, networkMessages }}>
{children}
</APIDataContext.Provider>
);
};

export const useData = () => {
const context = useContext(APIDataContext);
if (context === undefined) {
throw new Error("useData must be used within a APIDataContextProvider");
}
return context;
};
9 changes: 9 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ module.exports = withNextra({
}
];
},
async rewrites() {
return [
{
source: '/api/statistics/total_messages/:path*',
destination: 'https://xcallscan.xyz/api/statistics/total_messages/:path*'
},
// Add other rewrites here if needed
];
},
webpack: (config, { isServer }) => {
if (isServer) {
require("./scripts/generate-sitemap");
Expand Down
21 changes: 12 additions & 9 deletions pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ import { Analytics } from '@vercel/analytics/react';
import Layout from '../components/layout';
import { MendableChatBubble } from "@mendable/search";
import { Topbar } from '../components/topbar';
import { APIDataContextProvider } from '../contexts/APIDataContext';

function MyApp({ Component, pageProps }) {
return (
<main lang="en" className="font-montserrat">
<Layout>
<Topbar />
<Component {...pageProps} />
<MendableChatBubble
anon_key='4a621d80-aa5b-43cc-8600-dd155943ba19' cmdShortcutKey='m' style={{ darkMode: true, accentColor: "#00B8CC" }} />
</Layout>
<Analytics />
</main>
<APIDataContextProvider>
<main lang="en" className="font-montserrat">
<Layout>
<Topbar />
<Component {...pageProps} />
<MendableChatBubble
anon_key='4a621d80-aa5b-43cc-8600-dd155943ba19' cmdShortcutKey='m' style={{ darkMode: true, accentColor: "#00B8CC" }} />
</Layout>
<Analytics />
</main>
</APIDataContextProvider>
)
}

Expand Down
47 changes: 47 additions & 0 deletions types/DataTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export interface XCallFee {
[x: string]: any;
amount: number;
denomination: string;
price: number;
}

export interface XCallFees {
[key: string]: XCallFee;
}

export interface DataContextType {
loading: boolean;
totalMessages: number;
networkMessages: Record<string, NetworkMessages>;
}

export interface DatabaseDataContextType {
ICONArrayDaily: string[];
ArchwayArrayDaily: string[];
InjectiveArrayDaily: string[];
BNBArrayDaily: string[];
AvalancheArrayDaily: string[];
EthereumArrayDaily: string[];
NeutronArrayDaily: string[];
BaseArrayDaily: string[];
ArbArrayDaily: string[];
}

export interface RelayWallet {
address: string;
balance: number;
denomination: string;
}

export type RelayWallets = Record<string, RelayWallet>;

export interface RelayDataContextType {
relayWallets: RelayWallets;
loading: boolean;
error: string | null;
}

export interface NetworkMessages {
src: number;
dest: number;
}

0 comments on commit c2d09f7

Please sign in to comment.