/ src / hooks / use-feed-state-string.ts
use-feed-state-string.ts
 1  import { useMemo } from 'react';
 2  import useStateString from './use-state-string';
 3  import { useSubplebbit, useSubplebbitsStates } from '@plebbit/plebbit-react-hooks';
 4  
 5  const clientHosts: { [key: string]: string } = {};
 6  
 7  const getClientHost = (clientUrl: string): string => {
 8    if (!clientHosts[clientUrl]) {
 9      try {
10        clientHosts[clientUrl] = new URL(clientUrl).hostname || clientUrl;
11      } catch (e) {
12        clientHosts[clientUrl] = clientUrl;
13      }
14    }
15    return clientHosts[clientUrl];
16  };
17  
18  const useFeedStateString = (subplebbitAddresses?: string[]): string | undefined => {
19    // single subplebbit feed state string
20    const subplebbitAddress = subplebbitAddresses?.length === 1 ? subplebbitAddresses[0] : undefined;
21    const subplebbit = useSubplebbit({ subplebbitAddress });
22    const singleSubplebbitFeedStateString = useStateString(subplebbit);
23  
24    // multiple subplebbit feed state string
25    const { states } = useSubplebbitsStates({ subplebbitAddresses });
26  
27    const multipleSubplebbitsFeedStateString = useMemo(() => {
28      if (subplebbitAddress) {
29        return;
30      }
31  
32      // e.g. Resolving 2 addresses from infura.io, fetching 2 IPNS, 1 IPFS from cloudflare-ipfs.com, ipfs.io
33      let stateString = '';
34  
35      if (states['resolving-address']) {
36        const { subplebbitAddresses, clientUrls } = states['resolving-address'];
37        if (subplebbitAddresses.length && clientUrls.length) {
38          stateString += `resolving ${subplebbitAddresses.length} ${subplebbitAddresses.length === 1 ? 'address' : 'addresses'} from ${clientUrls
39            .map(getClientHost)
40            .join(', ')}`;
41        }
42      }
43  
44      // find all page client and sub addresses
45      const pagesStatesClientHosts = new Set();
46      const pagesStatesSubplebbitAddresses = new Set();
47      for (const state in states) {
48        if (state.match('page')) {
49          states[state].clientUrls.forEach((clientUrl) => pagesStatesClientHosts.add(getClientHost(clientUrl)));
50          states[state].subplebbitAddresses.forEach((subplebbitAddress) => pagesStatesSubplebbitAddresses.add(subplebbitAddress));
51        }
52      }
53  
54      if (states['fetching-ipns'] || states['fetching-ipfs'] || pagesStatesSubplebbitAddresses.size) {
55        // separate 2 different states using ', '
56        if (stateString) {
57          stateString += ', ';
58        }
59  
60        // find all client urls
61        const clientHosts = new Set([...pagesStatesClientHosts]);
62        states['fetching-ipns']?.clientUrls.forEach((clientUrl) => clientHosts.add(getClientHost(clientUrl)));
63        states['fetching-ipfs']?.clientUrls.forEach((clientUrl) => clientHosts.add(getClientHost(clientUrl)));
64  
65        if (clientHosts.size) {
66          stateString += 'fetching ';
67          if (states['fetching-ipns']) {
68            stateString += `${states['fetching-ipns'].subplebbitAddresses.length} IPNS`;
69          }
70          if (states['fetching-ipfs']) {
71            if (states['fetching-ipns']) {
72              stateString += ', ';
73            }
74            stateString += `${states['fetching-ipfs'].subplebbitAddresses.length} IPFS`;
75          }
76          if (pagesStatesSubplebbitAddresses.size) {
77            if (states['fetching-ipns'] || states['fetching-ipfs']) {
78              stateString += ', ';
79            }
80            stateString += `${pagesStatesSubplebbitAddresses.size} ${pagesStatesSubplebbitAddresses.size === 1 ? 'page' : 'pages'}`;
81          }
82          stateString += ` from ${[...clientHosts].join(', ')}`;
83        }
84      }
85  
86      // capitalize first letter
87      stateString = stateString.charAt(0).toUpperCase() + stateString.slice(1);
88  
89      // if string is empty, return undefined instead
90      return stateString === '' ? undefined : stateString;
91    }, [states, subplebbitAddress]);
92  
93    if (singleSubplebbitFeedStateString) {
94      return singleSubplebbitFeedStateString;
95    }
96    return multipleSubplebbitsFeedStateString;
97  };
98  
99  export default useFeedStateString;