react-icons/fi#FiCheckCircle TypeScript Examples
The following examples show how to use
react-icons/fi#FiCheckCircle.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Transaction.tsx From dxvote with GNU Affero General Public License v3.0 | 6 votes |
Transaction: React.FC<TransactionProps> = ({ transaction }) => {
const { chainId } = useWeb3React();
const networkName = getChains().find(chain => chain.id === chainId).name;
return (
<TransactionContainer>
<Link
href={getBlockchainLink(transaction.hash, networkName)}
target="_blank"
>
{transaction.summary} <FiArrowUpRight />
</Link>
<Icon>
{!transaction.receipt ? (
<PendingCircle height="16px" width="16px" color="#000" />
) : transaction.receipt?.status === 1 ? (
<FiCheckCircle />
) : (
<FiXCircle />
)}
</Icon>
</TransactionContainer>
);
}
Example #2
Source File: Copy.tsx From dxvote with GNU Affero General Public License v3.0 | 6 votes |
export default function CopyHelper({ toCopy, children = null }) {
const [isCopied, setCopied] = useCopyClipboard();
return (
<CopyIcon onClick={() => setCopied(toCopy)}>
<TransactionStatusText>
{children} {isCopied ? <FiCheckCircle /> : <FiCopy />}
</TransactionStatusText>
</CopyIcon>
);
}
Example #3
Source File: Timeline.tsx From portfolio with MIT License | 6 votes |
TimelineItem: React.FC<TimelineItemProps> = ({
icon = FiCheckCircle,
boxProps = {},
skipTrail = false,
children,
...props
}) => {
const color = useColorModeValue("gray.700", "gray.500");
return (
<Flex minH={20} {...props}>
<Flex flexDir="column" alignItems="center" mr={4} pos="relative">
<Circle
size={12}
bg={useColorModeValue("gray.600", "gray.500")}
opacity={useColorModeValue(0.07, 0.15)}
sx={{}}
/>
<Box
as={icon}
size="1.25rem"
color={color}
pos="absolute"
left="0.875rem"
top="0.875rem"
/>
{!skipTrail && <Box w="1px" flex={1} bg={color} my={1} />}
</Flex>
<Box pt={3} {...boxProps}>
{children}
</Box>
</Flex>
);
}
Example #4
Source File: index.tsx From GoBarber with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, error: <FiAlertCircle size={24} />, success: <FiCheckCircle size={24} />, }
Example #5
Source File: index.tsx From gobarber-project with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, error: <FiAlertCircle size={24} />, success: <FiCheckCircle size={24} />, }
Example #6
Source File: index.tsx From vagasExplorer with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, error: <FiAlertCircle size={24} />, sucess: <FiCheckCircle size={24} />, }
Example #7
Source File: index.tsx From rocketredis with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, success: <FiCheckCircle size={24} />, error: <FiAlertCircle size={24} /> }
Example #8
Source File: index.tsx From front-entenda-direito with GNU General Public License v3.0 | 5 votes |
icons = { info: <FiInfo size={24} />, success: <FiCheckCircle size={24} />, error: <FiAlertCircle size={24} />, }
Example #9
Source File: index.tsx From front-entenda-direito with GNU General Public License v3.0 | 5 votes |
icons = { info: <FiInfo size={24} />, success: <FiCheckCircle size={24} />, error: <FiAlertCircle size={24} />, }
Example #10
Source File: index.tsx From ecoleta with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, error: <FiAlertCircle size={24} />, success: <FiCheckCircle size={24} />, }
Example #11
Source File: story-timeline.tsx From portfolio with MIT License | 5 votes |
StoryTimeline: React.FC<StoryTimelineProps> = ({
icon = FiCheckCircle,
boxProps = {},
index,
year,
skipTrail = false,
children,
...props
}) => {
const [isOpen, setIsOpen] = React.useState(true);
const open = () => setIsOpen(!isOpen);
const close = () => setIsOpen(false);
const color = useColorModeValue("gray.700", "gray.200");
let place = index % 2 === 0 ? "right" : "left";
return (
<Flex minH={20} {...props}>
<Flex flexDir="column" alignItems={"center"} minHeight={"8rem"} mr={4}>
<Popover
returnFocusOnClose={false}
isOpen={isOpen}
onClose={close}
placement={place}
closeOnBlur={false}
// variant="responsive"
width={["9.3rem", "13rem", "15rem", "100%"]}
>
<PopoverTrigger>
<Box onClick={open} position="relative">
<Circle
size={12}
bg={useColorModeValue("gray.600", "gray.500")}
opacity={useColorModeValue(0.07, 0.15)}
sx={{}}
/>
{year ? (
<Box
fontSize={15}
fontWeight={"bold"}
color={color}
pos="absolute"
left="0.5rem"
top="0.875rem"
>
{year}
</Box>
) : (
<Box
as={icon}
size="1.25rem"
color={color}
pos="absolute"
left="0.875rem"
top="0.875rem"
/>
)}
</Box>
</PopoverTrigger>
<Box fontSize={15}>
{!year && (
<PopoverContent padding={["0.2rem", "0.2rem", "0.7rem"]}>
<PopoverArrow />
{/* <PopoverCloseButton /> */}
<PopoverBody>
<Box overflow="scroll">{children}</Box>
</PopoverBody>
</PopoverContent>
)}
</Box>
</Popover>
{!skipTrail && <Box w="1px" flex={1} bg={color} />}
</Flex>
</Flex>
);
}
Example #12
Source File: index.tsx From gobarber-web with MIT License | 5 votes |
icons = { info: <FiInfo size={24} />, error: <FiAlertCircle size={24} />, success: <FiCheckCircle size={24} />, }
Example #13
Source File: index.tsx From dxvote with GNU Affero General Public License v3.0 | 5 votes |
IconMap = { [ResultState.SUCCESS]: FiCheckCircle, [ResultState.ERROR]: FiXOctagon, [ResultState.INFO]: FiHelpCircle, [ResultState.WARNING]: FiAlertTriangle, }
Example #14
Source File: WalletInfoBox.tsx From dxvote with GNU Affero General Public License v3.0 | 5 votes |
export default function WalletInfoBox({ openOptions }: Props) {
const { account, connector, chainId } = useWeb3React();
const { ensName, imageUrl } = useENSAvatar(account, MAINNET_ID);
const [isCopied, copyAddress] = useClipboard(account, 3000);
const networkName = NETWORK_NAMES[chainId];
return (
<Wrapper>
<ConnectionStatusRow>
<ConnectionStatusText>
<LiveIndicator />
Connected to {findWalletType(connector)}
</ConnectionStatusText>
{isDesktop && (
<div>
<Button onClick={openOptions}>Change</Button>
</div>
)}
</ConnectionStatusRow>
<WalletAddressRow>
<IconHolder>
<Avatar src={imageUrl} defaultSeed={account} size={24} />
</IconHolder>
<AddressText>{ensName || shortenAddress(account)}</AddressText>
</WalletAddressRow>
<Row>
<ConnectionActionButton
variant="minimal"
onClick={copyAddress}
iconLeft
>
{isCopied ? <FiCheckCircle /> : <FiCopy />}
{isCopied ? 'Copied Address!' : 'Copy Address'}
</ConnectionActionButton>
<ExternalLink
href={getBlockchainLink(account, networkName, 'address')}
target="_blank"
>
<ConnectionActionButton variant="minimal" iconLeft>
<FiExternalLink />
View on Explorer
</ConnectionActionButton>
</ExternalLink>
</Row>
{isMobile && (
<CenteredButton onClick={openOptions}>Change Connection</CenteredButton>
)}
</Wrapper>
);
}
Example #15
Source File: index.tsx From dxvote with GNU Affero General Public License v3.0 | 4 votes |
ProposalsPage = observer(() => {
const {
context: { daoStore, configStore, providerStore },
} = useContext();
const { getRep } = useRep();
const votingMachines = configStore.getNetworkContracts().votingMachines;
const networkName = configStore.getActiveChainName();
const { account } = providerStore.getActiveWeb3React();
const userEvents = daoStore.getUserEvents(account);
const {
proposals,
loading,
titleFilter,
setTitleFilter,
stateFilter,
setStateFilter,
schemesFilter,
setSchemesFilter,
} = useFilteredProposals();
const allProposals = daoStore.getAllProposals();
const activeProposalsCount = allProposals.filter(
proposal =>
proposal.stateInVotingMachine > VotingMachineProposalState.Executed
).length;
const history = useHistory();
return (
<ProposalsWrapper>
<SidebarWrapper>
<ProposalTableHeaderActions>
<NewProposalButton>
<LinkButton route={`/${networkName}/create/type`} width="200px">
+ New Proposal
</LinkButton>
</NewProposalButton>
<TitleSearch value={titleFilter} onFilter={setTitleFilter} />
<StatusSearch value={stateFilter} onFilter={setStateFilter} />
<SchemeSearch value={schemesFilter} onFilter={setSchemesFilter} />
<strong style={{ alignSelf: 'center' }}>
{allProposals.length} Total Proposals
</strong>
<strong style={{ alignSelf: 'center' }}>
{activeProposalsCount} Active Proposals
</strong>
</ProposalTableHeaderActions>
<FooterWrap>
<ProposalsExporter />
<Footer />
</FooterWrap>
</SidebarWrapper>
{loading && (
<LoadingBox>
<div className="loader">
<PulsingIcon size={80} inactive={false} />
</div>
</LoadingBox>
)}
{!loading && (
<TableProposal>
<TableHeader>
<TableRow>
<HeaderCell>Title</HeaderCell>
<HeaderCell>Scheme</HeaderCell>
<HeaderCell>Status</HeaderCell>
<HeaderCell>Stakes</HeaderCell>
<HeaderCell>Votes</HeaderCell>
</TableRow>
</TableHeader>
<TableBody>
{proposals.map((proposal, i) => {
const positiveStake = formatNumberValue(
normalizeBalance(proposal.positiveStakes, 18),
1
);
const negativeStake = formatNumberValue(
normalizeBalance(proposal.negativeStakes, 18),
1
);
const repAtCreation = getRep(
proposal.creationEvent.blockNumber
).totalSupply;
const positiveVotesPercentage = formatPercentage(
proposal.positiveVotes.div(repAtCreation),
2
);
const negativeVotesPercentage = formatPercentage(
proposal.negativeVotes.div(repAtCreation),
2
);
const timeToBoost = timeToTimestamp(proposal.boostTime);
const timeToFinish = timeToTimestamp(proposal.finishTime);
const votingMachineTokenName =
votingMachines[
daoStore.getVotingMachineOfProposal(proposal.id).address
].type == 'DXDVotingMachine'
? 'DXD'
: 'GEN';
const voted =
userEvents.votes.findIndex(
event => event.proposalId === proposal.id
) > -1;
const staked =
userEvents.stakes.findIndex(
event => event.proposalId === proposal.id
) > -1;
const created =
userEvents.newProposal.findIndex(
event => event.proposalId === proposal.id
) > -1;
const proposerVotedDown =
daoStore
.getVotesOfProposal(proposal.id)
.findIndex(
vote =>
vote.voter === proposal.proposer && isVoteNo(vote.vote)
) > -1;
return (
<StyledTableRow
onClick={() =>
history.push(`/${networkName}/proposal/${proposal.id}`)
}
key={`row-${i}`}
>
<DataCell
weight="800"
wrapText="true"
fontSize="inherit"
align="left"
>
<Link
to={`/${networkName}/proposal/${proposal.id}`}
component={UnstyledAnchor}
>
{created && (
<FiFeather
style={{ minWidth: '15px', margin: '0px 2px' }}
title="You created"
/>
)}
{voted && (
<FiCheckCircle
style={{ minWidth: '15px', margin: '0px 2px' }}
title="You voted"
/>
)}
{staked && (
<FiCheckSquare
style={{ minWidth: '15px', margin: '0px 2px' }}
title="You staked"
/>
)}
{proposerVotedDown && (
<FiAlertTriangle
style={{ minWidth: '15px', margin: '0px 2px' }}
title="The proposer downvoted this proposal. It may be incorrect."
/>
)}
{proposal.title.length > 0 ? proposal.title : proposal.id}
</Link>
</DataCell>
<DataCell>
{daoStore.daoCache.schemes[proposal.scheme].name}
</DataCell>
<DataCell>
<span>
{proposal.status} <br />
{timeToBoost !== '' ? (
<small>
Boost {timeToBoost} <br />
</small>
) : (
<span></span>
)}
{timeToFinish !== '' ? (
<small>Finish {timeToFinish} </small>
) : (
<span></span>
)}
{proposal.pendingAction === PendingAction.Execute ||
proposal.pendingAction === PendingAction.Finish ? (
<small> Pending Finish Execution </small>
) : (
<span></span>
)}
</span>
</DataCell>
<DataCell>
<Positive>
{positiveStake.toString()} {votingMachineTokenName}{' '}
</Positive>
<Separator>|</Separator>
<Negative>
{negativeStake.toString()} {votingMachineTokenName}
</Negative>
</DataCell>
<DataCell>
<Positive>{positiveVotesPercentage} </Positive>
<Separator>|</Separator>
<Negative>{negativeVotesPercentage}</Negative>
</DataCell>
</StyledTableRow>
);
})}
</TableBody>
</TableProposal>
)}
</ProposalsWrapper>
);
})
Example #16
Source File: Configuration.tsx From dxvote with GNU Affero General Public License v3.0 | 4 votes |
ConfigPage = observer(() => {
const {
context: {
configStore,
pinataService,
etherscanService,
infuraService,
poktService,
alchemyService,
customRpcService,
},
} = useContext();
const networkName = configStore.getActiveChainName();
const [etherscanApiStatus, setEtherscanApiStatus] = React.useState(
etherscanService.auth
);
const [pinataKeyStatus, setPinataKeyStatus] = React.useState(
pinataService.auth
);
const [infuraKeyStatus, setInfuraKeyStatus] = React.useState(
infuraService.auth
);
const [poktStatus, setPoktStatus] = React.useState(poktService.auth);
const [alchemyKeyStatus, setAlchemyKeyStatus] = React.useState(
alchemyService.auth
);
const [customRpcUrlStatus, setCustomRpcUrlStatus] = React.useState(
customRpcService.auth
);
const [localConfig, setLocalConfig] = React.useState(
configStore.getLocalConfig()
);
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
function onApiKeyValueChange(value, key) {
localConfig[key] = value;
setLocalConfig(localConfig);
forceUpdate();
}
function saveConfig() {
configStore.setLocalConfig(localConfig);
}
async function testApis() {
await pinataService.isAuthenticated();
await etherscanService.isAuthenticated(networkName);
await infuraService.isAuthenticated();
await poktService.isAuthenticated();
await alchemyService.isAuthenticated();
await customRpcService.isAuthenticated();
setPinataKeyStatus(pinataService.auth);
setEtherscanApiStatus(etherscanService.auth);
setInfuraKeyStatus(infuraService.auth);
setPoktStatus(poktService.auth);
setAlchemyKeyStatus(alchemyService.auth);
setCustomRpcUrlStatus(customRpcService.auth);
}
async function pinDXvoteHashes() {
pinataService.updatePinList();
}
async function clearCache() {
localStorage.clear();
caches.delete(`dxvote-cache`);
window.location.reload();
}
return (
<Box centered>
<h2>
API Keys <Question question="8" />
</h2>
<FormContainer>
<Row>
<FormLabel>Etherscan:</FormLabel>
<InputBox
type="text"
serviceName="etherscan"
onChange={event =>
onApiKeyValueChange(event.target.value, 'etherscan')
}
value={localConfig.etherscan}
></InputBox>
<FormLabel>
{etherscanApiStatus ? <FiCheckCircle /> : <FiX />}
</FormLabel>
</Row>
<Row>
<FormLabel>Pinata:</FormLabel>
<InputBox
type="text"
serviceName="pinata"
onChange={event =>
onApiKeyValueChange(event.target.value, 'pinata')
}
value={localConfig.pinata}
></InputBox>
<FormLabel>{pinataKeyStatus ? <FiCheckCircle /> : <FiX />}</FormLabel>
</Row>
<Row>
<FormLabel>RPC:</FormLabel>
<Dropdown
onChange={event =>
onApiKeyValueChange(event.target.value, 'rpcType')
}
value={localConfig.rpcType}
>
<option value="">Default</option>
<option value="pokt">Pokt</option>
<option value="infura">Infura</option>
<option value="alchemy">Alchemy</option>
<option value="custom">Custom</option>
</Dropdown>
</Row>
{localConfig.rpcType === 'pokt' && (
<Row>
<FormLabel>Pokt:</FormLabel>
<InputBox
type="text"
serviceName="pokt"
onChange={event =>
onApiKeyValueChange(event.target.value, 'pokt')
}
value={localConfig.pokt}
></InputBox>
<FormLabel>{poktStatus ? <FiCheckCircle /> : <FiX />}</FormLabel>
</Row>
)}
{localConfig.rpcType === 'infura' && (
<Row>
<FormLabel>Infura:</FormLabel>
<InputBox
type="text"
serviceName="infura"
onChange={event =>
onApiKeyValueChange(event.target.value, 'infura')
}
value={localConfig.infura}
></InputBox>
<FormLabel>
{infuraKeyStatus ? <FiCheckCircle /> : <FiX />}
</FormLabel>
</Row>
)}
{localConfig.rpcType === 'alchemy' && (
<Row>
<FormLabel>Alchemy:</FormLabel>
<InputBox
type="text"
serviceName="alchemy"
onChange={event =>
onApiKeyValueChange(event.target.value, 'alchemy')
}
value={localConfig.alchemy}
></InputBox>
<FormLabel>
{alchemyKeyStatus ? <FiCheckCircle /> : <FiX />}
</FormLabel>
</Row>
)}
{localConfig.rpcType === 'custom' && (
<Row>
<FormLabel>RPC URL:</FormLabel>
<InputBox
type="text"
serviceName="customRpcUrl"
onChange={event =>
onApiKeyValueChange(event.target.value, 'customRpcUrl')
}
value={localConfig.customRpcUrl}
></InputBox>
<FormLabel>
{customRpcUrlStatus ? <FiCheckCircle /> : <FiX />}
</FormLabel>
</Row>
)}
</FormContainer>
<Row>
<FormLabel>Pin DXdao hashes on start</FormLabel>
<InputBox
type="checkbox"
checked={localConfig.pinOnStart}
onChange={event =>
onApiKeyValueChange(event.target.checked, 'pinOnStart')
}
></InputBox>
</Row>
<Row>
<Button onClick={saveConfig}>Save</Button>
<Button onClick={testApis}>Test Apis</Button>
<Button onClick={clearCache}>Clear Cache</Button>
<Button onClick={pinDXvoteHashes}>Pin DXVote Hashes</Button>
</Row>
</Box>
);
})
Example #17
Source File: Cache.tsx From dxvote with GNU Affero General Public License v3.0 | 4 votes |
CachePage = observer(() => {
// Set html title to cache to differentiate from dxvote dapp
document.title = 'Cache';
const {
context: { cacheService, configStore, notificationStore, ipfsService },
} = useContext();
const [updateProposalTitles, setUpdateProposalTitles] = React.useState(false);
const [buildingCacheState, setBuildingCacheState] = React.useState(0);
const [updatedCacheHash, setUpdatedCacheHash] = React.useState({
proposalTitles: {},
configHashes: {},
configs: {},
caches: {},
});
const [resetCache, setResetCache] = React.useState({
mainnet: false,
rinkeby: false,
xdai: false,
arbitrum: false,
arbitrumTestnet: false,
});
const [localConfig, setLocalConfig] = React.useState(
configStore.getLocalConfig()
);
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
async function resetCacheOptions() {
configStore.resetLocalConfig();
setLocalConfig(configStore.getLocalConfig());
setBuildingCacheState(0);
setResetCache({
mainnet: false,
rinkeby: false,
xdai: false,
arbitrum: false,
arbitrumTestnet: false,
});
setUpdatedCacheHash({
proposalTitles: {},
configHashes: {},
configs: {},
caches: {},
});
setUpdateProposalTitles(false);
}
async function uploadToIPFS(content) {
ipfsService.upload(content);
}
async function runCacheScript() {
setBuildingCacheState(1);
const updatedCache = await cacheService.getUpdatedCacheConfig(
{
1: {
rpcUrl: localConfig.mainnet_rpcURL,
toBlock: localConfig.mainnet_toBlock,
reset: resetCache.mainnet,
},
4: {
rpcUrl: localConfig.rinkeby_rpcURL,
toBlock: localConfig.rinkeby_toBlock,
reset: resetCache.rinkeby,
},
100: {
rpcUrl: localConfig.xdai_rpcURL,
toBlock: localConfig.xdai_toBlock,
reset: resetCache.xdai,
},
42161: {
rpcUrl: localConfig.arbitrum_rpcURL,
toBlock: localConfig.arbitrum_toBlock,
reset: resetCache.arbitrum,
},
421611: {
rpcUrl: localConfig.arbitrumTestnet_rpcURL,
toBlock: localConfig.arbitrumTestnet_toBlock,
reset: resetCache.arbitrumTestnet,
},
},
updateProposalTitles
);
console.log('[Updated Cache]', updatedCache);
setUpdatedCacheHash(updatedCache);
setBuildingCacheState(2);
forceUpdate();
}
function onApiKeyValueChange(value, key) {
localConfig[key] = value;
setLocalConfig(localConfig);
configStore.setLocalConfig(localConfig);
forceUpdate();
}
function downloadAll() {
var zip = new JSZip();
var cache = zip.folder('cache');
var configs = zip.folder('configs');
zip.file(
'default.json',
JSON.stringify(
{
mainnet: updatedCacheHash.configHashes['mainnet'],
xdai: updatedCacheHash.configHashes['xdai'],
arbitrum: updatedCacheHash.configHashes['arbitrum'],
rinkeby: updatedCacheHash.configHashes['rinkeby'],
arbitrumTestnet: updatedCacheHash.configHashes['arbitrumTestnet'],
},
null,
2
)
);
zip.file(
'proposalTitles.json',
JSON.stringify(updatedCacheHash.proposalTitles, null, 2)
);
NETWORKS.map((network, i) => {
cache.file(
network.name + '.json',
JSON.stringify(updatedCacheHash.caches[network.name], null, 2)
);
const configFolder = configs.folder(network.name);
configFolder.file(
'config.json',
JSON.stringify(updatedCacheHash.configs[network.name], null, 2)
);
});
zip.generateAsync({ type: 'blob' }).then(function (content) {
saveAs(content, 'dxvote-cache.zip');
});
}
if (window.location.hash.length > 7) {
const searchParams = new URLSearchParams(window.location.hash.substring(7));
setUpdateProposalTitles(searchParams.get('proposalTitles') ? true : false);
NETWORKS.map((network, i) => {
const networkName = network.name;
if (searchParams.get(networkName + '_toBlock'))
localConfig[networkName + '_toBlock'] = searchParams.get(
networkName + '_toBlock'
);
if (searchParams.get(networkName + '_targetHash'))
localConfig[networkName + '_targetHash'] = searchParams.get(
networkName + '_targetHash'
);
if (searchParams.get(networkName + '_reset')) {
resetCache[networkName] = true;
}
});
setLocalConfig(localConfig);
setResetCache(resetCache);
configStore.setLocalConfig(localConfig);
window.location.assign(window.location.origin + '/#cache');
forceUpdate();
}
function getOptionsLink(): string {
let optionsLinkUrl =
window.location.origin + '/' + window.location.hash + '?';
if (updateProposalTitles)
optionsLinkUrl = optionsLinkUrl = 'proposalTitles=1&';
NETWORKS.map((network, i) => {
const networkName = network.name;
if (localConfig[networkName + '_toBlock'])
optionsLinkUrl =
optionsLinkUrl +
networkName +
'_toBlock=' +
localConfig[networkName + '_toBlock'] +
'&';
if (localConfig[networkName + '_targetHash'])
optionsLinkUrl =
optionsLinkUrl +
networkName +
'_targetHash=' +
localConfig[networkName + '_targetHash'] +
'&';
if (resetCache[networkName])
optionsLinkUrl = optionsLinkUrl + networkName + '_reset=1&';
});
optionsLinkUrl = optionsLinkUrl.slice(0, -1);
return optionsLinkUrl;
}
return buildingCacheState === 1 ? (
<LoadingBox>
<div className="loader">
{' '}
<PulsingIcon size={80} inactive={false} />
<LoadingProgressText>
{notificationStore.globalMessage}
</LoadingProgressText>
</div>
</LoadingBox>
) : (
<Box>
<FormContainer>
{NETWORKS.map((network, i) => {
const networkName = network.name;
return (
networkName !== 'localhost' && (
<div key={`networkOptions${i}`}>
<RowAlignedLeft>
{' '}
<strong>{toCamelCaseString(networkName)}</strong>{' '}
</RowAlignedLeft>
<RowAlignedLeft>
<FormLabel>Block:</FormLabel>
<InputBox
type="text"
onChange={event =>
onApiKeyValueChange(
event.target.value,
networkName + '_toBlock'
)
}
value={localConfig[networkName + '_toBlock']}
style={{ width: '100px' }}
></InputBox>
<FormLabel>RPC:</FormLabel>
<InputBox
type="text"
onChange={event =>
onApiKeyValueChange(
event.target.value,
networkName + '_rpcURL'
)
}
value={localConfig[networkName + '_rpcURL']}
style={{ width: '100%' }}
></InputBox>
<FormLabel>Reset</FormLabel>
<InputBox
type="checkbox"
checked={resetCache[networkName]}
onChange={() => {
resetCache[networkName] = !resetCache[networkName];
setResetCache(resetCache);
forceUpdate();
}}
></InputBox>
</RowAlignedLeft>
<RowAlignedLeft>
<FormLabel>Target Config Hash:</FormLabel>
<InputBox
type="text"
onChange={event =>
onApiKeyValueChange(
event.target.value,
networkName + '_targetHash'
)
}
value={localConfig[networkName + '_targetHash']}
style={{ width: '400px' }}
></InputBox>
{updatedCacheHash.configs[networkName] && (
<div>
<Button
onClick={() =>
uploadToIPFS(
JSON.stringify(
updatedCacheHash.configs[networkName],
null,
2
)
)
}
>
<FiUpload></FiUpload> Config
</Button>
<Button
onClick={() =>
uploadToIPFS(
JSON.stringify(
updatedCacheHash.caches[networkName],
null,
2
)
)
}
>
<FiUpload></FiUpload> Cache
</Button>
</div>
)}
</RowAlignedLeft>
{updatedCacheHash.configs[networkName] && (
<RowAlignedLeft>
Received Config Hash:{' '}
{updatedCacheHash.configHashes[networkName]}
{' '}
<FormLabel>
{updatedCacheHash.configHashes[networkName] ==
localConfig[networkName + '_targetHash'] ? (
<FiCheckCircle />
) : (
<FiX />
)}
</FormLabel>
</RowAlignedLeft>
)}
</div>
)
);
})}
</FormContainer>
<Row style={{ justifyContent: 'left' }}>
<FormLabel>Update Proposal Titles</FormLabel>
<InputBox
type="checkbox"
checked={updateProposalTitles}
onChange={() => setUpdateProposalTitles(!updateProposalTitles)}
></InputBox>
</Row>
{buildingCacheState === 2 && (
<Row>
<Button onClick={downloadAll}>
{' '}
<FiDownload></FiDownload> Download All
</Button>
</Row>
)}
<Row>
<Button onClick={runCacheScript}>Build Cache</Button>
<Button onClick={resetCacheOptions}>Reset Options</Button>
<CopyButton>
<Copy toCopy={getOptionsLink()}>Build Link</Copy>
</CopyButton>
</Row>
</Box>
);
})
Example #18
Source File: Upload.tsx From tobira with Apache License 2.0 | 4 votes |
UploadMain: React.FC = () => {
// TODO: on first mount, send an `ocRequest` to `info/me.json` and make sure
// that connection works. That way we can show an error very early, before
// the user selected a file.
const { t } = useTranslation();
const relayEnv = useRelayEnvironment();
const [files, setFiles] = useState<FileList | null>(null);
const [uploadState, setUploadState] = useRefState<UploadState | null>(null);
const [metadata, setMetadata] = useRefState<Metadata | null>(null);
const progressHistory = useRef<ProgressHistory>([]);
useNavBlocker(() => !!uploadState.current && uploadState.current.state !== "done");
// Get user info
const user = useUser();
if (user === "none" || user === "unknown") {
// TODO: if not logged in, suggest doing so
return <div css={{ textAlign: "center" }}>
<ErrorBox>{t("upload.not-authorized")}</ErrorBox>
</div>;
}
/** Called when the files are selected. Starts uploading those files. */
const onFileSelect = async (files: FileList) => {
setFiles(files);
const onProgressCallback = (progress: Progress): void => {
if (uploadState.current === null) {
return unreachable("no upload state after calling `startUpload`");
}
onProgress(progress, progressHistory.current, uploadState.current, setUploadState);
};
const onDone = (mediaPackage: string) => {
if (metadata.current === null) {
setUploadState({ state: "waiting-for-metadata", mediaPackage });
} else {
finishUpload(relayEnv, mediaPackage, metadata.current, user, setUploadState);
}
};
startUpload(relayEnv, files, setUploadState, onProgressCallback, onDone);
};
if (files === null) {
return <FileSelect onSelect={onFileSelect} />;
} else if (uploadState.current === null) {
// This never happens as, when files are selected, the upload is
// instantly started and the state is set to `starting`. Check the only
// use of `setFiles` above and notice how the upload state is set
// immediately afterwards.
return unreachable("upload state is null, but there are files");
} else if (uploadState.current.state === "done") {
return <div css={{
display: "flex",
flexDirection: "column",
alignItems: "center",
marginTop: "max(16px, 10vh - 50px)",
gap: 32,
}}>
<FiCheckCircle css={{ fontSize: 64, color: "var(--happy-color-lighter)" }} />
{t("upload.finished")}
</div>;
} else {
const onMetadataSave = (metadata: Metadata): void => {
if (uploadState.current === null) {
return bug("uploadState === null on metadata save");
}
setMetadata(metadata);
if (uploadState.current.state === "waiting-for-metadata") {
// The tracks have already been uploaded, so we can finish the upload now.
const mediaPackage = uploadState.current.mediaPackage;
finishUpload(relayEnv, mediaPackage, metadata, user, setUploadState);
}
};
const hasUploadError = uploadState.current.state === "error";
return (
<div css={{
display: "flex",
flexDirection: "column",
alignItems: "stretch",
gap: 32,
width: "100%",
maxWidth: 800,
margin: "0 auto",
}}>
<UploadState state={uploadState.current} />
<div css={{ overflowY: "auto" }}>
{/* TODO: Show something after saving metadata.
- Just saying "saved" is kind of misleading because the data is only local.
- Maybe just show the form, but disable all inputs?
- ...
*/}
{!metadata.current
? <MetaDataEdit onSave={onMetadataSave} disabled={hasUploadError} />
: !hasUploadError && (
<div css={{ margin: "0 auto", maxWidth: 500 }}>
<Card kind="info">{t("upload.still-uploading")}</Card>
</div>
)
}
</div>
</div>
);
}
}
Example #19
Source File: transactions.tsx From dxvote with GNU Affero General Public License v3.0 | 4 votes |
TransactionsProvider = ({ children }) => {
const { chainId, account } = useWeb3React();
const [transactions, setTransactions] = useLocalStorage<TransactionState>(
`transactions/${account}`,
{}
);
const [pendingTransaction, setPendingTransaction] =
useState<PendingTransaction>(null);
// Get the transactions from the current chain
const allTransactions = useMemo(() => {
return transactions[chainId] ? Object.values(transactions[chainId]) : [];
}, [transactions, chainId]);
const addTransaction = (
txResponse: providers.TransactionResponse,
summary?: string
) => {
if (!txResponse.hash) return;
const transaction: Transaction = {
hash: txResponse.hash,
from: txResponse.from,
summary,
addedTime: Date.now(),
};
setTransactions(prevState => ({
...prevState,
[chainId]: {
...prevState[chainId],
[transaction.hash]: transaction,
},
}));
};
const clearAllTransactions = () => {
setTransactions(prevState => ({
...prevState,
[chainId]: {},
}));
};
const finalizeTransaction = useCallback(
(hash: string, receipt: providers.TransactionReceipt) => {
if (!transactions[chainId] || !transactions[chainId][hash]) {
return;
}
setTransactions(prevState => ({
...prevState,
[chainId]: {
...prevState[chainId],
[hash]: {
...prevState[chainId][hash],
receipt: {
transactionHash: receipt.transactionHash,
blockNumber: receipt.blockNumber,
status: receipt.status,
},
confirmedTime: Date.now(),
},
},
}));
},
[transactions, chainId, setTransactions]
);
// Mark the transactions as finalized when they are mined
const provider = useJsonRpcProvider();
useEffect(() => {
let isSubscribed = true;
allTransactions
.filter(transaction => !transaction.receipt)
.forEach(transaction => {
provider.waitForTransaction(transaction.hash).then(receipt => {
if (isSubscribed) finalizeTransaction(transaction.hash, receipt);
});
});
return () => {
isSubscribed = false;
};
}, [allTransactions, finalizeTransaction, provider]);
// Update the pending transaction notifications when finalized
useEffect(() => {
allTransactions.forEach(transaction => {
if (transaction.receipt && toast.isActive(transaction.hash)) {
if (transaction.receipt.status === 1) {
toast.update(transaction.hash, {
isLoading: false,
render: (
<TransactionOutcome
summary={transaction.summary}
chainId={chainId}
transactionHash={transaction.hash}
/>
),
icon: <FiCheckCircle />,
type: toast.TYPE.SUCCESS,
autoClose: 15000,
});
} else {
toast.update(transaction.hash, {
isLoading: false,
render: (
<TransactionOutcome
summary={transaction.summary}
chainId={chainId}
transactionHash={transaction.hash}
/>
),
icon: <FiXCircle />,
type: toast.TYPE.ERROR,
autoClose: 15000,
});
}
}
});
}, [allTransactions, chainId]);
// Trigger a new transaction request to the user wallet and track its progress
const createTransaction = async (
summary: string,
txFunction: () => Promise<providers.TransactionResponse>,
showModal: boolean = true
) => {
setPendingTransaction({
summary,
showModal,
cancelled: false,
transactionHash: null,
});
let transactionHash = null;
try {
const txResponse = await txFunction();
transactionHash = txResponse.hash;
addTransaction(txResponse, summary);
setPendingTransaction(pendingTransaction => ({
...pendingTransaction,
transactionHash,
}));
toast(<TransactionPending summary={summary} />, {
toastId: transactionHash,
autoClose: false,
isLoading: true,
});
} catch (e) {
console.error('Transaction execution failed', e);
setPendingTransaction(pendingTransaction => ({
...pendingTransaction,
cancelled: true,
}));
}
};
return (
<TransactionsContext.Provider
value={{
transactions: allTransactions,
pendingTransaction,
createTransaction,
clearAllTransactions,
}}
>
{children}
<TransactionModal
message={pendingTransaction?.summary}
transactionHash={pendingTransaction?.transactionHash}
onCancel={() => setPendingTransaction(null)}
txCancelled={pendingTransaction?.cancelled}
/>
</TransactionsContext.Provider>
);
}