chore: first project commit
This commit is contained in:
240
src/App.js
Normal file
240
src/App.js
Normal file
@@ -0,0 +1,240 @@
|
||||
import "./App.css";
|
||||
import "animate.css";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
//import namehash from "eth-ens-namehash"; // DO NOT REMOVE COMMENT
|
||||
import { Keccak } from "sha3";
|
||||
//import axiosClient from "axios"; // DO NOT REMOVE COMMENT
|
||||
|
||||
import Card from "@mui/material/Card";
|
||||
import CardActions from "@mui/material/CardActions";
|
||||
import ButtonBase from "@mui/material/ButtonBase";
|
||||
|
||||
import OpenSeaIcon from "./asset/image/opensea-icon.svg";
|
||||
import EnsIcon from "./asset/image/ens-icon.jpeg";
|
||||
|
||||
import { hexToDec } from "./utility";
|
||||
|
||||
//var ensContract = new EnsContract();
|
||||
|
||||
/* vanilla js to adapt height to actual viewport vs therotical */
|
||||
let vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty("--vh", `${vh}px`);
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
let vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty("--vh", `${vh}px`);
|
||||
});
|
||||
/* end vanilla js */
|
||||
|
||||
function App() {
|
||||
const [seconds, setSeconds] = useState("00");
|
||||
const [currentEnsImage, setCurrentEnsImage] = useState("");
|
||||
const ensImages = {};
|
||||
const donationLink =
|
||||
"https://heliowallet.com/ethereum-donation?address=0x2652CBE035CF346A4E085D4C2Fb30F2B5Abf3d3d&amount=0.01&accessWallet=1&qrCode=1ðBalance=1";
|
||||
|
||||
useEffect(() => {
|
||||
setSeconds(getSeconds());
|
||||
setInterval(() => {
|
||||
setSeconds(getSeconds());
|
||||
setCurrentEnsImage(ensImages[getEnsName()]);
|
||||
}, 1000);
|
||||
|
||||
preloadImages();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const preloadImages = async () => {
|
||||
// load all ens names for next 1000 minutes
|
||||
const ensNames = [getEnsName()];
|
||||
for (let i = 1; i <= 1000; i++) {
|
||||
ensNames.push(getEnsName(i));
|
||||
}
|
||||
|
||||
// load images for each ens name
|
||||
await downloadEnsImage(ensNames[0], 0);
|
||||
for (let i = 1; i <= 2; i++) {
|
||||
await downloadEnsImage(ensNames[i], 1000);
|
||||
}
|
||||
for (let i = 3; i <= 1000; i++) {
|
||||
await downloadEnsImage(ensNames[i], 30000);
|
||||
}
|
||||
};
|
||||
|
||||
const downloadEnsImage = async (ensName, timeDelay) => {
|
||||
let resolve = function (ensName) {
|
||||
ensImages[ensName] = getEnsImageUri(ensName);
|
||||
};
|
||||
let reject = function (ensName) {
|
||||
ensImages[ensName] = "";
|
||||
};
|
||||
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
resolve(ensName);
|
||||
};
|
||||
img.onerror = () => {
|
||||
reject(ensName);
|
||||
};
|
||||
img.src = getEnsImageUri(ensName);
|
||||
|
||||
await new Promise((r) => setTimeout(r, timeDelay));
|
||||
};
|
||||
|
||||
const getEnsImageUri = (ensName) => {
|
||||
return `https://metadata.ens.domains/mainnet/0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85/${getLabelHash(
|
||||
ensName
|
||||
)}/image`;
|
||||
};
|
||||
|
||||
const getEnsDetailsUri = (ensName) => {
|
||||
return `https://app.ens.domains/name/${ensName}/details`;
|
||||
};
|
||||
|
||||
const getOpenSeaUri = (ensName) => {
|
||||
const tokenId = hexToDec(getLabelHash(ensName).replace("0x", ""));
|
||||
return `https://opensea.io/assets/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/${tokenId}`;
|
||||
};
|
||||
|
||||
// const getNameHash = (ensName) => { // DO NOT REMOVE COMMENT
|
||||
// return namehash.hash(ensName);
|
||||
// };
|
||||
|
||||
const getLabelHash = (ensName) => {
|
||||
const label = ensName.replace(".eth", "");
|
||||
|
||||
const hasher = new Keccak(256);
|
||||
hasher.update(label);
|
||||
|
||||
return "0x" + hasher.digest("hex");
|
||||
};
|
||||
|
||||
const getEnsName = (minutesToAdd) => {
|
||||
let now = new Date();
|
||||
if (minutesToAdd) {
|
||||
now = new Date(now.getTime() + minutesToAdd * 60000);
|
||||
}
|
||||
|
||||
const hour =
|
||||
now.getHours() < 10 ? `0${now.getHours()}` : now.getHours().toString();
|
||||
const minute =
|
||||
now.getMinutes() < 10
|
||||
? `0${now.getMinutes()}`
|
||||
: now.getMinutes().toString();
|
||||
return hour + "h" + minute + ".eth";
|
||||
};
|
||||
|
||||
const getSeconds = () => {
|
||||
const now = new Date();
|
||||
const seconds =
|
||||
now.getSeconds() < 10
|
||||
? `0${now.getSeconds()}`
|
||||
: now.getSeconds().toString();
|
||||
return seconds;
|
||||
};
|
||||
|
||||
const isEnsImageLoading = () => {
|
||||
return !currentEnsImage;
|
||||
};
|
||||
|
||||
const renderLoadingRipple = () => {
|
||||
return (
|
||||
<div className="lds-grid-container">
|
||||
<div className="lds-grid" style={{ margin: "auto" }}>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderCardContent = () => {
|
||||
return (
|
||||
<div className="card-content">
|
||||
<img src={currentEnsImage} className="card-image" alt="ens avatar" />
|
||||
<div className="card-counter">
|
||||
<code>{seconds}</code>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="App-header container">
|
||||
<div className="col">
|
||||
<div className="row"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="App-body container align-self-center">
|
||||
<div className="col">
|
||||
<div className="row card-row">
|
||||
<Card raised={true} className="card card-size">
|
||||
{isEnsImageLoading()
|
||||
? renderLoadingRipple()
|
||||
: renderCardContent()}
|
||||
<CardActions sx={{ marginBottom: 1, marginTop: 1 }}>
|
||||
<div style={{ margin: "auto" }}>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
marginRight: 2,
|
||||
}}
|
||||
>
|
||||
<a
|
||||
href={getOpenSeaUri(getEnsName())}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
src={OpenSeaIcon}
|
||||
className="icon-size"
|
||||
alt="opensea logo"
|
||||
/>
|
||||
</a>
|
||||
</ButtonBase>
|
||||
<ButtonBase>
|
||||
<a
|
||||
href={getEnsDetailsUri(getEnsName())}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
src={EnsIcon}
|
||||
className="icon-size"
|
||||
style={{ borderRadius: "50%" }}
|
||||
alt="ens logo"
|
||||
/>
|
||||
</a>
|
||||
</ButtonBase>
|
||||
</div>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="row mt-4">
|
||||
<h4>24H Club</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="App-footer container">
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
Donate to the project:
|
||||
<a href={`${donationLink}`} target="_blank" rel="noreferrer">
|
||||
04h59.eth
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user