add state string hooks

This commit is contained in:
plebeius.eth
2024-03-22 14:15:35 +01:00
parent 08458c0c93
commit 1a97ab7657
2 changed files with 166 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
import { useMemo } from 'react';
import useStateString from './use-state-string';
import { useSubplebbit, useSubplebbitsStates } from '@plebbit/plebbit-react-hooks';
const clientHosts: { [key: string]: string } = {};
const getClientHost = (clientUrl: string): string => {
if (!clientHosts[clientUrl]) {
try {
clientHosts[clientUrl] = new URL(clientUrl).hostname || clientUrl;
} catch (e) {
clientHosts[clientUrl] = clientUrl;
}
}
return clientHosts[clientUrl];
};
const useFeedStateString = (subplebbitAddresses?: string[]): string | undefined => {
// single subplebbit feed state string
const subplebbitAddress = subplebbitAddresses?.length === 1 ? subplebbitAddresses[0] : undefined;
const subplebbit = useSubplebbit({ subplebbitAddress });
const singleSubplebbitFeedStateString = useStateString(subplebbit);
// multiple subplebbit feed state string
const { states } = useSubplebbitsStates({ subplebbitAddresses });
const multipleSubplebbitsFeedStateString = useMemo(() => {
if (subplebbitAddress) {
return;
}
// e.g. Resolving 2 addresses from infura.io, fetching 2 IPNS, 1 IPFS from cloudflare-ipfs.com, ipfs.io
let stateString = '';
if (states['resolving-address']) {
const { subplebbitAddresses, clientUrls } = states['resolving-address'];
if (subplebbitAddresses.length && clientUrls.length) {
stateString += `resolving ${subplebbitAddresses.length} ${subplebbitAddresses.length === 1 ? 'address' : 'addresses'} from ${clientUrls
.map(getClientHost)
.join(', ')}`;
}
}
// find all page client and sub addresses
const pagesStatesClientHosts = new Set();
const pagesStatesSubplebbitAddresses = new Set();
for (const state in states) {
if (state.match('page')) {
states[state].clientUrls.forEach((clientUrl) => pagesStatesClientHosts.add(getClientHost(clientUrl)));
states[state].subplebbitAddresses.forEach((subplebbitAddress) => pagesStatesSubplebbitAddresses.add(subplebbitAddress));
}
}
if (states['fetching-ipns'] || states['fetching-ipfs'] || pagesStatesSubplebbitAddresses.size) {
// separate 2 different states using ', '
if (stateString) {
stateString += ', ';
}
// find all client urls
const clientHosts = new Set([...pagesStatesClientHosts]);
states['fetching-ipns']?.clientUrls.forEach((clientUrl) => clientHosts.add(getClientHost(clientUrl)));
states['fetching-ipfs']?.clientUrls.forEach((clientUrl) => clientHosts.add(getClientHost(clientUrl)));
if (clientHosts.size) {
stateString += 'fetching ';
if (states['fetching-ipns']) {
stateString += `${states['fetching-ipns'].subplebbitAddresses.length} IPNS`;
}
if (states['fetching-ipfs']) {
if (states['fetching-ipns']) {
stateString += ', ';
}
stateString += `${states['fetching-ipfs'].subplebbitAddresses.length} IPFS`;
}
if (pagesStatesSubplebbitAddresses.size) {
if (states['fetching-ipns'] || states['fetching-ipfs']) {
stateString += ', ';
}
stateString += `${pagesStatesSubplebbitAddresses.size} ${pagesStatesSubplebbitAddresses.size === 1 ? 'page' : 'pages'}`;
}
stateString += ` from ${[...clientHosts].join(', ')}`;
}
}
// capitalize first letter
stateString = stateString.charAt(0).toUpperCase() + stateString.slice(1);
// if string is empty, return undefined instead
return stateString === '' ? undefined : stateString;
}, [states, subplebbitAddress]);
if (singleSubplebbitFeedStateString) {
return singleSubplebbitFeedStateString;
}
return multipleSubplebbitsFeedStateString;
};
export default useFeedStateString;
+67
View File
@@ -0,0 +1,67 @@
import { useMemo } from 'react';
import { useClientsStates } from '@plebbit/plebbit-react-hooks';
interface CommentOrSubplebbit {
state?: string;
publishingState?: string;
updatingState?: string;
}
interface States {
[key: string]: string[];
}
const clientHosts: { [key: string]: string } = {};
const getClientHost = (clientUrl: string): string => {
if (!clientHosts[clientUrl]) {
try {
clientHosts[clientUrl] = new URL(clientUrl).hostname || clientUrl;
} catch (e) {
clientHosts[clientUrl] = clientUrl;
}
}
return clientHosts[clientUrl];
};
const useStateString = (commentOrSubplebbit: CommentOrSubplebbit): string | undefined => {
const { states } = useClientsStates({ comment: commentOrSubplebbit }) as { states: States };
return useMemo(() => {
let stateString: string | undefined = '';
for (const state in states) {
const clientUrls = states[state];
const clientHosts = clientUrls.map((clientUrl) => getClientHost(clientUrl));
if (clientHosts.length === 0) {
continue;
}
if (stateString) {
stateString += ', ';
}
const formattedState = state.replaceAll('-', ' ').replace('ipfs', 'IPFS').replace('ipns', 'IPNS');
stateString += `${formattedState} from ${clientHosts.join(', ')}`;
}
if (!stateString && commentOrSubplebbit?.state !== 'succeeded') {
if (commentOrSubplebbit?.publishingState && commentOrSubplebbit?.publishingState !== 'stopped' && commentOrSubplebbit?.publishingState !== 'succeeded') {
stateString = commentOrSubplebbit.publishingState;
} else if (commentOrSubplebbit?.updatingState !== 'stopped' && commentOrSubplebbit?.updatingState !== 'succeeded') {
stateString = commentOrSubplebbit.updatingState;
}
if (stateString) {
stateString = stateString.replaceAll('-', ' ').replace('ipfs', 'IPFS').replace('ipns', 'IPNS');
}
}
if (stateString) {
stateString = stateString.charAt(0).toUpperCase() + stateString.slice(1);
}
return stateString === '' ? undefined : stateString;
}, [states, commentOrSubplebbit]);
};
export default useStateString;