Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b17606d7b | ||
|
|
99515f2904 | ||
|
|
24844a976d | ||
|
|
825534dc82 | ||
|
|
3b250e7c8b | ||
|
|
afefc1a9f4 | ||
|
|
ba90e063a7 | ||
|
|
2861720455 | ||
|
|
86739dfaad | ||
|
|
7c110287c0 | ||
|
|
0a4ab2bc6a | ||
|
|
d87adfd7d5 | ||
|
|
7364abbbf2 | ||
|
|
8d856fc697 | ||
|
|
46a5527d27 |
@@ -40,9 +40,9 @@ function App() {
|
||||
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
||||
<AnnouncementBanner>
|
||||
<div className="font-alpha calt uppercase text-center text-lg text-white">
|
||||
<span className="pr-4">Mainnet sim 2 coming in March!</span>
|
||||
<span className="pr-4">Mainnet sim 2 is live!</span>
|
||||
<ExternalLink href="https://fairground.wtf/">
|
||||
Learn more
|
||||
Come help stress test the network
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</AnnouncementBanner>
|
||||
|
||||
@@ -2761,7 +2761,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "86666.297",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "66423.0550858143113891258",
|
||||
"locked_amount": "66363.3098645820638555771",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "86666.297",
|
||||
@@ -2827,7 +2827,7 @@
|
||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||
"total_added": "2500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1273.962148962149",
|
||||
"locked_amount": "1270.50582519332525",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2500",
|
||||
@@ -3215,7 +3215,7 @@
|
||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||
"total_added": "37500",
|
||||
"total_removed": "3376.096819125",
|
||||
"locked_amount": "31853.1307550644575",
|
||||
"locked_amount": "31800.99946286065125",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -3370,7 +3370,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "66362.45240571775784592",
|
||||
"locked_amount": "66302.761694482463735865",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -3436,7 +3436,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "62600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "32027.95129375950986",
|
||||
"locked_amount": "31984.79667681380592",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10000",
|
||||
@@ -3629,7 +3629,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "2749.923896499239",
|
||||
"locked_amount": "2746.477042110604",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -3840,7 +3840,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "97499.58",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "8317.5854908512324839724",
|
||||
"locked_amount": "8259.0344635706695729506",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "97499.58",
|
||||
@@ -3873,7 +3873,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "135173.4239508",
|
||||
"total_removed": "98230.390980249184455396",
|
||||
"locked_amount": "11368.703394764008547704146912",
|
||||
"locked_amount": "11288.674248884641168728801336",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "135173.4239508",
|
||||
@@ -3919,7 +3919,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "32499.86",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "3499.0645789825988556482",
|
||||
"locked_amount": "3474.433172927820788048",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "32499.86",
|
||||
@@ -3952,7 +3952,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "10833.29",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1138.9115663398697575689",
|
||||
"locked_amount": "1130.8942826865467812457",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10833.29",
|
||||
@@ -3985,7 +3985,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "22749.93",
|
||||
"total_removed": "4720.860935375",
|
||||
"locked_amount": "4257.5058062827227483966",
|
||||
"locked_amount": "4227.535409358637757934",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "6500",
|
||||
@@ -4137,7 +4137,7 @@
|
||||
"tranche_end": "2023-05-01T00:00:00.000Z",
|
||||
"total_added": "22500",
|
||||
"total_removed": "4913.13257745",
|
||||
"locked_amount": "7675.414364640885075",
|
||||
"locked_amount": "7644.13558931859975",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -4412,7 +4412,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "928642.9598472029154",
|
||||
"locked_amount": "498239.748616742685424742",
|
||||
"locked_amount": "496902.418486694568232482",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -36792,7 +36792,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "615950.831401702010493",
|
||||
"locked_amount": "790122.349697050685985728513",
|
||||
"locked_amount": "788067.33889606523904645906",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -38140,8 +38140,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "581783.18955280438622952",
|
||||
"locked_amount": "8101410.7069629630393713585116348828548256",
|
||||
"total_removed": "582201.49676312452960452",
|
||||
"locked_amount": "8094123.7706069735612090126362156915950257",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -38665,6 +38665,11 @@
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x9e97de704d81fdca889591198e04f05367514f11f4a1eddcbd6363aadb861955"
|
||||
},
|
||||
{
|
||||
"amount": "418.307210320143375",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x1438fbbc780cb382033855d295fa2511deed15cd64506a62ae4e3cfe82b3678e"
|
||||
},
|
||||
{
|
||||
"amount": "535.4042378778335",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -40446,6 +40451,12 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x9e97de704d81fdca889591198e04f05367514f11f4a1eddcbd6363aadb861955"
|
||||
},
|
||||
{
|
||||
"amount": "418.307210320143375",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x1438fbbc780cb382033855d295fa2511deed15cd64506a62ae4e3cfe82b3678e"
|
||||
},
|
||||
{
|
||||
"amount": "535.4042378778335",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -41660,8 +41671,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "259998.8875",
|
||||
"withdrawn_tokens": "126948.853176863592875",
|
||||
"remaining_tokens": "133050.034323136407125"
|
||||
"withdrawn_tokens": "127367.16038718373625",
|
||||
"remaining_tokens": "132631.72711281626375"
|
||||
},
|
||||
{
|
||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||
@@ -43904,8 +43915,8 @@
|
||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "5576533.539587892391509156",
|
||||
"locked_amount": "1757725.410382134892287839107650954",
|
||||
"total_removed": "5577113.077460725181649906",
|
||||
"locked_amount": "1750998.157265811220227145011388614",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129284.449",
|
||||
@@ -44129,6 +44140,11 @@
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0x07f42fed87b386a135f1b3be72112768a812687d6751cfd74e287ed3af3c16b7"
|
||||
},
|
||||
{
|
||||
"amount": "579.53787283279014075",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0x904f971f68cc70ba987688b8b26bcbd4e16ab1964b095de013e364f3ae7530c6"
|
||||
},
|
||||
{
|
||||
"amount": "800.792718381487871",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -47102,6 +47118,12 @@
|
||||
"tranche_id": 3,
|
||||
"tx": "0x07f42fed87b386a135f1b3be72112768a812687d6751cfd74e287ed3af3c16b7"
|
||||
},
|
||||
{
|
||||
"amount": "579.53787283279014075",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x904f971f68cc70ba987688b8b26bcbd4e16ab1964b095de013e364f3ae7530c6"
|
||||
},
|
||||
{
|
||||
"amount": "800.792718381487871",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -49618,8 +49640,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "359123.469575",
|
||||
"withdrawn_tokens": "315430.56325738551649575",
|
||||
"remaining_tokens": "43692.90631761448350425"
|
||||
"withdrawn_tokens": "316010.1011302183066365",
|
||||
"remaining_tokens": "43113.3684447816933635"
|
||||
},
|
||||
{
|
||||
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
|
||||
@@ -50963,7 +50985,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "5778205.3912159303",
|
||||
"total_removed": "3063522.787392713967070295",
|
||||
"locked_amount": "377584.536736576014422212956155541",
|
||||
"locked_amount": "374926.558344229352055062527996886",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "552496.6455",
|
||||
@@ -53013,7 +53035,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "34799.2735287010685",
|
||||
"locked_amount": "125199.40284140018681746501978692",
|
||||
"locked_amount": "124873.77463304148219969237087774",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
.pre-loader {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.pre-loader .loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #000;
|
||||
}
|
||||
.pre-loader .pre-loader-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.pre-loader .pre-loader-wrapper {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(0) {
|
||||
animation-delay: 0ms;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:first-child {
|
||||
animation-delay: -50ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(3) {
|
||||
animation-delay: -0.6s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(4) {
|
||||
animation-delay: 0.4s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(5) {
|
||||
animation-delay: -0.5s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(6) {
|
||||
animation-delay: 0.3s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(7) {
|
||||
animation-delay: -1.4s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(8) {
|
||||
animation-delay: 2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(9) {
|
||||
animation-delay: -0.9s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(10) {
|
||||
animation-delay: 1.5s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(11) {
|
||||
animation-delay: -0.55s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(12) {
|
||||
animation-delay: 1.2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(13) {
|
||||
animation-delay: -0.65s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(14) {
|
||||
animation-delay: 0.7s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(15) {
|
||||
animation-delay: -3.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(16) {
|
||||
animation-delay: 1.6s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item {
|
||||
animation: flickering 0.4s linear infinite alternate;
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
html.dark .pre-loader .loader-item {
|
||||
background: #fff;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
(function () {
|
||||
var storedTheme = window.localStorage.getItem('theme');
|
||||
if (
|
||||
storedTheme === 'dark' ||
|
||||
(!storedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
})();
|
||||
@@ -21,8 +21,10 @@ export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
|
||||
<>
|
||||
<AnnouncementBanner>
|
||||
<div className="font-alpha calt uppercase text-center text-lg text-white">
|
||||
<span className="pr-4">Mainnet sim 2 coming in March!</span>
|
||||
<ExternalLink href="https://fairground.wtf/">Learn more</ExternalLink>
|
||||
<span className="pr-4">Mainnet sim 2 is live!</span>
|
||||
<ExternalLink href="https://fairground.wtf/">
|
||||
Come help stress test the network
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</AnnouncementBanner>
|
||||
<Nav navbarTheme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'} />
|
||||
|
||||
@@ -5,6 +5,7 @@ import { VoteValue } from '@vegaprotocol/types';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useUserVoteQuery } from './__generated__/Vote';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/react-helpers';
|
||||
import type { FinalizedVote } from '@vegaprotocol/governance';
|
||||
|
||||
export enum VoteState {
|
||||
NotCast = 'NotCast',
|
||||
@@ -21,25 +22,14 @@ export type Vote = {
|
||||
party: { id: string };
|
||||
};
|
||||
|
||||
export type Votes = Array<Vote | null>;
|
||||
|
||||
export function getUserVote(pubkey: string, yesVotes?: Votes, noVotes?: Votes) {
|
||||
const yesVote = yesVotes?.find((v) => v && v.party.id === pubkey);
|
||||
const noVote = noVotes?.find((v) => v && v.party.id === pubkey);
|
||||
if (yesVote) {
|
||||
return yesVote;
|
||||
} else if (noVote) {
|
||||
return noVote;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the status of a users given vote in a given proposal and provides
|
||||
* a function to send a vote transaction to your wallet
|
||||
*/
|
||||
export function useUserVote(proposalId: string | null | undefined) {
|
||||
export function useUserVote(
|
||||
proposalId: string | null | undefined,
|
||||
finalizedVote?: FinalizedVote | null
|
||||
) {
|
||||
const { pubKey } = useVegaWallet();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const [timeout, setTimeoutValue] = useState<any>(null);
|
||||
@@ -50,10 +40,27 @@ export function useUserVote(proposalId: string | null | undefined) {
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey || !proposalId,
|
||||
});
|
||||
const [userVote, setUserVote] = useState<FinalizedVote | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
const userVote = removePaginationWrapper(
|
||||
data?.party?.votesConnection?.edges
|
||||
).find(({ proposalId: pId }) => proposalId === pId);
|
||||
useEffect(() => {
|
||||
if (finalizedVote?.vote.value) {
|
||||
setUserVote(finalizedVote);
|
||||
} else if (data?.party?.votesConnection?.edges) {
|
||||
// This sets the vote (if any) when the user first loads the page
|
||||
setUserVote(
|
||||
removePaginationWrapper(data?.party?.votesConnection?.edges).find(
|
||||
({ proposalId: pId }) => proposalId === pId
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [
|
||||
finalizedVote?.vote.value,
|
||||
data?.party?.votesConnection?.edges,
|
||||
finalizedVote,
|
||||
proposalId,
|
||||
]);
|
||||
|
||||
// If user vote changes update the vote state
|
||||
useEffect(() => {
|
||||
|
||||
@@ -22,6 +22,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance={null}
|
||||
spamProtectionMinTokens={null}
|
||||
currentStakeAvailable={new BigNumber(1)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -43,6 +45,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance={null}
|
||||
spamProtectionMinTokens={null}
|
||||
currentStakeAvailable={new BigNumber(1)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -75,6 +79,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance={null}
|
||||
spamProtectionMinTokens={null}
|
||||
currentStakeAvailable={new BigNumber(1)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -97,6 +103,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance={null}
|
||||
spamProtectionMinTokens={null}
|
||||
currentStakeAvailable={new BigNumber(0)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -120,6 +128,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance="2000000000000000000"
|
||||
spamProtectionMinTokens="1000000000000000000"
|
||||
currentStakeAvailable={new BigNumber(1)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -145,6 +155,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance="2000000000000000000"
|
||||
spamProtectionMinTokens="1000000000000000000"
|
||||
currentStakeAvailable={new BigNumber(10)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
@@ -167,6 +179,8 @@ describe('Vote buttons', () => {
|
||||
minVoterBalance="2000000000000000000"
|
||||
spamProtectionMinTokens="1000000000000000000"
|
||||
currentStakeAvailable={new BigNumber(10)}
|
||||
dialog={() => <div>Blah</div>}
|
||||
submit={() => Promise.resolve()}
|
||||
/>
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { AsyncRenderer, Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { addDecimal, toBigNum } from '@vegaprotocol/react-helpers';
|
||||
import { useVoteSubmit } from '@vegaprotocol/governance';
|
||||
import { ProposalState, VoteValue } from '@vegaprotocol/types';
|
||||
import {
|
||||
AppStateActionType,
|
||||
@@ -16,6 +15,7 @@ import { VoteState } from './use-user-vote';
|
||||
import { ProposalMinRequirements, ProposalUserAction } from '../shared';
|
||||
import { VoteTransactionDialog } from './vote-transaction-dialog';
|
||||
import { useVoteButtonsQuery } from './__generated__/Stake';
|
||||
import type { DialogProps } from '@vegaprotocol/wallet';
|
||||
|
||||
interface VoteButtonsContainerProps {
|
||||
voteState: VoteState | null;
|
||||
@@ -24,6 +24,8 @@ interface VoteButtonsContainerProps {
|
||||
proposalState: ProposalState;
|
||||
minVoterBalance: string | null;
|
||||
spamProtectionMinTokens: string | null;
|
||||
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
|
||||
dialog: (props: DialogProps) => JSX.Element;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -62,11 +64,12 @@ export const VoteButtons = ({
|
||||
currentStakeAvailable,
|
||||
minVoterBalance,
|
||||
spamProtectionMinTokens,
|
||||
submit,
|
||||
dialog: Dialog,
|
||||
}: VoteButtonsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { appDispatch } = useAppState();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { submit, Dialog } = useVoteSubmit();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { VoteProgress } from '@vegaprotocol/governance';
|
||||
import { useVoteSubmit, VoteProgress } from '@vegaprotocol/governance';
|
||||
import { formatNumber } from '../../../../lib/format-number';
|
||||
import { ConnectToVega } from '../../../../components/connect-to-vega';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
@@ -44,7 +44,8 @@ export const VoteDetails = ({
|
||||
} = useVoteInformation({ proposal });
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { voteState, voteDatetime } = useUserVote(proposal?.id);
|
||||
const { submit, Dialog, finalizedVote } = useVoteSubmit();
|
||||
const { voteState, voteDatetime } = useUserVote(proposal?.id, finalizedVote);
|
||||
const defaultDecimals = 2;
|
||||
const daysLeft = t('daysLeft', {
|
||||
daysLeft: formatDistanceToNow(new Date(proposal?.terms.closingDatetime)),
|
||||
@@ -188,6 +189,8 @@ export const VoteDetails = ({
|
||||
minVoterBalance={minVoterBalance}
|
||||
spamProtectionMinTokens={spamProtectionMinTokens}
|
||||
className="flex"
|
||||
submit={submit}
|
||||
dialog={Dialog}
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
|
||||
@@ -125,19 +125,12 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
validateMarketDataRow(1, 'Long', '0.008508132993273576');
|
||||
});
|
||||
|
||||
it('price monitoring trigger displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Price monitoring trigger 1').click();
|
||||
|
||||
validateMarketDataRow(0, 'Horizon Secs', '43,200');
|
||||
validateMarketDataRow(1, 'Probability', '1');
|
||||
validateMarketDataRow(2, 'Auction Extension Secs', '600');
|
||||
});
|
||||
|
||||
it('price monitoring bound displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Price monitoring bound 1').click();
|
||||
|
||||
validateMarketDataRow(0, 'Min Valid Price', '6.54701 ');
|
||||
validateMarketDataRow(1, 'Max Valid Price', '7.97323 ');
|
||||
it('price monitoring bounds displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Price monitoring bounds 1').click();
|
||||
cy.get('p.col-span-1').contains('99.99999% probability price bounds');
|
||||
cy.get('p.col-span-1').contains('Within 43,200 seconds');
|
||||
validateMarketDataRow(0, 'Highest Price', '7.97323 ');
|
||||
validateMarketDataRow(1, 'Lowest Price', '6.54701 ');
|
||||
validateMarketDataRow(2, 'Reference Price', '7.22625 ');
|
||||
});
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export const Banner = () => {
|
||||
<Icon name="cross" className="w-6 h-6" ariaLabel="dismiss" />
|
||||
</button>
|
||||
<div>
|
||||
<span className="pr-4">Mainnet sim 2 coming in March!</span>
|
||||
<span className="pr-4">Mainnet sim 2 is live!</span>
|
||||
<ExternalLink href="https://fairground.wtf/">Learn more</ExternalLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,11 +9,15 @@ export const Preloader = () => {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
html.dark body{
|
||||
background: #000;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div className="pre-loader">
|
||||
<Loader forceTheme="light" preloader />
|
||||
<Loader />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
useInitializeEnv,
|
||||
} from '@vegaprotocol/environment';
|
||||
import './styles.css';
|
||||
import './gen-styles.scss';
|
||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
||||
import { Footer } from '../components/footer';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
@@ -19,12 +19,13 @@ export default function Document() {
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<script src="/theme-setter.js" type="text/javascript" async />
|
||||
{['1', 'true'].includes(process.env['NX_USE_ENV_OVERRIDES'] || '') ? (
|
||||
/* eslint-disable-next-line @next/next/no-sync-scripts */
|
||||
<script src="/assets/env-config.js" type="text/javascript" />
|
||||
) : null}
|
||||
</Head>
|
||||
<body className="font-alpha">
|
||||
<body className="font-alpha dark:bg-black dark:text-white">
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
|
||||
@@ -4,17 +4,10 @@
|
||||
min-height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
@for $i from 0 through 16 {
|
||||
.loader-item:nth-child(#{$i}) {
|
||||
@if $i % 2 == 0 {
|
||||
animation-delay: #{$i * 50 * random(5)}ms;
|
||||
animation-direction: reverse;
|
||||
} @else {
|
||||
animation-delay: #{$i * -50 * random(5)}ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
||||
.loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: black;
|
||||
}
|
||||
.pre-loader-center {
|
||||
align-items: center;
|
||||
@@ -27,24 +20,39 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@for $i from 0 through 16 {
|
||||
.loader-item:nth-child(#{$i}) {
|
||||
@if $i % 2 == 0 {
|
||||
animation-delay: #{$i * 50 * random(5)}ms;
|
||||
animation-direction: reverse;
|
||||
} @else {
|
||||
animation-delay: #{$i * -50 * random(5)}ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
.loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: black;
|
||||
animation: flickering 0.4s steps(2, jump-none) alternate infinite;
|
||||
animation: flickering 0.4s linear alternate infinite;
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
html.dark {
|
||||
.pre-loader {
|
||||
.loader-item {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,73 +5,10 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(0) {
|
||||
animation-delay: 0ms;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:first-child {
|
||||
animation-delay: -0.2s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(2) {
|
||||
animation-delay: 0.1s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(3) {
|
||||
animation-delay: -0.15s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(4) {
|
||||
animation-delay: 1s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(5) {
|
||||
animation-delay: -0.25s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(6) {
|
||||
animation-delay: 0.3s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(7) {
|
||||
animation-delay: -1.05s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(8) {
|
||||
animation-delay: 0.8s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(9) {
|
||||
animation-delay: -0.9s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(10) {
|
||||
animation-delay: 0.5s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(11) {
|
||||
animation-delay: -2.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(12) {
|
||||
animation-delay: 2.4s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(13) {
|
||||
animation-delay: -0.65s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(14) {
|
||||
animation-delay: 0.7s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(15) {
|
||||
animation-delay: -3s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(16) {
|
||||
animation-delay: 2.4s;
|
||||
animation-direction: reverse;
|
||||
.pre-loader .loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #000;
|
||||
}
|
||||
.pre-loader .pre-loader-center {
|
||||
align-items: center;
|
||||
@@ -84,11 +21,81 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
.pre-loader .loader-item {
|
||||
background: #000;
|
||||
}
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(0) {
|
||||
animation-delay: 0ms;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:first-child {
|
||||
animation-delay: -50ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(3) {
|
||||
animation-delay: -0.6s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(4) {
|
||||
animation-delay: 0.4s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(5) {
|
||||
animation-delay: -0.5s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(6) {
|
||||
animation-delay: 0.3s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(7) {
|
||||
animation-delay: -1.4s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(8) {
|
||||
animation-delay: 2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(9) {
|
||||
animation-delay: -0.9s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(10) {
|
||||
animation-delay: 1.5s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(11) {
|
||||
animation-delay: -0.55s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(12) {
|
||||
animation-delay: 1.2s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(13) {
|
||||
animation-delay: -0.65s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(14) {
|
||||
animation-delay: 0.7s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(15) {
|
||||
animation-delay: -3.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(16) {
|
||||
animation-delay: 1.6s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #000;
|
||||
animation: flickering 0.4s steps(2, jump-none) infinite alternate;
|
||||
animation: flickering 0.4s linear infinite alternate;
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
@@ -104,3 +111,6 @@
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
html.dark .pre-loader .loader-item {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
(function () {
|
||||
var storedTheme = window.localStorage.getItem('theme');
|
||||
if (
|
||||
storedTheme === 'dark' ||
|
||||
(!storedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
})();
|
||||
@@ -68,6 +68,32 @@ describe('AccountsTable', () => {
|
||||
'1,256.00',
|
||||
'Breakdown',
|
||||
'Deposit',
|
||||
'Withdraw',
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
});
|
||||
const rows = await screen.findAllByRole('row');
|
||||
expect(rows.length).toBe(6);
|
||||
});
|
||||
|
||||
it('should apply correct formatting in view as user mode', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<AccountTable
|
||||
rowData={singleRowData}
|
||||
onClickAsset={() => null}
|
||||
isReadOnly={true}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const cells = await screen.findAllByRole('gridcell');
|
||||
const expectedValues = [
|
||||
'tBTC',
|
||||
'1,256.00',
|
||||
'1,256.00',
|
||||
'1,256.00',
|
||||
'Breakdown',
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
|
||||
@@ -154,7 +154,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
}
|
||||
maxWidth={300}
|
||||
/>
|
||||
{!props.isReadOnly && (
|
||||
{
|
||||
<AgGridColumn
|
||||
colId="breakdown"
|
||||
headerName=""
|
||||
@@ -193,29 +193,33 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
{!props.isReadOnly && (
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
)}
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
{!props.isReadOnly && (
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
}
|
||||
</AgGrid>
|
||||
<Dialog size="medium" open={openBreakdown} onChange={setOpenBreakdown}>
|
||||
<div className="h-[35vh] w-full m-auto flex flex-col">
|
||||
|
||||
@@ -267,24 +267,24 @@ const FeesBreakdownTooltip = ({
|
||||
data-testid="fee-breakdown-tooltip"
|
||||
className="max-w-sm border border-neutral-600 bg-neutral-100 dark:bg-neutral-800 px-4 py-2 z-20 rounded text-sm break-word text-black dark:text-white"
|
||||
>
|
||||
<dl className="grid grid-cols-2 gap-x-2">
|
||||
<dt>{t('Infrastructure fee')}</dt>
|
||||
<dd className="text-right">
|
||||
<dl className="grid grid-cols-3 gap-x-1">
|
||||
<dt className="col-span-1">{t('Infrastructure fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.infrastructureFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
</dd>
|
||||
<dt>{t('Liquidity fee')}</dt>
|
||||
<dd className="text-right">
|
||||
<dt className="col-span-1">{t('Liquidity fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.liquidityFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
</dd>
|
||||
<dt>{t('Maker fee')}</dt>
|
||||
<dd className="text-right">
|
||||
<dt className="col-span-1">{t('Maker fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.makerFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
</dd>
|
||||
<dt>{t('Total fees')}</dt>
|
||||
<dd className="text-right">{valueFormatted}</dd>
|
||||
<dt className="col-span-1">{t('Total fees')}</dt>
|
||||
<dd className="text-right col-span-2">{valueFormatted}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,8 @@ import { useVoteEvent } from './use-vote-event';
|
||||
import type { VoteValue } from '@vegaprotocol/types';
|
||||
import type { VoteEventFieldsFragment } from './__generated__/VoteSubsciption';
|
||||
|
||||
export type FinalizedVote = VoteEventFieldsFragment;
|
||||
|
||||
export const useVoteSubmit = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { send, transaction, setComplete, Dialog } = useVegaTransaction();
|
||||
|
||||
@@ -317,8 +317,10 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
<div className="text-xs">
|
||||
<div className="grid grid-cols-2 text-xs mb-4">
|
||||
<p className="col-span-1">
|
||||
{t('%s% probability of trading', [
|
||||
formatNumber(trigger.probability * 100),
|
||||
{t('%s probability price bounds', [
|
||||
formatNumberPercentage(
|
||||
new BigNumber(trigger.probability).times(100)
|
||||
),
|
||||
])}
|
||||
</p>
|
||||
<p className="col-span-1 text-right">
|
||||
@@ -338,6 +340,11 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-4">
|
||||
{t('Results in %s seconds auction if breached', [
|
||||
trigger.auctionExtensionSecs.toString(),
|
||||
])}
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -166,7 +166,7 @@ export const OrderListManager = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{hasActiveOrder && (
|
||||
{!isReadOnly && hasActiveOrder && (
|
||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||
<Button
|
||||
size="sm"
|
||||
|
||||
@@ -73,7 +73,7 @@ export const DropdownMenuContent = forwardRef<
|
||||
<DropdownMenuPrimitive.Content
|
||||
{...contentProps}
|
||||
ref={forwardedRef}
|
||||
className="min-w-[290px] bg-neutral-200 dark:bg-white p-2 rounded"
|
||||
className="min-w-[290px] bg-neutral-200 dark:bg-white p-2 rounded text-black"
|
||||
align="start"
|
||||
sideOffset={10}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
@for $i from 0 through 16 {
|
||||
.loader-item:nth-child(#{$i}) {
|
||||
@if $i % 2 == 0 {
|
||||
animation-delay: #{$i * 50 * random(5)}ms;
|
||||
animation-direction: reverse;
|
||||
} @else {
|
||||
animation-delay: #{$i * -50 * random(5)}ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
.loader-item {
|
||||
animation: flickering 0.4s linear alternate infinite;
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import styles from './loader.module.scss';
|
||||
|
||||
const pseudoRandom = (seed: number) => {
|
||||
let value = seed;
|
||||
@@ -12,27 +13,10 @@ const pseudoRandom = (seed: number) => {
|
||||
export interface LoaderProps {
|
||||
size?: 'small' | 'large';
|
||||
forceTheme?: 'dark' | 'light';
|
||||
preloader?: boolean;
|
||||
}
|
||||
|
||||
export const Loader = ({
|
||||
size = 'large',
|
||||
forceTheme,
|
||||
preloader,
|
||||
}: LoaderProps) => {
|
||||
const [, forceRender] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = preloader
|
||||
? undefined
|
||||
: setInterval(() => {
|
||||
forceRender((x) => !x);
|
||||
}, 100);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [preloader]);
|
||||
|
||||
const itemClasses = classNames('loader-item', {
|
||||
export const Loader = ({ size = 'large', forceTheme }: LoaderProps) => {
|
||||
const itemClasses = classNames('loader-item', styles['loader-item'], {
|
||||
'dark:bg-white bg-black': !forceTheme,
|
||||
'bg-white': forceTheme === 'dark',
|
||||
'bg-black': forceTheme === 'light',
|
||||
|
||||
Reference in New Issue
Block a user