Skip to content

Commit

Permalink
Merge pull request #593 from api3dao/main
Browse files Browse the repository at this point in the history
Initiate release
  • Loading branch information
hiletmis authored Feb 27, 2025
2 parents 90e7960 + c1f5efc commit fb5b8a4
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/wet-cities-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@api3/logos': minor
---

Adds dApp support
36 changes: 29 additions & 7 deletions helpers/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs/promises');
const { rename } = require('fs');
const { getChains, dapis } = require('@api3/dapi-management');
const { getChains, dapis, api3Contracts } = require('@api3/dapi-management');

module.exports = {
sanitizeName,
Expand All @@ -15,9 +15,15 @@ module.exports = {
getSupportedChains,
getApiProviders,
getSupportedFeeds,
toPascalCase
getDapps,
toPascalCase,
isStringMatch
};

function getDapps() {
return api3Contracts.DAPPS.map((dapp) => dapp.alias);
}

function getApiProviders() {
const providers = [...new Set(dapis.map((dapi) => dapi.providers).flat())];
const filteredApiProviders = providers.filter((api) => !api.match(/(.*)(-mock)/));
Expand All @@ -43,8 +49,10 @@ function getSupportList(mode) {
return getSupportedFeeds();
case 'api-provider':
return getApiProviders();
case 'dapp':
return getDapps();
default:
break;
return [];
}
}

Expand All @@ -56,8 +64,10 @@ function getManualLogos(mode) {
return [];
case 'api-provider':
return [];
case 'dapp':
return [];
default:
break;
return [];
}
}

Expand All @@ -79,14 +89,24 @@ function sanitizeName(name, suffix = '', prefix = '') {
return prefix + componentName + suffix;
}

function generateSwitchCase(array, prefix) {
function isStringMatch(val1, val2) {
return sanitizeName(val1).toLowerCase() === sanitizeName(val2).toLowerCase();
}

function generateSwitchCase(files, array, prefix) {
const sanitized = array.map((item) => {
return sanitizeName(item, '', '');
});

const file_prefix = prefix === 'Chain' ? 'Chain' : '';

const filtered = [...new Set(sanitized)];
return filtered
.map((item) => `case "${sanitizeName(item).toLowerCase()}":\n\treturn ${prefix}${sanitizeName(item, '')};\n`)
.map((item) => {
let filename = checkFile(files, item, file_prefix);
if (item !== 'Placeholder' && filename === 'Placeholder.svg') return '';
return `case "${sanitizeName(item).toLowerCase()}":\n\treturn ${prefix}${sanitizeName(item, '')};\n`;
})
.join('');
}

Expand All @@ -111,6 +131,7 @@ function generateImports(files, array, prefix, file_prefix, path, format) {
return filtered
.map((item) => {
let filename = checkFile(files, item, file_prefix);
if (item !== 'Placeholder' && filename === 'Placeholder.svg') return '';
return formatImport(item, filename, prefix, path, format);
})
.join('');
Expand Down Expand Up @@ -192,7 +213,8 @@ async function copySvgFiles(files, logosDir, prefix = '') {
files.forEach(async (file) => {
const isSupported =
supportList.some(
(item) => item.toLowerCase() === file.replace('.svg', '').replace('Chain', '').toLowerCase()
(item) =>
sanitizeName(item).toLowerCase() === file.replace('.svg', '').replace('Chain', '').toLowerCase()
) || exceptions.some((item) => file.includes(item));
if (!isSupported) return;
await fs.copyFile(`./optimized/${prefix}/${file}`, `${logosDir}/${file}`);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"optimize-chain-logos": "rimraf ./optimized/chain & svgo -q -p 8 -f ./raw/chains -o ./optimized/chain",
"optimize-symbol-logos": "rimraf ./optimized/symbol & svgo -q -p 8 -f ./raw/symbols -o ./optimized/symbol",
"optimize-api-provider-logos": "rimraf ./optimized/api-provider & svgo -q -p 8 -f ./raw/api-providers -o ./optimized/api-provider",
"build": "pnpm run optimize-chain-logos && pnpm run optimize-symbol-logos && pnpm run optimize-api-provider-logos && node scripts/build-svg.js",
"optimize-dapp-logos": "rimraf ./optimized/dapp & svgo -q -p 8 -f ./raw/dapps -o ./optimized/dapp",
"build": "pnpm run optimize-chain-logos && pnpm run optimize-symbol-logos && pnpm run optimize-api-provider-logos && pnpm run optimize-dapp-logos && node scripts/build-svg.js",
"fetch": "node scripts/fetch-missing.js",
"version-check": "node scripts/version-check.js",
"package": "pnpm run build",
Expand Down
17 changes: 17 additions & 0 deletions raw/dapps/Placeholder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 12 additions & 8 deletions scripts/build-svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ const utils = require('../helpers/utils');

const outputPath = './dist';

const categories = ['chain', 'symbol', 'api-provider'];
const categories = ['chain', 'symbol', 'api-provider', 'dapp'];

let chainLightLogos = [];
let apiProviderLightLogos = [];
let symbolLightLogos = [];
let dappsLightLogos = [];

function getLogoList(mode) {
switch (mode) {
Expand All @@ -19,8 +20,10 @@ function getLogoList(mode) {
return [...symbolLightLogos, ...utils.getManualLogos(mode), ...utils.getSupportedFeeds()];
case 'api-provider':
return [...apiProviderLightLogos, ...utils.getManualLogos(mode), ...utils.getApiProviders()];
case 'dapp':
return [...dappsLightLogos, ...utils.getManualLogos(mode), ...utils.getDapps()];
default:
break;
return [];
}
}

Expand All @@ -41,8 +44,8 @@ async function buildLogos(format = 'esm', dir, mode, batchName) {
await fs.appendFile(`${outDir}/${batchName}Missing.json`, JSON.stringify(getMissingLogos(files, mode)), 'utf-8');
}

function buildSwitchCase(mode) {
return utils.generateSwitchCase(getLogoList(mode), utils.toPascalCase(mode));
function buildSwitchCase(files, mode) {
return utils.generateSwitchCase(files, getLogoList(mode), utils.toPascalCase(mode));
}

function buildLogoImports(files, mode, format) {
Expand All @@ -69,7 +72,7 @@ async function buildBatch(files, outDir, format = 'esm', batchName, mode) {

const imports = buildLogoImports(files, mode, format);

let code = await babelTransform(format, imports, batchName, mode);
let code = await babelTransform(files, format, imports, batchName, mode);

if (format === 'cjs') {
code = code.replace('export default', 'module.exports =');
Expand All @@ -78,11 +81,11 @@ async function buildBatch(files, outDir, format = 'esm', batchName, mode) {
await fs.writeFile(`${outDir}/${batchName}.js`, code, 'utf-8');
}

async function babelTransform(format, imports, batchName, mode) {
async function babelTransform(files, format, imports, batchName, mode) {
let { code } = await babel.transformAsync(
`
${imports}
${utils.generateFunction(batchName, buildSwitchCase(mode), mode)}`,
${utils.generateFunction(batchName, buildSwitchCase(files, mode), mode)}`,
{
presets: [['@babel/preset-react', { useBuiltIns: true }]]
}
Expand Down Expand Up @@ -111,7 +114,8 @@ async function findLightLogos() {
const [chainFiles, apiProviderFiles, symbolFiles] = await Promise.all([
fs.readdir('./optimized/chain', 'utf-8'),
fs.readdir('./optimized/api-provider', 'utf-8'),
fs.readdir('./optimized/symbol', 'utf-8')
fs.readdir('./optimized/symbol', 'utf-8'),
fs.readdir('./optimized/dapp', 'utf-8')
]);

chainLightLogos = chainFiles.filter((file) => file.includes('light')).map((file) => file.replace('Chain', ''));
Expand Down
12 changes: 6 additions & 6 deletions scripts/fetch-missing.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const fetch = require('node-fetch');

let missingLogos = [];

const categories = ['chain', 'symbol', 'api-provider'];
const categories = ['chain', 'symbol', 'api-provider', 'dapp'];

let dbx = null;

Expand Down Expand Up @@ -41,6 +41,8 @@ function getLogoList(mode) {
return [...utils.getManualLogos(mode), ...utils.getSupportedFeeds()];
case 'api-provider':
return [...utils.getManualLogos(mode), ...utils.getApiProviders()];
case 'dapp':
return [...utils.getManualLogos(mode), ...utils.getDapps()];
default:
break;
}
Expand Down Expand Up @@ -75,10 +77,8 @@ async function searchLogos() {
missingLogos.map((missingLogoCategory) => {
missingLogoCategory.logos.map((missingLogo) => {
foundLogos.map((foundLogo) => {
if (
utils.sanitizeName(foundLogo.name).toLowerCase() ===
`${utils.sanitizeName(missingLogo).toLowerCase()}`
) {
const isCategoryMatch = foundLogo.path_lower.includes(missingLogoCategory.category);
if (utils.isStringMatch(foundLogo.name, missingLogo) && isCategoryMatch) {
downloadLogos(missingLogoCategory.category, foundLogo);
}
});
Expand All @@ -93,7 +93,7 @@ async function searchLogos() {
async function fetchLogos() {
const dbx = await getDropbox();
try {
const response = await dbx.filesListFolder({ path: '', recursive: true });
const response = await dbx.filesListFolder({ path: '', recursive: true, limit: 1000 });
return response.result.entries;
} catch (error) {
console.error(error);
Expand Down
4 changes: 3 additions & 1 deletion scripts/version-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const dropbox = require('dropbox');
const fetch = require('node-fetch');
const crypto = require('crypto');

const categories = ['chain', 'symbol', 'api-provider'];
const categories = ['chain', 'symbol', 'api-provider', 'dapp'];

let dbx = null;

Expand Down Expand Up @@ -39,6 +39,8 @@ function getLogoList(mode) {
return [...utils.getManualLogos(mode), ...utils.getSupportedFeeds()];
case 'api-provider':
return [...utils.getManualLogos(mode), ...utils.getApiProviders()];
case 'dapp':
return [...utils.getManualLogos(mode), ...utils.getDapps()];
default:
break;
}
Expand Down
17 changes: 10 additions & 7 deletions viewer/src/Components/ChainsView.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import { useState } from 'react';
import Title from '../Custom/Title';
import InfoView from '../Custom/InfoView';

const getSupportedChains = (isTestnet) => {
const getSupportedChains = (isTestnet, searchArg) => {
const supportedChainIds = getChains()
.filter((chain) => chain.stage !== 'retired')
.filter((chain) =>
searchArg ? chain.alias.includes(searchArg.toLowerCase()) || chain.id.includes(searchArg) : true
)
.map((chain) => chain.id);
return api3Contracts.CHAINS.filter((chain) => supportedChainIds.includes(chain.id) && chain.testnet === isTestnet);
};

const ChainList = ({ isTestnet, chain }) => {
const ChainList = ({ isTestnet, searchArg }) => {
const [selectedChain, setSelectedChain] = useState('');

return getSupportedChains(isTestnet).map((chain, index) => {
return getSupportedChains(isTestnet, searchArg).map((chain, index) => {
return (
<Flex
p={3}
Expand Down Expand Up @@ -51,7 +54,7 @@ const ChainList = ({ isTestnet, chain }) => {
};

const ChainsView = () => {
const [chain, setChain] = useState('');
const [searchArg, setSearchArg] = useState('');

return (
<Flex p={3} gap={3} bgColor={'white'} wrap={'wrap'} alignItems="center" justifyContent="center">
Expand All @@ -61,11 +64,11 @@ const ChainsView = () => {
{getSupportedChains(true).length} testnet chains
</Text>
</Flex>
<SearchRow text={chain} setText={setChain} placeholder={'Enter a chain'} />
<SearchRow text={searchArg} setText={setSearchArg} placeholder={'Enter a chain id or chain name'} />
<Title header={'Mainnets'} />
<ChainList isTestnet={false} chain={chain} />
<ChainList isTestnet={false} searchArg={searchArg} />
<Title header={'Testnets'} />
<ChainList isTestnet={true} chain={chain} />
<ChainList isTestnet={true} searchArg={searchArg} />
</Flex>
);
};
Expand Down
66 changes: 66 additions & 0 deletions viewer/src/Components/DappView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Flex, Text, Image } from '@chakra-ui/react';
import { DappLogo } from '@api3/logos';
import SearchRow from '../Custom/SearchRow';
import { useState } from 'react';
import InfoView from '../Custom/InfoView';
import { api3Contracts } from '@api3/dapi-management';

const DappView = () => {
const [searchArg, setSearchArg] = useState('');
const [selectedDapp, setSelectedDapp] = useState('');

const getDapps = () => {
const dapps = [...new Set(api3Contracts.DAPPS)];
return dapps.filter((dapp) => dapp.name.toLowerCase().includes(searchArg.toLowerCase()));
};

return (
<Flex p={3} gap={3} bgColor={'white'} wrap={'wrap'} alignItems="center" justifyContent="center">
<Flex width={'100%'}>
<Text fontSize="md" fontWeight="bold" ml={2}>
There is a total of {getDapps().length} dapps
</Text>
</Flex>
<SearchRow text={searchArg} setText={setSearchArg} placeholder={'Enter a dapp name'} />

{getDapps().map((dapp, index) => {
return (
<Flex
p={3}
boxShadow={'md'}
width={'310px'}
height={'80px'}
bgColor={'gray.100'}
key={index}
alignItems="center"
justifyContent="left"
onMouseDown={() => setSelectedDapp(dapp.alias)}
cursor={'pointer'}
>
{selectedDapp !== dapp.alias ? (
<>
<Image src={DappLogo(dapp.alias)} width={50} height={50} bgColor={'white'} p={2} />
<Image
src={DappLogo(dapp.alias, true)}
width={50}
height={50}
bgColor={'black'}
p={2}
/>
<Text fontSize="md" fontWeight="bold" ml={2}>
{dapp.name}
</Text>
</>
) : (
<>
<InfoView method={'Dapp'} feed={dapp.alias} onExit={() => selectedDapp(null)} />
</>
)}
</Flex>
);
})}
</Flex>
);
};

export default DappView;
2 changes: 2 additions & 0 deletions viewer/src/Components/Welcome.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import SymbolsView from './SymbolsView';
import ChainsView from './ChainsView';
import ApiProviderView from './ApiProviderView';
import DappView from './DappView';
import MissingLogosView from './MissingLogosView';
import Docs from './Docs';
import { VStack } from '@chakra-ui/react';
Expand All @@ -21,6 +22,7 @@ const Welcome = () => {
<ExpandableView header={'Symbols'} view={<SymbolsView />} />
<ExpandableView header={'Chains'} view={<ChainsView />} />
<ExpandableView header={'ApiProviders'} view={<ApiProviderView />} />
<ExpandableView header={'Dapps'} view={<DappView />} />
<ExpandableView header={'Missing Logos'} view={<MissingLogosView />} />
<ExpandableView header={'How to use'} view={<Docs />} />
</VStack>
Expand Down

0 comments on commit fb5b8a4

Please sign in to comment.